[Story] Reading list page #9
No Reviewers
Labels
Clear labels
agent/analyst-drafted
agent/analyst-drafted
needs/human-decision
needs/human-decision
needs/security-review
needs/security-review
tier/t0
tier/t1
tier/t2
tier/t3
kind
bug
kind
bug
kind
epic
kind
epic
kind
initiative
EPPP programme initiative
kind
story
kind
story
kind
task
EPPP engineering card/task decomposed from a story
kind
toil
kind
toil
loop
1
loop
1
loop
2
loop
2
loop
3
loop
3
risk
agent-full
risk
agent-full
risk
human-gated
risk
human-gated
risk
human-only
risk
human-only
size
l
size
l
size
m
size
m
size
s
size
s
status
blocked
status
blocked
status
done
Workflow: Done
status
in-progress
status
in-progress
status
proposed
status
proposed
status
ready
status
ready
status
review
status
review
stream
checkout
stream
checkout
stream
onboarding
stream
onboarding
stream
platform
stream
platform
trivial — implementer only, auto-merge
standard — implementer + reviewer + tester
complex — security if triggered, human merge
critical — full chain + security, human merge
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Fabrika/PersonalBlog#9
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Implements the reading list page for issue #8 — a static page that renders curated links grouped by category from a single data file. No backend, no automated import/scraping, no search/filter UI (per scope).
What changed
reading.html— new page with a#reading-listcontainer; loads the renderer module (js/reading-list.js).data/reading-list.js— the single data file. Schema:title,url,category, and an optional one-linenote. Adding a link means editing this file only.js/reading-list.js— pure renderer: groups entries by category (first-seen order), HTML-escapes all text, skips invalid entries, de-duplicates category ids; guarded browser wiring renders the data file into the page.reading.html; the Reading page marks its own linkaria-current="page".css/style.css— category/list styles; two-column grid on wide screens andoverflow-wrapon links so 500+ entries stay scannable and usable.tests/reading-list.test.js— component, data-integrity, renderer, and 500-entry fixture tests.package.json— test script nownode --test(see Risks).Criterion → test mapping
tests/reading-list.test.js→ "renders links grouped by category from the data file"; "renders correctly against a 500+ entry fixture" (per-section grouping and counts); "renderer module loads the reading list data file"; "reading page renders a reading list container and loads the renderer module"tests/reading-list.test.js→ "each rendered link has a valid href and shows its title, with the note shown only when present"; "every entry in the data file has a title, a category, and a valid http(s) url"; "seed data includes an entry without a note so the optional path is exercised"tests/reading-list.test.js→ "renders correctly against a 500+ entry fixture" (500 entries all rendered, grouping intact, render time bound < 5s); responsive two-column layout incss/style.csstests/reading-list.test.js→ "a new link can be added by editing only the data file"; README "Reading list" section documents the schema and the edit-only workflowOut of scope (as specified in the issue)
Risks / notes
package.jsontest script changed fromnode --test tests/tonode --test: on some Node builds (reproduced locally on v22.23.2)--testtreats a directory argument as a module path and exits before running any tests; no-arg discovery finds the sametests/*.test.jsfiles on Node ≥ 18.13 and is what CI now runs..gitea/workflows/ci.ymlrunsnpm test; this Gitea instance has no Actions runner (same situation as PR #6), so runs stay "Waiting to run" (pending) — there are no failing checks, and the suite is verified green locally (30/30,npm test).data/reading-list.jsis starter content the owner can replace/extend.Rollback