@@ -54,14 +54,18 @@ rust/leanspec-http/tests/
5454├── common/
5555│ ├── mod.rs # Test utilities
5656│ ├── fixtures.rs # Test fixtures (sample specs)
57- │ └── server.rs # Test server setup
57+ │ ├── server.rs # Test server setup
58+ │ └── schema_validator.rs # Schema validation utilities
5859├── integration/
5960│ ├── projects_test.rs # Project management APIs
6061│ ├── specs_test.rs # Spec operations
6162│ ├── search_test.rs # Search functionality
6263│ ├── stats_test.rs # Statistics
6364│ ├── deps_test.rs # Dependencies
6465│ └── validate_test.rs # Validation
66+ ├── schemas/
67+ │ ├── nextjs_reference.rs # Reference schemas from Next.js API
68+ │ └── compatibility_test.rs # Schema compatibility tests
6569└── scenarios/
6670 ├── multi_project_test.rs # Multi-project scenarios
6771 └── error_cases_test.rs # Error handling
@@ -75,6 +79,12 @@ rust/leanspec-http/tests/
7579- Verify responses match expected format
7680- Test error conditions and edge cases
7781
82+ ** Schema Compatibility Tests** (NEW):
83+ - Validate Rust response schemas match Next.js API schemas
84+ - Ensure field names match (camelCase vs snake_case)
85+ - Verify response structure compatibility
86+ - Test serialization consistency
87+
7888** Test Fixtures** :
7989- Reusable test projects with known spec structure
8090- Sample specs with various statuses, priorities, tags
@@ -84,6 +94,7 @@ rust/leanspec-http/tests/
8494- ` axum-test ` or raw Axum router testing
8595- ` reqwest ` for HTTP client
8696- ` serde_json ` for response validation
97+ - ` schemars ` for JSON Schema generation and validation
8798- ` tempfile ` for temporary test projects
8899- ` tokio::test ` for async tests
89100
@@ -94,10 +105,14 @@ rust/leanspec-http/tests/
94105- [ ] Create test fixture generator (sample specs)
95106- [ ] Create test server helper (spawn with temp registry)
96107- [ ] Add test utilities (assertions, matchers)
108+ - [ ] Set up schema validation utilities
109+ - [ ] Document reference Next.js API schemas
97110
98111### Phase 2: Project Management Tests (Day 2)
99112- [ ] Test GET ` /api/projects ` (list all, empty state, multi-project)
113+ - [ ] Validate response schema matches Next.js ` /api/local-projects `
100114- [ ] Test POST ` /api/projects ` (add valid, invalid path, duplicate)
115+ - [ ] Validate request/response schema compatibility
101116- [ ] Test GET ` /api/projects/{id} ` (existing, not found)
102117- [ ] Test PATCH ` /api/projects/{id} ` (update name, favorite, color)
103118- [ ] Test DELETE ` /api/projects/{id} ` (remove, not found, current project)
@@ -107,16 +122,23 @@ rust/leanspec-http/tests/
107122
108123### Phase 3: Spec Operations Tests (Day 3)
109124- [ ] Test GET ` /api/specs ` (list all, empty, with filters)
125+ - [ ] Validate response schema matches Next.js ` /api/projects/[id]/specs `
126+ - [ ] Compare field serialization: camelCase vs snake_case
110127- [ ] Test GET ` /api/specs ` with query params (status, priority, tags, assignee)
111128- [ ] Test GET ` /api/specs/{spec} ` (by number, by name, not found)
112129- [ ] Test GET ` /api/specs/{spec} ` (verify required_by computed)
130+ - [ ] Validate SpecDetail schema matches Next.js spec detail
113131- [ ] Test POST ` /api/search ` (query, filters, empty results)
132+ - [ ] Validate SearchResponse schema compatibility
114133- [ ] Test POST ` /api/search ` (ranking by relevance)
115134
116135### Phase 4: Stats & Dependencies Tests (Day 4)
117136- [ ] Test GET ` /api/stats ` (empty project, various statuses)
137+ - [ ] Validate StatsResponse schema matches Next.js ` /api/projects/[id]/stats `
138+ - [ ] Compare field names: byStatus, byPriority, byTag
118139- [ ] Test GET ` /api/stats ` (verify counts by status, priority, tags)
119140- [ ] Test GET ` /api/deps/{spec} ` (simple dependency)
141+ - [ ] Validate DependencyResponse schema
120142- [ ] Test GET ` /api/deps/{spec} ` (transitive dependencies)
121143- [ ] Test GET ` /api/deps/{spec} ` (circular dependencies)
122144- [ ] Test GET ` /api/deps/{spec} ` (spec not found)
@@ -150,6 +172,8 @@ rust/leanspec-http/tests/
150172- [ ] All happy path scenarios tested
151173- [ ] All error conditions tested
152174- [ ] Multi-project switching tested
175+ - [ ] ** Schema compatibility validated with Next.js APIs**
176+ - [ ] ** All response fields use camelCase serialization**
153177- [ ] Tests run in CI
154178- [ ] Tests pass consistently
155179
@@ -158,9 +182,41 @@ rust/leanspec-http/tests/
158182- [ ] Concurrent request testing
159183- [ ] Large dataset testing (100+ specs)
160184- [ ] Test documentation/examples
185+ - [ ] JSON Schema exports for documentation
161186
162187## Test Examples
163188
189+ ### Schema Validation Test
190+
191+ ``` rust
192+ #[tokio:: test]
193+ async fn test_spec_response_schema_compatibility () {
194+ let app = test_server_with_fixtures (). await ;
195+
196+ // Get spec from Rust API
197+ let res = app . get (" /api/specs/001-test-spec" ). send (). await ;
198+ assert_eq! (res . status (), 200 );
199+
200+ let spec : SpecDetail = res . json (). await ;
201+
202+ // Validate required fields exist and use camelCase
203+ assert! (spec . spec_number. is_some ());
204+ assert! (! spec . spec_name. is_empty ());
205+ assert! (! spec . title. is_none ());
206+ assert! (! spec . status. is_empty ());
207+ assert! (! spec . content_md. is_empty ());
208+ assert! (! spec . file_path. is_empty ());
209+
210+ // Validate field serialization matches Next.js format
211+ let json = serde_json :: to_value (& spec ). unwrap ();
212+ assert! (json . get (" specNumber" ). is_some ()); // camelCase
213+ assert! (json . get (" specName" ). is_some ()); // camelCase
214+ assert! (json . get (" contentMd" ). is_some ()); // camelCase
215+ assert! (json . get (" filePath" ). is_some ()); // camelCase
216+ assert! (json . get (" createdAt" ). is_some ()); // camelCase
217+ }
218+ ```
219+
164220### Project Management Test
165221
166222``` rust
@@ -182,6 +238,11 @@ async fn test_list_projects() {
182238 let body : ProjectsListResponse = res . json (). await ;
183239 assert_eq! (body . projects. len (), 1 );
184240 assert! (body . current_project_id. is_some ());
241+
242+ // Validate schema matches Next.js /api/local-projects
243+ let json = serde_json :: to_value (& body ). unwrap ();
244+ assert! (json . get (" projects" ). is_some ());
245+ assert! (json . get (" currentProjectId" ). is_some ()); // camelCase
185246}
186247
187248#[tokio:: test]
@@ -271,19 +332,56 @@ async fn test_search_relevance_ranking() {
271332
272333## Notes
273334
335+ ### Schema Compatibility Strategy
336+
337+ ** Reference Implementation** : Next.js API routes in ` packages/ui/src/app/api/ `
338+ - ` /api/local-projects ` → Rust ` /api/projects `
339+ - ` /api/projects/[id]/specs ` → Rust ` /api/specs `
340+ - ` /api/projects/[id]/stats ` → Rust ` /api/stats `
341+ - ` /api/projects/[id]/dependencies ` → Rust ` /api/deps/{spec} `
342+
343+ ** Validation Approach** :
344+ 1 . Extract sample responses from Next.js API routes
345+ 2 . Compare field names and structure
346+ 3 . Validate camelCase serialization in Rust responses
347+ 4 . Document any intentional differences
348+ 5 . Create compatibility tests that would fail on schema drift
349+
350+ ** Key Fields to Validate** :
351+ - ` specNumber ` (not ` spec_number ` )
352+ - ` specName ` (not ` spec_name ` )
353+ - ` contentMd ` (not ` content_md ` )
354+ - ` filePath ` (not ` file_path ` )
355+ - ` createdAt ` , ` updatedAt ` , ` completedAt ` (not snake_case)
356+ - ` dependsOn ` , ` requiredBy ` (not snake_case)
357+ - ` byStatus ` , ` byPriority ` , ` byTag ` in stats (not snake_case)
358+
359+ ** Current Status** : ✅ Rust types already use ` #[serde(rename_all = "camelCase")] ` - tests will validate this continues working.
360+
274361### Why Integration Tests First?
275362
2763631 . ** Verify current state** : Ensure existing APIs work before adding new ones
2773642 . ** Regression prevention** : Catch breaking changes immediately
278- 3 . ** Documentation** : Tests serve as API usage examples
279- 4 . ** Confidence** : Safe to refactor with comprehensive tests
280- 5 . ** Prerequisites** : Spec 190 backend work needs this foundation
365+ 3 . ** Schema validation** : Ensure compatibility with Next.js APIs
366+ 4 . ** Documentation** : Tests serve as API usage examples
367+ 5 . ** Confidence** : Safe to refactor with comprehensive tests
368+ 6 . ** Prerequisites** : Spec 190 backend work needs this foundation
369+
370+ ### Why Schema Alignment Matters
371+
372+ ** API Compatibility** is critical because:
373+ - ** @leanspec/ui-vite ** expects exact same response format as Next.js APIs
374+ - Field names must match (camelCase in JSON, not snake_case)
375+ - Frontend code should work unchanged when switching backends
376+ - Type safety: TypeScript types in frontend must match Rust serialization
377+ - No adapter layer needed if schemas are identical
281378
282379### Testing Philosophy
283380
284381** Focus on behavior, not implementation** :
285382- Test HTTP responses, not internal state
286383- Verify response formats match frontend expectations
384+ - ** Validate schema compatibility with Next.js APIs**
287385- Test edge cases and error conditions
288386- Use realistic fixtures that mirror production data
289387
0 commit comments