tracker
All repositories: gitoria
10.5 KB
# Decisions — tracker.worldapi.org<!-- generated by the antcolony librarian (antcolony-scheduler: ./colony librarian) from librarian/decisions.json — do not edit by hand, it is rewritten -->The creator's decisions for **tracker.worldapi.org** — current state only (superseded ones: `DECISIONS-archive.md` beside this file).**A decision here overrides anything else; ask only if it is not decided here.**Each entry: date · the creator's exact words in quotes · where it was said · "means" = a READING (the librarian's or the architect's), not the creator's words — when in doubt, the quote counts.## Contents- [ident registration](#ident-registration) — 1- [look and style](#look-and-style) — 1- [tracker concept](#tracker-concept) — 11## ident registration- 2026-09-27 · **"Before you can test:** register the app in ident (/apps) for the origin https://tracker.worldapi.org and give me the key and secret — until then the sign-in button shows "not registered with ident yet"."** · [tracker.worldapi.org #1 — Step 1: an empty tracker with the ident login](https://tickets.worldapi.org/projects/tracker.worldapi.org/1)- means (the librarian's reading, not the creator's words): Register the tracker app in ident (/apps) for origin https://tracker.worldapi.org and give the creator the key and secret; without this the sign-in button stays broken.## look and style- 2026-09-27 · **"Fixed by the architect after your correction: now NO button has a border — also "Log out", the signed-in ident status and the identities in the ident dropdown. Only an inverted button (class "inverted", accent outline) would have one; tracker has none yet."** · [tracker.worldapi.org #3 — Design notes from the first test: no borders on the header and the bu…](https://tickets.worldapi.org/projects/tracker.worldapi.org/3)- means (the librarian's reading, not the creator's words): No border on any tracker button including "Log out", the signed-in ident status pill, and identities in the ident dropdown; only class "inverted" (accent outline) buttons keep a border — tracker currently has none.## tracker concept- 2026-09-27 · **"Step 5 (/unwatched) is live — step 6 can start."** · [tracker.worldapi.org #6 — Step 6: /schedule — the upcoming episodes of the shows you follow](https://tickets.worldapi.org/projects/tracker.worldapi.org/6)- means (the librarian's reading, not the creator's words): Tracker step 6 (/schedule) is now unblocked and may begin; the hold is lifted.- 2026-09-27 · **"Step 4 (the show page) is live — step 5 can start."** · [tracker.worldapi.org #5 — Step 5: /unwatched — the unwatched episodes of the shows you follow](https://tickets.worldapi.org/projects/tracker.worldapi.org/5)- means (the librarian's reading, not the creator's words): Tracker step 5 (/unwatched) is now unblocked and may begin; the hold is lifted.- 2026-09-27 · **"Posters: the old tracker kept them as files (storage/posters/<id>.jpg); those files are gone — they were never in the backup (see LOG). Keep the placeholder for now; getting posters again from TMDB (the show's tmdbId) is a later step with the TMDB token. The open point that matters in this step is the check click: it must really toggle (and a season's check all its episodes)."** · [tracker.worldapi.org #4 — Step 4: the show page /shows/:slug with seasons, episodes and watch c…](https://tickets.worldapi.org/projects/tracker.worldapi.org/4)- means (the librarian's reading, not the creator's words): Real poster images are out of scope now (files lost, not backed up); keep the placeholder and defer TMDB re-fetching to a later ticket. For this step, prioritize making the watch check actually toggle, including a season check toggling all its episodes.- 2026-09-27 · [tracker.worldapi.org #6 — Step 6: /schedule — the upcoming episodes of the shows you follow](https://tickets.worldapi.org/projects/tracker.worldapi.org/6) · the creator wrote:> Step 6: /schedule — the upcoming episodes of the shows you follow>> A list of the episodes still to come from the shows you follow, soonest first, without checks.> **Test:** open /schedule — only future episodes of followed shows, the next one on top, no check icons.> **Details:**> - Creator: "/schedule has a similar list without check icons for he upcoming episodes of shows followed".> - Upcoming = release date after today; order soonest first (decided by the architect; the creator named the order only for /unwatched).> - Same row layout as /unwatched (step 5) minus the check.- means (the librarian's reading, not the creator's words): Build /schedule: upcoming (release date after today) episodes of followed shows, soonest first, same row layout as /unwatched but without the check icon.- 2026-09-27 · [tracker.worldapi.org #5 — Step 5: /unwatched — the unwatched episodes of the shows you follow](https://tickets.worldapi.org/projects/tracker.worldapi.org/5) · the creator wrote:> - Creator: "/unwatched lists all unwatched episodes of shows followed in release date desc order"; "check icon is a disc with a check in it".> - Only episodes already released (release date today or earlier); each row: check icon, show title, episode number, episode title, release date; the show links to /shows/:slug.> - Same check icon and watch logic as the show page (step 4) — reuse, don't copy.- means (the librarian's reading, not the creator's words): Build /unwatched: list unwatched episodes of followed shows, newest release first, only already-released episodes; each row shows check icon, show title, episode number, episode title, release date, show links to /shows/:slug; reuse the show page's check icon and watch logic, don't duplicate it.- 2026-09-27 · **"/shows/:slug shows the poster on the left, right of it the title of the show, the genre pills, below the plot summary, below that the artists just as normal links, separated with comma color red, genres are blue i think, this is the show header. then all sesions in reverse order, latest on top, below them collapsable their episodes episodes first the round check icon, if the episode was watche by the user looking its solid, if not its regular. then the episode number, then the title. the last season is not collpased. click on the check adds a watch. the season also has a check, if the season is checked or unchecked all its episodes get checked or unchecked. artists link to /person/<artist-slug> the genre to /genre/<genre-slug>"** · [tracker.worldapi.org #4 — Step 4: the show page /shows/:slug with seasons, episodes and watch c…](https://tickets.worldapi.org/projects/tracker.worldapi.org/4)- means (the librarian's reading, not the creator's words): Build /shows/:slug exactly as specified: poster left, title/genre pills/plot right, artists below as red comma-separated links, genre pills blue, artist/genre links use slugs; seasons listed reverse-chronological, all collapsible except the latest; each episode shows a check icon (solid disc if the…- 2026-09-27 · **"The old data itself had 36,194 episodes without a season link (and 3 watches without a target) — kept as they were; they can be re-linked by show + season number later."** · [tracker.worldapi.org #2 — Step 2: move the old tracker data into the new app](https://tickets.worldapi.org/projects/tracker.worldapi.org/2)- means (the librarian's reading, not the creator's words): Episodes without a season link and watches without a target were migrated as-is, not dropped or fixed now; a later step may re-link them by matching show + season number.- 2026-09-27 · **"Copy calendar.worldapi.org's login unchanged: the header in components/main.hl with <ident-selector>, users.hl, login.js, and the login routes in project.hl. Open those files in /media/STORAGE/projects/calendar.worldapi.org — not ident's test app."** · [tracker.worldapi.org #1 — Step 1: an empty tracker with the ident login](https://tickets.worldapi.org/projects/tracker.worldapi.org/1)- means (the librarian's reading, not the creator's words): Tracker's login must copy calendar's unchanged (identity selector in header, homepage stays empty, no centered sign-in); rejected for not matching.- 2026-09-27 · **"Step 1 is live (https://tickets.worldapi.org/projects/tracker.worldapi.org/1) — step 2 can start."** · [tracker.worldapi.org #2 — Step 2: move the old tracker data into the new app](https://tickets.worldapi.org/projects/tracker.worldapi.org/2)- means (the librarian's reading, not the creator's words): Tracker step 2 (moving old data into the new app) is now unblocked and may begin; the earlier hold is lifted.- 2026-09-27 · **"Every record gets a NEW mpackdb id. Build the map old id → new id, then re-point EVERY reference: Show.seasons/genres/cast, Season.show/episodes, Episode.show/season, Person.shows, Follow.oid/userId, Watch.oid (episode or season, sometimes a plain string)/userId."** · [tracker.worldapi.org #2 — Step 2: move the old tracker data into the new app](https://tickets.worldapi.org/projects/tracker.worldapi.org/2)- means (the librarian's reading, not the creator's words): Tracker step 2: migrate old MongoDB export into new app db with fresh mpackdb ids via an old→new id map, re-pointing every reference listed; only user is creator (ident az5b2), old password hash dropped; build an idempotent one-off tool in tools/ that prints counts and proves counts match, zero d…- 2026-09-27 · [tracker.worldapi.org #1 — Step 1: an empty tracker with the ident login](https://tickets.worldapi.org/projects/tracker.worldapi.org/1) · the creator wrote:> Step 1: an empty tracker with the ident login>> The new tracker starts as an empty app: sign in with ident, then an empty homepage.> **Test:** open https://tracker.worldapi.org, sign in with ident, see the empty homepage with your name and a sign-out.> **Details:**> - New Hybriel app in its own folder, set up like calendar/notes (vendored Hybriel, deploy script, container, port 45008).> - Login exactly like calendar: ident only, no own passwords.> - Nothing else: no shows, no data, no design from the old app. The next steps come from the creator (see CONCEPT.md).> - Proof: a gate with a real ident copy and a real browser: signed out → sign in → homepage → sign out.- means (the librarian's reading, not the creator's words): Tracker step 1 is a new Hybriel app (own folder, vendored Hybriel, deploy script, container, port 45008) with ident-only login like calendar (no own passwords); build nothing else — no shows, data, or design from the old app; further steps wait for the creator via CONCEPT.md.
Branches
- mainmain branch
Latest commits
- b10f00c8tracker#39: double episodes — migrated episodes whose TMDB id TMDB replaced are adopted by their number in the sync (old id -> migratedTmdbId); merge.hl step 3 merges each season's doubles at start (keeper: most watches > synced > first; watches moved/parked; tombstones into mergedEpisodes, nothing deleted); tools/count-duplicate-episodes.hl; gate fixture + paths-m039; live copy 850 -> 0 in 64 s; gates 373/0, 32/0, 52/0mre
- 8751adb8tracker: report 032mre
- 9bce1f65tracker mission 032: STATUS gate files + the hour-boundary flakemre
- 718bfb89tracker#37 (mission 032): /people = everyone, last updated first (updatedAt stamped by the person fill; view built at boot, touched people first at once), photo + name tiles (person colour) with the /movies pagination, /people/<letter> removed; photo = our file, tmdbProfile, a cast/crew entry's profile (in-memory map at boot), else the new 'no photo' placeholder; new cast/crew/created_by people keep tmdbProfile; search people rows with the photo; /settings = the heading only; util.hl sortDesc starts from sorted runs (same result, 105k: 1.6 s -> 0.15 s); gates 369/0, 32/0, 52/0, check-theme 0; README/STATUS/LOGmre
- 96ba683adeploy.sh: a gate without a 'passed,' line (check-theme) no longer ends the scriptmre
- eb3b9205tracker: report 031mre
- 9b5d2e89tracker mission 031: README (What it does, Test: four gates + the #32 checks, Files: theme/, new pages), STATUS (real copy, A/B load, how to repeat, open points), LOGmre
- 39950e4ctracker#32 (mission 031): the WorldAPI theme (theme/ vendored verbatim from layouts.worldapi.org 85b5654; styles.hl inherits it: accent green-dark, type colours 1-6; own base/header rules, row lines, genre-pill and inverted-button frames removed, the season foldable keeps its line; check-theme 21 -> 0, 4th deploy gate; main actions class primary) and the #32 header (theme AppHeader/MainMenu/UserMenu/Sidebar/ContentFirst: desktop brand, search, Series|Shows|Movies|Genres|People, user icon with Unwatched..Settings, Logout; signed out the ident selector, phone the iD icon dropdown; phone menu in the sidebar overlay; marked entry by :has); /find -> /search/<q>, /genres, /people(/<letter>), /settings; main { ContentFirst { slot } } works around the hl:web one-line slot bug; gates 365/0, 32/0, 52/0, check-theme 0mre
- a386dc92tracker: reports 029 + 030mre
- 71e0fd7dtracker missions 029 + 030: README (What it does, Files, gate count), STATUS (real-copy numbers, how to repeat, open points), LOGmre
- d36ea6eatracker#34 + #35 (mission 030): Follow directly under the poster, as wide as the poster (show.hl, styles.hl); the status pill next to a series' title — TVmaze's status (new tvmazeStatus, stored by the sync's TVmaze merge) else TMDB's, TVmaze Ended + TMDB Canceled = Canceled, inverted (filled, dark text, no border), green running / yellow pending / red canceled / muted ended (shows.hl statusOf); the daily delta asks TVmaze's status of an unfollowed series TVmaze's change list names (dailysync.hl syncRunStep, sync.hl syncTvmazeStatus); the status backfill after the details repair (backfill.hl, jobs.hl statusTick; resumable, 550 ms per TVmaze request); gates 354/0, 32/0, 52/0mre
- 7d7d4487tracker#33 (mission 029): reduced titles — every title TMDB's details never went through this app (no detailsAt, no tmdbSync) is incomplete (shows.hl isIncomplete; the old tracker's migrated rows passed #26's test: 5,697 non-adult on the live copy, 691 series without seasons); the repair job does the visibly reduced first (shows.hl missingParts), the page completes one on open; a title TMDB has no poster for (The Remaining) shows the placeholder; tools/count-incomplete.hl; gate fixtures stand for synced titles (tmdbSync), tests/seed-reduced.hl + #33 checks; gates 347/0, 32/0, 52/0mre
- 661c2592tracker: report 028mre
- 27c916fatracker mission 028: README ("Code order", the new file map), STATUS (counts before/after, tests, how to repeat, open), LOGmre
- d924f398tracker mission 028: comments name the new files (sync.hl, dailysync.hl, backfill.hl, credits.hl, jobs.hl, images.hl …); tools/ref-params.py + tools/lambda-audit.py also scan lib/ (they globbed the root only), lambda-audit counts a plain `x = p` alias like `let x = p`mre
- 2e89b968tracker mission 028 (code order) 5/5 let: `let` only where a variable is reassigned — 667 never-reassigned lets became plain declarations (project.hl, lib/, components/, tools/, tests/); kept: 264 in loop bodies (a plain declaration there is 'Cannot reassign' on the 2nd pass), 234 reassigned, 27 whose name is also a member/outer/free name (a plain write would rebind it); tools/let-audit.py decides and fixes (README 'Code order'); tests/realdata-m028.{sh,mjs} = the page-output diff on a real copy; gates 342/0, 32/0, 52/0, real-copy pages identicalmre
- 54796ff2tracker mission 028 (code order) 4/5 thin faces + last copies: the show page's check/follow faces call lib/watches.hl toggleWatched / toggleSeasonWatched (seasonAllWatched moved there) and lib/follows.hl toggleFollowed; both logins (header selector face, /login/callback) share lib/users.hl userOfCode; todayStr/listOf copies in components and the export readers copied into tools/migrate.hl + tools/old-short-ids.hl now once (lib/util.hl, lib/export.hl); gates 342/0, 32/0, 52/0; old-short-ids output byte-identical, migrate output identicalmre
- 06b078e3tracker mission 028 (code order) 3/5 project.hl is the map: config, routes, wiring and a feature → file index (914 → 258 lines); the background jobs (daily sync run, backfills, details repair, credits job, merge, short ids, collection seed) moved unchanged into lib/jobs.hl (a class: their state is reassigned every step, a static cannot be; one instance made after the server), the login callback into lib/users.hl, poster/photo serving into lib/images.hl, the /shows/<slug> rule into lib/shows.hl showsMovedPath; route handlers are thin wrappers; gates 342/0, 32/0, 52/0, real-copy pages identicalmre
- 94716fd2tracker mission 028 (code order) 2/5 util + topics: lib/util.hl holds envOr, storageDir, postersDir, profilesDir, newId, hexDigits, todayStr, dateOr, textOr, hasId, listOr, firstOf, sortDesc once (were copied into up to 5 files); tmdbsync.hl split into tmdb.hl (TMDB/TVmaze requests), sync.hl (one title's sync), sync-helpers.hl, backfill.hl; details.hl split into details.hl, credits.hl, credits-helpers.hl (isIncomplete to shows.hl); search-helpers.hl (words, query, ranking, slugs); collections.hl (the TMDB collection seed, out of franchises.hl); deltasync.hl renamed dailysync.hl; no behaviour change: gates 342/0, 32/0, 52/0, real-copy pages identicalmre
- 186079b0tracker mission 028 (code order) 1/5 move: every root .hl except project.hl into lib/ (styles.hl into components/), import paths only; gates 342/0, 32/0, 52/0; real-copy pages identicalmre