feat: complete Phase 1 foundation scaffold
Some checks failed
CI / Lint (push) Has been cancelled
CI / TypeCheck (push) Has been cancelled
CI / Test (push) Has been cancelled
Deploy / Docker Build & Push (map[context:. dockerfile:apps/api/Dockerfile name:api]) (push) Has been cancelled
Deploy / Docker Build & Push (map[context:. dockerfile:apps/cms/Dockerfile name:cms]) (push) Has been cancelled
Deploy / Docker Build & Push (map[context:. dockerfile:apps/web/Dockerfile name:web]) (push) Has been cancelled
CI / Build (push) Has been cancelled
Deploy / Deploy (push) Has been cancelled

- Monorepo: Turborepo + pnpm workspaces with 7 apps/packages
- Backend: NestJS scaffold with 9 modules (auth, tenant, curriculum, simulation, portfolio, ai-coach, analytics, classroom, gamification)
- Frontend: React 18 + Vite + TailwindCSS + shadcn/ui with 10 pages, 14 UI primitives, 3 Zustand stores
- Database: Prisma schema with 19 models, 13 enums, seed script, multi-tenant ready
- Docker: Dev, production, and Portainer Compose files with Traefik reverse proxy
- Configuration: .env.example (47 vars), Zod validation, frontend-safe env exposure
- i18n: English + Greek locale files (10 files), ICU MessageFormat, react-i18next
- Shared packages: @investplay/types, @investplay/ui, @investplay/i18n, @investplay/utils
- CI/CD: GitHub Actions (lint, typecheck, test, build, deploy, PR checks)
- Documentation: CONTEXT.md, ARCHITECTURE.md (10 Mermaid diagrams), API.md, LOCALIZATION.md, DEVELOPMENT-ROADMAP.md
- Infrastructure: Dockerfiles (dev + prod), nginx configs, backup/healthcheck scripts
- Security: JWT auth guards, role-based access, rate limiting, Helmet, CORS, PII sanitization
This commit is contained in:
Lefteris Notas
2026-06-12 19:32:57 +03:00
parent fa71c60cfc
commit e75f913f1c
226 changed files with 17547 additions and 0 deletions

389
docs/DEVELOPMENT-ROADMAP.md Normal file
View File

@@ -0,0 +1,389 @@
# InvestPlay — Development Roadmap
> **Status:** Phase 1 — Foundation
> **Last Updated:** 2026-06-12
> **Target:** Production-grade, multi-tenant, multi-platform financial literacy platform
---
## Architecture Decisions
| Decision | Choice | Rationale |
|----------|--------|-----------|
| Monorepo Tool | **Turborepo** | Better DX than Nx for this scale; native ESM support |
| Package Manager | **pnpm** | Disk-efficient, strict dependency resolution |
| Backend Framework | **NestJS** | Modular, DI, GraphQL native, WebSocket integrated |
| Frontend Framework | **React + Vite** | Fast HMR, modern tooling, Capacitor/Tauri compatible |
| CMS | **Payload CMS** (self-hosted) | Code-first, TypeScript-native, block-based content, i18n built-in |
| Database ORM | **Prisma** | Type-safe, migration-first, multi-schema for tenant isolation |
| Cache | **Redis** | BullMQ queues + session store + rate limiting |
| Auth | **Clerk** (initial) → **Auth0** (B2B SSO) | Fast B2C start, SAML SSO for institutions |
| i18n Framework | **next-intl / react-i18next** | ICU message format, locale-aware routing |
| CSS Framework | **TailwindCSS** + **shadcn/ui** | Design tokens, accessible components |
| Containerization | **Docker Compose** (dev) + **Portainer** (prod) | Consistent local/remote, easy management |
| CI/CD | **GitHub Actions** | Free for public repos, Docker layer caching |
---
## Development Phases
### PHASE 1 — Foundation ✅ COMPLETED (2026-06-12)
**Goal:** Running monorepo, Docker dev environment, auth, basic API, empty UI shell
- [x] Project documentation and roadmap
- [x] Monorepo structure (Turborepo + pnpm workspaces)
- [x] Docker Compose for local dev (PostgreSQL, Redis, MinIO, Payload CMS)
- [x] Docker Compose for Contabo/Portainer production deployment
- [x] Environment variable system (.env per service, validation via Zod)
- [x] NestJS backend scaffold with core modules (75 files, 9 modules)
- [x] Prisma schema — 19 models, 13 enums, users, tenants, roles, classrooms
- [x] Auth module (JWT + SSO ready)
- [x] Tenant module (multi-tenancy, feature flags)
- [x] React + Vite frontend scaffold (55+ files, 10 pages, 14 UI primitives)
- [x] TailwindCSS + shadcn/ui design system
- [x] i18n infrastructure (EN + EL, 10 locale files, ICU MessageFormat)
- [x] Shared packages: `@investplay/types`, `@investplay/ui`, `@investplay/i18n`, `@investplay/utils`
- [x] Payload CMS scaffold with Docker support
- [x] ESLint + Prettier + Husky pre-commit hooks
- [x] CI pipeline (lint, typecheck, test, build) + deploy + PR checks
- [x] Comprehensive documentation (CONTEXT.md, ARCHITECTURE.md, API.md, LOCALIZATION.md)
### PHASE 2 — Core Learning (MVP B2C)
**Goal:** Self-guided learner can complete lessons and earn XP
- [ ] CMS block renderer in frontend (Hero, Text, Quiz, Calculator blocks)
- [ ] Lesson progression engine (track → module → lesson → block)
- [ ] XP and leveling system
- [ ] Badges and achievements
- [ ] Quiz/assessment engine
- [ ] User dashboard with progress visualization
- [ ] Streak tracking
- [ ] B2C auth flow (email + social)
### PHASE 3 — Simulations & Gamification
**Goal:** Interactive simulations and mini-games work end-to-end
- [ ] Blind Scenario engine (historical CSV → WebSocket tick stream)
- [ ] Synthetic market generator
- [ ] Portfolio management (virtual trades, ROI calculation)
- [ ] Budget Game (50/30/20 drag-and-drop)
- [ ] Debt Snowball mini-game
- [ ] Hype Trap narrative challenge
- [ ] Anti-cheat mechanisms
- [ ] Simulation leaderboards
### PHASE 4 — AI Coach
**Goal:** Context-aware educational AI with cost controls
- [ ] AI proxy service (NestJS → OpenAI/Gemini)
- [ ] Context injection pipeline
- [ ] Token bucket rate limiting (per user, per tenant)
- [ ] BYOK (Bring Your Own Key) mode
- [ ] Socratic prompt engineering
- [ ] Audit logging
- [ ] PII sanitization before LLM calls
- [ ] Graceful fallback when quota exhausted
### PHASE 5 — Classroom & Institutions (B2B MVP)
**Goal:** Teachers can manage classrooms and institutions can deploy
- [ ] Teacher dashboard
- [ ] Classroom creation with invite codes
- [ ] Assignment system
- [ ] Live "Time Machine" classroom simulation
- [ ] Cohort analytics and heatmaps
- [ ] Intervention alerts
- [ ] PDF/CSV report generation
- [ ] Institution admin panel
- [ ] White-label configuration
- [ ] Stripe Connect B2B billing
- [ ] SSO integration (SAML/OIDC)
### PHASE 6 — Mobile & Desktop
**Goal:** Native app wrappers for iOS, Android, Windows, macOS, Linux
- [ ] Capacitor wrapper (iOS + Android)
- [ ] Push notifications (FCM)
- [ ] Offline lesson caching
- [ ] Tauri v2 wrapper (Windows, macOS, Linux)
- [ ] Desktop-specific features (offline mode, system tray)
### PHASE 7 — Analytics & Reporting
**Goal:** Data-driven insights for institutions and platform operators
- [ ] Behavioral telemetry pipeline
- [ ] Aggregated materialized views (nightly rollups)
- [ ] Teacher analytics dashboard
- [ ] PDF/CSV automated report generation
- [ ] GDPR anonymization pipeline
- [ ] Opt-out mechanism for research aggregation
- [ ] "Gen Z Financial Behavior Index" report templates
### PHASE 8 — Localization Expansion
**Goal:** Full EU language support
- [ ] Add DE, FR, ES, IT, PT, NL locales
- [ ] CMS content localization workflow
- [ ] Locale-specific financial examples (taxes, regulations)
- [ ] RTL support readiness
- [ ] Locale-aware currency and number formatting
### PHASE 9 — Production Hardening
**Goal:** Enterprise-grade security, performance, and reliability
- [ ] Load testing (k6 / Artillery)
- [ ] Penetration testing
- [ ] Database backup/restore automation
- [ ] Disaster recovery plan
- [ ] Multi-region deployment (EU data residency)
- [ ] SOC 2 / ISO 27001 readiness
- [ ] SLA monitoring and alerting
---
## i18n Strategy
### Implementation
- **UI Strings:** `react-i18next` with ICU MessageFormat in JSON files per locale
- **Educational Content:** Payload CMS localized collections (each lesson has locale variants)
- **Currency/Number Formatting:** `Intl.NumberFormat` (browser-native, no extra library)
- **Date Formatting:** `Intl.DateTimeFormat` with locale-aware relative time
### Locale File Structure
```
packages/i18n/src/locales/
en/
common.json # Buttons, nav, errors
finance.json # Financial terms, instrument names
gamification.json # XP, badges, achievement names
classroom.json # Teacher dashboard, assignments
ai-coach.json # AI chat UI strings
gr/
common.json
finance.json
...
```
### Initial Languages (Phase 1)
- English (en) — Primary development language
- Greek (el) — Market entry requirement
### Expansion Languages (Phase 8)
- German (de), French (fr), Spanish (es), Italian (it), Portuguese (pt), Dutch (nl)
- All EU official languages eventually
---
## Deployment Architecture
### Local Development (Windows)
```
docker compose -f docker-compose.dev.yml up
```
Services:
- `api` — NestJS backend (hot-reload via tsx watch)
- `web` — Vite React frontend (HMR on port 5173)
- `cms` — Payload CMS (port 3000)
- `postgres` — PostgreSQL 16 (port 5432)
- `redis` — Redis 7 (port 6379)
- `minio` — S3-compatible storage (ports 9000/9001)
### Contabo Production (via Portainer)
```
docker compose -f docker-compose.prod.yml up -d
```
Portainer stack deployment with:
- Traefik reverse proxy (auto-SSL via Let's Encrypt)
- Multi-stage Docker builds (CI → GHCR → Portainer pull)
- Health checks on all containers
- Log rotation via Docker logging drivers
- Database backup sidecar container
---
## Environment Variables
All configuration through environment variables. No hardcoded secrets.
### Required ENV Files
```
.env.example # Template for all vars (committed)
.env # Local overrides (gitignored)
.env.production.example # Production template (committed)
```
### Key Variable Categories
| Category | Variables |
|----------|-----------|
| Database | `DATABASE_URL`, `DATABASE_POOL_MIN`, `DATABASE_POOL_MAX` |
| Redis | `REDIS_URL`, `REDIS_PASSWORD` |
| Auth | `JWT_SECRET`, `JWT_EXPIRES_IN`, `CLERK_SECRET_KEY` |
| AI | `OPENAI_API_KEY`, `GEMINI_API_KEY`, `AI_DEFAULT_DAILY_LIMIT` |
| Storage | `S3_ENDPOINT`, `S3_ACCESS_KEY`, `S3_SECRET_KEY`, `S3_BUCKET` |
| Email | `RESEND_API_KEY`, `EMAIL_FROM` |
| Billing | `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET` |
| Tenant | `TENANT_DEFAULT_AI_MODE`, `TENANT_MAX_TOKENS_MONTHLY` |
| i18n | `DEFAULT_LOCALE`, `SUPPORTED_LOCALES` |
---
## Repository Structure
```
investplay/
├── apps/
│ ├── api/ # NestJS backend
│ │ ├── src/
│ │ │ ├── modules/
│ │ │ │ ├── auth/
│ │ │ │ ├── tenant/
│ │ │ │ ├── curriculum/
│ │ │ │ ├── simulation/
│ │ │ │ ├── portfolio/
│ │ │ │ ├── ai-coach/
│ │ │ │ ├── analytics/
│ │ │ │ ├── classroom/
│ │ │ │ └── gamification/
│ │ │ ├── common/
│ │ │ │ ├── guards/
│ │ │ │ ├── decorators/
│ │ │ │ ├── filters/
│ │ │ │ └── interceptors/
│ │ │ ├── config/
│ │ │ └── main.ts
│ │ ├── prisma/
│ │ │ ├── schema.prisma
│ │ │ └── migrations/
│ │ ├── test/
│ │ ├── Dockerfile
│ │ └── package.json
│ ├── web/ # React + Vite frontend
│ │ ├── src/
│ │ │ ├── components/
│ │ │ ├── pages/
│ │ │ ├── hooks/
│ │ │ ├── stores/
│ │ │ ├── lib/
│ │ │ ├── styles/
│ │ │ └── i18n/
│ │ ├── public/
│ │ ├── index.html
│ │ ├── vite.config.ts
│ │ ├── Dockerfile
│ │ └── package.json
│ ├── cms/ # Payload CMS
│ │ ├── src/
│ │ │ └── collections/
│ │ ├── package.json
│ │ └── Dockerfile
│ ├── mobile/ # Capacitor wrapper
│ └── desktop/ # Tauri v2 wrapper
├── packages/
│ ├── types/ # @investplay/types
│ │ ├── src/
│ │ │ ├── user.ts
│ │ │ ├── tenant.ts
│ │ │ ├── curriculum.ts
│ │ │ ├── simulation.ts
│ │ │ ├── portfolio.ts
│ │ │ └── analytics.ts
│ │ └── package.json
│ ├── ui/ # @investplay/ui
│ │ ├── src/
│ │ │ ├── components/
│ │ │ └── lib/
│ │ └── package.json
│ ├── i18n/ # @investplay/i18n
│ │ ├── src/
│ │ │ └── locales/
│ │ └── package.json
│ └── utils/ # @investplay/utils
│ ├── src/
│ └── package.json
├── docker/
│ ├── docker-compose.dev.yml
│ ├── docker-compose.prod.yml
│ ├── traefik/
│ │ ├── traefik.yml
│ │ └── dynamic.yml
│ └── nginx/
│ └── nginx.conf
├── scripts/
│ ├── setup.sh
│ ├── seed.ts
│ └── backup.sh
├── docs/
│ ├── DEVELOPMENT-ROADMAP.md
│ ├── CONTEXT.md
│ ├── API.md
│ └── ARCHITECTURE.md
├── .github/
│ └── workflows/
│ ├── ci.yml
│ └── deploy.yml
├── .env.example
├── .env.production.example
├── turbo.json
├── pnpm-workspace.yaml
├── package.json
├── tsconfig.base.json
├── .eslintrc.js
├── .prettierrc
└── README.md
```
---
## Database Schema (Core Entities)
```
User — id, email, role, locale, tenantId, xp, level
Tenant — id, name, domain, branding, featureFlags, aiMode
Classroom — id, name, tenantId, teacherId, inviteCode
ClassroomStudent — id, classroomId, userId, joinedAt
Module — id, cmsId, track, order, tenantId
Lesson — id, cmsId, moduleId, order, estimatedMins
UserProgress — id, userId, lessonId, status, score, completedAt
QuizAttempt — id, userId, quizId, answers, score, timestamp
Trade — id, userId, simulationId, asset, amount, timestamp
Portfolio — id, userId, simulationId, cashBalance, holdings
Badge — id, name, description, icon, criteria
UserBadge — id, userId, badgeId, earnedAt
AILog — id, tenantId, userId, tokensUsed, timestamp
AnalyticsEvent — id, userId, eventType, metadata, timestamp
```
---
## Key Technical Decisions
### Multi-Tenancy Strategy
**Schema-level isolation** via PostgreSQL schemas (one per tenant) for maximum data isolation. Tenant-specific connection pooling via Prisma's multi-schema preview feature.
### API Design
- **Primary:** GraphQL for all CRUD operations (type-safe, no over-fetching)
- **Real-time:** WebSockets (Socket.io) for live simulations and leaderboards
- **Webhooks:** REST endpoints for Stripe, Resend, third-party integrations
### AI Cost Control
Backend-side hard enforcement (not reliant on OpenAI budget alerts):
- Redis token bucket per user (daily) and per tenant (monthly)
- Hard cutoff at quota exhaustion (no grace period)
- Admin alert when approaching 80% of monthly quota
### Security
- JWT with RS256 (asymmetric) for service-to-service auth
- GraphQL query depth limiting (max depth 7)
- Rate limiting on all public endpoints
- CORS whitelist per tenant domain
- Helmet.js for HTTP security headers
- Input validation via Zod on every endpoint
- Prompt injection defense in AI proxy
---
## Tracking
Progress tracked via this file. Each completed task gets `[x]`.
Git commits follow Conventional Commits format.
CI badges added once pipelines are running.