Skip to content

refactor(edda-serve): split lib.rs into api/ sub-modules#383

Merged
fagemx merged 2 commits intomainfrom
feat/375-split-edda-serve
Mar 27, 2026
Merged

refactor(edda-serve): split lib.rs into api/ sub-modules#383
fagemx merged 2 commits intomainfrom
feat/375-split-edda-serve

Conversation

@fagemx
Copy link
Copy Markdown
Owner

@fagemx fagemx commented Mar 27, 2026

Summary

  • Split the 8,781-line edda-serve/src/lib.rs into 16 focused files under src/api/ and src/
  • Production code in lib.rs reduced from ~4,400 lines to ~135 lines (mod declarations + serve() entrypoint)
  • Each domain module exports routes() / public_routes() / protected_routes() — router-per-module pattern eliminates the route duplication between serve() and test router()
  • Shared types extracted to error.rs, state.rs, helpers.rs, middleware.rs

New file structure

src/
├── lib.rs              (~135 lines production + ~4,500 lines tests)
├── error.rs            (AppError enum + IntoResponse)
├── state.rs            (ServeConfig, AppState, ChronicleContext)
├── helpers.rs          (validate_iso8601, time_now_rfc3339)
├── middleware.rs       (auth_middleware, is_localhost, generate_pairing_token)
└── api/
    ├── mod.rs
    ├── auth.rs         (device pairing endpoints)
    ├── events.rs       (health, status, context, decisions, log, note, decide, karvi)
    ├── drafts.rs       (draft approval workflow)
    ├── telemetry.rs    (cycle telemetry ingest and stats)
    ├── snapshots.rs    (snapshot CRUD, village stats, patterns)
    ├── analytics.rs    (recap, overview, projects)
    ├── dashboard.rs    (dashboard JSON + compute_attention)
    ├── metrics.rs      (quality, controls, overview metrics, trends)
    ├── policy.rs       (scope check, authz, approval, tool-tier)
    ├── briefs.rs       (task briefs, actors, dashboard HTML)
    ├── stream.rs       (SSE event stream)
    └── ingestion.rs    (ingestion evaluate/records/suggestions)

Verification

  • All 106 tests pass
  • Zero clippy warnings
  • Same public API: edda_serve::serve() and edda_serve::ServeConfig
  • Pure refactor — no behavior change

Closes #375

Test plan

  • cargo check -p edda-serve — compiles clean
  • cargo check -p edda-serve --tests — test compilation clean
  • cargo test -p edda-serve — 106/106 tests pass
  • cargo clippy -p edda-serve --all-targets — zero warnings
  • cargo fmt -p edda-serve — formatting clean

🤖 Generated with Claude Code

fagemx and others added 2 commits March 27, 2026 14:38
Split foundational types out of the 8.7K-line lib.rs into dedicated files:
- error.rs: AppError enum and IntoResponse impl
- state.rs: ServeConfig, AppState, ChronicleContext, PairingRequest
- helpers.rs: validate_iso8601, time_now_rfc3339
- middleware.rs: auth_middleware, is_localhost, generate_pairing_token

Part of GH-375.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract all HTTP handler functions from the monolithic lib.rs (8.7K lines)
into 12 domain-specific modules under api/:
- auth.rs: device pairing endpoints
- events.rs: health, status, context, decisions, log, note, decide, karvi
- drafts.rs: draft approval workflow
- telemetry.rs: cycle telemetry ingest and stats
- snapshots.rs: snapshot CRUD, village stats, patterns
- analytics.rs: recap, overview, projects
- dashboard.rs: dashboard JSON + compute_attention
- metrics.rs: quality, controls, overview metrics, trends
- policy.rs: scope check, authz, approval, tool-tier
- briefs.rs: task briefs, actors, dashboard HTML
- stream.rs: SSE event stream
- ingestion.rs: ingestion evaluate/records/suggestions

Each module exports routes() for the test router and
public_routes()/protected_routes() for the production server.
lib.rs production code reduced to ~135 lines (entrypoint + mod declarations).
All 106 tests pass, zero clippy warnings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@fagemx
Copy link
Copy Markdown
Owner Author

fagemx commented Mar 27, 2026

Code Review: PR #383 (Round 1) — LGTM 🎉

All P0 and P1 issues have been resolved.

Summary

This PR cleanly splits the 8,781-line edda-serve/src/lib.rs into 16 focused files under src/api/ and shared modules (error.rs, state.rs, helpers.rs, middleware.rs). The refactor is well-executed:

  • Route completeness verified: All routes from the original monolithic lib.rs are preserved in the new modular structure. The public_routes() / protected_routes() / routes() (test-only) pattern is consistent across events and auth modules, and all other modules use a single routes() function.

  • Cross-module references are correct: analyticsdashboard bidirectional imports and metricsdashboard imports all use proper pub(crate) visibility. The include_str!("../../static/dashboard.html") relative path from src/api/briefs.rs is correct.

  • Test coverage fully preserved: All 106 tests pass. Total async function count (164) matches the original. The test router() in lib.rs correctly merges all module routes without auth middleware, matching the original behavior.

  • Build quality: cargo check, cargo clippy --all-targets -- -D warnings, cargo test, and cargo fmt --check all pass clean.

Minor Observation (not blocking)

The bidirectional dependency between analytics.rs and dashboard.rs (analytics imports compute_attention from dashboard; dashboard imports OverviewResponse types from analytics) is a mild code smell. Consider consolidating shared types into a dedicated types.rs module in a follow-up. This does not affect correctness.

Verdict: LGTM ✅

No critical or high-priority issues remaining. This PR is ready for merge.


Completed after 1 round(s) of automated review-fix loop

@fagemx fagemx merged commit ade3ee2 into main Mar 27, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(serve): split edda-serve/src/lib.rs into sub-modules

1 participant