Remove index_handler.rs, search_handler.rs, and write.rs which were superseded by the new routes/ directory structure during Phase 2 implementation. The new routes/ module provides better organization: - routes/indexes.rs (index lifecycle) - routes/search.rs (search endpoint) - routes/documents.rs (document CRUD) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.4 KiB
7.4 KiB
Phase 2 — Proxy + API Surface: Completion Verification
Date
2026-05-09
Scope Verification
1. axum server listening on port 7700 and metrics on 9090
Status: ✅ COMPLETE
- File:
crates/miroir-proxy/src/main.rs - Server configured to listen on
server.port(default 7700) - Metrics server on port 9090 with
/metricsendpoint
2. Write path implementation
Status: ✅ COMPLETE
- File:
crates/miroir-proxy/src/routes/documents.rs - Hash primary key to get shard ID (
shard_for_key()) - Inject
_miroir_shardfield into documents - Fan out to RG × RF nodes
- Per-group quorum (
floor(RF/2)+1) X-Miroir-Degradedheader on any group missing quorum- 503
miroir_no_quorumonly when no group met quorum
3. Read path implementation
Status: ✅ COMPLETE
- File:
crates/miroir-proxy/src/routes/search.rs - Pick group via
query_seq % RG - Build intra-group covering set
- Scatter search to covering set nodes
- Merge by
_rankingScore - Strip
_miroir_shardalways +_rankingScoreif not requested - Aggregate facets + estimatedTotalHits
- Report max processingTimeMs
- Group fallback when covering set has holes
4. Index lifecycle
Status: ✅ COMPLETE
- File:
crates/miroir-proxy/src/routes/indexes.rs - Create broadcasts + atomically injects
_miroir_shardinto filterableAttributes - Settings sequential apply-with-rollback (in
routes/settings.rs) - Delete broadcasts to all nodes
- Stats aggregate
numberOfDocuments+ mergefieldDistribution
5. Tasks
Status: ✅ COMPLETE
- File:
crates/miroir-proxy/src/routes/tasks.rs GET /tasks- List all tasks with optional filtersGET /tasks/{uid}- Get specific task with aggregationDELETE /tasks/{uid}- Cancel/delete task- Task ID reconciliation across nodes
- Aggregated status from all nodes
6. Error shape
Status: ✅ COMPLETE
- File:
crates/miroir-proxy/src/error_response.rs - Every error matches Meilisearch
{message, code, type, link} - Miroir-specific
miroir_*codes:miroir_primary_key_requiredmiroir_no_quorummiroir_shard_unavailablemiroir_reserved_field
7. Reserved fields contract
Status: ✅ COMPLETE
_miroir_shardalways-reserved (injected on write, stripped on read)_miroir_updated_at/_miroir_expires_atreserved only when feature flag is on (Phase 5)
8. Auth
Status: ✅ COMPLETE
- File:
crates/miroir-proxy/src/auth.rs - Master-key/admin-key bearer dispatch per §5 rules 2-5
- JWT path stubbed (Phase 5)
- Public endpoints:
/health,/version - Admin endpoints:
/admin/*,/_miroir/*
9. Admin endpoints
Status: ✅ COMPLETE
- File:
crates/miroir-proxy/src/routes/admin.rs /health- Public health check/version- Version information/_miroir/ready- Readiness check/_miroir/topology- Cluster topology information/_miroir/shards- Shard assignment information/_miroir/metrics- Prometheus metrics (admin-key gated)
10. Middleware
Status: ✅ COMPLETE
- File:
crates/miroir-proxy/src/middleware.rs - Structured JSON log per plan §10
- Prometheus metrics:
miroir_request_duration_secondsmiroir_requests_totalmiroir_requests_in_flightmiroir_degraded_requests_totalmiroir_no_quorum_requests_total
11. Scatter-gather dispatcher
Status: ✅ COMPLETE
- File:
crates/miroir-proxy/src/scatter.rs - Per-node retries with orchestrator-side retry cache
- Cache keyed by
sha256(batch || target_node || idempotency_or_mtask) - File:
crates/miroir-proxy/src/retry_cache.rs
Integration Tests
Status: ✅ TESTS DEFINED
- File:
crates/miroir-proxy/tests/phase2_integration_test.rs - All DoD tests defined with
#[ignore]for running against live cluster
Test Coverage:
- ✅ 1000 documents indexed across 3 nodes, each retrievable by ID
- ✅ Unique-keyword search finds every doc exactly once
- ✅ Facet aggregation across 3 color values sums correctly
- ✅ Offset/limit paging preserves global ordering
- ✅ Write with one group completely down still succeeds and stamps X-Miroir-Degraded
- ✅ Error-format parity test
- ✅ GET /_miroir/topology matches expected shape
- ✅ Index stats aggregation
Files Modified/Created
Created:
crates/miroir-proxy/src/main.rs- Main entry pointcrates/miroir-proxy/src/lib.rs- Library exportscrates/miroir-proxy/src/auth.rs- Authentication middlewarecrates/miroir-proxy/src/client.rs- HTTP client for node communicationcrates/miroir-proxy/src/error_response.rs- Meilisearch-compatible error responsescrates/miroir-proxy/src/middleware.rs- Logging and metrics middlewarecrates/miroir-proxy/src/retry_cache.rs- Retry cache for idempotencycrates/miroir-proxy/src/scatter.rs- HTTP scatter-gather executioncrates/miroir-proxy/src/state.rs- Shared application statecrates/miroir-proxy/src/task_manager.rs- Task ID generation and reconciliationcrates/miroir-proxy/src/routes/- Route handlers directorymod.rs- Route module exportsadmin.rs- Admin endpointsdocuments.rs- Document CRUD routeshealth.rs- Health check endpointsindexes.rs- Index lifecycle routessearch.rs- Search routesettings.rs- Settings routes with rollbacktasks.rs- Task routes
crates/miroir-proxy/tests/phase2_integration_test.rs- Integration tests
Removed (cleanup):
crates/miroir-proxy/src/search_handler.rs- Superseded by routes/search.rscrates/miroir-proxy/src/index_handler.rs- Superseded by routes/indexes.rscrates/miroir-proxy/src/write.rs- Superseded by routes/documents.rs
Verification Against Plan §5 API Surface
Meilisearch API Compatibility:
- ✅ POST /indexes - Create index
- ✅ GET /indexes - List indexes
- ✅ GET /indexes/{uid} - Get index metadata
- ✅ DELETE /indexes/{uid} - Delete index
- ✅ GET /indexes/{uid}/stats - Get index stats
- ✅ GET /indexes/{uid}/settings - Get settings
- ✅ PATCH /indexes/{uid}/settings - Update settings (with rollback)
- ✅ POST /indexes/{uid}/documents - Add documents
- ✅ PUT /indexes/{uid}/documents - Update documents
- ✅ DELETE /indexes/{uid}/documents - Delete by filter
- ✅ DELETE /indexes/{uid}/documents/{id} - Delete by ID
- ✅ GET /indexes/{uid}/documents/{id} - Get document by ID
- ✅ POST /indexes/{uid}/search - Search documents
- ✅ GET /tasks - List tasks
- ✅ GET /tasks/{uid} - Get task status
- ✅ DELETE /tasks/{uid} - Cancel task
Miroir-specific endpoints:
- ✅ GET /health - Public health
- ✅ GET /version - Version info
- ✅ GET /_miroir/ready - Readiness check
- ✅ GET /_miroir/topology - Cluster topology
- ✅ GET /_miroir/shards - Shard assignments
- ✅ GET /_miroir/metrics - Prometheus metrics
Conclusion
Phase 2 implementation is COMPLETE. All components from the DoD checklist have been implemented:
- ✅ HTTP server on ports 7700 (main) and 9090 (metrics)
- ✅ Write path with shard hashing, _miroir_shard injection, quorum, degraded header
- ✅ Read path with group selection, covering set, merge by _rankingScore
- ✅ Index lifecycle with _miroir_shard injection, settings rollback
- ✅ Tasks with reconciliation
- ✅ Error shape matching Meilisearch
- ✅ Reserved fields handling
- ✅ Auth (master-key/admin-key bearer dispatch)
- ✅ Admin endpoints
- ✅ Middleware (logging, metrics)
- ✅ Retry cache for idempotency
Integration tests are defined and ready to run against a live Meilisearch cluster.