Overview
Backend tech stack, architecture overview, and project structure
Backend Overview
The backend is a production-ready Symfony application that ships with user authentication, subscription payments, an admin panel, and a CI/CD pipeline — all wired together with hexagonal architecture and CQRS.
Tech Stack
PHP 8.4
The latest version of PHP with modern features: readonly properties, enums, fibers, typed class constants, and property hooks. PHP 8.4 brings significant performance improvements and keeps the codebase concise with constructor promotion and match expressions.
Symfony 7.4
Enterprise-grade framework with long-term support. Symfony's component architecture means you only use what you need — from routing and dependency injection to security and messaging. The ecosystem includes mature tooling for testing, profiling, and debugging.
FrankenPHP
A modern PHP application server built on top of Caddy. Unlike traditional setups (Nginx + PHP-FPM), FrankenPHP embeds PHP directly into the Caddy web server.
Key benefits:
- Worker mode — keeps the application booted in memory between requests, dramatically reducing response times
- Automatic HTTPS — inherits Caddy's automatic TLS certificate provisioning via Let's Encrypt
- HTTP/2 and HTTP/3 — native support out of the box
- Single binary deployment — no need to configure Nginx, PHP-FPM, and a reverse proxy separately
Supporting Technologies
| Component | Technology |
|---|---|
| Database | PostgreSQL 16 |
| Cache / Queue | Redis 7 |
| Payments | Stripe (recurring + one-time) |
| Emails | Brevo (production) / Mailpit (dev) |
| Social Login | Firebase Authentication |
| Auth Tokens | JWT (access) + Refresh Tokens |
| Admin Panel | EasyAdmin |
| Deployment | Dokploy + GitHub Container Registry |
| CI/CD | GitHub Actions |
What's Included
User Management
- Email/password registration with email validation
- Social login via Firebase (Google, Apple, etc.)
- JWT access tokens + single-use refresh tokens
- Forgot password / reset password flow
- Change password, user profile
- Rate limiting on auth endpoints
Revenue & Payments
- Free / Starter / Pro plan tiers with feature gating
- Stripe Checkout (recurring and one-time payments)
- Stripe webhook handling (5 events)
- Guest and authenticated checkout
Backoffice Admin Panel
- EasyAdmin dashboard for users and subscriptions
- Search, filter, and edit records
- Manual GitHub organization invite action
Communication
- Transactional emails (welcome, password reset, password changed)
- Brevo for production, Symfony Mailer + Mailpit for development
Developer Experience
- Hexagonal architecture with CQRS
- Full test suite — unit (fakes, no DB) + functional (real HTTP + DB)
- PHPStan static analysis, PHP CS Fixer
- OpenAPI/Swagger documentation at
/api/doc
Project Structure
src/
├── Shared/ # Cross-context utilities
│ ├── Domain/ValueObject/ # Reusable value objects
│ └── Infrastructure/
│ ├── Admin/ # EasyAdmin dashboard & CRUD
│ ├── EventListener/ # Global exception listeners
│ ├── Http/ # OpenAPI doc controller
│ ├── Persistence/Doctrine/ # Custom Doctrine types
│ └── RateLimiting/ # Auth rate limit checker
│
├── UserManagement/ # Bounded context: auth & users
│ ├── Domain/
│ │ ├── Model/ # User, tokens
│ │ ├── Port/ # Repository & service interfaces
│ │ ├── Event/ # UserCreated, PasswordChanged
│ │ └── Exception/ # Domain exceptions
│ ├── Application/ # One folder per feature (CQRS)
│ │ ├── SignUp/
│ │ ├── Login/
│ │ ├── SocialLogin/
│ │ ├── ForgotPassword/
│ │ ├── ResetPassword/
│ │ └── ...
│ └── Infrastructure/
│ ├── Http/ # Controllers
│ ├── Persistence/ # Doctrine repos + read models
│ ├── Email/ # Brevo + Symfony Mailer adapters
│ └── Firebase/ # Social token verifier
│
└── Subscription/ # Bounded context: payments
├── Domain/
│ ├── Model/ # Subscription, PlanType, Feature
│ ├── Port/ # Payment gateway interfaces
│ └── Event/ # SubscriptionPaid
├── Application/
│ ├── CreateCheckoutSession/
│ ├── GetAvailablePlans/
│ ├── SyncSubscription/
│ └── ...
└── Infrastructure/
├── Http/ # Controllers + webhook
├── Persistence/ # Doctrine repos + read models
└── Stripe/ # Stripe payment gateway