stemedb/ai-lookup/patterns/api-documentation.md
jordan 1ce4004807 feat: Complete Phase 2 (The Cortex) - query, lens, and API layers
This commit adds the read path (Cortex) to complement the write path (Spine):

## Crates
- stemedb-api: HTTP API with axum + utoipa OpenAPI
  - /v1/assert, /v1/query, /v1/epoch, /v1/skeptic, /v1/trace, /v1/audit
  - Metered endpoints with quota enforcement
  - Ed25519 signature verification
- stemedb-lens: Truth resolution lenses
  - RecencyLens, ConsensusLens, ConfidenceLens
  - VoteAwareConsensusLens (Ballot Box pattern)
  - TrustAwareAuthorityLens (The Hive pattern)
  - SkepticLens (conflict analysis)
  - EpochAwareLens (paradigm-safe queries)
- stemedb-query: Query engine with materialized views

## Storage Extensions
- VoteStore: Vote aggregation with cached counts
- TrustRankStore: Agent reputation with decay
- AuditStore: Query audit trail
- IndexStore: SP/P/S index structures
- SupersessionStore: Epoch supersession chains

## SDKs
- sdk/go/steme: Go HTTP client with Ed25519 signing
- sdk/go/adk: ADK-Go tools for AI agents

## Documentation
- Updated CLAUDE.md, architecture.md, roadmap.md
- New ai-lookup entries for all services
- Use case docs for consumer health intelligence
- Arena roadmap for simulation advancement

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:22:44 -07:00

55 lines
2.4 KiB
Markdown

# API Documentation Pattern
**Last Updated:** 2026-01-31
**Confidence:** High
## Summary
Episteme uses a "define once, document everywhere" approach. Rust types are the single source of truth for both runtime behavior and API documentation. The `utoipa` crate generates OpenAPI 3.1 specs at compile time from derive macros on the same structs used for JSON serialization.
**Key Facts:**
- `utoipa` chosen over `aide` for compile-time generation and framework-agnostic design
- `utoipa-axum` provides `OpenApiRouter` that collects handler metadata automatically
- `utoipa-swagger-ui` serves interactive docs in dev mode
- `widdershins` converts OpenAPI JSON to Slate-compatible markdown in CI
- No separate schema files to maintain; types ARE the schema
## The Stack
| Layer | Tool | Purpose |
|-------|------|---------|
| Type definitions | `serde` + `utoipa::ToSchema` | Single struct defines JSON shape AND OpenAPI schema |
| Handler docs | `#[utoipa::path]` | Documents endpoint alongside implementation |
| Router | `utoipa_axum::OpenApiRouter` | Collects all handler metadata automatically |
| Spec output | `/api-doc/openapi.json` | OpenAPI 3.1 spec, no build step |
| Dev UI | `utoipa-swagger-ui` | Interactive API explorer at `/swagger-ui` |
| Published docs | `widdershins` + Slate | CI generates static docs from OpenAPI spec |
## Adding a New Endpoint (Quick Reference)
1. Define DTO types with `#[derive(Serialize, Deserialize, ToSchema)]`
2. Write handler function
3. Annotate with `#[utoipa::path(post, path = "/foo", ...)]`
4. Register on `OpenApiRouter` - docs update automatically
5. No manual schema sync needed
**File Pointer:** `.claude/guides/backend/api-endpoints.md` for full procedure.
## Why utoipa Over aide
- Compile-time generation fits zero-cost philosophy
- Framework-agnostic (future gRPC won't require rewrite)
- Larger ecosystem (SwaggerUI, Redoc, Scalar, RapiDoc crates)
- Already macro-heavy codebase (rkyv derives) - one more derive is natural
## gRPC (Future)
When added, `.proto` files will be the source for gRPC docs via `protoc-gen-doc`.
Both HTTP and gRPC will share the same internal types via `From<>` conversions.
The DTO layer keeps internal `rkyv` types separate from public API contracts.
## Related Topics
- [API Service](../services/api.md) - Endpoints and crate structure
- [Error Handling](./error-handling.md) - thiserror + context pattern