k2gl/pragmatic-franken

GitHub: k2gl/pragmatic-franken

基于 FrankenPHP 与 Symfony 8 的生产级 PHP 起步模板,采用垂直切片+CQRS 架构,集成生产镜像、CI 验证和 AI agent 协作支持。

Stars: 3 | Forks: 1

# 实用 FrankenPHP [![CI](https://img.shields.io/github/actions/workflow/status/k2gl/pragmatic-franken/ci.yml?branch=main&label=CI&logo=github)](https://github.com/k2gl/pragmatic-franken/actions/workflows/ci.yml) [![最新稳定版本](https://img.shields.io/packagist/v/k2gl/pragmatic-franken?logo=packagist&logoColor=white)](https://packagist.org/packages/k2gl/pragmatic-franken) [![PHP 8.5](https://img.shields.io/badge/PHP-8.5-777bb4?logo=php&logoColor=white)](https://www.php.net/releases/8.5/) [![FrankenPHP 1.x](https://img.shields.io/badge/FrankenPHP-1.x-006b5b?logo=docker&logoColor=white)](https://frankenphp.dev/) [![Symfony 8](https://img.shields.io/badge/Symfony-8-000000?logo=symfony&logoColor=white)](https://symfony.com/) [![PHPStan Level 10](https://img.shields.io/badge/PHPStan-Level%2010-2a5ea7?logo=php&logoColor=white)](https://phpstan.org) [![许可证](https://img.shields.io/packagist/l/k2gl/pragmatic-franken?color=yellowgreen)](https://packagist.org/packages/k2gl/pragmatic-franken) **实用 FrankenPHP** 是一个基于 PHP 8.5 / Symfony 8 / FrankenPHP 的起步模板,它脱胎于 真实的Production项目——并且将经验与教训反哺于此。它基于 Messenger 实现了垂直切片 + CQRS,采用 PostgreSQL 17,支持 worker 模式,提供真实的 Production镜像以及供应链证明。目标是:复刻它并在第一天就交付真实的 产品,由人类和 AI agent 共同运营。 **这些承诺均由 CI 验证,绝非空口无凭:** - **Production镜像**会在每次 PR 时启动(`prod-image` 作业:构建 → 运行 → `/ready`); - **脚手架生成的代码无需修改即可通过 PHPStan 10 + 测试**(`agent-smoke` 作业); - 发布的镜像携带 **SLSA 构建来源证明**,并且部署门禁会对其进行校验(ADR-0014); - 文档经过了**基于现实的校验**(`make docs-check`:路由、Makefile 目标、ADR 同步)。 有关架构规则和代码层面的指导,请参阅 **[AGENTS.md](AGENTS.md)** —— 这是唯一的真理来源,不超过 2 000 个 token,对开发者和 AI 工具同样适用。 ## 技术栈 | 层级 | 选择 | 原因 | |---|---|---| | 应用服务器 | FrankenPHP 1.x (Caddy + worker 模式) | 单一二进制文件,HTTP/3,保持内核常驻 | | 框架 | Symfony 8.0 | 成熟,基于 attribute 的装配 | | 总线 | Symfony Messenger (CQRS) | 同步 command/query,异步事件 | | 数据库 | PostgreSQL 17 | Doctrine ORM 3 | | 队列 | 基于 Doctrine transport 的 Messenger | 无需额外扩展,可审查,经过Production验证 | | 缓存 | Redis 7 (Predis) | 随时可用于缓存和自定义需求 | | 前端(默认) | AssetMapper + Twig | HTML 优先,无需 Webpack/Vite | | 代码风格 | Laravel Pint (PSR-12) | 一键自动修复 | | 静态分析 | PHPStan level 10 | 在 CI 中强制执行 | | 测试 | PHPUnit 12 + Zenstruck (Foundry, Browser, Messenger-Test) + DAMA + Faker + Fluent Assertions | 测试金字塔 60/30/10 | ## 快速开始 **路径 1 — 模板 + Docker**(只需要 Docker): ``` gh repo create my-app --template k2gl/pragmatic-franken --clone && cd my-app # 或:git clone https://github.com/k2gl/pragmatic-franken.git my-app make install # env, containers, deps, migrations make init name=my-app # rename + real secrets (optionally: prune=1 reset-git=1) make smoke # bin/console + /ready ``` **路径 2 — composer create-project**(宿主机需要 PHP ≥ 8.5): ``` composer create-project k2gl/pragmatic-franken my-app cd my-app && make install && make init name=my-app ``` 应用将通过 `https://my-app.localhost:${HTTPS_PORT:-4750}` 启动(浏览器 会自动解析 `*.localhost` —— 无需修改 `/etc/hosts`)。尝试以下示例 API:`POST /tasks`、`GET /tasks`、`POST /tasks/{id}/complete` —— 完成操作 会通过 Mercure 在 `/tasks` 推送实时更新。 ## 为什么不直接用 symfony/skeleton? | | **pragmatic-franken** | symfony/skeleton | dunglas/symfony-docker | API Platform | |---|---|---|---|---| | 架构理念 | 垂直切片 + CQRS,18 项 ADR | 无 | 无 | API 优先框架 | | Production镜像 | 每次 PR 都会构建、启动并扫描 | — | 会构建 | 会构建 | | 真实的垂直示例 | entity → migration → factory → tests | — | — | 生成的 CRUD | | 部署方案 | VDS 上的蓝绿部署 + 备份 + DR 演练 | — | — | k8s helm | | 供应链 | 来源证明 + 离线验证器 + 门禁 | — | — | — | | Agent 支持 | AGENTS.md(≤2k token)+ 经 CI 验证的脚手架 | — | — | — | | 最适用于 | 在单台 VDS 上运行且由 agent 参与流程的产品 API/应用 | 需要原生框架 | 需要原生 Docker | 你的产品本身就*是* API | 坦诚的非目标:核心不包含 auth(使用 recipe 替代),不捆绑 SPA,不包含 Kubernetes,不采用多数据库。 ## 日常命令 | 命令 | 效果 | |---|---| | `make up` / `make down` | 启动 / 停止容器 | | `make shell` (别名 `make e`) | 在应用容器内开启 shell | | `make test` | 运行 PHPUnit,快速失败 | | `make check` | Pint + PHPStan(pre-commit 门禁) | | `make ci` | lint-check + 分析 + 测试(CI 一致性) | | `make smoke` | 端到端冒烟测试 | | `make slice context=Foo feature=Bar` | 搭建垂直切片脚手架 | | `make adr title="My Decision"` | 搭建新的 ADR 脚手架 | | `make docs-check` | 根据现实校验文档(路由、目标、预算) | | `make agent-smoke` | 证明生成的脚手架代码无需修改即可通过所有门禁 | | `make db-seed` | 演示数据(`app:seed`) | ## 项目布局 ``` src/ # application code Kernel.php # App\Kernel (Symfony MicroKernel) SharedKernel/ # cross-context infra (repository base, problem+json listeners) Context/{Name}/ # bounded contexts: Entity/, Repository/, Features/{Feature}/ Health/Features/Healthz/ # reference slice (JSON, /healthz + /ready) Home/Features/Index/ # reference slice (Twig + AssetMapper, /) config/ bin/ public/ assets/ # standard Symfony layout migrations/ # Doctrine migrations docs/ # ADRs and guides (Tier 2) adr/ # ADRs with YAML front-matter guides/ # development, testing, worker-mode, … dev/ # codegen helpers (create-slice, new-adr, check-docs) ops/ # deployment scripts tests/ # mirrors src/ — tests/Context/{Name}/Features/{Feature}/ docker/ # Dockerfile, Caddyfile, php.ini AGENTS.md # Tier-1 agent context, ≤ 2 000 tokens ``` 示例切片(`Health/Healthz`、`Home/Index`、`Task`)是参考实现 —— `Healthz` 是 ADR-0005 健康检查的规范,`Task` 是完整的 entity → migration → factory → tests 垂直切片的规范;`Home/Index` 是非规范性的(对于纯 API 或 SPA 项目可以将其删除)。 ## 架构决策 所有决策都存放在 [`docs/adr/`](docs/adr/) 中。每个 ADR 都带有 YAML front-matter(`status`、`date`、`audience`、`summary`),以便 agent 无需加载全部内容即可快速浏览。 | ADR | 主题 | 状态 | |---|---|---| | [0001](docs/adr/0001-vertical-slices.md) | 垂直切片 | 已接受 | | [0002](docs/adr/0002-messenger-transport.md) | Messenger Transport | 已接受 | | [0003](docs/adr/0003-pragmatic-symfony-architecture.md) | 实用主义宪章 | 已接受 | | [0004](docs/adr/0004-frankenphp-runtime.md) | FrankenPHP Runtime | 已接受 | | [0005](docs/adr/0005-health-checks.md) | 健康检查 | 已接受 | | [0006](docs/adr/0006-memory-management.md) | 内存管理 | 已接受 | | [0007](docs/adr/0007-asset-mapper.md) | AssetMapper | 已接受 | | [0008](docs/adr/0008-testing-strategy.md) | 测试策略 | 已接受 | | [0009](docs/adr/0009-shared-architecture.md) | 共享架构 | 已接受 | | [0010](docs/adr/0010-documentation-and-ai-layout.md) | 文档与 AI 布局 | 已接受 | | [0011](docs/adr/0011-event-sourcing-lite.md) | 事件溯源精简版 | 已接受 | | [0012](docs/adr/0012-ubiquitous-language.md) | 统一语言与实体放置 | 已接受 | | [0013](docs/adr/0013-doctrine-repository-pattern.md) | Doctrine Repository 模式 | 已接受 | | [0014](docs/adr/0014-supply-chain-security.md) | 供应链安全 | 已接受 | | [0015](docs/adr/0015-scheduler-and-periodic-tasks.md) | 调度器与定期任务 | 已接受 | | [0016](docs/adr/0016-http-response-contract.md) | HTTP 响应契约 | 已接受 | | [0017](docs/adr/0017-parallel-agent-sessions.md) | 并行 Agent 会话 | 已接受 | | [0018](docs/adr/0018-input-validation-and-invariants.md) | 输入校验与领域不变式 | 已接受 | ## 指南 - [`docs/guides/development.md`](docs/guides/development.md) — 日常命令,切片脚手架详情 - [`docs/guides/testing.md`](docs/guides/testing.md) — 具体的 PHPUnit + Foundry + Messenger-Test 模式 - [`docs/guides/worker-mode.md`](docs/guides/worker-mode.md) — 调试 FrankenPHP worker 行为 - [`docs/guides/mercure-integration.md`](docs/guides/mercure-integration.md) — 通过 FrankenPHP 内置的 Mercure hub 实现实时 SSE - [`docs/guides/sdk-generation.md`](docs/guides/sdk-generation.md) — 从 PHP Result DTO 自动生成 TypeScript 类型 - [`docs/guides/deployment.md`](docs/guides/deployment.md) — 单 VDS 拓扑结构,零停机部署 - [`docs/guides/disaster-recovery.md`](docs/guides/disaster-recovery.md) — 备份与恢复演练 - [`docs/guides/parallel-sessions.md`](docs/guides/parallel-sessions.md) — 为并行 agent 提供隔离的 worktree 堆栈 - [`docs/guides/supply-chain.md`](docs/guides/supply-chain.md) — 签名发布,部署前验证 ## 配方(可选功能) 已在基于此骨架成长起来的真实Production项目中得到验证,以文档形式提供而非 直接捆绑:[JWT 认证](docs/recipes/jwt-auth.md) · [功能开关](docs/recipes/feature-flags.md) · [SPA 前端](docs/recipes/spa-frontend.md) · [预览环境](docs/recipes/preview-environments.md)。 ## 紧跟模板 复刻的分支不会直接合并模板 —— 它们只应用变更。每次发布都会附带一个 [`UPGRADE.md`](UPGRADE.md) 条目,其中包含少数值得移植的更改;请参阅 [`docs/guides/fork-maintenance.md`](docs/guides/fork-maintenance.md)。 ## AI agent 该仓库在根目录附带了一个 `AGENTS.md` 文件,按照约定,旨在供每个 AI 工具读取。不存在 `.cursorrules`、`.windsurfrules`、`.cursor/rules/*` 或特定工具的 prompt 文件 —— 其原理请参阅 [ADR-0010](docs/adr/0010-documentation-and-ai-layout.md)。 本地的 Claude Code 设置位于 `.claude/settings.local.json`(已添加到 gitignore)中;并行的 agent 会话通过 `dev/worktree.sh` 获得隔离的堆栈([ADR-0017](docs/adr/0017-parallel-agent-sessions.md))。 ## 贡献 请参阅 [`.github/CONTRIBUTING.md`](.github/CONTRIBUTING.md)。消息头要求使用 Conventional Commits。CI 门禁包括:Pint、PHPStan level 10、PHPUnit。`make ci` 用于在本地模拟流水线。 ## 许可证 MIT。
标签:CQRS, Docker, ffuf, OpenVAS, PHP, Symfony, Syscall, Web开发, 后端架构, 安全防御评估, 请求拦截