Files
zeavis-edu/CLAUDE.md
T
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

6.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Repository overview

This repository contains the ZeaVis Edu application: a corn leaf disease classifier with a machine-learning pipeline (EfficientNetV2B0 training and export), a Rust/Axum/ONNX Runtime inference service, and a fullstack TypeScript application (React frontend, Elysia backend, PostgreSQL).

The ML pipeline lives under Machine_Learning/. The inference service lives under apps/ml-service/. Most ML commands should be run from the Machine_Learning/ directory unless noted otherwise.

Common commands

cd Machine_Learning

Set up a Python environment:

python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Run local dataset preprocessing after placing dataset_1.zip, dataset_2.zip, and dataset_3.zip beside preprocessing.py:

python preprocessing.py

Export a trained Keras model to SavedModel and TFLite after placing the Colab-trained model at best_model/best_model.keras:

python save_model.py

Convert the SavedModel export to ONNX for the Rust ML service:

python convert_onnx.py

Convert the SavedModel export to TensorFlow.js via CLI:

export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
tensorflowjs_converter \
  --input_format=tf_saved_model \
  --output_format=tfjs_graph_model \
  --signature_name=serving_default \
  --saved_model_tags=serve \
  model/saved_model \
  model/tfjs_model

Open the training notebook locally if needed:

jupyter notebook notebook.ipynb

There is no project test suite, lint command, or build system configured in the ML pipeline.

Fullstack app commands

The TypeScript application scaffold lives at the repository root and uses Bun workspaces with Moon tasks.

Install dependencies:

bun install

Run all development tasks through Moon:

bun run dev

Run type checks:

bun run typecheck

Run production builds:

bun run build

Run the API directly:

cd apps/api && bun run start

Run the web app directly:

cd apps/web && bun run dev

Run the ML service directly:

cd apps/ml-service && cargo run

High-level architecture

  • Machine_Learning/preprocessing.py prepares the training dataset locally. It extracts three source ZIP files, merges selected class folders into dataset/, maps selected Mandarin labels from Dataset 3 via desc.json, removes known problematic image files, then creates dataset.zip for upload to Google Drive/Colab.
  • Machine_Learning/notebook.ipynb is the training workflow intended for Google Colab with GPU enabled. It trains an EfficientNetV2B0-based classifier and saves the best model to Google Drive as best_model.keras.
  • Machine_Learning/save_model.py is the production export step. It loads best_model/best_model.keras, rebuilds a clean EfficientNetV2B0 architecture without training-time augmentation layers, copies weights into that model, exports model/saved_model/, and writes model/model.tflite.
  • Machine_Learning/convert_onnx.py converts the SavedModel to ONNX format (model/model.onnx) for use by the Rust inference service.
  • TensorFlow.js export is intentionally done with the tensorflowjs_converter CLI rather than from Python to avoid protobuf/runtime conflicts documented in the README.
  • apps/ml-service/ is a Rust/Axum service that loads the ONNX model and serves HTTP endpoints for health checks, metadata, and image classification predictions. It uses ONNX Runtime for cross-platform inference performance.

Fullstack application architecture

The root TypeScript workspace is a Bun + Moon monorepo:

  • apps/web/ contains the React + Vite + TypeScript frontend with React Router, TanStack Query, Zustand, Tailwind, and shadcn/ui-style components.
  • apps/api/ contains the Elysia backend with health/status routes and Drizzle/PostgreSQL configuration.
  • apps/ml-service/ contains the Rust/Axum inference service with ONNX Runtime for model predictions.
  • packages/shared/ contains shared TypeScript types and utilities consumed by both apps.

The backend reads DATABASE_URL for Drizzle/PostgreSQL, but the initial health/status endpoints do not require a live database connection. The ML service reads MODEL_PATH (default ../../Machine_Learning/model/model.onnx) and MODEL_INPUT_SIZE (default 224).

Model labels and dataset mapping

The classifier targets four Indonesian labels:

  • Bercak Daun — Gray Leaf Spot
  • Hawar Daun — Northern/Southern Leaf Blight
  • Karat Daun — Common Rust
  • Daun Sehat — healthy corn leaf

Dataset handling is part of the model logic:

  • Dataset 1 contributes Bercak Daun, Hawar Daun, and Daun Sehat; its Karat Daun folder is intentionally ignored because the README states it is not representative.
  • Dataset 2 contributes Common_Rust mapped to Karat Daun and Healthy mapped to Daun Sehat.
  • Dataset 3 is routed through Mandarin label mappings in PEMETAAN_KATEGORI inside preprocessing.py.

Important generated/local artifacts

The following files/directories are generated or externally supplied during the ML workflow and may not exist in a fresh clone:

  • Machine_Learning/dataset_1.zip, dataset_2.zip, dataset_3.zip — manually downloaded source datasets.
  • Machine_Learning/dataset/ and Machine_Learning/dataset.zip — generated by preprocessing.py.
  • Machine_Learning/best_model/best_model.keras — trained model downloaded from Colab/Google Drive.
  • Machine_Learning/model/saved_model/, model/model.tflite, model/model.onnx, and model/tfjs_model/ — production exports.

Notes for future changes

  • Keep README command examples and this file in sync when changing the ML pipeline.
  • Preserve the current class label names unless the training notebook, preprocessing mappings, and downstream app/API expectations are updated together.
  • save_model.py assumes the clean architecture matches the trained model weights exactly; changes to the notebook model architecture usually require corresponding changes in build_clean_model().
  • The Rust ML service expects the ONNX model at the path specified by MODEL_PATH. Ensure convert_onnx.py is run after save_model.py to generate the ONNX artifact before deploying the service.