Repository navigation
v0.1.0 — Phase 1: Core API
Phase 1 — shipped
- Brand onboarding — admin endpoint to register a brand (name, slug).
- API key management — per-brand key issuance and revocation. Plain keys are returned once at creation; only SHA-256 hashes are persisted. Cross-tenant revocation is rejected.
- Product registry — products owned by a brand, with optional
external_refandmetadata. Tenant isolation enforced at the query layer. - Provenance events — typed events (
manufactured,inspected,shipped,sold,transferred) recorded against a product, with optional JSONB detail. - Public verification endpoint —
/verify/:product_idreturns aPublicProductprojection (noexternal_ref, nometadata), brand, full event timeline, and the latest confirmed anchor batch. - Base mainnet anchor service — background task on a 2-hour tick. Submits a self-transaction containing
keccak256("genuflow:anchor:v1") ++ records_hashand waits for 3 block confirmations before marking the batch final. - Idempotent submission + recovery — pending rows are persisted between broadcast and confirmation. On RPC drop or process restart, the next tick resumes via on-chain receipt lookup; if a tx is dropped from the mempool past TTL, the row is deleted (FK
ON DELETE SET NULLreleases its events) and the next tick re-broadcasts cleanly. No duplicate anchors under sustained RPC instability.
Workspace
crates/common— shared types andAppErrorcrates/db— SQLx queries and migrationscrates/anchor— Base anchor background servicecrates/api— Axum server, handlers, middleware
#![deny(warnings)] enforced workspace-wide. No unwrap, expect, or println in production paths. All errors propagate as AppError; tracing throughout. cargo clippy --workspace --all-targets -- -D warnings clean.