v3: comments say what the code can't — the documentation pass wanted JSDoc on every export and every field of an exported interface, which filled the code with restatements ("The dump.", "Whether it is loading.", "The props of X.", "Renders the X.") and module docs that told a reader nothing ("The hot and new feeds, and the props every main feed of the index takes."); some were wrong as well as vague. Every comment in api/, shared/ and src/ is rewritten under one rule, now stated in the README's "Comments" section: every module and export still has a JSDoc, and it gives context (who uses it and where), usage (what a caller must know: a precondition, what it leaves to the caller, a side effect) or its place in the chain (where its input comes from, where its output goes); a field, parameter, private function or local gets one only when it adds to its parent's, and context about a whole type goes on the type; a type's doc is phrased from the value's side ("Returned to Y by X when Z", "Passed to Y by X"); full sentences, as short as they can be, no label-colon-list; // goes wherever the code isn't obvious and says why, and the section banners and narration go. Every claim was checked against the code, which turned up some forty comments that were wrong: DumpCard's claimed it was only used by the hot and new feeds, the WebSocket welcome claimed to be a socket's first message (presence comes first), UpdateUserRequest said null removes a description (it keeps it), deletedDumpIds leaves out that it also holds dumps made private, THEME_COLOR claimed to mirror index.html's, and the like. The routers' JSDoc now says where they are mounted and what becomes of a thrown APIException. doc-lint.ts lets a field without a doc through; a module or export without one still fails. No code changes; 204 backend and 628 frontend tests pass, and doc:lint, deno check, deno lint and tsc are clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
khannurien
2026-09-29 14:31:14 +00:00
parent 42e0356d21
commit 0d4e344d77
287 changed files with 5679 additions and 5135 deletions

87
mod.ts
View File

@@ -1,55 +1,56 @@
/**
* A small invite-only social platform for sharing links and files. The
* repository holds three parts: the backend in `api/`, the frontend in `src/`,
* and in `shared/` whatever crosses the wire between them. This reference
* documents all three; [every module](./all_symbols.html) is listed by path,
* so they come grouped by part and layer.
* Documents gerbeur, a small invite-only social platform for sharing links and
* files. The repository holds three parts: the backend in `api/`, the
* frontend in `src/`, and in `shared/` whatever crosses the wire between them.
* [Every module](./all_symbols.html) is listed by path, so the list groups
* them by part and layer.
*
* ## Backend — `api/`
* ## Backend, in `api/`
*
* An Oak server over SQLite that answers the API and the WebSocket, and serves
* the built frontend. `api/main.ts` builds the application and listens. A
* request goes through a route, which parses it and answers. The route calls
* services, which hold the logic and every SQL query; they read rows through
* the model, and reach other sites only through `remote/`. Each folder holds
* one kind of module, and each file is named after its domain:
* An Oak server over SQLite answers the API and the WebSocket, and serves the
* built frontend. `api/main.ts` builds the application and listens. A request
* goes to a route, which parses it, calls services and answers. The services
* hold the logic and every SQL query, read rows through the model, and reach
* other sites only through `remote/`. Each folder holds one kind of module,
* and each file is named after its domain.
*
* - `routes/` — the HTTP API. Each router's page lists its endpoints: method
* and path, who may call it, what it does.
* - `middleware/` — what runs around every route: auth, errors, OG tags.
* - `services/` — the logic and every SQL query, one module per domain.
* - `model/` — per table, its row type, guard and mappers.
* - `validators/` — the request-body guards.
* - `remote/` — the only place that fetches from other sites; its `providers/`
* build the previews of each kind of site.
* - `lib/` — helpers that belong to no layer.
* - `db/` — the handle, its creation, migration and startup housekeeping;
* `db/migrations/` are applied in order, each once.
* - `config.ts` — the settings read from the environment; `scripts/` — the
* icon generator.
* - `routes/` holds the HTTP API. Each router's page lists its endpoints, with
* their method and path, who may call them, and what they do.
* - `middleware/` holds what runs around the routes, which is auth, errors and
* the Open Graph tags.
* - `services/` holds the logic and every SQL query, one module per domain.
* - `model/` holds each table's row type, guard and mappers.
* - `validators/` holds the guards of the request bodies.
* - `remote/` is the only place that fetches from other sites, and its
* `providers/` build the previews of each kind of site.
* - `lib/` holds the helpers that belong to no layer.
* - `db/` opens, creates and migrates the database, and cleans it up at
* startup. `db/migrations/` are applied in order, each once.
* - `config.ts` reads the settings from the environment, and `scripts/` holds
* the icon generator.
*
* ## Shared — `shared/`
* ## Shared, in `shared/`
*
* The types and constants both halves use, one module per domain: the API
* envelope, each domain's types and request bodies, the socket protocol, the
* validation limits and the role permissions. It imports nothing from either
* half. The server sends `Date`s; the client reads the same types through
* `Wire<T>`, with every `Date` an ISO string.
* The types and constants both halves use sit here, one module per domain.
* They are the API envelope, each domain's types and request bodies, the
* socket protocol, the validation limits and the role permissions. `shared/`
* imports nothing from either half. The server sends `Date`s, and the client
* reads the same types through `Wire<T>`, where every `Date` is an ISO string.
*
* ## Frontend — `src/`
* ## Frontend, in `src/`
*
* The React app, built with Vite and translated with Lingui. `main.tsx` mounts
* it, `App.tsx` holds the providers and the route table, `i18n.ts` the
* language. A page reads the API and the socket through contexts and hooks, and
* draws with components; utils hold what isn't React at all.
* The React app is built with Vite and translated with Lingui. `main.tsx`
* mounts it, `App.tsx` holds the providers and the route table, and `i18n.ts`
* sets the language. A page reads the API and the socket through contexts and
* hooks, and draws with components, while utils hold what isn't React at all.
*
* - `pages/` — one component per route, each naming it, and the two guards
* that wrap the routes for the signed in and the signed out.
* - `config/` — settings read at startup.
* - `contexts/` — a `FooContext` holding the state and its `FooProvider`.
* - `hooks/` — every hook.
* - `components/` — only components.
* - `utils/` — every module that isn't React.
* - `pages/` holds one component per route, each naming its route, and the two
* guards that keep routes to signed-in or signed-out visitors.
* - `config/` holds the settings read at startup.
* - `contexts/` holds, for each domain, a `FooContext` with its state and the
* `FooProvider` that fills it.
* - `hooks/` holds every hook, and `components/` only components.
* - `utils/` holds every module that isn't React.
*
* Every layer but `pages/` and `config/` is split into the same domains (auth,
* category, chat, comment, dump, editor, feed, form, layout, player, playlist,