From a6d8ddec3b9eb39430df613330dc3d42b9d845dd Mon Sep 17 00:00:00 2001 From: lila Date: Fri, 17 Apr 2026 15:52:50 +0200 Subject: [PATCH] formatting --- documentation/deployment.md | 20 +-- documentation/spec.md | 18 +-- packages/db/drizzle/meta/0005_snapshot.json | 115 ++++----------- packages/db/drizzle/meta/0006_snapshot.json | 148 +++++--------------- packages/db/drizzle/meta/_journal.json | 2 +- 5 files changed, 82 insertions(+), 221 deletions(-) diff --git a/documentation/deployment.md b/documentation/deployment.md index 5912d2f..e51400c 100644 --- a/documentation/deployment.md +++ b/documentation/deployment.md @@ -12,19 +12,19 @@ This document describes the production deployment of the lila vocabulary trainer ### Subdomain Routing -| Subdomain | Service | Container port | -|---|---|---| -| `lilastudy.com` | Frontend (nginx serving static files) | 80 | -| `api.lilastudy.com` | Express API | 3000 | -| `git.lilastudy.com` | Forgejo (web UI + container registry) | 3000 | +| Subdomain | Service | Container port | +| ------------------- | ------------------------------------- | -------------- | +| `lilastudy.com` | Frontend (nginx serving static files) | 80 | +| `api.lilastudy.com` | Express API | 3000 | +| `git.lilastudy.com` | Forgejo (web UI + container registry) | 3000 | ### Ports Exposed to the Internet -| Port | Service | -|---|---| -| 80 | Caddy (HTTP, redirects to HTTPS) | -| 443 | Caddy (HTTPS) | -| 2222 | Forgejo SSH (git clone/push) | +| Port | Service | +| ---- | -------------------------------- | +| 80 | Caddy (HTTP, redirects to HTTPS) | +| 443 | Caddy (HTTPS) | +| 2222 | Forgejo SSH (git clone/push) | All other services (Postgres, API, frontend) communicate only over the internal Docker network. diff --git a/documentation/spec.md b/documentation/spec.md index 4bf2835..637da00 100644 --- a/documentation/spec.md +++ b/documentation/spec.md @@ -290,15 +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 | 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 | ❌ | +| 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) diff --git a/packages/db/drizzle/meta/0005_snapshot.json b/packages/db/drizzle/meta/0005_snapshot.json index cfbb350..1a57e01 100644 --- a/packages/db/drizzle/meta/0005_snapshot.json +++ b/packages/db/drizzle/meta/0005_snapshot.json @@ -110,12 +110,8 @@ "name": "account_user_id_user_id_fk", "tableFrom": "account", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -149,12 +145,8 @@ "name": "deck_terms_deck_id_decks_id_fk", "tableFrom": "deck_terms", "tableTo": "decks", - "columnsFrom": [ - "deck_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deck_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -162,12 +154,8 @@ "name": "deck_terms_term_id_terms_id_fk", "tableFrom": "deck_terms", "tableTo": "terms", - "columnsFrom": [ - "term_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["term_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -175,10 +163,7 @@ "compositePrimaryKeys": { "deck_terms_deck_id_term_id_pk": { "name": "deck_terms_deck_id_term_id_pk", - "columns": [ - "deck_id", - "term_id" - ] + "columns": ["deck_id", "term_id"] } }, "uniqueConstraints": {}, @@ -265,10 +250,7 @@ "unique_deck_name": { "name": "unique_deck_name", "nullsNotDistinct": false, - "columns": [ - "name", - "source_language" - ] + "columns": ["name", "source_language"] } }, "policies": {}, @@ -368,12 +350,8 @@ "name": "session_user_id_user_id_fk", "tableFrom": "session", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -383,9 +361,7 @@ "session_token_unique": { "name": "session_token_unique", "nullsNotDistinct": false, - "columns": [ - "token" - ] + "columns": ["token"] } }, "policies": {}, @@ -435,12 +411,8 @@ "name": "term_glosses_term_id_terms_id_fk", "tableFrom": "term_glosses", "tableTo": "terms", - "columnsFrom": [ - "term_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["term_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -450,10 +422,7 @@ "unique_term_gloss": { "name": "unique_term_gloss", "nullsNotDistinct": false, - "columns": [ - "term_id", - "language_code" - ] + "columns": ["term_id", "language_code"] } }, "policies": {}, @@ -488,12 +457,8 @@ "name": "term_topics_term_id_terms_id_fk", "tableFrom": "term_topics", "tableTo": "terms", - "columnsFrom": [ - "term_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["term_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -501,12 +466,8 @@ "name": "term_topics_topic_id_topics_id_fk", "tableFrom": "term_topics", "tableTo": "topics", - "columnsFrom": [ - "topic_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["topic_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -514,10 +475,7 @@ "compositePrimaryKeys": { "term_topics_term_id_topic_id_pk": { "name": "term_topics_term_id_topic_id_pk", - "columns": [ - "term_id", - "topic_id" - ] + "columns": ["term_id", "topic_id"] } }, "uniqueConstraints": {}, @@ -591,10 +549,7 @@ "unique_source_id": { "name": "unique_source_id", "nullsNotDistinct": false, - "columns": [ - "source", - "source_id" - ] + "columns": ["source", "source_id"] } }, "policies": {}, @@ -650,9 +605,7 @@ "topics_slug_unique": { "name": "topics_slug_unique", "nullsNotDistinct": false, - "columns": [ - "slug" - ] + "columns": ["slug"] } }, "policies": {}, @@ -748,12 +701,8 @@ "name": "translations_term_id_terms_id_fk", "tableFrom": "translations", "tableTo": "terms", - "columnsFrom": [ - "term_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["term_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -763,11 +712,7 @@ "unique_translations": { "name": "unique_translations", "nullsNotDistinct": false, - "columns": [ - "term_id", - "language_code", - "text" - ] + "columns": ["term_id", "language_code", "text"] } }, "policies": {}, @@ -844,9 +789,7 @@ "user_email_unique": { "name": "user_email_unique", "nullsNotDistinct": false, - "columns": [ - "email" - ] + "columns": ["email"] } }, "policies": {}, @@ -927,9 +870,5 @@ "roles": {}, "policies": {}, "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file + "_meta": { "columns": {}, "schemas": {}, "tables": {} } +} diff --git a/packages/db/drizzle/meta/0006_snapshot.json b/packages/db/drizzle/meta/0006_snapshot.json index b583776..4578a80 100644 --- a/packages/db/drizzle/meta/0006_snapshot.json +++ b/packages/db/drizzle/meta/0006_snapshot.json @@ -110,12 +110,8 @@ "name": "account_user_id_user_id_fk", "tableFrom": "account", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -149,12 +145,8 @@ "name": "deck_terms_deck_id_decks_id_fk", "tableFrom": "deck_terms", "tableTo": "decks", - "columnsFrom": [ - "deck_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deck_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -162,12 +154,8 @@ "name": "deck_terms_term_id_terms_id_fk", "tableFrom": "deck_terms", "tableTo": "terms", - "columnsFrom": [ - "term_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["term_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -175,10 +163,7 @@ "compositePrimaryKeys": { "deck_terms_deck_id_term_id_pk": { "name": "deck_terms_deck_id_term_id_pk", - "columns": [ - "deck_id", - "term_id" - ] + "columns": ["deck_id", "term_id"] } }, "uniqueConstraints": {}, @@ -265,10 +250,7 @@ "unique_deck_name": { "name": "unique_deck_name", "nullsNotDistinct": false, - "columns": [ - "name", - "source_language" - ] + "columns": ["name", "source_language"] } }, "policies": {}, @@ -335,12 +317,8 @@ "name": "lobbies_host_user_id_user_id_fk", "tableFrom": "lobbies", "tableTo": "user", - "columnsFrom": [ - "host_user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["host_user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -350,9 +328,7 @@ "lobbies_code_unique": { "name": "lobbies_code_unique", "nullsNotDistinct": false, - "columns": [ - "code" - ] + "columns": ["code"] } }, "policies": {}, @@ -401,12 +377,8 @@ "name": "lobby_players_lobby_id_lobbies_id_fk", "tableFrom": "lobby_players", "tableTo": "lobbies", - "columnsFrom": [ - "lobby_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["lobby_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -414,12 +386,8 @@ "name": "lobby_players_user_id_user_id_fk", "tableFrom": "lobby_players", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -427,10 +395,7 @@ "compositePrimaryKeys": { "lobby_players_lobby_id_user_id_pk": { "name": "lobby_players_lobby_id_user_id_pk", - "columns": [ - "lobby_id", - "user_id" - ] + "columns": ["lobby_id", "user_id"] } }, "uniqueConstraints": {}, @@ -514,12 +479,8 @@ "name": "session_user_id_user_id_fk", "tableFrom": "session", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -529,9 +490,7 @@ "session_token_unique": { "name": "session_token_unique", "nullsNotDistinct": false, - "columns": [ - "token" - ] + "columns": ["token"] } }, "policies": {}, @@ -581,12 +540,8 @@ "name": "term_glosses_term_id_terms_id_fk", "tableFrom": "term_glosses", "tableTo": "terms", - "columnsFrom": [ - "term_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["term_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -596,10 +551,7 @@ "unique_term_gloss": { "name": "unique_term_gloss", "nullsNotDistinct": false, - "columns": [ - "term_id", - "language_code" - ] + "columns": ["term_id", "language_code"] } }, "policies": {}, @@ -634,12 +586,8 @@ "name": "term_topics_term_id_terms_id_fk", "tableFrom": "term_topics", "tableTo": "terms", - "columnsFrom": [ - "term_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["term_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -647,12 +595,8 @@ "name": "term_topics_topic_id_topics_id_fk", "tableFrom": "term_topics", "tableTo": "topics", - "columnsFrom": [ - "topic_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["topic_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -660,10 +604,7 @@ "compositePrimaryKeys": { "term_topics_term_id_topic_id_pk": { "name": "term_topics_term_id_topic_id_pk", - "columns": [ - "term_id", - "topic_id" - ] + "columns": ["term_id", "topic_id"] } }, "uniqueConstraints": {}, @@ -737,10 +678,7 @@ "unique_source_id": { "name": "unique_source_id", "nullsNotDistinct": false, - "columns": [ - "source", - "source_id" - ] + "columns": ["source", "source_id"] } }, "policies": {}, @@ -796,9 +734,7 @@ "topics_slug_unique": { "name": "topics_slug_unique", "nullsNotDistinct": false, - "columns": [ - "slug" - ] + "columns": ["slug"] } }, "policies": {}, @@ -894,12 +830,8 @@ "name": "translations_term_id_terms_id_fk", "tableFrom": "translations", "tableTo": "terms", - "columnsFrom": [ - "term_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["term_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -909,11 +841,7 @@ "unique_translations": { "name": "unique_translations", "nullsNotDistinct": false, - "columns": [ - "term_id", - "language_code", - "text" - ] + "columns": ["term_id", "language_code", "text"] } }, "policies": {}, @@ -990,9 +918,7 @@ "user_email_unique": { "name": "user_email_unique", "nullsNotDistinct": false, - "columns": [ - "email" - ] + "columns": ["email"] } }, "policies": {}, @@ -1073,9 +999,5 @@ "roles": {}, "policies": {}, "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file + "_meta": { "columns": {}, "schemas": {}, "tables": {} } +} diff --git a/packages/db/drizzle/meta/_journal.json b/packages/db/drizzle/meta/_journal.json index e0701fa..4ae9761 100644 --- a/packages/db/drizzle/meta/_journal.json +++ b/packages/db/drizzle/meta/_journal.json @@ -52,4 +52,4 @@ "breakpoints": true } ] -} \ No newline at end of file +}