Compile the API instead of running its TypeScript in production.

The unit's ExecStart named src/index.ts, so every start depended on the host
having Node 22.18 or newer for native type stripping. A deploy onto a host with
Node 20 met ERR_UNKNOWN_FILE_EXTENSION, exited in under a second, and was
restarted 464 times over fifteen hours with nothing anywhere going red.

api/tsconfig.json now emits to api/dist. The source keeps its explicit .ts import
specifiers, which is what makes `node --watch src/index.ts` work in development;
rewriteRelativeImportExtensions turns them into .js on the way out, so what runs
in production is ordinary ESM that any Node from 20.18 up will start.

`pnpm build` builds shared, then api, then web. `pnpm dev` is unchanged.

deploy/ is tracked rather than ignored: the unit files are the thing an operator
copies to /etc/systemd/system, and the alert unit added next has to live
somewhere a deploy can find it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
michilis
2026-08-25 15:58:53 +02:00
co-authored by Claude Opus 5
parent 06ba3d35e7
commit 65307ba278
10 changed files with 455 additions and 17 deletions
+2 -2
View File
@@ -4,7 +4,7 @@
"version": "2.0.0",
"type": "module",
"engines": {
"node": ">=22.18"
"node": ">=20.18"
},
"scripts": {
"dev": "pnpm --parallel --filter ./api --filter ./web dev",
@@ -12,7 +12,7 @@
"dev:web": "pnpm --filter ./web dev",
"seed": "pnpm --filter ./api seed",
"bones": "pnpm --filter ./web bones",
"build": "pnpm --filter ./shared build && pnpm --filter ./web build",
"build": "pnpm --filter ./shared build && pnpm --filter ./api build && pnpm --filter ./web build",
"start": "pnpm --filter ./web start",
"check:links": "pnpm --filter ./web check:links",
"typecheck": "pnpm -r typecheck",