Skip to content

Commit 1d0ac10

Browse files
robmsmtclaude
andauthored
dev safety + launched_by-driven tier + pending status (#28)
Frontend - Tier (24/7 vs Slurm badge) now derived from the peer's launched_by label instead of a hardcoded model list. Persistent launchers (k8s, cscs_L1) → 24/7; anything else (username from model-launch, empty) → Slurm. New helper getTierFromLaunchedBy replaces getModelTier in ModelCard and ModelList. - Pending status surfaces on the collapsed card via a traffic-light dot (green/amber+pulsing/grey) AND a muted-grey tile treatment (grayscale logo+badges, gray-500/400 text, faint background wash). Amber dot stays vivid against the grey card. Local-dev safety - Makefile guards _guard-local-db and _guard-local-api refuse to run if .env DATABASE_URL or frontend/.env VITE_API_URL points at a non-localhost host. Closes a foot-gun where prod creds in .env let `make dummy-run` attempt alembic upgrade head against prod Neon. - Committed .env.example and frontend/.env.example templates (with !.env.example in .gitignore so the un-ignore actually works) so a fresh clone bootstraps cleanly via `make run`. Fixture - dnt_table_dev_live.json gains 6 real k8s peer entries pulled from prod DNT, so `make dummy-run` shows a representative mix of k8s 24/7 models + Slurm jobs (incl. a pending one) for UI iteration. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 02e9f06 commit 1d0ac10

8 files changed

Lines changed: 527 additions & 27 deletions

File tree

.env.example

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copy this to .env (the Makefile does this automatically on first run).
2+
# Fill in the REPLACE_WITH_* placeholders with values from
3+
# rob-poc/serving-api/dev/secrets.yaml. Never put prod values here —
4+
# the Makefile's _guard-local-db will refuse non-local DATABASE_URL.
5+
6+
# ── Local Postgres (matches what `make db-up` spins up) ──────────────────────
7+
DATABASE_URL=postgresql://serving:serving@localhost:5433/serving
8+
9+
# ── Auth0 (research.computer tenant) ─────────────────────────────────────────
10+
AUTH0_DOMAIN=researchcomputer.eu.auth0.com
11+
AUTH0_API_AUDIENCE=https://researchcomputer.eu.auth0.com/
12+
AUTH0_ISSUER=https://researchcomputer.eu.auth0.com/
13+
AUTH0_ALGORITHMS=RS256
14+
AUTH0_CLIENT_ID=REPLACE_WITH_AUTH0_CLIENT_ID
15+
AUTH0_CLIENT_SECRET=REPLACE_WITH_AUTH0_CLIENT_SECRET
16+
AUTH_SECRET=REPLACE_WITH_RANDOM_STRING
17+
AUTH_TRUST_HOST=true
18+
19+
VITE_AUTH0_CLIENT_ID=REPLACE_WITH_VITE_AUTH0_CLIENT_ID
20+
VITE_AUTH0_DOMAIN=researchcomputer.eu.auth0.com
21+
22+
# ── OpenTela / OCF (peer discovery + LLM routing) ────────────────────────────
23+
# Point at the dev OpenTela head for live model discovery, or use
24+
# OTELA_FIXTURE_PATH (set by `make dummy-run`) to read a static snapshot.
25+
OCF_HEAD_ADDR=http://148.187.108.177:8092
26+
27+
# ── Langfuse (observability — optional; leave blank to disable) ──────────────
28+
LANGFUSE_HOST=https://cloud.langfuse.com
29+
LANGFUSE_PUBLIC_KEY=
30+
LANGFUSE_SECRET_KEY=
31+
32+
# ── CSCS L1 passthrough (optional; leave blank to disable) ───────────────────
33+
# When both are set, requests for L1-hosted Apertus models forward here
34+
# instead of OpenTela. See backend/services/cscs_l1_service.py.
35+
CSCS_L1_BASE_URL=
36+
CSCS_L1_API_KEY=
37+
38+
# ── Logfire (observability — optional) ───────────────────────────────────────
39+
LOGFIRE_TOKEN=

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*.pyc
22
*.env
33
*.env*
4+
!.env.example
45
details.json
56
secrets/*.json
67
.venv/*

Makefile

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: install install-dev format check test run dummy-run db-up db-down migrate _ensure-env _ensure-frontend-env
1+
.PHONY: install install-dev format check test run dummy-run db-up db-down migrate _ensure-env _ensure-frontend-env _guard-local-db _guard-local-api
22

33
UV_EXTRA ?=
44

@@ -66,18 +66,46 @@ db-down:
6666
-docker stop $(PG_CONTAINER) > /dev/null 2>&1
6767
-docker rm $(PG_CONTAINER) > /dev/null 2>&1
6868

69-
migrate: _ensure-env db-up
69+
# Refuse to run any DB-touching target if .env points at a non-local host.
70+
# We never want `make run` / `make migrate` to accidentally apply migrations
71+
# or open connections against a remote (prod/staging) database — the local
72+
# Postgres container is the only acceptable target for dev commands.
73+
_guard-local-db: _ensure-env
74+
@url=$$(grep -E '^DATABASE_URL=' .env | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'"); \
75+
host=$$(echo "$$url" | sed -E 's|^[^:]+://[^@]*@([^:/?]+).*|\1|'); \
76+
case "$$host" in \
77+
localhost|127.0.0.1|::1|"") ;; \
78+
*) echo "REFUSING: .env DATABASE_URL host '$$host' is not local."; \
79+
echo "Local dev must not run against prod/staging. Set DATABASE_URL=$(DATABASE_URL) in .env."; \
80+
exit 1;; \
81+
esac
82+
83+
# Same guard for the frontend — VITE_API_URL is what `npm run dev` reads,
84+
# so a prod URL there silently makes the local UI hit prod even when the
85+
# local backend is running fine. That's exactly what tripped up dummy-run
86+
# the first time around. Empty / unset is fine (frontend defaults apply).
87+
_guard-local-api: _ensure-frontend-env
88+
@url=$$(grep -E '^VITE_API_URL=' frontend/.env | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'"); \
89+
host=$$(echo "$$url" | sed -E 's|^[^:]+://([^:/?]+).*|\1|'); \
90+
case "$$host" in \
91+
localhost|127.0.0.1|::1|"") ;; \
92+
*) echo "REFUSING: frontend/.env VITE_API_URL host '$$host' is not local."; \
93+
echo "Local dev must not call prod/staging API. Set VITE_API_URL=http://localhost:8080 in frontend/.env."; \
94+
exit 1;; \
95+
esac
96+
97+
migrate: _ensure-env _guard-local-db db-up
7098
alembic upgrade head
7199

72-
run: _ensure-env _ensure-frontend-env db-up migrate
100+
run: _ensure-env _ensure-frontend-env _guard-local-api db-up migrate
73101
uvicorn backend.main:app --reload --host 0.0.0.0 --port 8080 & \
74102
cd frontend && npm run dev & \
75103
wait
76104

77105
# Same as `run` but forces the model list to come from the synthesised
78106
# upgraded fixture instead of the live OpenTela endpoint. Useful for
79107
# iterating on the model-card UI without depending on prod state.
80-
dummy-run: _ensure-env _ensure-frontend-env db-up migrate
108+
dummy-run: _ensure-env _ensure-frontend-env _guard-local-api db-up migrate
81109
OTELA_FIXTURE_PATH=$(PWD)/backend/tests/fixtures/dnt_table_dev_live.json \
82110
uvicorn backend.main:app --reload --host 0.0.0.0 --port 8080 & \
83111
cd frontend && npm run dev & \

0 commit comments

Comments
 (0)