google-agents-cli-scaffold
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
local-frappe
Local Frappe development environment for testing APIs before production deployment. Use when developing or testing Python/API changes locally.
Full skill instructions
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.
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).
cd docker-dev
dev.bat start # Windows (first run takes 10-15 minutes)
./dev.sh start # Linux/Mac
| 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
# 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
| 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) |
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
# 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}
# hrms/api/__init__.py
from hrms.api.my_new_api import (
hello,
get_data,
)
dev.bat sync
curl http://localhost:8000/api/method/hrms.api.my_new_api.hello
| 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 |
| 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.
# Check logs
dev.bat logs
# Or directly
docker logs frappe-dev
# Force sync and clear cache
dev.bat sync
# If still not working, restart Frappe
dev.bat restart
# Check MariaDB is healthy
docker ps
# Should show mariadb-dev as (healthy)
# 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 downloads and installs:
Total: 10-15 minutes. Subsequent starts are fast (~30 seconds).
# APIs with @frappe.whitelist(allow_guest=True)
curl http://localhost:8000/api/method/hrms.api.hello.hello
# 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
# 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"]'
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.
docker commit - Corrupts the Python environment__init__.py - API won't be whitelistedno_cache=true (see below)Local development allows bench build because:
Production prohibits bench build because:
| 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 |
All code and asset changes MUST go through Docker image rebuild.
When you push to production:
Never "hot-fix" production by running bench commands.
See /deploy-frappe for the full CSS 404 root cause analysis and fix.
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>"
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:
For full-stack local development, run both Frappe AND bei-tasks locally:
cd F:\Dropbox\Projects\BEI-ERP\docker-dev
powershell -Command "docker compose up -d"
# Wait for Frappe to start (~30 seconds if already initialized)
# 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"}}
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)
cd F:\Dropbox\Projects\bei-tasks
npm run dev
# Frontend runs at http://localhost:3000
# 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",...}}
| 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 |
# 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"
allow_guest=True)dev.localhost, production uses hq.bebang.ph/deploy-frappe - Production deployment (ONLY after local testing)/frappe-sql-bulk - Bulk data operations/frappe-doctype - DocType developmentThe 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.
| Employee ID | Password | Role | |
|---|---|---|---|
| TEST-STAFF-001 | [email protected] | BeiTest2026! | Store Staff |
| TEST-SUPERVISOR-001 | [email protected] | BeiTest2026! | Store Supervisor |
| TEST-AREA-001 | [email protected] | BeiTest2026! | Area Supervisor |
| TEST-HR-001 | [email protected] | BeiTest2026! | HR User |
# 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.', '[email protected]', 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-%';\""
]'
| 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.
# 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", "=", "[email protected]"]]}'
# Expected: Returns employee record
"No employee found" but employee exists:
bench --site hq.bebang.ph mariadb not direct RDS connectionAPI returns 401:
Container not found:
frappe_backend, frappe_frontend, etc.frappe_backend.1.xxxxxdocker service ls to verify servicesdocker ps -qf name=frappe_backend to get container IDHR pages show "Failed to get employee data":
app/api/hr/*/route.ts uses Authorization: token headerCode deployed but changes not visible:
no_cache=true when deploying/deploy-frappe for details on when to use no_cachecurl https://hq.bebang.ph/api/method/hrms.api.hello.hellobuild_version field showing deployment timestampThe 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.
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
Set up tracing, logging, and monitoring for deployed ADK agents across Cloud Trace, BigQuery, and third-party platforms.
Enterprise Azure infrastructure architect generating Bicep or Terraform from workload descriptions.
Plan and configure production-ready Azure Kubernetes Service clusters with Day-0 and Day-1 best practices.
Raw mechanical interfaces fusing Swiss typographic print with military terminal aesthetics. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects. For data-heavy dashboards, portfolios, or editorial sites that need to feel like declassified blueprints.
Web search, scraping, extraction, crawling, and monitoring via ScrapeGraph AI CLI.
Skill for working with Firebase Hosting (Classic). Use this when you want to deploy static web apps, Single Page Apps (SPAs), or simple microservices. Do NOT use for Firebase App Hosting.
Deploy and manage web apps with Firebase App Hosting. Use this skill when deploying Next.js/Angular apps with backends.
Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".
Build SEO-optimized pages at scale using templates, data, and proven playbook patterns.
Design and build isolated, reusable Convex backend components with clear boundaries and app-facing wrappers.
Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".
Opus.ai: Revolutionize Your Web Experience
Build a no-code AI app in minutes.
An IDE for code migration from legacy to modern frameworks through coding agents.
Automate CGI animation in live-action scenes
Branded artistic QR-code concepts
Launch a website in seconds with AI.
Streamline Your Coding Experience with AI Code Helper
Convert any screenshot or design to clean code.