Files
the-daily-epub/docs/plans/briefs/web-dashboard/handoff-step1.md
T
thalladaandClaude Fable 5.1 69cd736455 Web dashboard step 1: migration, sessions, users CLI, public site
Migration 0004 (users, sessions, config_changes, profile_versions, jobs,
rating_events.user_id, runs.report_json, issues.issue_json), the issue
snapshot writer and loader, the web module skeleton with layout and static
assets, axum-login/tower-sessions over a sqlx session store, password-auth
users with a CLI, the login throttle, the origin check, security headers,
and the public issue pages, archive, Atom feed and robots.txt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHyYupFdBiR4VfoUM7NjSM
2026-09-03 04:38:22 +00:00

73 lines
4.1 KiB
Markdown

# Step 1 handoff — foundation
## Landed
- Added migration `0004_web.sql`: users, SQLite-backed sessions and indexes,
rating attribution, config/profile/job history, report/issue snapshots, and
the candidate article/run index. `RatingEvent`/`RatedArticle` now carry a
nullable user id.
- Persisted full `runs.report_json`, final `issues.report_json`, and a compact
`issues.issue_json` with article bodies removed. The issue loader rehydrates
bodies from `articles` and has a reduced-row fallback for pre-migration
issues. `GenerateOutcome` exposes `run_id`.
- Added the `web` skeleton, final shared-state shape, Askama layout/error/public
templates, embedded CSS/JS/favicon with SHA-256 ETags, security/cache/request
headers, and `DisabledRunner`/`MockRunner` stubs.
- Added `axum-login` at the required git revision, the local sqlx 0.9 session
store, password-auth users/backend, session/auth route layers, role guards,
same-origin POST middleware, login governor and cleanup tasks, login/logout,
account/password/session revocation, and session-or-Basic file downloads.
- Added public latest/archive/issue pages, the stripped `PublicIssue` boundary,
Atom feed, and robots policy. Anonymous page loads remain session-cookie-free.
- Added all `daily-epub users` commands without the pipeline lock, new server
configuration/defaults/validation, example config, and README command/route/
reverse-proxy documentation.
- Expanded `tests/m7_server.rs` to cover env-only public routes, dashboard
redirect, CLI admin bootstrap, and a real TCP login/account request.
## Deviations and follow-up
- `rpassword` could not be added: it is absent from the local Cargo cache and
this sandbox cannot resolve `index.crates.io` (three retries failed). The CLI
currently uses an equivalent Unix `/dev/tty` no-echo double prompt and keeps
`--password-stdin`. Replace that helper with `rpassword::prompt_password`
after adding the dependency in a network-enabled environment.
- Cargo resolved direct `toml_edit` to 0.22.27 rather than the plan's observed
0.25.x release; it was selected by `cargo add` for the available toolchain and
lock graph, not hand-pinned.
- The finished issue report is attached immediately after `finish_run`, rather
than during the earlier issue snapshot write, because publish timing and the
final run status are not complete at snapshot time. The stored observable
value is the same final serialized report.
- The pinned axum-login source confirms `AuthSession::user().await`, immutable
`login`/`logout`, the macro route layers, and session key
`"axum-login.data"`; the implementation follows those real APIs.
- Full signed-in issue/article rendering and the real `POST /rate` handler are
step 2. Step 1 supplies the protected dashboard overview and admin-only 501
rate stub so route-guard tests exercise the final boundary.
## Verification
- `cargo fmt --check`: pass.
- `cargo clippy --all-targets -- -D warnings`: pass.
- `cargo test` with sandbox-bound tests skipped: **389 passed, 0 failed**.
Excluded were the four named Anthropic listener tests, the relative-URL
listener test, five `server::tests` listener tests, both `m7_server` TCP
tests, and three existing OpenAI fake-server tests that also bind loopback.
- Focused `cargo test web:: -- --nocapture`: **16 passed, 0 failed**.
- `cargo tree -i` shows one `sqlx` version (0.9.0) and one
`libsqlite3-sys` version (0.37.0).
## Orchestrator review (2026-09-03)
- `rpassword` added (the sandbox had no network); `read_password_hidden` is
now `rpassword::prompt_password`. `toml_edit` moved to 0.25 as the plan says.
- **Deviation from plan §8 kept on purpose:** `/files/*` with *no* Basic auth
configured stays public, exactly as before. The plan wanted a redirect to
`/login` there, but the public OPDS feed's acquisition links point at those
files and an e-reader cannot log in; acceptance criterion 11 ("`/files`
behave as before") and "OPDS clients are unaffected" win. With Basic auth
configured, a session cookie of any role bypasses it.
- A short new password on `/account/password` is a 400 form error, not a 500.
- Full suite outside the sandbox: 370 lib + all integration tests green.