Initial commit -- did OMO do a good job?
Check / check (push) Failing after 1m27s
Check / guardrails (push) Failing after 39s
Check / bundle (push) Successful in 1m4s

This commit is contained in:
2026-09-01 18:29:46 -04:00
commit 20a6c26f7c
179 changed files with 21704 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
Todo 19 — news-web UI (CSR) with Leptos 0.8
Completed: 2026-09-01
Scope
- Scaffolded `crates/news-web` as a Leptos 0.8 client-side-rendered (CSR)
web app, mirroring `runway-web`'s Trunk + Tailwind v4 toolchain.
- Implemented three API client routes against the same-origin `/api/*` proxy:
- GET /api/stories
- POST /api/feedback
- GET /api/config
- Built three UI views:
- Story list: table of clusters with title, source count, importance,
relevance, percentile badges, server decision, and per-row feedback
buttons (Interested / Not interested).
- Config view: read-only summary of topics, notification settings, and
sources.
- Error / loading states for both data fetches and feedback actions.
- Kept the WASM bundle lean by avoiding `news-core` and any markdown/chart
libraries.
Verification
- `cargo check -p news-web --target wasm32-unknown-unknown` passes.
- `trunk build --release` succeeds; generated WASM is
`news-web-263e7ab3a1a1c8aa_bg.wasm` at 525 KiB (well under the 1.8 MiB
budget enforced by todo 20).
- `cargo fmt --all --check`, `cargo clippy --workspace --all-targets -- -D warnings`,
and `cargo test --workspace` all pass (87 tests total).
Playwright QA — happy path
- Seeded a temporary SQLite database with one source and one story cluster
("Mars Rover Finds Water").
- Started `target/debug/news-server` on port 3000 and `trunk serve` on
port 8080 with Trunk proxying `/api` to the backend.
- Navigated to http://127.0.0.1:8080/ in Playwright.
- Asserted the story title "Mars Rover Finds Water" rendered in the table.
- Clicked the "Interested" feedback button.
- Asserted the per-row "Saved" success indicator appeared.
- Verified the network request log contained:
POST http://127.0.0.1:8080/api/feedback => 200 OK
- Captured screenshot: `.omo/evidence/task-19-news-triage.png`
Playwright QA — failure path
- Stopped the backend server (port 3000).
- Reloaded http://127.0.0.1:8080/ in Playwright.
- Asserted the visible error state text "Could not load stories" appeared.
- Verified the network request log contained:
GET http://127.0.0.1:8080/api/stories => 500 Internal Server Error
- Captured screenshot: `.omo/evidence/task-19-news-triage-failure.png`
Evidence files
- `.omo/evidence/task-19-news-triage.png` — happy-path story list with
feedback success state.
- `.omo/evidence/task-19-news-triage-failure.png` — failure-path error state.
- `.omo/evidence/task-19-news-triage.txt` — this file.
Notes / gotchas
- Leptos 0.8's `Action::new` requires `Send` futures, which are not available
on `wasm32-unknown-unknown`. On WASM, use `Action::new_local` for actions
backed by `gloo_net` (or any non-Send JS future).
- `news-server` stores `source.kind` and `raw_items.kind` as snake_case strings
(`rss_atom`, `news`). Seeding with `rss` or any other string causes a startup
parse error (`InvalidStoredValue`).
- The Playwright MCP was configured to launch Google Chrome at
`/opt/google/chrome/chrome`; on this Arch box that required installing the
system `chromium` package and symlinking `/opt/google/chrome/chrome ->
/usr/bin/chromium` so the MCP could launch the browser.