feat: walking skeleton — live-render aura + data-server docs from Gitea

The first runnable DocSite server (plan docs/plans/0001-walking-skeleton.md):
`docsite serve` renders the published docs of aura and data-server live from
their Gitea main revisions, dark-themed, navigated from the DocSite-owned
whitelist registry; `docsite check` validates every nav reference against the
live sources with an exit code. Built across nine TDD tasks — config (registry
whitelist + traversal guard), gitea read-only client (Fetcher trait, injected
for offline tests), render (comrak GFM + syntect), theme (embedded dark CSS +
shell), revision-keyed cache, reference validator, axum server, main wiring.

All five domain invariants land: read-only Gitea access via the Fetcher trait;
single source of truth via the (repo,path,sha) cache; reference integrity
detected (check + a fail-loud render-time error block) never enforced;
whitelist publishing with path-traversal refusal; the closed directive
vocabulary's no-op expansion seam reserved in render.

Verification (run by the orchestrator): cargo build green; cargo test green —
40 tests (32 lib unit + 7 e2e via an injected MockFetcher + 1 gated live smoke
that reached the real Gitea this run); cargo clippy --all-targets -D warnings
clean.

Held quality findings (plan-prescribed / plan-deferred, not defects; tracked
as follow-up issues): nav_html interpolates the registry slug/page into the
href unescaped (operator-trusted registry — latent, not a live vector);
GiteaClient's 404->NotFound status mapping (the invariant-3 broken-reference
signal) is covered only by the gated live smoke's happy path, not a unit test.

Resolved API deviations from the plan text (newer crate versions): reqwest
0.13 renamed feature rustls-tls -> rustls; comrak 0.52 deprecated `Plugins`
(used `comrak::options::Plugins`); axum 0.8 capture syntax `/{slug}/{*page}`.

refs #1
This commit is contained in:
2026-06-28 16:43:20 +02:00
parent 27e09a395b
commit cb82987c33
16 changed files with 3673 additions and 4 deletions
+16
View File
@@ -0,0 +1,16 @@
//! Gated smoke test against the real Gitea. Skips cleanly when Gitea is
//! unreachable (the project's skip-on-no-dependency convention) so it never
//! fails on an offline machine.
use docsite::gitea::{Fetcher, GiteaClient};
#[test]
fn aura_glossary_is_fetchable_from_live_gitea() {
let client = GiteaClient::new("http://192.168.178.103:3000");
match client.fetch_raw("Brummel/aura", "main", "docs/glossary.md") {
Ok(body) => assert!(!body.is_empty(), "live glossary should be non-empty"),
Err(e) => {
eprintln!("skip: live Gitea unreachable or auth-gated: {e:?}");
}
}
}