Files
dashboard/.claude/skills/run-app/SKILL.md
T

5.0 KiB

name, description
name description
run-app Launch the AI Insight chicken-farm dashboard locally (Postgres + Ollama in Docker, RAG service, Node backend, Vite frontend) and smoke-test that every service answers. Use when asked to run, start, serve, or screenshot this app, or to verify a change works in the real running app.

Running the AI Insight dashboard locally

Five services must be up. start_all.sh only handles three of them — it assumes Postgres and Ollama are already running in Docker. If Docker is down, the backend exits immediately with ECONNREFUSED 127.0.0.1:15432 and the dashboard renders with no data.

Service Port Started by
Postgres 16 15432 Docker (dashboard-database)
Ollama 11434 Docker (dashboard-llm)
RAG service (Python) 5002 start_all.sh
Backend (Node/Express) 5001 start_all.sh
Frontend (Vite) 3000, falls back to 3001 start_all.sh

1. Bring up Docker

Docker Desktop is frequently not running. Launch it and wait — the daemon takes 30-60s, so poll rather than assuming.

open -a Docker
for i in $(seq 1 90); do docker info >/dev/null 2>&1 && break; sleep 2; done
docker info >/dev/null 2>&1 || echo "Docker daemon still down — stop here"

Then start only the two infra containers. Do not docker compose up everything: the backend / frontend / rag containers would fight the native processes start_all.sh launches for the same ports.

cd "/Users/alfredaluthfihermana/Documents/MAGANG/AI INSIGHT WEB"
docker compose up -d database llm
until docker exec dashboard-database pg_isready -U dashboard_user -d dashboard_db >/dev/null 2>&1; do sleep 1; done

Ollama port conflict

If Ollama.app is running natively it holds port 11434 and the dashboard-llm container cannot bind it. Quit the native app first:

osascript -e 'quit app "Ollama"' 2>/dev/null

Confirm the model named in backend/.env (LLM_MODEL_NAME, currently qwen2.5:7b) is actually pulled — AI Insight calls fail with a model-not-found error otherwise:

curl -s http://localhost:11434/api/tags | python3 -c "import sys,json;print([m['name'] for m in json.load(sys.stdin).get('models',[])])"
# expect qwen2.5:7b to be present; pull with:
#   docker exec dashboard-llm ollama pull qwen2.5:7b

2. Start the app services

start_all.sh ends in tail -f /tmp/backend.log, so it never exits — run it in the background, not the foreground.

cd "/Users/alfredaluthfihermana/Documents/MAGANG/AI INSIGHT WEB"
bash start_all.sh   # run backgrounded

It writes logs to /tmp/rag_service.log, /tmp/backend.log, /tmp/frontend.log. The RAG service lives outside this repo, at /Users/alfredaluthfihermana/Documents/MAGANG/AI Insight/rag_service.py.

To restart just the backend after a change:

pkill -f "node server.js"
cd "/Users/alfredaluthfihermana/Documents/MAGANG/AI INSIGHT WEB/backend" && (npm run dev > /tmp/backend.log 2>&1 &)

3. Smoke-test — don't stop at "it started"

The backend health route is /health, not /api/health (/api/health returns 404 and looks like a dead backend when it isn't).

grep -m1 "Local:" /tmp/frontend.log          # actual frontend port
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:5001/health
curl -s http://localhost:5001/api/kandangs | head -c 200
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:5002/health

/api/kandangs returning {"success":true,"data":[{"name":"Kandang Atas"... is the real proof the DB is wired up — a 200 on /health alone does not tell you Postgres is reachable.

Frontend port drifts

Port 3000 is often held by an unrelated Python process, and Vite silently falls back to 3001. Always read the real URL from /tmp/frontend.log rather than assuming 3000. If the AI Insight pages show CORS errors in the browser console, the origin whitelist in backend/server.js (the cors({ origin: [...] }) call near the top) does not include the port Vite actually picked. It currently allows 3000, 3001, 3002, 5173, 5174, 5002 — add the new port there if Vite drifts past those.

4. Drive it

For the AI Insight work specifically, open the running URL and exercise the topic pages (berat_ayam, fcr, eef, iot_panel, hitung_karung) in components/shared/PageAiInsight.tsx and components/counting/ChickenCountingAiInsight.tsx — check the per-topic summary grid renders, the insight text is not [object Object], and the Unduh PDF button produces a readable file. Generating an insight requires Ollama to be up (step 1); it is the slowest path, so allow time.

Stopping

pkill -f "rag_service.py"; pkill -f "node server.js"; pkill -f vite
docker compose stop database llm    # optional