gitoriaLog in with ident

tracker

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commitb638e99db638e99dMerge t38 (tracker#38 pagination, #35 Returning/Airing label) into main: LOG/STATUS keep both sides; pager gate follows #37's /people (everyone, last updated first: seed updatedAt); gates pager 229/0, browser 374/0mreb638e99d/reports/022-tracker-headings-series-split.md

9.0 KB

  1. # Report 068 — tracker#20 typed headings + tracker#21 Series / Shows split
  2. **Commit**: `1ed5457` on branch `t20` (worktree loreana:/media/STORAGE/projects/tracker-wt20, from fa1f9df). Not pushed, not merged,
  3. not deployed. main and the other worktrees were not touched.
  4. ## Built
  5. - **#20**: every heading reads "<Type> | <name>": the type word in its colour, a muted bar, the name in white.
  6. - Title page: Movie / Series / Show. Also genre and person pages.
  7. - Lists `/movies`, `/series`, `/shows` show their type word; `/my/series` and `/my/shows` say "My Series" / "My Shows".
  8. - The same colours on the homepage row headings, the search labels and the filmography labels.
  9. - Colours: Movie yellow, Series greenDark (the accent), Show purple, Genre blue, Person orange.
  10. - Franchise (blueLight) and Timeline (greenLight) are defined as CSS classes only, for t19's pages.
  11. - **#21**: every TV title has a kind, `series` or `show`.
  12. - Show = TMDB type Reality / Talk Show / News / Video, or one of our genres Reality / Talk / News. Everything else is a series.
  13. - `kind` and `tmdbType` are stored by the daily sync, the adult backfill, the search import, and a new **kind backfill**:
  14. - one TMDB request per title that has no show genre;
  15. - it runs after the adult backfill and resumes after a restart;
  16. - `TRACKER_KINDS=0` switches it off.
  17. - Before a title has a stored kind, its genres decide.
  18. - **Pages and addresses**:
  19. - Lists: `/series` and `/shows` (+ `/page/N`).
  20. - Title pages: `/series/<slug>`, `/shows/<slug>`, and `/movies/<slug>` (new).
  21. - Old links: `/shows/<slug>` of a series → **301** `/series/<slug>`; of a movie → **301** `/movies/<slug>`.
  22. - `/my/series` and `/my/shows`.
  23. - Home: 5 tiles (Unwatched, Schedule, Series, Shows, Movies) and 3 rows.
  24. - Every link goes through `shows.hl titlePath`: lists, search, filmography, `/my/*`, `/<shortId>`, the page an import opens.
  25. - **Docs**: `docs/kinds.md` (new). README (summary, config, What it does, Test, Files). STATUS entry on top.
  26. ## Decisions
  27. - **Movies moved to `/movies/<slug>`.** `/shows/` now means TV shows; old movie links answer 301. This is my decision, not in
  28. the ticket.
  29. - **`/shows/<slug>` is a function route** (`project.hl showsRoute`). hl:web cannot redirect from a component route.
  30. - For a show, the route renders the Show component itself through hl:web internals (`server.router.match`, `server.page`,
  31. `hostOf`, `requestHeaders`, `sessions`).
  32. - Re-check this when hl:web is re-vendored. The kinds gate covers it: hydration, a season face and Follow all work on that page.
  33. - Consequence: a link to a show is a full page load. Series and movie pages are still client-side.
  34. - The search's TMDB results ("Fetch from web") say **TV** instead of a kind, because TMDB's search has no TV type.
  35. ## Files touched (merge notes: t26 and t19 also change show.hl, project.hl, styles.hl)
  36. | File | Change |
  37. |---|---|
  38. | `project.hl` | imports, `showsRoute`, routes (`/movies/:slug`, `/series*`, `/shows/:slug` as a function route, `/my/:tv` instead of `/my/shows`), the kind backfill block + one clock line + one log line |
  39. | `components/show.hl` | header comment, 1 import, `slugInfoOf` replaces `initialCollapsedOf`, `pageKind` / `typeText` / `typeClass` members, the h1 line |
  40. | `styles.hl` | 1 import line, colour tokens after `colorGenre`, a "typed headings" block before "/shows/:slug", home h2 colours, `homeNav` 3 columns (5 in the media block) |
  41. | `shows.hl` | new block "kind of a title" before `posterName` |
  42. | `catalog.hl` | two TV lists (`shows` beside `series`), `rekeyed`, `latestShows`, `showsPage`, counts, `tileOf` href |
  43. | `tmdbsync.hl` | 1 import, header comment, type stored in `syncShow` and `backfillTitle`, `needsKind` / `kindBackfillQueue` / `kindTitle` |
  44. | `search.hl` | import, `tmdbType` / `kind` on an import, `path` in its answer |
  45. | `people.hl` | import, filmography `href` / `typeLabel` / `typeClass` |
  46. | `shortids.hl` | `shortIdPath` uses `titlePath` |
  47. | `components/home.hl`, `myshows.hl`, `allshows.hl`, `movies.hl`, `genre.hl`, `person.hl`, `search.hl`, `mymovies.hl`, `unwatched.hl`, `schedule.hl` | headings, links, labels |
  48. | `tests/browser.mjs` | URLs (`/series/`, `/movies/`, `/my/series`, `#home-series`), h1 → `type-name` selectors, 5 home tiles, web label "TV", `TRACKER_KINDS: '0'` in `startServer` |
  49. | `tests/faketmdb.mjs` | `type: s.type` in TV details |
  50. New files:
  51. - `components/allseries.hl`
  52. - `docs/kinds.md`
  53. - `tests/kinds.mjs`, `tests/seed-kinds.hl`, `tests/realdata-068.mjs`
  54. - `tools/count-kinds.hl`
  55. ## Gates (final tree)
  56. ```
  57. TRACKER_GATE_SHOTS=/tmp/w068/shots TRACKER_GATE_PORT=8761 TRACKER_GATE_IDENT_PORT=8762 TRACKER_GATE_CHROME=8763-8765 TRACKER_GATE_TMDB_PORT=8766 node tests/kinds.mjs
  58. 32 passed, 0 failed
  59. TRACKER_GATE_SHOTS=/tmp/w068/main-shots TRACKER_GATE_PORT=8761 TRACKER_GATE_IDENT_PORT=8762 TRACKER_GATE_CHROME=8763-8765 TRACKER_GATE_TMDB_PORT=8766 node tests/browser.mjs
  60. 266 passed, 0 failed
  61. ```
  62. - The shots directory must exist before `tests/browser.mjs` runs (`mkdir -p` first).
  63. - One earlier run of browser.mjs hit an mpackdb LockTimeout in the short-id resume check right after a server stop. The rerun passed.
  64. `tests/kinds.mjs` covers:
  65. - Kinds from the stored data.
  66. - The sync storing the type: a followed Reality title moves to `/shows` without a restart.
  67. - The kind backfill: stop and resume, no title asked twice, ≥ 260 ms between requests, a 404 handled, nothing to do on the next start.
  68. - Both lists, the 301s, and every heading's words and computed colours.
  69. - The function-rendered show page: a season closes and opens; Follow works.
  70. - Signed in: home rows and tiles, `/my/series` and `/my/shows`.
  71. - Search labels and links; a talk-show import opens `/shows/<slug>`.
  72. - Filmography labels.
  73. - 390 / 1280 px: nothing scrolls sideways, and the long name wraps.
  74. ## Real data (copy of the live `storage/`, :8760, real TMDB; copy, sessions and `.env` link removed afterwards)
  75. - **Backfill**: 1,789 TV titles in **838 s**, 1,613 requests, 11 TMDB 404s, 0 retries.
  76. - **Kinds**: 1,577 series and 212 shows. 176 shows came from the genre (no request), 36 from TMDB's type.
  77. - **TMDB types**: Scripted 1,337, Miniseries 179, Documentary 50, Reality 16, Talk Show 15, Video 4, News 1.
  78. - **Public lists**: 1,601 series / 173 shows before the backfill (genres only), **1,565 / 209** after; 4,650 movies.
  79. - **Spot checks** (12 names; 10 are in our data, all correct):
  80. - Show: Saturday Night Live, The Tonight Show Starring Jimmy Fallon, Last Week Tonight, Late Show with Stephen Colbert, Hot Ones.
  81. - Series: Reacher, Foundation, Doctor Who, Chernobyl, Severance.
  82. - **Page times during the backfill** (curl every 5 s, 156 each, avg / max):
  83. | Page | avg | max |
  84. |---|---|---|
  85. | `/` | 0.094 s | 3.5 s |
  86. | `/series` | 0.055 s | 2.6 s |
  87. | `/shows` | 0.024 s | 0.21 s |
  88. | `/series/Reacher` | 0.19 s | 0.48 s |
  89. - 4 answers took more than 1 s, about every 170 s. The cause was not found.
  90. - Idle afterwards: average 0.029 s.
  91. - **Browser** (signed in as the creator, full load in ms):
  92. | Page | 390 | 1280 |
  93. |---|---|---|
  94. | `/series/Reacher` | 290 | 243 |
  95. | `/shows/Saturday-Night-Live` | 395 | 380 |
  96. | movie page | 251 | 246 |
  97. | `/my/series` (126 rows) | 1,410 | 384 |
  98. | `/my/shows` | 220 | 217 |
  99. | every list / genre / person / search | ≤ 351 | ≤ 351 |
  100. - Headings and colours right, nothing scrolls sideways, 0 console problems.
  101. ## Screenshots (looked at, on Loreana)
  102. - Gate: `/tmp/w068/shots/{series-page,show-page,movie-page,genre,person,series-list,shows-list,movies-list,home,my-series,my-shows,search}-{390,1280}.png`
  103. - Main gate: `/tmp/w068/main-shots/`
  104. - Real data: `/tmp/w068/real/{home,series-list,shows-list,movies-list,series,show,movie,genre,person,my-series,my-shows,search}-{390,1280}.png`
  105. - `/tmp/w068` also holds older files from other workers; mine are the names above.
  106. ## Open points
  107. 1. **Merge** with main (062), t19 and t26.
  108. - t19's franchise pages need the typed h1 (`type-franchise` / `type-timeline`).
  109. - t19's `/shows/` links should use `titlePath`. Until then they still work through the 301.
  110. 2. **TMDB type "Video"** is anime OVAs here (Halo Legends, .hack//Liminality, Carnival Phantasm). The architect's rule makes them
  111. Shows. Should Video become Series? (creator to decide)
  112. 3. **Deploy**: the first start runs the kind backfill after the adult backfill, about 14 min.
  113. 4. The 2–3.5 s answers during the backfill (probably mpackdb rewriting shows.db; not investigated).
  114. 5. Titles added by the person fill get a stored kind only at the next start. Until then the genres decide.
  115. 6. **Ports**: on Loreana 8765 (node pid 1047) and 8766 on the tailscale address belong to other services. My gates still ran (the
  116. fake TMDB binds 127.0.0.1). Nothing of mine is left running.
  117. ## Hybriel
  118. - **No component-route redirect.** hl:web cannot answer 301 from a component route or fall through from a function route.
  119. - Workaround: `showsRoute` renders the component through hl:web internals.
  120. - Candidate for a hybriel ticket: a component route should be able to answer a redirect, or a function route should be able to
  121. hand over to the next route.
  122. - No other new issues.

Branches

Latest commits

  • b638e99dMerge t38 (tracker#38 pagination, #35 Returning/Airing label) into main: LOG/STATUS keep both sides; pager gate follows #37's /people (everyone, last updated first: seed updatedAt); gates pager 229/0, browser 374/0mre
  • f8ffa4dbtracker: report 032 + The Remaining + #39mre
  • 7565a863tracker: LOG timemre
  • 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
  • 9448d643tracker#35 follow-up (mission 033): TVmaze 'Running' is labelled 'Returning', or 'Airing' while a non-special episode of the two newest seasons is released within today +-7 days (data unchanged); gate fixtures Running/Airing/Aired + a special; browser 366/0, kinds 32/0, franchises 52/0, pager 229/0, check-theme 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
  • 03ec792ftracker#38 (mission 033): pagination goes exactly to the clicked page — tilelist read the clicked button's text after pagination.hl's own handler had rebuilt the buttons (real clicks only); now li.current, else the button's own text; new gate tests/pager.mjs (5 lists x 11 pages, 390/1280, real + script clicks, Back/Forward) 229/0; browser 365/0, kinds 32/0, franchises 52/0, check-theme 0mre
  • 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