An intelligent inventory management system for Vietnamese businesses featuring invoice scanning, voice commands, and batch photo counting.
- Invoice Scanning - Claude AI extracts data from receipt/invoice images
- Voice Commands - Whisper + Claude for Vietnamese/English inventory commands
- Batch Photo Counting - Grounding DINO for zero-shot object detection
- Odoo Integration - Sync with Odoo ERP for purchase orders and inventory
| Component | Technology |
|---|---|
| Backend | Python 3.11+, FastAPI, SQLAlchemy, Celery |
| Mobile | React Native, Expo |
| Web | React, Vite, TypeScript |
| Database | PostgreSQL |
| Cache/Queue | Redis |
| Storage | MinIO/S3 |
| Auth | Keycloak |
| AI | Anthropic Claude, OpenAI Whisper, Grounding DINO |
- Python 3.11+
- Node.js 18+
- PostgreSQL 15+
- Redis 7+
- Docker & Docker Compose (optional)
The easiest way to run the full stack:
cd infrastructure
docker-compose up -dThis starts all services: API, PostgreSQL, Redis, MinIO, and Keycloak.
cd backend
# Create virtual environment
python -m venv venv
# Activate virtual environment
# Windows:
venv\Scripts\activate
# Linux/Mac:
source venv/bin/activate
# Install dependencies
python -m pip install -r requirements.txt
# Copy environment file and configure
copy .env.example .env # Windows
cp .env.example .env # Linux/Mac
# Run database migrations
alembic upgrade head
# Start the API server
uvicorn app.main:app --reload --port 8000The API will be available at http://localhost:8000
API documentation: http://localhost:8000/api/v1/docs
In a separate terminal:
cd backend
celery -A app.tasks.celery_app worker --loglevel=info --pool=solocd web
# Install dependencies
npm install
# Start development server
npm run devThe web app will be available at http://localhost:5173
cd mobile
# Install dependencies
npm install
# Start Expo development server
npx expo start
# Run on specific platform
npx expo start --ios # iOS Simulator
npx expo start --android # Android EmulatorCreate a .env file in the backend directory. See backend/.env.example for all options.
# AI Services
ANTHROPIC_API_KEY=sk-ant-... # Required for invoice scanning
OPENAI_API_KEY=sk-... # Required for voice commands
# Database
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=khoai
POSTGRES_PASSWORD=your_password
POSTGRES_DB=khoai
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
# Storage (MinIO/S3)
S3_ENDPOINT=http://localhost:9000
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin
S3_BUCKET_INVOICES=invoices
S3_BUCKET_VOICE=voice
S3_BUCKET_COUNTING=counting# Keycloak (disable for development)
KEYCLOAK_ENABLED=false
KEYCLOAK_URL=http://localhost:8080
KEYCLOAK_REALM=khoai
KEYCLOAK_CLIENT_ID=khoai-api
# Odoo Integration
ODOO_URL=http://localhost:8069
ODOO_DB=odoo
ODOO_USERNAME=admin
ODOO_PASSWORD=adminFor local development without Keycloak, use the dev token:
curl -H "Authorization: Bearer dev-token" http://localhost:8000/api/v1/productskho-ai/
├── backend/ # FastAPI backend
│ ├── app/
│ │ ├── api/ # REST endpoints
│ │ ├── core/ # Security, database
│ │ ├── models/ # SQLAlchemy models
│ │ ├── schemas/ # Pydantic schemas
│ │ ├── services/ # Business logic
│ │ └── tasks/ # Celery tasks
│ ├── alembic/ # Database migrations
│ └── tests/ # Backend tests
├── mobile/ # React Native/Expo app
├── web/ # React/Vite web app
├── infrastructure/ # Docker, seed scripts, Keycloak config
└── docs/ # Architecture and workflow documentation
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/invoices/scan |
Upload and scan invoice |
| GET | /api/v1/invoices |
List invoices |
| GET | /api/v1/invoices/{id} |
Get invoice details |
| PUT | /api/v1/invoices/{id} |
Update invoice |
| POST | /api/v1/invoices/{id}/confirm |
Confirm invoice |
| POST | /api/v1/voice/command |
Process voice command |
| POST | /api/v1/counting/analyze |
Analyze batch photos |
| GET | /api/v1/products |
List products |
| GET | /api/v1/locations |
List warehouse locations |
The project includes seed scripts for Xe Kem (Vietnamese Ice Cream & Dessert Shop) to populate Odoo and KhoAI with real business data. This is useful for development, testing, and demo purposes.
- Odoo 17 running at
localhost:8069with databasexekemcreated - KhoAI backend running at
localhost:8000 - PostgreSQL, Redis, and MinIO running
backend/.envconfigured with Odoo credentials
cd infrastructure
docker-compose -f docker-compose.odoo.yml up -dOpen http://localhost:8069 and create the xekem database if it doesn't exist. Install the Inventory and Purchase modules.
This creates suppliers, product categories, warehouses, and ~90 products in Odoo:
cd infrastructure
python seed_xekem_odoo.pyWhat gets created:
| Data | Count | Details |
|---|---|---|
| Product Categories | 23 | Hierarchical: Packaging > Cups & Lids, Dry Materials > Spices, etc. |
| Warehouses | 2 | Mississauga (MSS), North York (NYK) |
| Suppliers | 17 | Cash & Carry, Mr. Dairy, PreGel, Viet Thai, Foods Up, etc. |
| Products | ~90 | Cups, lids, boxes, syrups, powders, dairy, frozen items, fresh ingredients |
Each product has a SKU (e.g., PKG-CC-003), category, cost price, and linked supplier.
This syncs Odoo data to KhoAI and configures supplier name patterns for invoice auto-detection:
cd infrastructure
python seed_xekem_khoai.pyWhat it does:
- Syncs suppliers from Odoo to KhoAI (
POST /api/v1/suppliers/sync) - Updates supplier name patterns for auto-detection from invoice vendor names, e.g.:
- "Cash & Carry" invoice → matches supplier
CCvia patterns["cash & carry", "cash and carry", "c&c"] - "FreshCo" invoice → matches supplier
WSvia patterns["freshco", "nofrills", "walmart"]
- "Cash & Carry" invoice → matches supplier
- Syncs products from Odoo to KhoAI (
POST /api/v1/products/sync)
# Check suppliers are synced with patterns
curl -H "Authorization: Bearer dev-token" \
"http://localhost:8000/api/v1/suppliers?page_size=100"
# Test supplier auto-detection
curl -H "Authorization: Bearer dev-token" \
"http://localhost:8000/api/v1/suppliers/detect/by-vendor-name?vendor_name=Cash%20%26%20Carry"
# Check products are synced
curl -H "Authorization: Bearer dev-token" \
"http://localhost:8000/api/v1/products?page_size=100"Upload a test receipt from backend/tests/receipts/xekem/:
curl -X POST -H "Authorization: Bearer dev-token" \
-F "file=@backend/tests/receipts/xekem/CashAndCarry_2026Feb03.png" \
"http://localhost:8000/api/v1/invoices/scan"Or use the web UI at http://localhost:5173 to upload and review invoices.
| File | Supplier | Items |
|---|---|---|
CashAndCarry_2026Feb03.png |
Cash & Carry | Cups, lids, boxes, gloves, parchment paper |
FoodsUp_2026Feb02.png |
Foods Up | Eggs, flour, sugar |
FreshCo_2026Feb05.png |
FreshCo (Western) | Dairy, fresh produce |
HDBio_2026Jan30.png |
HD Bio | Packaging boxes, containers |
MrDairy_2026Feb04.png |
Mr. Dairy | Milk, whipping cream, butter |
PreGel_2026Jan25.png |
PreGel | Ice cream base, stabilizer |
VietThai_2026Jan28.png |
Viet Thai | Thai tea, condensed milk, frozen durian |
MilkTeaSupply_2026Jan31.png |
Milk Tea Supply | Syrups, tea, flavourings |
SeowNation_2026Feb05.png |
Seow Nation | Frozen durian |
LuckySupermarket_2026Feb01.png |
Lucky Supermarket | Asian groceries, spices |
See docs/Invoice-Scanning-to-Odoo-Flow.md for the complete workflow from scanning to receiving inventory in Odoo.
See docs/XeKem-Data-Migration-Plan.md for the full spreadsheet analysis and product catalog design.
cd backend
pytest tests/ -vpip install email-validatorEnsure you're using the latest code with lazy imports in service files.
Make sure PostgreSQL is running:
# Docker
docker-compose up -d postgres
# Or check local PostgreSQL serviceMake sure Redis is running:
# Docker
docker-compose up -d redis
# Or check local Redis serviceProprietary - All rights reserved