formatting
This commit is contained in:
parent
7f56ad89e6
commit
a6d8ddec3b
5 changed files with 82 additions and 221 deletions
|
|
@ -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) |
|
||||
|
|
|
|||
|
|
@ -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 | ✅ |
|
||||
|
|
|
|||
|
|
@ -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": {} }
|
||||
}
|
||||
|
|
@ -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": {} }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue