Full Stack FastAPI Template — Spec vs Reality
Spec source: README.md
Scope: Source code only — infrastructure config files (Docker, CI/CD, YAML) not analysed
Coverage: ████░░░░░░ 6/14 features fully implemented, 2 partial, 1 missing, 5 not verifiable from source
Feature Coverage
| Feature | Spec Intent | Code Reality | Status |
|---|---|---|---|
| Dark mode support | Frontend UI can be toggled between light and dark mode. | ThemeProvider in theme-provider.tsx supports dark, light, and system themes. Appearance.tsx provides UI for selection. | ✅ Implemented |
| JWT authentication | Users can authenticate using JWT tokens. | security.py defines create_access_token, deps.py validates JWT in get_current_user. | ✅ Implemented |
| Secure password hashing | Passwords are hashed before storage. | security.py uses PasswordHash with Argon2 and Bcrypt; crud.py hashes passwords before saving. | ✅ Implemented |
| Email-based password recovery | Users can request a password reset via email. | Frontend recover-password.tsx exists and SDK includes recoverPassword/resetPassword, but no backend route for recover... | ⚠️ Partial |
| Mailcatcher for local email testing | Emails are caught by Mailcatcher during development. | No source code evidence for Mailcatcher; likely configured in Docker Compose. | ~ Too vague to verify |
| Traefik reverse proxy | Incoming requests are routed through Traefik. | No source code evidence; Traefik is infrastructure. | ~ Too vague to verify |
| Automatic HTTPS certificates | Automatic HTTPS certificates via Traefik. | No source code evidence; depends on infrastructure. | ~ Too vague to verify |
| CI/CD with GitHub Actions | Automated tests on push and deployment on merge. | No source code evidence; CI/CD is infrastructure. | ~ Too vague to verify |
| Playwright End-to-End testing | End-to-end tests with Playwright. | Multiple spec files (admin.spec.ts, login.spec.ts, etc.) and utility files exist. | ✅ Implemented |
| Pytest tests | Backend tests using Pytest. | No Python test files found in the provided evidence. | ❌ Not found |
| Docker Compose for dev and prod | Application runnable with Docker Compose. | No source code evidence; Docker Compose is infrastructure. | ~ Too vague to verify |
| Automatically generated frontend client | Frontend client generated from API specification. | sdk.gen.ts, types.gen.ts, schemas.gen.ts are generated; openapi-ts.config.ts configures generation. | ✅ Implemented |
| Copier project generation | New projects can be generated using Copier. | post_gen_project.py runs after Copier generation, but Copier template files not evidenced. | ⚠️ Partial |
| Interactive API documentation | API documented with Swagger UI and ReDoc. | FastAPI framework provides automatic documentation; evidenced by backend API routers. | ✅ Implemented |
What the code does that the spec never mentioned
These behaviors exist in the codebase but have no entry in any spec document. They represent implicit engineering decisions — security contracts, undocumented constraints, behavioral choices — that the spec author either assumed, forgot, or decided after writing the spec.
1. Timing attack prevention
The authenticate function in crud.py uses a dummy hash when user is not found to prevent timing attacks.
Evidence: crud.py:L40-L45
Why it matters: Security-conscious authentication that mitigates an OWASP timing attack vector, showing proactive security design.
2. Token stored in localStorage
The useAuth.ts login function stores the JWT access token in localStorage, making it vulnerable to XSS attacks.
Evidence: useAuth.ts:L41
Why it matters: Storing tokens in localStorage is a common security risk; a CTO should assess if httpOnly cookies are a better alternative.
3. Dual hashing algorithm (Argon2+Bcrypt)
Password hashing uses PasswordHash from argon2-cffi, which internally uses both Argon2 and Bcrypt hashers.
Evidence: security.py:L12
Why it matters: Uses a robust hashing library, but combining algorithms may add unnecessary complexity; verify intended security posture.
4. Sidebar state persisted in cookie
Sidebar open/close state is stored in a cookie with a 7-day max age and synced across tabs.
Evidence: sidebar.tsx:L1-L8, L107
Why it matters: Persisting UI state in cookies affects performance and security; ensure no sensitive data leaked and cookie flags are set correctly.
Gaps and Risks
🔴 Password recovery backend HIGH
No backend endpoint for password recovery is evidenced, despite frontend and SDK support.
Question for the team: Is the password recovery endpoint fully implemented on the backend, and does it send emails?
🔴 Pytest backend tests HIGH
No evidence of Pytest test files; backend may be untested.
Question for the team: Are there backend tests using Pytest that were not included in the provided evidence?
🟡 Email integration for recovery MEDIUM
Although testEmail endpoint exists, there is no evidence that password recovery actually sends an email.
Question for the team: Does the password recovery flow actually send an email, or is it stubbed?
Questions for the Engineering Team
- Is the password recovery endpoint (POST /api/v1/password-recovery/) fully implemented with email sending, or is it pending?
- Are there any Pytest test files for the backend that were not included in the provided code samples?
- What is the rationale behind storing the JWT token in localStorage instead of using httpOnly cookies?
- Is the combined Argon2/Bcrypt hashing intentional, and does it meet the required security standards?
- How is the cookie for sidebar state configured in terms of Secure and HttpOnly flags?
Generated by Verifiably — every finding is grounded in file:line evidence from the codebase, not training data.