Notre avis
Met en place un environnement de développement Frappe local pour tester les API avant déploiement en production.
Points forts
- Cycle de test rapide (secondes vs 15-20 minutes de déploiement production)
- Environnement identique à la production (Frappe/ERPNext v15)
- Scripts d'assistance simplifiant la synchronisation et les tests
- Documentation claire des commandes et de la structure des fichiers
Limites
- Nécessite Docker et des ressources système importantes
- Premier démarrage long (10-15 minutes)
- Ne couvre pas les tests d'intégration avec des services externes
Lorsque vous développez ou modifiez des API Frappe/ERPNext et devez valider rapidement les changements avant de les pousser en production.
Pour des modifications d'infrastructure ou de configuration qui ne concernent pas le code Python/Frappe, ou lorsque l'environnement local ne peut pas reproduire fidèlement la production.
Analyse de sécurité
SûrThe skill describes local development commands for a Frappe environment. It contains no destructive system-level commands (e.g., rm -rf /), no exfiltration patterns, and no obfuscated or remote execution payloads. The 'reset' command is clearly marked as destructive but is confined to Docker containers and requires explicit user invocation.
Aucun point d'attention détecté
Exemples
Start Frappe local dev environment using docker-devSync my local API changes to the Frappe container and test the hello endpointHelp me add a new API endpoint to hrms/api/my_new_api.py and update the __init__.pyname: local-frappe description: Local Frappe development environment for testing APIs before production deployment. Use when developing or testing Python/API changes locally. allowed-tools: Bash, Read, Grep, Edit, Write user-invocable: true
/local-frappe - Local Frappe Development
CRITICAL: TEST LOCALLY FIRST - NO EXCEPTIONS
NEVER deploy Frappe/Python changes directly to production.
| Action | Time | When to Use | |--------|------|-------------| | Local test | Seconds | ALWAYS - every code change | | Production deploy | 15-20 min | ONLY after local testing passes |
The 15-20 minute production build/deploy cycle is UNACCEPTABLE for iterative development.
What This Command Does
Sets up and manages a local Frappe development environment for testing BEI custom APIs before deploying to production.
MANDATORY: Always test changes locally BEFORE pushing to production. The local environment matches production (Frappe v15, ERPNext v15, HRMS v15).
Quick Start
cd docker-dev
dev.bat start # Windows (first run takes 10-15 minutes)
./dev.sh start # Linux/Mac
Access
| URL | Purpose | |-----|---------| | http://localhost:8000 | Frappe web UI | | http://localhost:8000/api/method/frappe.ping | API test endpoint | | http://localhost:8000/api/method/hrms.api.hello.hello | BEI test API | | localhost:3307 | MariaDB (user: root, pass: admin) |
Login: Administrator / admin
Development Workflow
Standard Workflow (Edit → Sync → Test)
# 1. Edit your API file locally
# Example: hrms/api/employee_clearance.py
# 2. Sync to container and clear cache
dev.bat sync
# 3. Test your API
curl http://localhost:8000/api/method/hrms.api.employee_clearance.get_status
# 4. When ready, commit and push to production
git add .
git commit -m "feat: Add employee clearance API"
git push origin production
Helper Commands
| Command | Description |
|---------|-------------|
| dev.bat start | Start all containers (first run: 10-15 min) |
| dev.bat stop | Stop all containers |
| dev.bat restart | Restart Frappe to pick up code changes |
| dev.bat sync | Copy API files and clear cache (quick reload) |
| dev.bat shell | Open bash shell in container |
| dev.bat bench | Run bench command (e.g., dev.bat bench migrate) |
| dev.bat logs | Follow Frappe logs |
| dev.bat test | Test hello API endpoint |
| dev.bat migrate | Run database migrations |
| dev.bat status | Show container status |
| dev.bat reset | Delete everything and start fresh (DESTRUCTIVE) |
File Structure
docker-dev/
├── docker-compose.yml # Container orchestration
├── dev.bat # Windows helper script
└── dev.sh # Linux/Mac helper script
hrms/api/ # BEI custom API files (synced to container)
├── __init__.py # API exports (CRITICAL - update when adding new APIs)
├── hello.py # Test endpoint
├── employee_clearance.py # Clearance APIs
├── enrichment.py # Data enrichment APIs
├── google_chat.py # Google Chat integration
├── google_drive.py # Google Drive integration
├── google_login.py # Google OAuth
├── oauth_tokens.py # OAuth token management
├── onboarding.py # Employee onboarding
└── roster.py # Shift roster APIs
Adding a New API
1. Create your API file
# hrms/api/my_new_api.py
import frappe
@frappe.whitelist(allow_guest=True)
def hello():
"""Test endpoint."""
return {"message": "Hello from my new API!"}
@frappe.whitelist()
def get_data():
"""Requires authentication."""
return {"user": frappe.session.user}
2. Update init.py
# hrms/api/__init__.py
from hrms.api.my_new_api import (
hello,
get_data,
)
3. Sync and test
dev.bat sync
curl http://localhost:8000/api/method/hrms.api.my_new_api.hello
Container Configuration
| Component | Value |
|-----------|-------|
| Frappe Image | frappe/bench:v5.25.11 |
| Bench Location | /workspace/frappe-bench |
| API Mount | /bei-api (read-only from hrms/api/) |
| Site Name | dev.localhost |
| MariaDB Port | 3307 (external), 3306 (internal) |
| Web Port | 8000 |
| Socket.IO Port | 9000 |
Volumes
| Volume | Purpose |
|--------|---------|
| docker-dev_frappe-bench | Frappe bench directory (apps, sites, etc.) |
| docker-dev_mariadb-data | Database data |
Note: Volumes persist data across container restarts. To completely reset, use docker compose down -v.
Troubleshooting
Container won't start
# Check logs
dev.bat logs
# Or directly
docker logs frappe-dev
API changes not visible
# Force sync and clear cache
dev.bat sync
# If still not working, restart Frappe
dev.bat restart
Database connection errors
# Check MariaDB is healthy
docker ps
# Should show mariadb-dev as (healthy)
Need fresh start
# WARNING: This deletes all data
dev.bat reset
# Or manually:
docker compose -f docker-dev/docker-compose.yml down -v
dev.bat start
First run taking too long
First run downloads and installs:
- Frappe Framework (~3 min)
- ERPNext (~5 min)
- HRMS (~3 min)
- Site creation (~2 min)
Total: 10-15 minutes. Subsequent starts are fast (~30 seconds).
Testing APIs
Without authentication
# APIs with @frappe.whitelist(allow_guest=True)
curl http://localhost:8000/api/method/hrms.api.hello.hello
With authentication
# Get session cookie first
curl -c cookies.txt -X POST http://localhost:8000/api/method/login \
-d "usr=Administrator" -d "pwd=admin"
# Then use the cookie
curl -b cookies.txt http://localhost:8000/api/method/hrms.api.roster.get_roster
Using bench execute
# Run Python code directly
dev.bat bench execute hrms.api.hello.hello
# With arguments
dev.bat bench execute "hrms.api.employee_clearance.get_status" --args '["HR-EMP-0001"]'
When to Deploy to Production
After testing locally:
-
Commit changes:
git add hrms/api/ git commit -m "feat: Add employee clearance API" -
Push to production branch:
git push origin production -
Monitor GitHub Actions: https://github.com/Bebang-Enterprise-Inc/hrms/actions
-
Verify production:
curl https://hq.bebang.ph/api/method/hrms.api.hello.hello
See /deploy-frappe skill for full production deployment options.
DO NOT DO
- NEVER edit files directly in the container - Changes are lost on restart
- NEVER use
docker commit- Corrupts the Python environment - NEVER push untested code to production - Always test locally first
- NEVER skip updating
__init__.py- API won't be whitelisted - NEVER assume production deploy will pick up code changes - Use
no_cache=true(see below)
CRITICAL: Local vs Production Asset Handling
Why Local Works But Production Breaks
Local development allows bench build because:
- Single container environment
- No persistent asset volumes (fresh start each time)
- Development mode reloads assets on change
Production prohibits bench build because:
- Multi-container architecture (frontend + backend)
- Persistent volumes don't auto-update
- Assets baked into Docker image at build time
What This Means For You
| Action | Local | Production |
|--------|-------|------------|
| bench build | ✅ OK | ❌ NEVER |
| bench migrate | ✅ OK | ⚠️ Only via isolated container |
| Edit Python files | ✅ Sync + restart | ❌ Rebuild image |
| Edit CSS/JS | ✅ Sync + restart | ❌ Rebuild image |
The Production Rule
All code and asset changes MUST go through Docker image rebuild.
When you push to production:
- GitHub Actions rebuilds the entire Docker image
- New CSS/JS hashes are baked into image
- Assets volume should be deleted before deploy
- Fresh containers get consistent assets
Never "hot-fix" production by running bench commands.
See /deploy-frappe for the full CSS 404 root cause analysis and fix.
Testing Custom WWW Pages Locally
Creating Custom Pages (like login)
-
Create your page file:
hrms/www/bei-login.html # The HTML template hrms/www/bei-login.py # Optional Python context handler -
If redirecting from an existing route, add to
hrms/hooks.py:website_redirects = [ {"source": "/login", "target": "/bei-login", "redirect_http_status": 302}, ] -
Sync to container:
dev.bat sync -
Test locally:
# Check redirect curl -sI http://localhost:8000/login | grep -i location # Check page renders curl -s http://localhost:8000/bei-login | grep -o "<title>.*</title>"
Important: Production Deployment Uses Docker Cache
After testing locally, you MUST use no_cache=true when deploying:
gh workflow run "Build and Deploy Frappe HRMS" --repo Bebang-Enterprise-Inc/hrms -f no_cache=true -f run_migrate=true
Why: Docker cache doesn't detect when git repo contents change. Without no_cache=true, the build serves cached layers from previous builds.
How to verify fresh build: Check GitHub Actions build time:
- ~2 min = CACHED (old code)
- ~5-10 min = FRESH (new code)
Running bei-tasks Frontend Locally (Added 2026-01-24)
For full-stack local development, run both Frappe AND bei-tasks locally:
1. Start Local Frappe
cd F:\Dropbox\Projects\BEI-ERP\docker-dev
powershell -Command "docker compose up -d"
# Wait for Frappe to start (~30 seconds if already initialized)
2. Generate API Keys (First Time Only)
# Login to get session cookie
curl -c cookies.txt -X POST "http://localhost:8000/api/method/login" \
-d "usr=Administrator&pwd=admin"
# Generate API keys
curl -b cookies.txt -X POST \
"http://localhost:8000/api/method/frappe.core.doctype.user.user.generate_keys?user=Administrator"
# Returns: {"message":{"api_key":"xxx","api_secret":"yyy"}}
3. Configure bei-tasks for Local Frappe
Create/update F:\Dropbox\Projects\bei-tasks\.env.development.local:
# Local Development Environment
NEXT_PUBLIC_FRAPPE_URL=http://localhost:8000
# Local Frappe API credentials (from step 2)
FRAPPE_API_KEY=your-api-key
FRAPPE_API_SECRET=your-api-secret
# App Configuration
NEXT_PUBLIC_APP_NAME=BEI Tasks (LOCAL)
4. Start Local bei-tasks
cd F:\Dropbox\Projects\bei-tasks
npm run dev
# Frontend runs at http://localhost:3000
5. Test the Connection
# Test Frappe API directly
curl -H "Authorization: token api-key:api-secret" \
"http://localhost:8000/api/method/hrms.api.onboarding.get_session?token=test"
# Expected: {"message":{"success":false,"error":"Session not found",...}}
Local Development Stack
| Component | URL | Purpose | |-----------|-----|---------| | Frappe Backend | http://localhost:8000 | API + Admin UI | | bei-tasks Frontend | http://localhost:3000 | React/Next.js app | | MariaDB | localhost:3307 | Database | | Socket.IO | localhost:9000 | Realtime |
Syncing Code Changes
# After editing hrms/api/*.py files:
cd F:\Dropbox\Projects\BEI-ERP\docker-dev
# Sync files and clear cache
powershell -Command "docker exec frappe-dev bash -c 'cp -f /bei-api/*.py /workspace/frappe-bench/apps/hrms/hrms/api/ && cd /workspace/frappe-bench && bench --site dev.localhost clear-cache'"
# If whitelist decorators changed, restart Frappe
powershell -Command "docker restart frappe-dev"
Important Notes
- Authentication Required: Local APIs need authentication (no
allow_guest=True) - Session Cookie OR Token Auth: Use either method for local testing
- Different Site: Local uses
dev.localhost, production useshq.bebang.ph - No Test Data: Local DB is empty - create test data as needed
Related Skills
/deploy-frappe- Production deployment (ONLY after local testing)/frappe-sql-bulk- Bulk data operations/frappe-doctype- DocType development
Production Testing Infrastructure (Added 2026-01-23)
CRITICAL: Database Architecture Discovery
The Frappe system at hq.bebang.ph uses a LOCAL Docker database via Docker Swarm (migrated 2026-01-29).
| Component | Service Name | Purpose |
|-----------|--------------|---------|
| Backend | frappe_backend | Frappe/ERPNext/HRMS (Gunicorn) |
| Database | frappe_db | MariaDB (LOCAL) |
| Frontend | frappe_frontend | Nginx proxy |
| WebSocket | frappe_websocket | Socket.IO |
| Queue | frappe_queue-short, frappe_queue-long | Background workers |
| Scheduler | frappe_scheduler | Cron jobs |
Note: Production now uses Docker Swarm (9 services). Container names changed from frappe_docker-backend-1 to dynamic names under frappe_backend.1.xxxx.
Common Mistake: AWS SSM commands often connect to the RDS database (frappe-hrms-db.ctmwomgscn66.ap-southeast-1.rds.amazonaws.com), but the live Frappe instance uses the local Docker database. This causes "no employees found" issues when testing.
Production Test Accounts
| Employee ID | Email | Password | Role | |-------------|-------|----------|------| | TEST-STAFF-001 | test.staff@bebang.ph | BeiTest2026! | Store Staff | | TEST-SUPERVISOR-001 | test.supervisor@bebang.ph | BeiTest2026! | Store Supervisor | | TEST-AREA-001 | test.area@bebang.ph | BeiTest2026! | Area Supervisor | | TEST-HR-001 | test.hr@bebang.ph | BeiTest2026! | HR User |
Inserting Test Data into Production
# 1. Get AWS credentials
export AWS_ACCESS_KEY_ID=$(doppler secrets get AWS_ACCESS_KEY_ID --project bei-erp --config dev --plain)
export AWS_SECRET_ACCESS_KEY=$(doppler secrets get AWS_SECRET_ACCESS_KEY --project bei-erp --config dev --plain)
export AWS_DEFAULT_REGION=ap-southeast-1
# 2. Run SQL on the CORRECT database (via Swarm backend container)
aws ssm send-command \
--instance-ids "i-026b7477d27bd46d6" \
--document-name "AWS-RunShellScript" \
--parameters 'commands=[
"docker exec $(docker ps -qf name=frappe_backend) bench --site hq.bebang.ph mariadb --execute \"INSERT INTO tabEmployee (name, employee_name, first_name, status, gender, date_of_birth, date_of_joining, company, user_id, creation, modified, owner, modified_by) VALUES ('TEST-STAFF-001', 'Test Staff', 'Test', 'Active', 'Male', '1990-01-01', '2024-01-01', 'Bebang Enterprise Inc.', 'test.staff@bebang.ph', NOW(), NOW(), 'Administrator', 'Administrator');\""
]'
# 3. Verify
aws ssm send-command \
--instance-ids "i-026b7477d27bd46d6" \
--document-name "AWS-RunShellScript" \
--parameters 'commands=[
"docker exec $(docker ps -qf name=frappe_backend) bench --site hq.bebang.ph mariadb --execute \"SELECT name, employee_name, user_id FROM tabEmployee WHERE name LIKE 'TEST-%';\""
]'
API Credentials for bei-tasks
| Environment | Key | Secret | Source |
|-------------|-----|--------|--------|
| Production (Vercel) | 4a17c23aca83560 | 38ecc0e1054b1d2 | Doppler bei-erp |
| Local (.env.local) | Same | Same | Doppler bei-erp |
IMPORTANT: HR API routes use token auth (not session cookies) for Employee lookups because regular Frappe users don't have Employee read permission.
Verifying API Connection
# Test from production
curl -X POST https://hq.bebang.ph/api/resource/Employee \
-H "Authorization: token 4a17c23aca83560:38ecc0e1054b1d2" \
-H "Content-Type: application/json" \
-d '{"filters": [["user_id", "=", "test.staff@bebang.ph"]]}'
# Expected: Returns employee record
Troubleshooting Production Tests
-
"No employee found" but employee exists:
- Check you're querying the Docker database, not RDS
- Use
bench --site hq.bebang.ph mariadbnot direct RDS connection
-
API returns 401:
- Verify Vercel env vars match Doppler
- Redeploy after env var changes
-
Container not found:
- Production now uses Docker Swarm (migrated 2026-01-29)
- Service names:
frappe_backend,frappe_frontend, etc. - Container names are dynamic:
frappe_backend.1.xxxxx - Use
docker service lsto verify services - Use
docker ps -qf name=frappe_backendto get container ID
-
HR pages show "Failed to get employee data":
- HR APIs need token auth, not session auth
- Check
app/api/hr/*/route.tsusesAuthorization: tokenheader
-
Code deployed but changes not visible:
- Docker build caching issue - use
no_cache=truewhen deploying - See
/deploy-frappefor details on when to use no_cache - Verify with:
curl https://hq.bebang.ph/api/method/hrms.api.hello.hello - Response should include
build_versionfield showing deployment timestamp
- Docker build caching issue - use
Deployment Verification Endpoint
The hello API includes deployment info for verification:
curl -s https://hq.bebang.ph/api/method/hrms.api.hello.hello | python -m json.tool
Expected response:
{
"message": {
"message": "Hello from Frappe HRMS!",
"timestamp": "2026-01-29 10:04:11.569399",
"build_version": "2026-01-29T12:16:00+08:00",
"deployment": "docker-swarm"
}
}
If build_version doesn't update after deployment, rebuild with no_cache=true.
Expert Next.js App Router
Developpement
Un skill qui transforme Claude en expert Next.js App Router.
Générateur de README
Developpement
Crée des README.md professionnels et complets pour vos projets.
Rédacteur de Documentation API
Developpement
Génère de la documentation API complète au format OpenAPI/Swagger.