- Add environment-aware CORS and secure cookie support:
* Add secureCookies config to env.ts based on SECURE_COOKIES env var or https detection
* Integrate @elysiajs/cors with credentials and origin configuration
* Update cookie helpers to use SameSite=None; Secure in production
- Wrap expert review update and insert in database transaction for atomicity:
* Ensures diagnosis status update and review insert succeed together
* Rolls back both operations if either fails
* Preserves behavior: only update if status is needs_review, return badRequest if no row updated
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add proper id/htmlFor associations for verified/corrected radio inputs
- Clear correctedDiseaseSlug when switching verdict to verified to prevent stale state
- Add required={verdict === 'corrected'} to disease select
- Add loading state distinguishing between loading reviews/diseases and empty queue
- Add type="button" to diagnosis list selection buttons
- Improve selected diagnosis image alt text to include disease name
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Track the active object URL in previewUrlRef to ensure the cleanup effect
revokes the correct URL on unmount, avoiding closure over stale state.
When replacing or clearing preview, revoke the ref's current URL and set
it to null. On unmount, revoke previewUrlRef.current if present.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Prevent object URL leaks in image-classification-form by revoking previous preview URL before replacing it, revoking after successful submit, and revoking on component unmount
- Improve preview image alt text from generic "Preview" to descriptive Indonesian text "Pratinjau gambar daun jagung untuk diagnosis"
- Use auth store setter consistently in dashboard-page logout instead of direct setState call
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Clear error state before submitting credentials in login page
- Clear error state before submitting registration in register page
- Add optional onFieldChange callback to AuthForm to clear parent errors when fields change
- Add role="alert" to error paragraph for accessibility
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Extract toImageClassificationRecord helper function to eliminate duplicated
transformation code between getImageClassifications and createImageClassification.
Replace hardcoded fake disease object with explicit error when diagnosis.disease
is null, ensuring data integrity. Remove unnecessary type casts now that the
helper is properly typed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
In POST /reviews/:diagnosisId, perform the conditional diagnoses update
first with .returning() to determine whether a row was updated. The update
WHERE includes both id and status 'needs_review'. If no row is returned,
return badRequest and do not insert an expert review. Only after a
successful update insert expertReviews. This prevents concurrent reviewers
from both inserting review rows when only one update should win.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Reject diagnoses not in needs_review status with badRequest
- Make update conditional on both id and status needs_review using and()
- Simplify isDiagnosisRecordOrNull type guard with type alias
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Replace `function toReview(row: any)` with typed ReviewRow interface
- Reconstruct DiseaseCatalogItem explicitly from selected fields instead of casting
- Replace `.filter(Boolean)` with typed isDiagnosisRecord predicate
- Add proper type narrowing for verdict and correctedDiseaseSlug in toReview
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace unsafe `as any` casts with proper type guards using `isDiseaseSlug()`
and explicit type casting to `DiagnosisStatus` and `DiseaseCatalogItem`.
Replace non-null assertions with explicit null checks that return
`serviceUnavailable()` errors when database operations fail.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Implement diagnosis persistence routes with image upload, classification,
and prediction storage. Add missing HTTP error helpers (unauthorized,
forbidden) and update uploader client to use configurable base URL.
- Create POST /api/v1/diagnoses to upload images and store classifications
- Create GET /api/v1/diagnoses to list user's diagnoses (30 most recent)
- Create GET /api/v1/diagnoses/:id to retrieve diagnosis with predictions
- Add loadDiagnosisRecord helper for consistent diagnosis data loading
- Update uploader-client.ts to use env.uploaderBaseUrl
- Add unauthorized and forbidden error helpers to http-errors.ts
- Register diagnosisRoutes in main app
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Extend shared types for image classification, including PredictionProbability, UploaderMetadata, and ImageClassificationRecord.
- Create image_classifications table in the database with necessary fields and foreign key constraints.
- Implement disease mappers to convert database rows to shared disease records.
- Develop uploader client to handle image uploads to external service.
- Create image model service to load and classify images using TensorFlow.js.
- Add API routes for image classification, including GET for history and POST for new classifications.
- Implement frontend components for image classification form and display results.
- Update dashboard to integrate image classification functionality and display results.
- Document implementation plan for backend image classification.
- Add disease detail page component with data fetching and error handling
- Create shared types for diseases and classifications
- Implement API routes for diseases, classifications, and dashboard summary
- Develop reusable components for risk badge and disease card
- Build catalog page with search and filter functionality
- Update dashboard page with data-backed summary and manual classification form
- Register new routes in the web application
- Ensure type safety and consistency across shared modules
- Install bun dependencies and generate bun.lock
- Add @types/bun to API dev dependencies for Bun type support
- Add @types/react and @types/react-dom to web dev dependencies
- Fix web tsconfig.node.json composite project emit configuration
- Verify all packages typecheck and build successfully
- Verify API health and status endpoints respond correctly
All verification steps passed:
- bun install: 354 packages installed
- packages/shared typecheck: OK
- packages/shared build: OK (dist generated)
- apps/api typecheck: OK
- apps/api build: OK (0.76 MB bundle)
- apps/web typecheck: OK
- apps/web build: OK (dist generated)
- API /health endpoint: {"status":"ok"}
- API /api/v1/status endpoint: {"name":"ZeaVis Edu","status":"ok","version":"0.1.0"}