rojects/workspace/history/2026/07-July/12-Sunday/index.html

221 lines
10 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Session Summary — 12 July 2026</title>
<link rel="stylesheet" href="../../../../_assets_/styles.css">
<link rel="stylesheet" href="../../../../_assets_/nav.css">
</head>
<body>
<div class="page">
<header>
<p class="date">Sunday, 12 July 2026</p>
<h1>Roject — Session Summary</h1>
<p class="subtitle">
Full project directory restructure and first production deployment —
source/, build/app/, build/data/, source/pages/; Roject live at
roject.rokojori.com via nginx + systemd on Server A.
</p>
</header>
<section>
<h2>What we built</h2>
<div class="card">
<h3>Directory restructure</h3>
<p>
The project root was reorganised into two top-level directories that
cleanly separate source from build artefacts and runtime data:
</p>
<ul style="line-height:1.9;margin-top:0.75rem">
<li><code>source/</code> — all TypeScript source (components, editor, server, rojos, locales, library-ts submodule) plus locale data and HTML pages</li>
<li><code>build/app/</code> — compiled frontend output (was <code>public/</code>)</li>
<li><code>build/data/db/</code> — JSON user/project data (was <code>data/</code>)</li>
<li><code>build/data/storage/</code> — project files, sessions, layouts (was <code>storage/</code>)</li>
</ul>
<p style="margin-top:0.75rem">
The git submodule (<code>library-ts</code>) was moved with <code>git mv</code>
so <code>.gitmodules</code> stayed in sync automatically. The entire
<code>build/</code> tree is gitignored; <code>source/</code> is fully tracked.
</p>
<div class="tags">
<span class="tag">source/</span>
<span class="tag">build/app/</span>
<span class="tag">build/data/</span>
<span class="tag">git mv</span>
</div>
</div>
<div class="card">
<h3>source/pages/ + copy-pages build step</h3>
<p>
HTML pages (<code>editor.html</code>, <code>dashboard.html</code>, etc.)
moved from <code>build/app/</code> into <code>source/pages/</code> so they
are tracked in git as source files. A new <code>scripts/copy-pages.js</code>
(plain Node.js, no extra dependencies) copies them to <code>build/app/</code>
as the second step of <code>npm run build</code>:
</p>
<pre style="margin-top:0.75rem"><code>tsc --build tsconfig.client.json &amp;&amp; node scripts/copy-pages.js</code></pre>
<div class="tags">
<span class="tag">source/pages/</span>
<span class="tag">scripts/copy-pages.js</span>
<span class="tag">npm run build</span>
</div>
</div>
<div class="card">
<h3>First production deployment — roject.rokojori.com</h3>
<p>
Roject deployed to Server A and served publicly at
<code>https://roject.rokojori.com</code>. Stack: Node.js 20,
<code>ts-node</code> running <code>source/server/index.ts</code> managed
by a systemd service, nginx as TLS-terminating reverse proxy with a
Let's Encrypt certificate, port 3000 kept closed at the IONOS firewall.
</p>
<p style="margin-top:0.75rem">
Several build gaps were discovered and fixed during the deploy:
component CSS files were never in source control (moved to
<code>source/components/</code>); vendor libraries were in the gitignored
<code>build/app/vendor/</code> (moved to <code>source/vendor/</code>);
<code>mkdirSync</code> calls in the server lacked <code>{ recursive: true }</code>
causing a crash on a fresh clone; and the library-ts browser
<code>tsconfig.roject.json</code> still referenced the old
<code>public/</code> outDir instead of <code>build/app/</code>.
The copy script was also expanded to copy all non-TS static assets
(CSS, SVG, etc.) from all frontend source directories.
</p>
<div class="tags">
<span class="tag">roject.rokojori.com</span>
<span class="tag">systemd</span>
<span class="tag">nginx</span>
<span class="tag">Let's Encrypt</span>
<span class="tag">Node.js 20</span>
</div>
</div>
<div class="card">
<h3>EmailService — SMTP email sending</h3>
<p>
Added a thin email layer to the backend under
<code>source/server/email/</code>: an <code>EmailSender</code> interface,
an <code>SMTPEmailSender</code> implementation using Nodemailer, and an
<code>EmailService</code> static facade that instantiates the sender from
environment variables (<code>SMTP_HOST</code>, <code>SMTP_PORT</code>,
<code>SMTP_SECURE</code>, <code>SMTP_USER</code>, <code>SMTP_PASS</code>,
<code>SMTP_FROM</code>). Swapping the implementation requires changing one
line in <code>EmailService.ts</code>.
</p>
<div class="tags">
<span class="tag">Nodemailer</span>
<span class="tag">EmailSender interface</span>
<span class="tag">static facade</span>
<span class="tag">env vars</span>
</div>
</div>
</section>
<section>
<h2>Key Decisions</h2>
<div class="decision">
<strong>Two locale directories: source/locales/ vs source/locale-data/</strong>
<p>
<code>src/locales/</code> (TypeScript locale management code) moved to
<code>source/locales/</code>. The root <code>locales/</code> (raw locale
data files — <code>en/</code>) moved to <code>source/locale-data/</code>.
Merging them into one directory would have mixed TypeScript source with data
files; keeping them separate makes each directory's purpose unambiguous.
</p>
</div>
<div class="decision">
<strong>build/ fully gitignored, source/pages/ tracked</strong>
<p>
The old setup had <code>public/</code> gitignored with a <code>!public/*.html</code>
exception that never actually tracked the files. The new setup is cleaner:
all hand-written HTML pages live in <code>source/pages/</code> (tracked),
<code>build/</code> is entirely ignored, and the copy step bridges the two
at build time.
</p>
</div>
<div class="decision">
<strong>systemd over PM2</strong>
<p>
systemd is already present on every Linux server and integrates with
<code>journalctl</code> for log management. PM2 is easier for day-to-day
Node.js process management but adds an extra global dependency. For a
single-service deployment systemd is sufficient and keeps the server
dependency surface minimal.
</p>
</div>
<div class="decision">
<strong>Static assets belong in source/, not build/</strong>
<p>
CSS files, vendor libraries, and SVGs were historically placed directly
in <code>public/</code> (gitignored) and never tracked. A fresh server
clone exposes this immediately — nothing in <code>build/</code> exists
until the build runs, and the build can only copy what it finds in
<code>source/</code>. Moving all static assets to <code>source/</code>
makes them first-class source files and ensures a clean deploy from any
fresh clone.
</p>
</div>
<div class="decision">
<strong>Plain Node.js copy script, no npm dependency</strong>
<p>
<code>scripts/copy-pages.js</code> uses only <code>fs</code> and
<code>path</code> from the Node.js standard library. Adding a package like
<code>copyfiles</code> or <code>cpx</code> for a four-line operation would
be unnecessary complexity.
</p>
</div>
</section>
<section>
<h2>Structural Changes</h2>
<div class="card">
<p>
<code>src/</code><code>source/</code> (git mv, including library-ts submodule)<br>
<code>server/</code><code>source/server/</code> (git mv)<br>
<code>locales/</code><code>source/locale-data/</code> (git mv)<br>
<code>public/</code><code>build/app/</code> (filesystem move, gitignored)<br>
<code>data/</code><code>build/data/db/</code> (filesystem move, gitignored)<br>
<code>storage/</code><code>build/data/storage/</code> (filesystem move, gitignored)<br>
<code>source/pages/</code> — new: hand-written HTML pages (tracked)<br>
<code>scripts/copy-pages.js</code> — new: copies pages to build/app/ on build<br>
<code>tsconfig.client.json</code> — rootDir, outDir, include, exclude, references updated<br>
<code>tsconfig.json</code> — include updated<br>
<code>tsconfig.ts-node.json</code> — include updated<br>
<code>source/library-ts/browser/tsconfig.roject.json</code> — outDir updated<br>
<code>package.json</code> — main and build script updated<br>
<code>.gitignore</code> — replaced data/, storage/, public/ with build/<br>
<code>source/server/</code> — all __dirname paths and library-ts imports updated<br>
<code>source/components/*.css</code> — moved from build/app/ into source control<br>
<code>source/vendor/</code> — vendor libs moved from build/app/ into source control<br>
<code>source/library-ts/browser/tsconfig.roject.json</code> — outDir fixed in submodule, committed and pushed<br>
<code>scripts/copy-pages.js</code> — expanded to copy all non-TS static assets from all frontend source dirs<br>
<code>source/server/db.ts</code>, <code>storage.ts</code> — mkdirSync updated to use <code>{ recursive: true }</code><br>
<code>/etc/systemd/system/roject.service</code> — new on Server A<br>
<code>/etc/nginx/sites-available/roject</code> — new on Server A
</p>
</div>
</section>
<footer>
Roject &mdash; session log &mdash; 12 July 2026
</footer>
</div>
<script>var NAV_ROOT = '../../../../';</script>
<script src="../../../../_assets_/nav-data.js"></script>
<script src="../../../../_assets_/nav.js"></script>
</body>
</html>