feat(api): runnable web slice — no-account GEDCOM import → tree/places #5

Merged
charles merged 1 commit from feat/web-import-slice into main 2026-06-17 12:30:44 +00:00
Owner

Something testable. A thin end-to-end vertical slice you can run and click.

just dev        # → http://127.0.0.1:8080

Upload a GEDCOM → see the parsed persons + de-duplicated places with relevance badges and family-anchor labels. Deterministic, no account, no LLM, no DB.

Changes

  • axum 0.8 + maud + tokio in geneatrip-api.
  • GET / upload form; POST /parse-gedcom multipart → gedcom::parseto_tree → tree/places HTML; routed through service.validate_tree (anonymous path, FR-OV-01).
  • First external deps (axum/tokio/maud) — crates.io fetch confirmed working locally; this PR also proves it in CI.
  • just dev runs the server; ROADMAP notes the slice.

Verification

  • just qa green (+ a render unit test).
  • Manual: server boots; a 2-person GEDCOM → "2 personnes · 2 lieux" with Lyon/lyon deduped, births + marriage anchored, High relevance — M1 normaliser visible in the browser.

Placeholder French strings; fluent i18n + a11y + the full screen set land in M7. Traces: FR-OV-01, FR-IMP-09/10/12 · tech-spec 06/07.

**Something testable.** A thin end-to-end vertical slice you can run and click. ``` just dev # → http://127.0.0.1:8080 ``` Upload a GEDCOM → see the parsed persons + **de-duplicated places** with relevance badges and family-anchor labels. Deterministic, **no account, no LLM, no DB**. ## Changes - axum 0.8 + maud + tokio in `geneatrip-api`. - `GET /` upload form; `POST /parse-gedcom` multipart → `gedcom::parse` → `to_tree` → tree/places HTML; routed through `service.validate_tree` (anonymous path, FR-OV-01). - **First external deps** (axum/tokio/maud) — crates.io fetch confirmed working locally; this PR also proves it in CI. - `just dev` runs the server; ROADMAP notes the slice. ## Verification - `just qa` green (+ a render unit test). - Manual: server boots; a 2-person GEDCOM → "2 personnes · 2 lieux" with Lyon/lyon deduped, births + marriage anchored, **High** relevance — M1 normaliser visible in the browser. Placeholder French strings; fluent i18n + a11y + the full screen set land in M7. Traces: FR-OV-01, FR-IMP-09/10/12 · tech-spec 06/07.
feat(api): runnable web slice — no-account GEDCOM import → tree/places view
All checks were successful
qa / qa-1 (pull_request) Successful in 22s
qa / qa (pull_request) Successful in 0s
qa / qa-1 (push) Successful in 2m33s
qa / qa (push) Successful in 0s
d72c4ac0f5
First end-to-end testable artifact (`just dev` → http://127.0.0.1:8080):
- axum 0.8 + maud + tokio in the geneatrip-api binary
- GET /            landing + GEDCOM upload form
- POST /parse-gedcom  multipart → gedcom::parse → to_tree → render persons,
  de-duplicated places with relevance badges + family-anchor labels; routes the
  tree through service.validate_tree (anonymous path, no account — FR-OV-01)
- first external deps cross the frontier (axum/tokio/maud) — crates.io fetch
  confirmed working in this env
- justfile `dev` now runs the server; ROADMAP notes the slice

Verified: server boots, GET / serves the page, POST of a 2-person GEDCOM returns
"2 personnes · 2 lieux" with Lyon/lyon deduped, marriage+births anchored, High
relevance — the M1 normaliser visible in the browser. just qa green (+ a render
unit test). Strings are placeholder French; fluent i18n + a11y + full screens
land in M7.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/geneatrip!5
No description provided.