Commit Graph

2 Commits

Author SHA1 Message Date
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.
All checks were successful
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
fb8364e24d v3: reworked posting — three panels, drafts, duplicate detection, upload progress
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 42s
Posting a dump was a single form where the important choices were the easiest
to miss. It is now three panels: link or file, why & where, playlists.

Composition:
- No more URL/File toggle. An empty panel offers both ways in at once and the
  kind follows what you actually did; a file dropped anywhere in the modal is
  accepted, not just on the zone.
- Categories and visibility get their own panel instead of a disclosure that
  read as optional, and the primary button stays "Next" until they've been
  seen. Visibility carries a real label now.
- The draft (link, title, why, categories, visibility) is mirrored to
  localStorage on every change and restored on reopen, so Escape or a stray
  backdrop click costs nothing. Only an attached file can't be restored, so
  that is the one case that asks before closing.
- URL dumps can carry a poster-supplied title instead of being stuck with
  whatever the page scraped, editable right under the preview.
- Multipart uploads go through XHR so there is a real progress bar and a
  percentage on the button, rather than 50 MB of silence.

Duplicates:
- New dumps.url_canonical column (+ index, backfilled by 0013) holding a lossy
  key that ignores scheme, www., trailing slashes, tracking parameters and
  YouTube share shapes. GET /api/dumps/by-url reads it, and the create form
  warns "already dumped by X" while it fetches the preview. Never blocking.

Fixes:
- /api/preview now reports whether the page was actually reached: a failed
  fetch still yields a hostname-only stub, so a dead link and a page without
  metadata used to render identically.
- The Web Share Target never worked. The manifest posts to "/", but the index
  redirect dropped the query string, so every Android share landed on the feed
  with nothing pre-filled.
- File dumps no longer take the extension into their title.
- The link field no longer autofocuses on touch, where it raised a keyboard
  over the modal.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiAPtJZeCYYk8rKehtLUQU
2026-09-08 14:40:37 +00:00