Commit Graph
100 Commits
Author SHA1 Message Date
Asep Haryana SaputraandGitHub 5a06e5c08c Merge pull request #36 from MythEclipse/main
Android
2026-06-14 23:48:29 +07:00
Asep Haryana SaputraandGitHub 3f77eb8283 Merge branch 'ATLAS-PJK-GM007:main' into main 2026-06-14 23:48:02 +07:00
Asep Haryana SaputraandGitHub dbf2bcfc4a Merge pull request #32 from MythEclipse/main
fix
2026-06-13 00:36:47 +07:00
Asep Haryana SaputraandGitHub 65adcd9d24 Merge pull request #31 from MythEclipse/main
fix(ci): download model files from HF root path to correct subdirs
2026-06-12 23:29:18 +07:00
Asep Haryana SaputraandGitHub 0aefa7f5ff Merge pull request #30 from MythEclipse/main
fix(ml): fix cbam_block, cardinality, Lambda serialization + update C…
2026-06-12 23:02:02 +07:00
Asep Haryana SaputraandGitHub af1565d704 Merge pull request #29 from MythEclipse/main
feat: update model
2026-06-12 22:56:44 +07:00
Asep Haryana SaputraandGitHub 790acab275 Merge pull request #26 from MythEclipse/main
remove model
2026-06-11 20:39:42 +07:00
Asep Haryana SaputraandGitHub ee3047a3a5 Delete .github/workflows/telemetry-ci-cd.yml 2026-06-08 01:00:17 +07:00
Asep Haryana SaputraandGitHub 791273ce35 Merge pull request #24 from MythEclipse/main
feat/metrics
2026-06-07 21:44:41 +07:00
Asep Haryana SaputraandGitHub 1106cbf62f Merge branch 'ATLAS-PJK-GM007:main' into main 2026-06-07 21:43:28 +07:00
Asep Haryana SaputraandGitHub 10c544a533 Merge pull request #22 from MythEclipse/main
traefik
2026-06-07 16:10:40 +07:00
Asep Haryana SaputraandGitHub 66fd725e01 Merge branch 'ATLAS-PJK-GM007:main' into main 2026-06-07 16:10:09 +07:00
Asep Haryana Saputra b713b72d2d fix: RiskBadge overflow on long disease names in catalog cards
- Add flex-wrap and min-w-0 to prevent RiskBadge from overflowing
  the card boundary when commonName is long (e.g., Northern/Southern Leaf Blight)
- Fix both catalog-page.tsx and disease-card.tsx for consistency
2026-06-02 09:39:01 +00:00
Asep Haryana SaputraandClaude Opus 4.7 81d083a2b8 fix(frontend): wrap catalog, disease detail, and expert reviews with MainLayout
- Add MainLayout wrapper to /catalog, /catalog/:slug, and /expert/reviews
  routes in app.tsx so they share the same navbar and footer as dashboard
- Remove duplicate header/layout/spacing from CatalogPage,
  DiseaseDetailPage, and ExpertReviewsPage
- Update ExpertReviewsPage to use consistent space-y layout pattern
  matching other pages
- Update CatalogPage to remove outer main wrapper since MainLayout
  provides the container

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 07:47:59 +00:00
Asep Haryana SaputraandClaude Opus 4.7 4d6ca4912c fix(frontend): align catalog with dashboard, make disease cards clickable, fix stat cards
- Make dashboard disease quick-access cards clickable → link to /catalog/:slug
- Update catalog page to match dashboard styling (4-column grid, consistent
  card design with colored dot, risk badge, line-clamp summary)
- Add URL param support to catalog (?risk=high) so dashboard's
  "Risiko Tinggi" stat card link works
- Remove confusing "Total Penyakit" stat card (was counting catalog rows,
  always 4). Replace with "Total Diagnosa" linking to /diagnoses,
  "Gagal" stat, and rename "Risiko Tinggi" to "Kategori Risiko Tinggi"
  linking to /catalog?risk=high

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 07:22:28 +00:00
Asep Haryana SaputraandClaude Opus 4.7 ba24cf1a05 fix(frontend): align pages with DB schema, fix auth, and improve UX
- Fix auth system: remove redirect bugs in login/register pages, register
  routes, wrap protected routes with AuthGuard, add AuthInitializer
- Add missing navbar links (Diagnosa, Pustaka, expert Review)
- Fix DiagnosesPage status filter to match DB DiagnosisStatus enum,
  support URL params (?status=, ?risk=) from dashboard links
- Replace hardcoded disease data on Dashboard with API-driven data,
  fix layout bugs (invalid gap-57 class, empty Button)
- Rewrite LibraryPage to use API instead of mock-diseases.ts
- Indonesian-ize Expert Reviews page labels and text
- Wrap DiagnosisDetailPage with MainLayout for consistent layout
- Improve ScanPage UX: image preview before upload, lucide icons,
  proper disease names in result modal, file size validation
- Delete dead code: mock-diseases.ts, unused form components,
  tailwind.config.ts (Tailwind v4 does not read v3 config)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 07:12:49 +00:00
Asep Haryana SaputraandGitHub a28d06cb02 Merge pull request #19 from ATLAS-PJK-GM007/selly/frontend
feat: update landing page and add new library and scan pages
2026-06-02 09:18:20 +07:00
Asep Haryana SaputraandGitHub de7c89d6b5 Merge pull request #18 from MythEclipse/main
fix: update .gitignore and modify Traefik rules for API and ML servic…
2026-05-29 14:40:21 +07:00
Asep Haryana Saputra d071426191 fix: update domain names in docker-compose.yml for web, api, and ml services 2026-05-28 20:01:48 +00:00
Asep Haryana Saputra 73772f5f56 fix: update Rust and Debian base images in Dockerfile 2026-05-23 13:31:04 +00:00
Asep Haryana Saputra e848d20276 fix: update Rust version and improve Dockerfile build process 2026-05-23 13:27:06 +00:00
Asep Haryana Saputra 8d04a17d84 feat: add Python setup and ONNX model generation to CI workflow 2026-05-23 13:16:08 +00:00
Asep Haryana Saputra 5b4f8d29df fix: update .gitignore to include target directory 2026-05-23 12:32:52 +00:00
Asep Haryana SaputraandClaude Opus 4.7 e03c8a60fe fix: align Rust ML service with verified cargo build
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 12:21:33 +00:00
Asep Haryana SaputraandClaude Opus 4.7 e2e3addd66 fix: align Rust ML service verification
Corrected API response format documentation in README:
- Health endpoint: removed non-existent model_path field
- Metadata endpoint: fixed field names (service_name, service_version instead of service, version) and label order
- Prediction endpoint: corrected response structure to match implementation (single prediction object with probabilities map, not array)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 11:09:16 +00:00
Asep Haryana Saputra 86371a6e31 docs: clarify ML service command context 2026-05-23 11:05:49 +00:00
Asep Haryana Saputra ea35ae4322 docs: clarify ML service port defaults 2026-05-23 11:01:41 +00:00
Asep Haryana SaputraandClaude Opus 4.7 f2e4c338bb docs: align Rust ONNX service deployment docs
- Update docker-compose.yml MODEL_PATH from best_model.keras to model.onnx
- Fix Machine_Learning/README.md TOC and section numbering (remove duplicate section 9, add Validasi Parity ONNX as section 9)
- Clarify parity validation as manual/recommended, not mandatory CI
- Update CLAUDE.md to document Rust/Axum/ONNX Runtime ML service and ONNX export workflow
- Simplify root README.md ML service section with port clarification (8001 local, 8000 container)
- Remove stale endpoint examples from root README (documented in apps/ml-service/README.md)
- Ensure no FastAPI/Uvicorn references in deployment documentation

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 10:58:08 +00:00
Asep Haryana SaputraandClaude Opus 4.7 abff278f49 docs: document Rust ONNX ML service
Update documentation to reflect migration from FastAPI/Uvicorn to Rust/Axum with ONNX Runtime:

- Root README: Update ML service description, tech stack, prerequisites, and run instructions to use Rust/Cargo instead of Python/Uvicorn
- Root README: Update model path references from best_model.keras to model.onnx
- Root README: Add model.onnx to artifact lists and generated files
- Root README: Update troubleshooting section with Rust-specific guidance
- Machine_Learning/README: Add table of contents entry for ONNX conversion
- Machine_Learning/README: Add Tahap 5 section documenting ONNX conversion with convert_onnx.py and validate_onnx_parity.py
- Machine_Learning/README: Update output table to include model.onnx with Rust ONNX Runtime usage
- apps/ml-service/README: Create comprehensive documentation for Rust Axum ONNX service including setup, endpoints, environment variables, testing, and troubleshooting

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 10:51:59 +00:00
Asep Haryana Saputra b1e99643f6 fix: allow ONNX model in Docker context 2026-05-23 10:48:01 +00:00
Asep Haryana SaputraandClaude Code ba33bc1f23 fix: make Rust ML Docker build include ONNX runtime assets
- Add 'download-binaries' feature to ort crate in Cargo.toml to ensure ONNX Runtime binaries are downloaded during build
- Update .dockerignore to allow Machine_Learning/model/model.onnx through build context while still excluding other generated model artifacts (saved_model, tfjs_model, tflite)
- Dockerfile can now successfully copy model.onnx at runtime

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-05-23 10:44:32 +00:00
Asep Haryana Saputra d33f334dc1 build: containerize Rust ML service 2026-05-23 10:38:58 +00:00
Asep Haryana Saputra b6987ff329 test: add ONNX parity validation script 2026-05-23 10:32:32 +00:00
Asep Haryana Saputra 6c5a56ade3 fix: capture ONNX conversion errors 2026-05-23 10:28:34 +00:00
Asep Haryana Saputra abba07b969 fix: improve ONNX conversion logging 2026-05-23 10:26:21 +00:00
Asep Haryana Saputra 4d82bbae34 feat: add ONNX conversion script 2026-05-23 09:57:19 +00:00
Asep Haryana Saputra 3d3f1d14fa refactor: replace Python ML service runtime with Rust 2026-05-23 09:50:39 +00:00
Asep Haryana Saputra b4975819eb feat: serve ML inference endpoints with Axum 2026-05-23 09:48:54 +00:00
Asep Haryana SaputraandClaude Opus 4.7 36e4a49ca7 fix: harden ONNX model wrapper
- Store ONNX Session in Option<Mutex<Session>> for thread-safe concurrent access
- Lock session before run() in predict(), map lock poisoning to PredictionFailed
- Preserve ModelUnavailable when session is None
- Reject non-finite values (NaN, +inf, -inf) in prediction_from_probabilities
- Add unit tests for NaN, positive infinity, and negative infinity rejection
- Keep all existing tests passing

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 09:44:25 +00:00
Asep Haryana Saputra fc34e52911 feat: add ONNX model inference wrapper 2026-05-23 09:41:30 +00:00
Asep Haryana Saputra ad4c897c41 feat: preprocess uploaded images in Rust 2026-05-23 09:38:10 +00:00
Asep Haryana Saputra ee872c644f fix: align ML service response schemas 2026-05-23 09:36:20 +00:00
Asep Haryana Saputra dce4d4f21c feat: define ML service API responses 2026-05-23 09:33:15 +00:00
Asep Haryana Saputra 96c38df124 feat: load ML service config from environment 2026-05-23 09:30:51 +00:00
Asep Haryana SaputraandClaude Opus 4.7 10e890cc42 feat: scaffold Rust ML service crate
Create Rust crate skeleton with Cargo.toml, main.rs, and config.rs.
Includes package metadata, dependencies (anyhow, axum, image, ndarray,
ort, serde, tokio, tower, tracing), and config module with LABELS
constants, SERVICE_NAME, SERVICE_VERSION, DEFAULT_INPUT_SIZE, and
resolve_model_path function. Config tests verify label order, relative
path resolution, and absolute path preservation.

Also includes approved spec and implementation plan documents.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 09:23:38 +00:00
Asep Haryana Saputra b735897dc2 fix: add LFS support in checkout step of deployment workflow 2026-05-22 22:22:07 +00:00
Asep Haryana Saputra 8cd128a438 fix: update ML_SERVICE_URL to use internal service endpoint in deployment configuration 2026-05-22 22:10:00 +00:00
Asep Haryana Saputra 4453758180 fix: update API proxy configuration to use internal service endpoint 2026-05-22 22:06:21 +00:00
Asep Haryana Saputra 193f83d9c5 fix: update VITE_API_BASE_URL fallback to an empty string in deployment workflow 2026-05-22 22:01:23 +00:00
Asep Haryana Saputra 2a12c998a8 fix: remove outdated comment regarding dynamic IMAGE_PREFIX in deployment workflow 2026-05-22 21:58:57 +00:00
Asep Haryana Saputra 83993febc7 fix: update comment to clarify dynamic IMAGE_PREFIX setting in deployment workflow 2026-05-22 21:58:00 +00:00
Asep Haryana Saputra 1d421ee948 feat: update deployment configuration and enhance VITE_API_BASE_URL handling 2026-05-22 21:53:01 +00:00
Asep Haryana Saputra 39039b4d27 fix: update environment variable setup in deployment script 2026-05-22 21:42:58 +00:00
Asep Haryana Saputra fbd85c7e3a fix: update image prefix setting and normalize repository name in deployment script 2026-05-22 21:41:21 +00:00
Asep Haryana Saputra a94fb50225 fix: normalize repository name to lowercase in deployment workflow 2026-05-22 21:40:42 +00:00
Asep Haryana Saputra a0f9d307fd feat: enhance deployment script to clone repository if not present 2026-05-22 21:38:52 +00:00
Asep Haryana Saputra 80df164a2b fix: improve validation of deployment secrets in workflow 2026-05-22 21:35:48 +00:00
Asep Haryana Saputra 64d63587c7 feat: validate deployment secrets and update SSH action version 2026-05-22 21:33:32 +00:00
Asep Haryana SaputraandClaude Opus 4.7 1978597bcf feat: add Docker deployment workflow
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 21:20:56 +00:00
Asep Haryana Saputra 5ca95907a0 feat: implement Docker deployment plan with web, API, and ML services 2026-05-22 20:11:37 +00:00
Asep Haryana SaputraandClaude Opus 4.7 1d4355e9f0 docs: add Docker deployment design
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 20:08:13 +00:00
Asep Haryana SaputraandClaude Opus 4.7 e84be0d42f fix: handle malformed ML service responses
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 20:00:01 +00:00
Asep Haryana SaputraandClaude Opus 4.7 b81fecaa3f chore: remove API local model dependencies
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:54:31 +00:00
Asep Haryana SaputraandClaude Opus 4.7 1689f3f44e feat: call ML service for image classification
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:53:10 +00:00
Asep Haryana SaputraandClaude Opus 4.7 9a642a8581 feat: add ML service URL config
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:50:25 +00:00
Asep Haryana SaputraandClaude Opus 4.7 b177662241 docs: add API ML service migration plan
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:49:04 +00:00
Asep Haryana SaputraandClaude Opus 4.7 b69b32f5b3 docs: add API ML service migration spec
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:46:48 +00:00
Asep Haryana SaputraandClaude Opus 4.7 c3e7453390 chore: remove local Claude artifact from tracking
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:41:00 +00:00
Asep Haryana SaputraandClaude Opus 4.7 ed8cecc3f5 fix: align ML service labels with training order
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:40:41 +00:00
Asep Haryana Saputra 59877bc17f chore: add __pycache__ to .gitignore 2026-05-22 19:35:44 +00:00
Asep Haryana SaputraandClaude Opus 4.7 47d9a53a44 docs: add ML service implementation plan
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:34:11 +00:00
Asep Haryana SaputraandClaude Opus 4.7 f08ba6753d chore: ignore ML service virtualenv
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:34:03 +00:00
Asep Haryana SaputraandClaude Opus 4.7 3b0416b946 docs: add ML service usage guide
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:30:05 +00:00
Asep Haryana SaputraandClaude Opus 4.7 a30071d8e8 feat: add ML service API routes
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:29:44 +00:00
Asep Haryana SaputraandClaude Opus 4.7 f3d2b8d72e feat: add ML model prediction service
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:29:13 +00:00
Asep Haryana SaputraandClaude Opus 4.7 ca9cbb12bf feat: add ML service response schemas
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:28:43 +00:00
Asep Haryana SaputraandClaude Opus 4.7 37831ba717 feat: add ML service Moon tasks
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:23:43 +00:00
Asep Haryana SaputraandClaude Opus 4.7 d21bd2e683 feat: scaffold ML service configuration
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:21:15 +00:00
Asep Haryana SaputraandClaude Opus 4.7 5b441282fc docs: add ML service design spec
Document the agreed FastAPI inference service boundary before implementation planning.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 19:14:56 +00:00
Asep Haryana Saputra 8415cbb2de feat: add database seeding script for disease catalog and expert user 2026-05-22 18:54:23 +00:00
Asep Haryana Saputra 1f4e0fbef3 fix: update environment variable usage in scripts and enhance CSS theming 2026-05-22 18:50:07 +00:00
Asep Haryana Saputra 553e8f49aa fix: remove deprecated baseUrl option from tsconfig files 2026-05-22 18:36:45 +00:00
Asep Haryana Saputra ab81168be7 chore: update dependencies and build scripts
- Updated @moonrepo/cli to version 2.2.5 and typescript to version 6.0.3 in package.json and shared package.json.
- Modified build script in package.json to run shared, api, and web builds.
- Removed unnecessary type and language declarations from shared moon.yml.
- Added ignoreDeprecations option in tsconfig.base.json to handle TypeScript 6.0 deprecations.
2026-05-22 18:30:40 +00:00
Asep Haryana Saputra 32a034a083 feat: add implementation plan and design for JS/TS dependency updates 2026-05-22 17:55:44 +00:00
Asep Haryana Saputra 1994b9ed17 Merge branch 'worktree-production-mvp' 2026-05-22 17:46:40 +00:00
Asep Haryana SaputraandClaude Opus 4.7 c623de9959 fix: harden production auth and review flow
- 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>
2026-05-22 17:32:57 +00:00
Asep Haryana Saputra 4478d51aae feat: add production MVP database migration 2026-05-22 17:19:46 +00:00
Asep Haryana SaputraandClaude Opus 4.7 be569ff675 fix: improve expert review form accessibility
- 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>
2026-05-22 17:17:24 +00:00
Asep Haryana Saputra 1b24e6f6a0 feat: add expert review UI 2026-05-22 17:11:56 +00:00
Asep Haryana SaputraandClaude Opus 4.7 0027c0ed05 fix: revoke active upload preview on unmount
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>
2026-05-22 17:09:24 +00:00
Asep Haryana SaputraandClaude Opus 4.7 7fb8b075b8 fix: clean up dashboard upload state
- 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>
2026-05-22 17:07:18 +00:00
Asep Haryana Saputra 1b5c16b135 feat: migrate dashboard to diagnosis workflow 2026-05-22 17:03:26 +00:00
Asep Haryana Saputra cf44a58486 feat: add diagnosis detail UI 2026-05-22 16:58:23 +00:00
Asep Haryana SaputraandClaude Opus 4.7 fd6f60f4f4 fix: clear auth form errors
- 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>
2026-05-22 16:55:47 +00:00
Asep Haryana Saputra 84fb808b53 feat: add frontend authentication flow 2026-05-22 16:51:01 +00:00
Asep Haryana SaputraandClaude Opus 4.7 9250696f54 fix: simplify diagnosis API aliases
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>
2026-05-22 16:46:43 +00:00
Asep Haryana Saputra 16a8935958 feat: add frontend production API client 2026-05-22 16:43:25 +00:00
Asep Haryana Saputra e9d6aabcdc fix: tighten dashboard summary types 2026-05-22 16:39:38 +00:00
Asep Haryana Saputra 02b002b021 feat: update dashboard for diagnosis workflow 2026-05-22 16:36:53 +00:00
Asep Haryana SaputraandClaude Opus 4.7 7712a5c6a1 fix: prevent duplicate expert reviews
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>
2026-05-22 16:34:02 +00:00