Case Study
FoodQCheck
A capstone AI product that screens the visual quality of UMKM dry snack products from a smartphone photo — React/Capacitor client, Cloudinary upload, FastAPI inference, and MobileNetV2 classification.
FoodQCheck is my D4 Software Engineering capstone project at Politeknik Negeri Padang. It helps UMKM producers of dry snack products — keripik, kerupuk, biskuit, and kukis — run a quick visual quality screen from a smartphone photo before a product goes to market.
The system is deliberately scoped as a visual pre-screening tool, not a food-safety certification system. It does not replace chemical, microbiological, or laboratory testing. Instead, it answers a practical production question: does this product look visually sellable or not?
Key Features
- Camera-to-result workflow: Capture or select a product photo, upload it, and receive a
Layak JualorTidak Layak Jualdecision with confidence score and short explanation. - Cloudinary-first image pipeline: The mobile client uploads photos to Cloudinary, then sends only the image URL to the inference API.
- MobileNetV2 inference API: FastAPI downloads the image, runs preprocessing, classifies with MobileNetV2, and stores the result with model version and threshold metadata.
- Detection history: Users can reopen previous results, review details, and manage their history.
- Admin dashboard: Operators can inspect detection volume, review records, and inspect model-facing artifacts such as Grad-CAM heatmaps.
- One React codebase, two clients: The same React app ships as a web SPA and an Android APK through Capacitor.
Technical Challenge
The hardest part was shipping a complete product loop under real capstone constraints: small visual dataset, server-side inference, mobile capture quality, and a result format that non-technical UMKM users can understand.
The solution was a clear end-to-end architecture:
React / Capacitor app
↓
Cloudinary image upload
↓
FastAPI receives image_url
↓
SSRF-guarded download + MobileNetV2 inference
↓
PostgreSQL stores detection history
↓
User result + admin review UI
On the model side, I used transfer learning with MobileNetV2, binary sigmoid output, and a production threshold of 0.3 chosen to prioritize recall for visually unsuitable products. On the product side, the API stores enough metadata — label, confidence, raw score, threshold used, model version, and explanation — so every result remains auditable after the demo ends.
Outcome
On the held-out test split of 72 images from a curated 509-image dataset:
- Accuracy: 91.67%
- Macro precision / recall: 91.74%
- F1-score: 91.67%
- Recall for
Tidak Layak Jual: 94.29%
The software side covers authentication, detection, history, admin review, Docker deployment with Caddy and PostgreSQL, and API contract tests. The project has been presented as a complete capstone system.
Tech Stack
- Mobile / Web: React 19, TypeScript, Vite, Tailwind CSS, Capacitor Android
- Backend: FastAPI, SQLAlchemy, Alembic, PostgreSQL, JWT auth
- Machine Learning: TensorFlow, MobileNetV2, Grad-CAM, custom training/evaluation pipeline
- Infrastructure: Cloudinary, Docker Compose, Caddy, Gunicorn/Uvicorn
- Source:
- Backend + ML: umkm-food-quality
- Mobile client: umkm-food-quality-mobile


