9.3 KiB
ZeaVis Edu Production MVP Design
Goal
Build a production-style MVP demo for ZeaVis Edu where authenticated users can upload corn leaf images, receive AI diagnosis results, track diagnosis history, and route low-confidence cases to expert review.
The MVP should feel complete end-to-end while staying focused on corn leaf disease diagnosis, education, and review workflows.
Scope
In scope
- Email/password registration, login, logout, and authenticated session handling.
- Google OAuth support when required environment variables are configured.
- User roles:
userandexpert. - PostgreSQL-backed persistence with Drizzle migrations.
- Image upload through the external uploader at
https://upload.asepharyana.tech. - Backend image classification with the existing TensorFlow.js model integration.
- Diagnosis records with top-k predictions, confidence, image metadata, and review status.
- User dashboard, diagnosis history, diagnosis detail page, and expert review queue.
- Existing disease catalog and disease detail pages remain available.
Out of scope
- Anonymous diagnosis history.
- Memory or local-file database fallback.
- Production email delivery for magic links or notifications.
- Multi-crop disease support.
- Offline mobile/PWA behavior.
- Admin CMS for editing disease content.
Architecture
The application remains a Bun + Moon monorepo with an Elysia API, React/Vite frontend, and shared TypeScript package.
Backend modules
auth: owns registration, login, logout, current-user lookup, password hashing, sessions, and optional Google OAuth routes.diagnoses: owns authenticated image diagnosis creation, diagnosis history, diagnosis detail retrieval, and diagnosis status transitions.expert: owns expert-only review queue and review submission.diseases: keeps the existing disease catalog API as the canonical disease label source.uploader: wraps the external upload API so the frontend never talks directly to the uploader service.image-model: keeps model loading and inference behind the existing backend classifier boundary.
Frontend modules
- Auth pages:
/loginand/register. - User workspace:
/dashboardfor upload, summary, recent diagnosis history, and catalog entry points. - Diagnosis detail:
/diagnoses/:idfor result, image, top predictions, disease education, status, and expert notes. - Expert workflow:
/expert/reviewsfor low-confidence review queue and review actions. - Existing catalog pages:
/catalogand/catalog/:slug.
Authentication and authorization
Email/password auth is required for the MVP. Passwords are stored only as secure hashes. Sessions are persisted in PostgreSQL and sent to the browser as HTTP-only cookies.
Google OAuth is optional. The API exposes Google OAuth routes only when GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and GOOGLE_REDIRECT_URI are all configured. The frontend hides the Google login button unless the API reports that OAuth is enabled.
Authorization rules:
- Unauthenticated users can access public landing and catalog content.
- Authenticated
useraccounts can create diagnoses and view only their own diagnoses. expertaccounts can access the expert review queue and submit reviews.- Expert accounts can also use normal user diagnosis features unless explicitly restricted later.
Data model
users
Stores identity and role data.
Fields:
idemailnamepasswordHashnullable for OAuth-only usersrole:userorexpertgoogleIdnullablecreatedAtupdatedAt
sessions
Stores server-side sessions.
Fields:
iduserIdtokenHashexpiresAtcreatedAt
diseases
Continues to store the education catalog and canonical disease labels.
diagnoses
Stores each uploaded classification request.
Fields:
iduserIdpredictedDiseaseIdnullable when inference failsimageUrluploaderPublicIdimageFileNameimageMimeTypeimageSizeBytesconfidencenullable when inference failsstatus:ai_verified,needs_review,expert_verified,expert_corrected, orfailedfailureReasonnullablecreatedAtupdatedAt
Status rules:
- Confidence
>= 0.7becomesai_verified. - Confidence
< 0.7becomesneeds_review. - Expert verification changes status to
expert_verified. - Expert correction changes status to
expert_corrected. - Successful upload followed by inference failure creates
failedwith a failure reason.
diagnosis_predictions
Stores top-k model predictions for each diagnosis.
Fields:
iddiagnosisIddiseaseIdnullable if a model label cannot be mappedmodelLabelconfidencerank
expert_reviews
Stores expert decisions.
Fields:
iddiagnosisIdexpertIdverdict:verifiedorcorrectedcorrectedDiseaseIdnullable for verified resultsnotescreatedAt
API design
Auth
POST /auth/register: creates a user account and session.POST /auth/login: creates a session for email/password credentials.POST /auth/logout: expires the current session.GET /auth/me: returns current user and feature flags such as Google OAuth availability.GET /auth/google: starts Google OAuth only when configured.GET /auth/google/callback: completes Google OAuth only when configured.
Diagnoses
POST /diagnoses: accepts multipart image upload, validates image constraints, uploads to the external uploader, runs model inference, stores diagnosis and predictions, and returns the created diagnosis.GET /diagnoses: returns diagnoses for the current user.GET /diagnoses/:id: returns one diagnosis if owned by the current user or accessible to the current expert.
Expert review
GET /expert/reviews: returns diagnoses withneeds_reviewstatus.POST /expert/reviews/:diagnosisId: verifies or corrects a diagnosis and stores expert notes.
Diseases
Existing disease catalog endpoints stay available and continue to back diagnosis result details.
External uploader integration
The API integrates with https://upload.asepharyana.tech through a backend adapter.
Upload request:
POST /api/uploadmultipart/form-datafile: binary payload- optional
fileName
Stored response fields:
public_iddownload_urlfile_namemime_typesize_bytesfile_type
The application stores download_url as the image URL shown in the UI and public_id for metadata/debugging. If the uploader fails, the diagnosis is not created and the API returns a clear upload failure response.
User experience
Standard user flow
- User registers or logs in.
- User opens the dashboard.
- User uploads a corn leaf image and sees preview/progress.
- API uploads, classifies, and stores the diagnosis.
- User sees diagnosis result with image, disease, confidence, top predictions, status, and recommended actions.
- User can revisit diagnosis history and details.
Low-confidence flow
For confidence below 70%, the user still sees the AI result, but the status clearly says the result is awaiting expert review. The result page explains that the AI prediction is provisional.
Expert flow
- Expert logs in.
- Expert opens
/expert/reviews. - Expert sees all diagnoses needing review.
- Expert opens a case, reviews the image and top predictions, then verifies or corrects the disease label with notes.
- The user-facing diagnosis status updates to expert verified or expert corrected.
Error handling
Validation happens at system boundaries:
- Registration and login payloads.
- Session cookie presence and validity.
- Role checks for expert endpoints.
- Upload file type and configured max size.
- Uploader response shape.
- Model label mapping to known disease records.
Failure behavior:
- Uploader failure returns an error and does not create a diagnosis.
- Inference failure after successful upload creates a
faileddiagnosis for auditability. - Low confidence is not treated as an error; it routes to review.
- Missing Google OAuth env hides Google OAuth from the UI.
Configuration
Required:
DATABASE_URLSESSION_SECRET
Optional:
UPLOADER_BASE_URL, defaulting tohttps://upload.asepharyana.techGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETGOOGLE_REDIRECT_URIUPLOAD_MAX_BYTESUPLOAD_ALLOWED_MIME_TYPES
PostgreSQL is mandatory. The application should fail clearly during startup or first database access when DATABASE_URL is missing or invalid.
Verification plan
Automated checks:
bun run typecheckbun run build- Drizzle migration generation/application check
Manual happy path:
- Register a user.
- Log in.
- Upload a valid corn leaf image.
- Confirm the diagnosis is saved and visible in history.
- Confirm diagnosis detail shows image, top predictions, disease information, confidence, and status.
- Log in as an expert.
- Review a low-confidence diagnosis.
- Confirm the user-facing diagnosis status and notes update.
Manual error path:
- Upload a non-image file and confirm validation error.
- Call a diagnosis endpoint while logged out and confirm unauthorized response.
- Access expert review as a non-expert and confirm forbidden response.
- Temporarily omit Google OAuth env and confirm Google login is hidden.
Catatan (2026-08-02): port produksi sekarang API 4006, nginx 4011, ML 4012; deploy Nix+systemd+Caddy.