-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
215 lines (181 loc) · 12.7 KB
/
Copy pathMakefile
File metadata and controls
215 lines (181 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# ─────────────────────────────────────────────────────────────────────────────
# AlcoaBase — Developer Makefile
# ─────────────────────────────────────────────────────────────────────────────
.PHONY: help up down rebuild logs backend-logs frontend-logs \
migrate migrate-generate migrate-downgrade migrate-history \
setup setup-status setup-admin setup-company setup-ai setup-complete \
test test-backend test-frontend lint shell-backend shell-frontend \
reset-db health
SHELL := /bin/bash
# ─────────────────────────────────────────────────────────────────────────────
# Configuration
# ─────────────────────────────────────────────────────────────────────────────
API_URL ?= http://localhost:8080
ADMIN_USERNAME ?= admin
ADMIN_EMAIL ?= admin@alcoabase.dev
ADMIN_PASSWORD ?= SecureP@ss2024!
ADMIN_FULLNAME ?= System Administrator
COMPANY_NAME ?= AlcoaBase Dev
COMPANY_FRAMEWORK ?= GMP
AI_MODE ?= mock
# ─────────────────────────────────────────────────────────────────────────────
# Docker Compose
# ─────────────────────────────────────────────────────────────────────────────
help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \
awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
up: ## Start all services (auto-starts vLLM based on MODEL_MANAGER_MODE in .env)
@MODE=$$(grep -E '^MODEL_MANAGER_MODE=' .env 2>/dev/null | cut -d= -f2 | tr -d ' "'); \
if [ "$$MODE" = "gpu" ]; then \
echo "Starting with GPU profile (MODEL_MANAGER_MODE=gpu)..."; \
docker compose --profile gpu up -d; \
elif [ "$$MODE" = "cpu" ]; then \
echo "Starting with CPU profile (MODEL_MANAGER_MODE=cpu)..."; \
docker compose --profile cpu up -d; \
else \
echo "Starting in mock mode (no vLLM)..."; \
docker compose up -d; \
fi
down: ## Stop all services
docker compose --profile gpu --profile cpu down
rebuild: ## Rebuild and restart all services
docker compose up -d --build
vllm-gpu: ## Start vLLM with GPU support (requires NVIDIA GPU ≥24 GB VRAM)
docker compose --profile gpu up -d vllm
@echo "Waiting for vLLM to load models (this may take 1-3 minutes)..."
@timeout 180 bash -c 'until curl -sf http://localhost:8000/health >/dev/null 2>&1; do sleep 5; echo " Waiting..."; done' && echo " ✓ vLLM ready!" || echo " ✗ vLLM did not become healthy within 3 minutes"
vllm-cpu: ## Start vLLM in CPU-only mode (slow, requires ≥32 GB RAM)
docker compose --profile cpu up -d vllm-cpu
@echo "Waiting for vLLM CPU to load models (this may take 5-10 minutes)..."
@timeout 600 bash -c 'until curl -sf http://localhost:8000/health >/dev/null 2>&1; do sleep 10; echo " Waiting..."; done' && echo " ✓ vLLM (CPU) ready!" || echo " ✗ vLLM did not become healthy within 10 minutes"
vllm-stop: ## Stop vLLM service (any mode)
docker compose --profile gpu --profile cpu stop vllm vllm-cpu 2>/dev/null || true
seed-alc: ## Run ALC corporate environment seed (Phase 8.2 — users, governance, agents)
@echo "Seeding AI task types and ALC corporate environment..."
@TOKEN=$$(curl -s -X POST $(API_URL)/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"$(ADMIN_USERNAME)","password":"$(ADMIN_PASSWORD)"}' | \
python3 -c "import sys,json; print(json.load(sys.stdin).get('access_token',''))"); \
if [ -z "$$TOKEN" ]; then echo " ✗ Login failed"; exit 1; fi; \
RESP=$$(curl -s -X POST $(API_URL)/api/admin/seed-alc-corporate \
-H "Authorization: Bearer $$TOKEN" \
-H "X-User-Id: 1" \
-H "X-Company-Id: 2" \
-H "X-Change-Reason: Phase 8.2 ALC corporate environment seed"); \
if echo "$$RESP" | grep -q '"error"'; then \
echo " ✗ Failed:"; echo "$$RESP" | python3 -m json.tool; exit 1; \
else \
echo " ✓ ALC corporate environment seeded"; \
echo "$$RESP" | python3 -c "import sys,json; d=json.load(sys.stdin); print(f' Users: {len(d.get(\"users\",{}).get(\"created\",[]))} created'); print(f' Folders: {len(d.get(\"folders\",{}).get(\"created\",[]))} created')"; \
fi
vllm-logs: ## Tail vLLM logs
docker compose logs -f vllm vllm-cpu 2>/dev/null || docker compose --profile gpu logs -f vllm
logs: ## Tail logs for all services
docker compose logs -f
backend-logs: ## Tail backend logs
docker compose logs -f backend
frontend-logs: ## Tail frontend logs
docker compose logs -f frontend
shell-backend: ## Open a shell in the backend container
docker compose exec backend bash
shell-frontend: ## Open a shell in the frontend container
docker compose exec frontend sh
# ─────────────────────────────────────────────────────────────────────────────
# Database Migrations (Alembic)
# ─────────────────────────────────────────────────────────────────────────────
migrate: ## Run all pending Alembic migrations
docker compose exec backend alembic upgrade head
@echo "Ensuring Continuum tables exist..."
docker compose exec backend python -c "exec(\"import asyncio\\nfrom sqlalchemy.orm import configure_mappers\\nfrom alcoabase.database import init_db, get_engine, Base\\nfrom alcoabase.models import *\\nconfigure_mappers()\\nasync def run():\\n await init_db()\\n e = get_engine()\\n async with e.begin() as c:\\n await c.run_sync(Base.metadata.create_all)\\n print(' Done.')\\nasyncio.run(run())\")"
migrate-generate: ## Auto-generate a new migration (usage: make migrate-generate MSG="add foo")
docker compose exec backend alembic revision --autogenerate -m "$(MSG)"
migrate-downgrade: ## Downgrade one migration step
docker compose exec backend alembic downgrade -1
migrate-history: ## Show migration history
docker compose exec backend alembic history --verbose
# ─────────────────────────────────────────────────────────────────────────────
# Setup Wizard
# ─────────────────────────────────────────────────────────────────────────────
setup-status: ## Check current setup wizard status
@curl -s $(API_URL)/api/v1/setup/status | python3 -m json.tool
setup: ## Run full setup wizard (creates admin, company, configures AI, seeds demo data)
@echo "═══════════════════════════════════════════════════════════════"
@echo " AlcoaBase Setup Wizard"
@echo "═══════════════════════════════════════════════════════════════"
@echo ""
@echo "Step 1/4: Creating root admin..."
@RESPONSE=$$(curl -s -X POST $(API_URL)/api/v1/setup/admin \
-H "Content-Type: application/json" \
-d '{"username":"$(ADMIN_USERNAME)","email":"$(ADMIN_EMAIL)","password":"$(ADMIN_PASSWORD)","full_name":"$(ADMIN_FULLNAME)"}'); \
TOKEN=$$(echo "$$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); t=d.get('access_token',''); print(t)" 2>/dev/null); \
if [ -z "$$TOKEN" ]; then \
echo " ✗ Failed! Response:"; \
echo "$$RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$$RESPONSE"; \
exit 1; \
fi; \
echo " ✓ Admin created ($(ADMIN_USERNAME))"; \
echo ""; \
echo "Step 2/4: Creating company..."; \
RESP2=$$(curl -s -X POST $(API_URL)/api/v1/setup/company \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $$TOKEN" \
-d '{"display_name":"$(COMPANY_NAME)","regulatory_framework":"$(COMPANY_FRAMEWORK)"}'); \
echo "$$RESP2" | python3 -c "import sys,json; d=json.load(sys.stdin); assert 'company_id' in d or 'detail' in d" 2>/dev/null; \
if echo "$$RESP2" | grep -q '"company_id"'; then \
echo " ✓ Company created ($(COMPANY_NAME))"; \
else \
echo " ✗ Failed! Response:"; echo "$$RESP2" | python3 -m json.tool 2>/dev/null || echo "$$RESP2"; exit 1; \
fi; \
echo ""; \
echo "Step 3/4: Configuring AI mode..."; \
RESP3=$$(curl -s -X POST $(API_URL)/api/v1/setup/ai-mode \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $$TOKEN" \
-d '{"mode":"$(AI_MODE)"}'); \
if echo "$$RESP3" | grep -q '"mode"'; then \
echo " ✓ AI mode set ($(AI_MODE))"; \
else \
echo " ✗ Failed! Response:"; echo "$$RESP3" | python3 -m json.tool 2>/dev/null || echo "$$RESP3"; exit 1; \
fi; \
echo ""; \
echo "Step 4/4: Completing setup..."; \
RESP4=$$(curl -s -X POST $(API_URL)/api/v1/setup/complete \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $$TOKEN" \
-d '{"seed_demo_data":true}'); \
if echo "$$RESP4" | grep -q '"message"'; then \
echo " ✓ Setup complete!"; \
else \
echo " ✗ Failed! Response:"; echo "$$RESP4" | python3 -m json.tool 2>/dev/null || echo "$$RESP4"; exit 1; \
fi; \
echo ""; \
echo "═══════════════════════════════════════════════════════════════"; \
echo " Login credentials:"; \
echo " Username: $(ADMIN_USERNAME)"; \
echo " Password: $(ADMIN_PASSWORD)"; \
echo "═══════════════════════════════════════════════════════════════"
# ─────────────────────────────────────────────────────────────────────────────
# Testing
# ─────────────────────────────────────────────────────────────────────────────
test: test-backend test-frontend ## Run all tests
test-backend: ## Run backend pytest tests
cd src/backend && uv run pytest -q --tb=short
test-frontend: ## Run frontend vitest tests
cd src/frontend && npx vitest run
lint: ## Run linters (backend + frontend)
cd src/backend && uv run ruff check .
cd src/frontend && npm run lint
# ─────────────────────────────────────────────────────────────────────────────
# Utilities
# ─────────────────────────────────────────────────────────────────────────────
reset-db: ## Drop and recreate the database (DESTRUCTIVE)
@echo "⚠️ This will destroy all data. Press Ctrl+C to cancel."
@sleep 3
docker compose exec postgres psql -U alcoabase -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
@echo "Database reset. Run 'make migrate' then 'make setup' to reinitialize."
health: ## Check health of all services
@echo -n "Backend: "; curl -sf $(API_URL)/health > /dev/null && echo "✓ OK" || echo "✗ DOWN"
@echo -n "Frontend: "; curl -sf http://localhost:3000/ > /dev/null && echo "✓ OK" || echo "✗ DOWN"
@echo -n "PostgreSQL: "; docker compose exec -T postgres pg_isready -q && echo "✓ OK" || echo "✗ DOWN"
@echo -n "Redis: "; docker compose exec -T redis redis-cli -a changeme_redis ping 2>/dev/null | grep -q PONG && echo "✓ OK" || echo "✗ DOWN"
@echo -n "OpenSearch: "; curl -sf http://localhost:9200/_cluster/health > /dev/null && echo "✓ OK" || echo "✗ DOWN"