formatting

This commit is contained in:
lila 2026-04-17 15:52:50 +02:00
parent 7f56ad89e6
commit a6d8ddec3b
5 changed files with 82 additions and 221 deletions

View file

@ -13,7 +13,7 @@ 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 |
@ -21,7 +21,7 @@ This document describes the production deployment of the lila vocabulary trainer
### Ports Exposed to the Internet
| Port | Service |
|---|---|
| ---- | -------------------------------- |
| 80 | Caddy (HTTP, redirects to HTTPS) |
| 443 | Caddy (HTTPS) |
| 2222 | Forgejo SSH (git clone/push) |

View file

@ -291,7 +291,7 @@ 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 | ✅ |

View file

@ -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": {}
}
"_meta": { "columns": {}, "schemas": {}, "tables": {} }
}

View file

@ -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": {}
}
"_meta": { "columns": {}, "schemas": {}, "tables": {} }
}