add-route

star 0

Add (or rename, or change the shape of) an HTTP route in the nowledge axum service following the project's documented multi-file workflow. Use when the user says "add a route", "add an endpoint", "expose a new API", "wire up POST/GET/PUT/PATCH/DELETE /v1/...", or when changing an existing route's path/method/schema.

dickwu By dickwu schedule Updated 5/21/2026

name: add-route description: Add (or rename, or change the shape of) an HTTP route in the nowledge axum service following the project's documented multi-file workflow. Use when the user says "add a route", "add an endpoint", "expose a new API", "wire up POST/GET/PUT/PATCH/DELETE /v1/...", or when changing an existing route's path/method/schema.

add-route

A new route in nowledge touches five files in a fixed order. Follow this checklist exactly — missing a step is the most common drift between the running service and the API docs.

Inputs to gather first

Before writing anything:

  1. HTTP method (GET, POST, PUT, PATCH, DELETE).
  2. Path (e.g. /v1/state/profile/facts/{fact_key}).
  3. Rust handler name (snake_case, matches src/routes.rs::build_router registration).
  4. Group label for the manifest (Health | Admin | Harness | Context | Debug | Filesystem | History | Links | LLM | Ingest | Rag | Sessions | State | Usage — pick from existing entries in doc/api_manifest.json).
  5. Authentication mode: None | UserGuard | UserGuard; owner default may apply | AdminGuard.
  6. Request and response schema names from src/models.rs (or new types you'll add there).

Step 1 — code

Edit in this order:

  1. src/models.rs — add or update the request/response structs and any DTOs. Derive Debug, Clone, Serialize, Deserialize and skip empty Option<...> with #[serde(skip_serializing_if = "Option::is_none")]. If the route is owner-scoped, the request should carry an Option<String> owner_user_id.
  2. src/store.rs — add the domain logic. Keep mutations behind StoreData and the RwLock. Use util::new_id("prefix") for new IDs and EventIndexResolver::idempotency_hash for any idempotency key.
  3. src/repository.rs — only if the route needs to persist through the Meili backend. Add the trait method on KnowledgeRepository, implement on both MeiliKnowledgeRepository and MemoryKnowledgeRepository. Memory impl is usually a no-op.
  4. src/routes.rs — register the handler in build_router and write the handler function. Use State<AppState>, the appropriate guard, and return Result<Json<Response>, ApiError>. For owner-scoped routes, call guard.apply_owner_default(&mut req.owner_user_id)? early.

Step 2 — tests

Add a regression test in tests/api_spec.rs (or a new dedicated test file if the surface is large). Use the existing helpers:

  • app() for unauthenticated runs.
  • authed_app() for owner-isolation tests (users u1, u2, admin).
  • call(app, method, uri, body) and call_with_token(app, method, uri, body, Some(token)) for dispatch.

At minimum cover the happy path. For owner-scoped routes, always add an owner-mismatch test (request from u1 for u2's data → 403). The owner-isolation invariant is load-bearing.

Step 3 — docs (do not skip)

Three coordinated updates:

  1. Create doc/api/{method_lowercase}_{path_with_underscores}.md using the template from doc/api/AGENTS.md. Path braces are dropped; segments joined with _. Examples:

    • GET /v1/fs/readget_v1_fs_read.md
    • POST /v1/admin/history/user-event-indexes:reconcilepost_v1_admin_history_user_event_indexes_reconcile.md

    Section order: Title (# METHOD /path), ## Summary, ## Handler, ## Path Parameters, ## Query Parameters, ## JSON Body Parameters (with Schema: line referencing the type in src/models.rs), ## Response, ## Errors and Access Rules, ## Internal Logic Call Graph (a Mermaid flowchart TD).

  2. Add a row to the index table in doc/README.md, alphabetized within its method group:

    | `METHOD` | `/v1/path` | `handler_name` | [api/<file>.md](api/<file>.md) |
    
  3. Append an entry to doc/api_manifest.json:

    {
      "method": "METHOD",
      "path": "/v1/path",
      "handler": "handler_name",
      "group": "GroupLabel",
      "file": "api/<file>.md"
    }
    

Step 4 — verify

Run the /verify gauntlet. If you bumped a public response shape, also rerun the relevant integration block by hand to confirm the docs match runtime behavior.

Cross-check

After everything is in place:

grep -nE '\.route\("' src/routes.rs | wc -l
ls doc/api/ | wc -l
jq 'length' doc/api_manifest.json

The doc count and manifest count should match the number of registered routes (currently 68 — update this number in doc/README.md's "Total documented APIs" line if it changes).

Install via CLI
npx skills add https://github.com/dickwu/nowledge --skill add-route
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator