khannurien
0d4e344d77
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 >
2026-09-29 14:31:14 +00:00
khannurien
d62e4a9883
v3: the backend is documented for deno doc, one way in every file, and the docs build and publish themselves — comments were in three shapes: file headers as // lines, as an untagged /** */ (which deno doc drops, only an @module block counts) or missing; 43 exports described by a // deno doc can't see, two JSDoc blocks sitting on the wrong declaration and one duplicated; endpoints commented in 5 of 18 route files, three ways, on router.get() calls no doc tool reads. The rule, applied to every non-test module of api/, migrations included: each opens with a /** … @module */ block; every export has JSDoc, and so does every field of an exported interface; a comment describing a declaration is /** */, // only notes code; functions open with a verb, everything else with a noun phrase; parameters are named in the prose, {@link} only for symbols in scope; whatever throws to its caller says so with @throws (for an APIException, the statuses and when); a router's JSDoc lists its endpoints, method and path, who may call it, what it does. deno doc --lint goes from 528 errors to none in api/ (shared/ keeps its 385; it is next). The lint also wanted explicit types on config.ts's settings and a few return types, JsonLdResult exported, and the routers typed Router. deno task doc builds the HTML reference into docs/ from every module of api/ and shared/ but the tests, deno task doc:lint lints it; the index page is the module doc of a root mod.ts (deno.json's exports), which introduces the backend, shared/ and the frontend to come and links every module, and mod.test.ts fails when one is missing. The docs workflow builds it on every push to main that touches them and publishes it to the gh-pages branch, like publish-assistant's. Two defects found along the way are fixed: a private playlist's cover was served to anyone who had its id or slug, and now needs its owner's media token, as private dump files do (playlistImageUrl adds it for private playlists only, so public cover URLs stay the same for everyone); og.ts and static.ts each filled index.html's placeholders, and now share lib/index-html.ts, so the OG middleware picks up a rebuilt index.html instead of keeping the first it read. The README states the documentation rule. 205 backend and 628 frontend tests pass.
...
Build and Publish Docker Image / build-and-push (push) Successful in 47s
Build and deploy docs / build-and-push (push) Successful in 26s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-09-27 21:07:40 +00:00
khannurien
d70761ecae
v3: youtube playlists get a tracklist too — the embed keeps playing the list, so the rows come from two halves: /api/youtube/playlist scrapes titles and lengths off the playlist page (current lockup rows and the older renderer, cached 6h), while the IFrame API attached to the iframe reports the position and takes row clicks and ⏮/⏭; the header names the playing video with the dump's title below it, like a bandcamp track; either half can fail — no scrape leaves the bare embed, no API leaves the rows as a table of contents — and the pause an API-enabled embed gives itself when the tab goes to the background is undone within a short window, so a later pause still stands
...
Build and Publish Docker Image / build-and-push (push) Successful in 42s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-09-19 21:51:10 +00:00
khannurien
2606ef4ccc
v3: native bandcamp playback and a queue in the global player
...
Build and Publish Docker Image / build-and-push (push) Successful in 43s
The player now holds a queue instead of a single item, so albums play
through and single tracks share the same code path. Adds a "stream" item
kind for expiring, remotely-hosted sources: Bandcamp signs its mp3 URLs
for ~24h, so an item carries the page it came from and re-resolves itself
on error or on a stale restored session, falling back to the iframe embed
if that fails too.
Gated behind GERBEUR_BANDCAMP_PLAYER (default "embed"), injected into a
meta tag the same way as site-name/site-emoji.
Also: player header gains artwork and a subtitle, volume persists across
queue advances and reloads, and cross-origin streams get a plain seek bar
rather than a waveform that can never decode.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01SbtjNsT5wvuABnfqhegZEJ
2026-08-22 12:14:28 +00:00
khannurien
6c4f410d9b
v3: added a chatbox
Build and Publish Docker Image / build-and-push (push) Has been cancelled
2026-06-29 20:25:10 +00:00
khannurien
fae25f3e6c
v3: added site-wide categories, added admin category management, various visual fixes
Build and Publish Docker Image / build-and-push (push) Successful in 2m52s
2026-06-28 16:23:44 +00:00
khannurien
856511777c
chore: smaller docker image, simplification pass on environment variables, fix direct navigation without vite
Build and Publish Docker Image / build-and-push (push) Successful in 46s
2026-04-08 19:43:19 +00:00
khannurien
1321e374bf
v3: performance pass, bundle size pass, i18n pass, docker pass
2026-04-08 13:19:39 +00:00
khannurien
cbb3505139
v3: search engine, responsive header with compact user menu
2026-03-29 11:56:31 +00:00
khannurien
f0f6472db6
v3: added attachments to resources, allow users to paste images into TextEditor, strengthened WS reliability
2026-03-27 08:53:32 +00:00
khannurien
ca70bdc14b
v3: added opengraph support to the app, wrote README instructions incl. a Docker image
2026-03-26 19:55:48 +00:00
khannurien
0cb5a798c7
v3: added journal view to the index, code organization pass
2026-03-25 21:07:17 +00:00
khannurien
c5051e3485
v3: added emoji picker, various bug and layout fixes
2026-03-22 20:24:29 +00:00
khannurien
608c6bc6a8
v3: follows, notifications, invite-only registration, unread markers
2026-03-21 18:42:47 +00:00
khannurien
7c098e7c4c
v2: global player, infinite scroll, image picker, threaded comments
2026-03-21 13:55:22 +00:00
khannurien
be426eb150
v1 feature: added playlists
2026-03-16 16:52:53 +00:00
khannurien
e88fed4e98
vibe coded v1
2026-03-16 07:34:49 +00:00
khannurien
6207a7549f
initial commit, boilerplate stuff
2026-03-15 17:15:46 +00:00