This is the official API Platform demo application, showcasing a full-stack modern web app with:
api/— Backend: API Platform 4.3 + Symfony 8.0 + Doctrine ORM 3, PHP ≥ 8.4pwa/— Frontend: Next.js 16 + React 19 + React Admin +@api-platform/admine2e/— End-to-end tests: Playwright 1.50helm/— Kubernetes deployment via Helm (GKE).github/— GitHub Actions workflows (CI, Claude)
Authentication is handled via Keycloak (OIDC) + JWT (web-token/jwt-bundle).
Real-time updates use Mercure (symfony/mercure-bundle).
- API Platform resources are defined in
api/src/ApiResource/ - Entities live in
api/src/Entity/; repositories inapi/src/Repository/ - State providers/processors in
api/src/State/ - Fixtures use Zenstruck Foundry (
api/src/DataFixtures/) - Doctrine migrations in
api/migrations/ - GraphQL is enabled alongside REST
- OpenAPI spec is auto-generated by API Platform
- Next.js App Router (
pwa/app/) - React Admin dashboard at
pwa/app/admin/ - Book-related pages at
pwa/app/books/, bookmarks atpwa/app/bookmarks/ - Components organized by domain:
pwa/components/{admin,book,bookmark,common,review}/ - TypeScript types for external APIs:
pwa/types/ - Package manager: pnpm
- Playwright tests in
e2e/tests/ - Mock server in
e2e/mock-server/ - E2E compose file:
compose.e2e.yaml
The project uses Docker Compose:
docker compose up -d # Start all services (php, database, pwa, keycloak)
docker compose -f compose.e2e.yaml up -d # For E2E testsNo Makefile exists — use docker compose exec for backend commands and pnpm inside pwa/.
# Run tests
docker compose exec php bin/phpunit
# Static analysis
docker compose exec php vendor/bin/phpstan analyse
# Rector (code quality)
docker compose exec php vendor/bin/rector process --dry-run
# Doctrine migrations
docker compose exec php bin/console doctrine:migrations:migratepnpm dev # Development server
pnpm build # Production build
pnpm lint # ESLint
pnpm lint:fix # ESLint auto-fixnpx playwright test # from e2e/CI note: There is no Docker environment in CI. Do NOT run
docker composeor container-level commands in GitHub Actions. The CI pipeline handles testing independently.
Follow Conventional Commits:
<type>(<scope>): <description>
- Valid types:
feat,fix,docs,style,refactor,perf,test,build,ci,chore,revert - Scopes:
api,pwa,e2e,helm,ci, or omitted for cross-cutting changes - Description: imperative mood, lowercase, no trailing period
- Individual commits are squashed on merge; only the PR title must conform
- PHP: PSR-12, strict types, PHP 8.4 features (readonly properties, enums, etc.)
- TypeScript/React: ESLint (
eslint.config.mjs), functional components, no class components - No debug statements:
console.log,dump(),dd(),var_dump()are never committed
- Backend is stateless: no server-side session state
- Frontend uses React Query for server state; local UI state with React hooks
- DTO contract (OpenAPI spec) is the single source of truth between backend and frontend
- If backend DTOs change, regenerate TS types:
cd pwa && npx openapi-typescript ../api/public/docs.jsonopenapi -o types/api.d.ts
- SOLID principles and Law of Demeter; deviations must be justified in code comments
- ADRs in
docs/adr/document architectural decisions — update when needed
| Layer | Tool | Location |
|---|---|---|
| Unit/Integration (PHP) | PHPUnit 12 | api/tests/ |
| Static analysis (PHP) | PHPStan 2 | api/ |
| E2E | Playwright 1.50 | e2e/tests/ |
| Frontend lint | ESLint 9 | pwa/ |
New or changed behaviour must have corresponding tests.
This project uses cutting-edge framework versions that may differ from training data:
- API Platform 4.3 (not 3.x)
- Symfony 8.0 (not 6.x or 7.x)
- Next.js 16 (not 14.x or 15.x)
- React 19 (not 18.x)
- React Admin 5 (not 4.x)
Before claiming that a class, method, attribute, or hook exists:
- Read the relevant source file in
api/vendor/orpwa/node_modules/ - Or check the official documentation via
mcp__context7__query-docs - Never assume an API exists based on older versions
When posting code review comments (Claude automated review), use Conventional Comments labels:
praise: something done wellnitpick: minor, non-blocking style issue — do not post (linters handle this)suggestion: concrete improvement proposalissue: blocking problem that must be fixedquestion: clarification neededthought: non-blocking observation
Format:
<label> (<decoration>): <subject>
<body>
```suggestion
<fixed code>
Review body structure:
1. **Summary** — 1-3 sentences on overall quality
2. **Resolved threads** — only if threads were resolved
3. **PR title check** — only if non-conforming
4. **Review checklist** (checked/unchecked)
5. **Inline comments** — count summary
6. **Footer** — `Generated with [Claude Code](https://claude.ai/code)`
---
## GitHub repository
- **Owner**: `api-platform`
- **Repo**: `demo`
- **Main branch**: `4.3`
- **Remote**: `git@github.com:api-platform/demo.git`