updating docs
This commit is contained in:
parent
fef7c82a3e
commit
fbc611c49f
4 changed files with 216 additions and 64 deletions
|
|
@ -63,9 +63,9 @@ These are not deleted from the plan — they are deferred. The architecture is a
|
|||
|
||||
## 4. Technology Stack
|
||||
|
||||
The monorepo structure and tooling are already set up. This is the full stack — the MVP uses a subset of it.
|
||||
The monorepo structure and tooling are already set up. This is the full stack.
|
||||
|
||||
| Layer | Technology | MVP? |
|
||||
| Layer | Technology | Status |
|
||||
| ------------ | ------------------------------ | ----------- |
|
||||
| Monorepo | pnpm workspaces | ✅ |
|
||||
| Frontend | React 18, Vite, TypeScript | ✅ |
|
||||
|
|
@ -77,10 +77,11 @@ The monorepo structure and tooling are already set up. This is the full stack
|
|||
| Database | PostgreSQL + Drizzle ORM | ✅ |
|
||||
| Validation | Zod (shared schemas) | ✅ |
|
||||
| Testing | Vitest, supertest | ✅ |
|
||||
| Auth | Better Auth (Google + GitHub) | ❌ post-MVP |
|
||||
| Auth | Better Auth (Google + GitHub) | ✅ |
|
||||
| Deployment | Docker Compose, Caddy, Hetzner | ✅ |
|
||||
| CI/CD | Forgejo Actions | ✅ |
|
||||
| Realtime | WebSockets (`ws` library) | ❌ post-MVP |
|
||||
| Cache | Valkey | ❌ post-MVP |
|
||||
| Deployment | Docker Compose, Hetzner, Nginx | ❌ post-MVP |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -88,14 +89,20 @@ The monorepo structure and tooling are already set up. This is the full stack
|
|||
|
||||
```text
|
||||
vocab-trainer/
|
||||
├── .forgejo/
|
||||
│ └── workflows/
|
||||
│ └── deploy.yml — CI/CD pipeline (build, push, deploy)
|
||||
├── apps/
|
||||
│ ├── api/
|
||||
│ │ └── src/
|
||||
│ │ ├── app.ts — createApp() factory, express.json(), error middleware
|
||||
│ │ ├── app.ts — createApp() factory, CORS, auth handler, error middleware
|
||||
│ │ ├── server.ts — starts server on PORT
|
||||
│ │ ├── errors/
|
||||
│ │ │ └── AppError.ts — AppError, ValidationError, NotFoundError
|
||||
│ │ ├── lib/
|
||||
│ │ │ └── auth.ts — Better Auth config (Google + GitHub providers)
|
||||
│ │ ├── middleware/
|
||||
│ │ │ ├── authMiddleware.ts — session validation for protected routes
|
||||
│ │ │ └── errorHandler.ts — central error middleware
|
||||
│ │ ├── routes/
|
||||
│ │ │ ├── apiRouter.ts — mounts /health and /game routers
|
||||
|
|
@ -111,10 +118,17 @@ vocab-trainer/
|
|||
│ │ ├── InMemoryGameSessionStore.ts
|
||||
│ │ └── index.ts
|
||||
│ └── web/
|
||||
│ ├── Dockerfile — multi-stage: dev + production (nginx:alpine)
|
||||
│ ├── nginx.conf — SPA fallback routing
|
||||
│ └── src/
|
||||
│ ├── routes/
|
||||
│ │ ├── index.tsx — landing page
|
||||
│ │ └── play.tsx — the quiz
|
||||
│ │ ├── play.tsx — the quiz
|
||||
│ │ ├── login.tsx — Google + GitHub login buttons
|
||||
│ │ ├── about.tsx
|
||||
│ │ └── __root.tsx
|
||||
│ ├── lib/
|
||||
│ │ └── auth-client.ts — Better Auth React client
|
||||
│ ├── components/
|
||||
│ │ └── game/
|
||||
│ │ ├── GameSetup.tsx — settings UI
|
||||
|
|
@ -131,7 +145,7 @@ vocab-trainer/
|
|||
│ └── db/
|
||||
│ ├── drizzle/ — migration SQL files
|
||||
│ └── src/
|
||||
│ ├── db/schema.ts — Drizzle schema
|
||||
│ ├── db/schema.ts — Drizzle schema (terms, translations, auth tables)
|
||||
│ ├── models/termModel.ts — getGameTerms(), getDistractors()
|
||||
│ ├── seeding-datafiles.ts — seeds terms + translations from JSON
|
||||
│ ├── seeding-cefr-levels.ts — enriches translations with CEFR data
|
||||
|
|
@ -139,7 +153,9 @@ vocab-trainer/
|
|||
│ └── index.ts
|
||||
├── scripts/ — Python extraction/comparison/merge scripts
|
||||
├── documentation/ — project docs
|
||||
├── docker-compose.yml
|
||||
├── docker-compose.yml — local dev stack
|
||||
├── docker-compose.prod.yml — production config reference
|
||||
├── Caddyfile — reverse proxy routing
|
||||
└── pnpm-workspace.yaml
|
||||
```
|
||||
|
||||
|
|
@ -178,13 +194,28 @@ HTTP Request
|
|||
|
||||
**Key principle:** all database code lives in `packages/db`. `apps/api` never imports `drizzle-orm` for queries — it only calls functions exported from `packages/db`.
|
||||
|
||||
### Production Infrastructure
|
||||
|
||||
```text
|
||||
Internet → Caddy (HTTPS termination)
|
||||
├── lilastudy.com → web container (nginx, static files)
|
||||
├── api.lilastudy.com → api container (Express, port 3000)
|
||||
└── git.lilastudy.com → forgejo container (git + registry, port 3000)
|
||||
|
||||
SSH (port 2222) → forgejo container (git push/pull)
|
||||
```
|
||||
|
||||
All containers communicate over an internal Docker network. Only Caddy (80/443) and Forgejo SSH (2222) are exposed to the internet.
|
||||
|
||||
---
|
||||
|
||||
## 7. Data Model (Current State)
|
||||
|
||||
Words are modelled as language-neutral concepts (terms) separate from learning curricula (decks). Adding a new language pair requires no schema changes — only new rows in `translations`, `decks`.
|
||||
|
||||
**Core tables:** `terms`, `translations`, `term_glosses`, `decks`, `deck_terms`, `categories`, `term_categories`
|
||||
**Core tables:** `terms`, `translations`, `term_glosses`, `decks`, `deck_terms`, `topics`, `term_topics`
|
||||
|
||||
**Auth tables (managed by Better Auth):** `user`, `session`, `account`, `verification`
|
||||
|
||||
Key columns on `terms`: `id` (uuid), `pos` (CHECK-constrained), `source`, `source_id` (unique pair for idempotent imports)
|
||||
|
||||
|
|
@ -201,9 +232,10 @@ Full schema is in `packages/db/src/db/schema.ts`.
|
|||
### Endpoints
|
||||
|
||||
```text
|
||||
POST /api/v1/game/start GameRequest → GameSession
|
||||
POST /api/v1/game/answer AnswerSubmission → AnswerResult
|
||||
GET /api/v1/health Health check
|
||||
POST /api/v1/game/start GameRequest → GameSession (requires auth)
|
||||
POST /api/v1/game/answer AnswerSubmission → AnswerResult (requires auth)
|
||||
GET /api/v1/health Health check (public)
|
||||
ALL /api/auth/* Better Auth handlers (public)
|
||||
```
|
||||
|
||||
### Schemas (packages/shared)
|
||||
|
|
@ -235,7 +267,7 @@ Typed error classes (`AppError` base, `ValidationError` 400, `NotFoundError` 404
|
|||
- **Session length**: 3 or 10 questions (configurable)
|
||||
- **Scoring**: +1 per correct answer (no speed bonus for MVP)
|
||||
- **Timer**: none in singleplayer MVP
|
||||
- **No auth required**: anonymous users
|
||||
- **Auth required**: users must log in via Google or GitHub
|
||||
- **Submit-before-send**: user selects, then confirms (prevents misclicks)
|
||||
|
||||
---
|
||||
|
|
@ -258,14 +290,15 @@ After completing a task: share the code, ask what to refactor and why. The LLM s
|
|||
|
||||
## 11. Post-MVP Ladder
|
||||
|
||||
| Phase | What it adds |
|
||||
| ----------------- | -------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||
| Auth | Auth | Better Auth (Google + GitHub), embedded in Express API, user rows in DB |
|
||||
| User Stats | Games played, score history, profile page |
|
||||
| Multiplayer Lobby | Room creation, join by code, WebSocket connection |
|
||||
| Multiplayer Game | Simultaneous answers, server timer, live scores, winner screen |
|
||||
| Deployment | Docker Compose prod config, Nginx, Let's Encrypt, Hetzner VPS |
|
||||
| Hardening | Rate limiting, error boundaries, CI/CD, DB backups |
|
||||
| Phase | What it adds | Status |
|
||||
| ----------------- | ------------------------------------------------------------------------------- | ------ |
|
||||
| Auth | Better Auth (Google + GitHub), embedded in Express API, user rows in DB | ✅ |
|
||||
| Deployment | Docker Compose, Caddy, Forgejo, CI/CD, Hetzner VPS | ✅ |
|
||||
| Hardening (partial) | CI/CD pipeline, DB backups | ✅ |
|
||||
| User Stats | Games played, score history, profile page | ❌ |
|
||||
| Multiplayer Lobby | Room creation, join by code, WebSocket connection | ❌ |
|
||||
| Multiplayer Game | Simultaneous answers, server timer, live scores, winner screen | ❌ |
|
||||
| Hardening (rest) | Rate limiting, error boundaries, monitoring, accessibility | ❌ |
|
||||
|
||||
### Future Data Model Extensions (deferred, additive)
|
||||
|
||||
|
|
@ -285,11 +318,16 @@ All are new tables referencing existing `terms` rows via FK. No existing schema
|
|||
- Game mechanic: simultaneous answers, 15-second server timer, all players see same question
|
||||
- Valkey for ephemeral room state, PostgreSQL for durable records
|
||||
|
||||
### Infrastructure (deferred)
|
||||
### Infrastructure (current)
|
||||
|
||||
- `app.yourdomain.com` → React frontend
|
||||
- `api.yourdomain.com` → Express API + WebSocket + Better Auth
|
||||
- Docker Compose with `nginx-proxy` + `acme-companion` for automatic SSL
|
||||
- `lilastudy.com` → React frontend (nginx serving static files)
|
||||
- `api.lilastudy.com` → Express API + Better Auth
|
||||
- `git.lilastudy.com` → Forgejo (git server + container registry)
|
||||
- Docker Compose with Caddy for automatic HTTPS via Let's Encrypt
|
||||
- CI/CD via Forgejo Actions (build on push to main, deploy via SSH)
|
||||
- Daily DB backups with cron, synced to dev laptop
|
||||
|
||||
See `deployment.md` for full infrastructure documentation.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -312,14 +350,14 @@ See `roadmap.md` for the full roadmap with task-level checkboxes.
|
|||
### Dependency Graph
|
||||
|
||||
```text
|
||||
Phase 0 (Foundation)
|
||||
└── Phase 1 (Vocabulary Data + API)
|
||||
└── Phase 2 (Singleplayer UI)
|
||||
└── Phase 3 (Auth)
|
||||
├── Phase 4 (Room Lobby)
|
||||
│ └── Phase 5 (Multiplayer Game)
|
||||
│ └── Phase 6 (Deployment)
|
||||
└── Phase 7 (Hardening)
|
||||
Phase 0 (Foundation) ✅
|
||||
└── Phase 1 (Vocabulary Data + API) ✅
|
||||
└── Phase 2 (Singleplayer UI) ✅
|
||||
├── Phase 3 (Auth) ✅
|
||||
│ └── Phase 6 (Deployment + CI/CD) ✅
|
||||
└── Phase 4 (Multiplayer Lobby)
|
||||
└── Phase 5 (Multiplayer Game)
|
||||
└── Phase 7 (Hardening)
|
||||
```
|
||||
|
||||
---
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue