pre torch.compile -chkpoint made
This commit is contained in:
107
tasks/multi-image-user-feedback/08-feedback-api-endpoint.md
Normal file
107
tasks/multi-image-user-feedback/08-feedback-api-endpoint.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# 08. Feedback API Endpoint for Accuracy Ratings and Storage Consent
|
||||
|
||||
meta:
|
||||
id: multi-image-user-feedback-08
|
||||
feature: multi-image-user-feedback
|
||||
priority: P1
|
||||
depends_on: [multi-image-user-feedback-01]
|
||||
tags: [api, backend, database]
|
||||
|
||||
objective:
|
||||
|
||||
- Create a POST endpoint at `/api/feedback` that accepts diagnosis feedback submissions (accuracy rating, notes, image storage consent) and persists them to the database.
|
||||
|
||||
deliverables:
|
||||
|
||||
- `src/app/api/feedback/route.ts` — new API route
|
||||
- `src/app/api/feedback/feedback.test.ts` — test file
|
||||
|
||||
steps:
|
||||
|
||||
1. Create `src/app/api/feedback/route.ts`:
|
||||
|
||||
Route: `POST /api/feedback`
|
||||
|
||||
Accepts JSON body matching `FeedbackRequest`:
|
||||
|
||||
```typescript
|
||||
{
|
||||
sessionId: string;
|
||||
imageIds: string[];
|
||||
userSpecies?: string;
|
||||
predictedDiseaseId: string;
|
||||
accuracyRating: "correct" | "incorrect" | "unsure";
|
||||
consentToStoreImages: boolean;
|
||||
userCorrectedSpecies?: string;
|
||||
notes?: string;
|
||||
}
|
||||
```
|
||||
|
||||
Handler logic:
|
||||
- Parse and validate request body
|
||||
- Generate UUID for `id`
|
||||
- Get `modelVersion` from model loader's `getStatus()`
|
||||
- Set `createdAt` to current timestamp
|
||||
- Insert into `diagnosisFeedback` table via Drizzle
|
||||
- Return `FeedbackResponse`: `{ success: true, id: string }`
|
||||
- Handle validation errors with 400 status
|
||||
- Handle DB errors with 500 status
|
||||
|
||||
Validation rules:
|
||||
- `sessionId` — required, non-empty string
|
||||
- `imageIds` — required, array of non-empty strings, min length 1
|
||||
- `accuracyRating` — required, must be one of "correct", "incorrect", "unsure"
|
||||
- `consentToStoreImages` — required, boolean
|
||||
- `userSpecies` — optional string
|
||||
- `userCorrectedSpecies` — optional string, only meaningful when accuracy is not "correct"
|
||||
- `notes` — optional string, max 500 characters (with error message if exceeded)
|
||||
|
||||
2. Create `src/lib/api/feedback.ts` — client-side helper:
|
||||
- `submitFeedback(data: FeedbackRequest): Promise<FeedbackResponse>`
|
||||
- POST to `/api/feedback` with JSON body
|
||||
- 15-second timeout
|
||||
- Handle network errors gracefully
|
||||
|
||||
3. Handle edge cases:
|
||||
- Invalid JSON body → 400 with descriptive error
|
||||
- Missing required fields → 400 listing missing fields
|
||||
- Invalid accuracyRating value → 400 with allowed values
|
||||
- Database unreachable → 500 with error message
|
||||
- Duplicate sessionId → allowed (user can submit multiple times for different predictions)
|
||||
|
||||
4. CORS and caching:
|
||||
- Add `Cache-Control: no-store` header
|
||||
- No authentication required (public endpoint for feedback)
|
||||
|
||||
tests:
|
||||
|
||||
- Unit: valid feedback submission returns 200 with success
|
||||
- Unit: missing required fields return 400
|
||||
- Unit: invalid accuracyRating returns 400
|
||||
- Unit: notes over 500 chars returns 400
|
||||
- Unit: empty imageIds array returns 400
|
||||
- Unit: client helper `submitFeedback()` makes correct fetch call
|
||||
- Unit: client helper handles network error gracefully
|
||||
- Integration: submit feedback and verify it exists in database
|
||||
|
||||
acceptance_criteria:
|
||||
|
||||
- POST /api/feedback accepts valid feedback and stores it
|
||||
- Invalid requests return appropriate 400 errors with descriptive messages
|
||||
- Database stores all fields correctly
|
||||
- Client helper function is usable from any feedback component
|
||||
- Endpoint returns `{ success: true, id }` on success
|
||||
|
||||
validation:
|
||||
|
||||
- `npx tsc --noEmit` passes
|
||||
- Unit tests pass: `npx vitest run src/app/api/feedback/`
|
||||
- Manual test: `curl -X POST http://localhost:3000/api/feedback -H 'Content-Type: application/json' -d '{"sessionId":"test","imageIds":["img1"],"predictedDiseaseId":"early-blight","accuracyRating":"correct","consentToStoreImages":false}'`
|
||||
- Verify stored data with direct DB query
|
||||
|
||||
notes:
|
||||
|
||||
- No auth needed for MVP — feedback is public and anonymous
|
||||
- imageIds reference images in the uploads directory; no automatic cleanup
|
||||
- A future task could add a review/admin dashboard for browsing feedback entries
|
||||
- Rate limiting could be added later if needed (by sessionId or IP)
|
||||
Reference in New Issue
Block a user