From 8dabd6333e71dc550b8ff67ae49a121110534545 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Mon, 23 Mar 2026 15:13:27 +0100 Subject: [PATCH 01/26] do not mount codebase as volume --- docker-compose.local.yml | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/docker-compose.local.yml b/docker-compose.local.yml index b2265f39..f8b86145 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -1,27 +1,12 @@ services: - db-init: - environment: - STITCH_DB_SEED_MODE: if-needed + api: environment: LOG_LEVEL: debug - volumes: - - ./deployments/api/src:/app/deployments/api/src - - ./packages:/app/packages - command: - - uvicorn - - stitch.api.main:app - - --host - - "0.0.0.0" - - --port - - "8000" - - --reload - - --reload-dir - - /app/deployments/api/src - - --reload-dir - - /app/packages - - --reload-exclude - - "*/tests/*" + + db-init: + environment: + STITCH_DB_SEED_MODE: if-needed seed: build: @@ -44,4 +29,3 @@ services: depends_on: api: condition: service_healthy - From 5d460f41abeffeae186e15ae62618e5a8725cc5a Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Mon, 23 Mar 2026 15:55:53 +0100 Subject: [PATCH 02/26] Remove prod-docker target --- Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Makefile b/Makefile index a2ff9ab9..2535f50e 100644 --- a/Makefile +++ b/Makefile @@ -148,9 +148,6 @@ dev-docker: reboot-docker: clean-docker $(DOCKER_COMPOSE_DEV) up --build -prod-docker: - $(DOCKER_COMPOSE) up - .PHONY: all build clean \ build-python \ check lint test format format-check \ From de62df0519038999d0686792d796e6c388fa1d91 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Mon, 23 Mar 2026 16:06:24 +0100 Subject: [PATCH 03/26] add compose profiles for services --- Makefile | 6 +++--- docker-compose.local.yml | 1 + docker-compose.yml | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 2535f50e..d645ff13 100644 --- a/Makefile +++ b/Makefile @@ -140,13 +140,13 @@ frontend-clean: # docker clean-docker: - $(DOCKER_COMPOSE_DEV) down --volumes --remove-orphans + $(DOCKER_COMPOSE_DEV) --profile "*" down --volumes --remove-orphans dev-docker: - $(DOCKER_COMPOSE_DEV) up + $(DOCKER_COMPOSE_DEV) --profile full up reboot-docker: clean-docker - $(DOCKER_COMPOSE_DEV) up --build + $(DOCKER_COMPOSE_DEV) --profile full up --build .PHONY: all build clean \ build-python \ diff --git a/docker-compose.local.yml b/docker-compose.local.yml index f8b86145..89274c5a 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -26,6 +26,7 @@ services: volumes: - ./deployments/seed/data:/mnt/data:ro restart: "no" + profiles: ["seed", "full"] depends_on: api: condition: service_healthy diff --git a/docker-compose.yml b/docker-compose.yml index f2a3a009..828f0f69 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,5 @@ services: + api: build: context: . @@ -25,9 +26,9 @@ services: retries: 3 start_period: 5s start_interval: 1s - ports: - "8000:8000" + profiles: ["api", "full"] depends_on: db: condition: service_healthy @@ -62,6 +63,7 @@ services: image: adminer:latest ports: - "8081:8080" + profiles: ["tools", "full"] depends_on: db: condition: service_healthy @@ -79,7 +81,6 @@ services: # db-init connects as the migrator role (DDL + seed) STITCH_DB_USER: stitch_migrator STITCH_DB_PASSWORD: ${STITCH_MIGRATOR_PASSWORD} - depends_on: db: condition: service_healthy @@ -97,6 +98,7 @@ services: VITE_API_URL: ${VITE_API_URL:-http://localhost:8000/api/v1} ports: - "3000:80" + profiles: ["frontend", "full"] volumes: db_data: From 415133a03efb023080f9cb2443520275028c90a1 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Mon, 23 Mar 2026 16:07:52 +0100 Subject: [PATCH 04/26] Move adminer to local services --- docker-compose.local.yml | 9 +++++++++ docker-compose.yml | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docker-compose.local.yml b/docker-compose.local.yml index 89274c5a..bcfaf651 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -8,6 +8,15 @@ services: environment: STITCH_DB_SEED_MODE: if-needed + adminer: + image: adminer:latest + ports: + - "8081:8080" + profiles: ["tools", "full"] + depends_on: + db: + condition: service_healthy + seed: build: context: . diff --git a/docker-compose.yml b/docker-compose.yml index 828f0f69..567f64af 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -59,15 +59,6 @@ services: - db_data:/var/lib/postgresql/data - ./deployments/db/00-init-roles.sh:/docker-entrypoint-initdb.d/00-init-roles.sh:ro - adminer: - image: adminer:latest - ports: - - "8081:8080" - profiles: ["tools", "full"] - depends_on: - db: - condition: service_healthy - db-init: build: context: . From 2b6db31ca905b402c9d135ce6df8555032b8d84b Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Mon, 23 Mar 2026 17:03:14 +0100 Subject: [PATCH 05/26] add deployment-specific stacks for dev environment --- Makefile | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d645ff13..3224222d 100644 --- a/Makefile +++ b/Makefile @@ -65,6 +65,12 @@ uv-sync-dev: uv-lock-check: $(UV) lock --check +api-dev: stack-api-dev + $(UV) run uvicorn stitch.api.main:app --host 0.0.0.0 --port 8000 --reload \ + --reload-dir deployments/api/src \ + --reload-dir packages \ + --reload-exclude '*/tests/*' + # --------------------------------------------------------------------- # Packages and source discovery # --------------------------------------------------------------------- @@ -131,7 +137,7 @@ frontend-format: $(FRONTEND_INSTALL_STAMP) frontend-format-check: $(FRONTEND_INSTALL_STAMP) $(NPM) run format:check -frontend-dev: $(FRONTEND_INSTALL_STAMP) +frontend-dev: $(FRONTEND_INSTALL_STAMP) stack-frontend-dev $(NPM) run dev frontend-clean: @@ -148,6 +154,12 @@ dev-docker: reboot-docker: clean-docker $(DOCKER_COMPOSE_DEV) --profile full up --build +stack-api-dev: + $(DOCKER_COMPOSE_DEV) --profile frontend --profile tools up --build -d + +stack-frontend-dev: + $(DOCKER_COMPOSE_DEV) --profile api --profile tools up --build -d + .PHONY: all build clean \ build-python \ check lint test format format-check \ From 2fd57069b0c2838014103f919375b34058d5795e Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Mon, 23 Mar 2026 19:35:01 +0100 Subject: [PATCH 06/26] wip: seeding for api container --- Makefile | 9 ++++++-- deployments/seed/src/stitch/seed/__main__.py | 4 +++- deployments/seed/src/stitch/seed/client.py | 22 ++++++++++++++++++++ docker-compose.local.yml | 3 --- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 3224222d..4351d8bf 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,12 @@ uv-lock-check: $(UV) lock --check api-dev: stack-api-dev - $(UV) run uvicorn stitch.api.main:app --host 0.0.0.0 --port 8000 --reload \ + STITCH_DB_USER=stitch_app \ + $(UV) run --env-file .env -- \ + uvicorn stitch.api.main:app \ + --host 0.0.0.0 \ + --port 8000 \ + --reload \ --reload-dir deployments/api/src \ --reload-dir packages \ --reload-exclude '*/tests/*' @@ -158,7 +163,7 @@ stack-api-dev: $(DOCKER_COMPOSE_DEV) --profile frontend --profile tools up --build -d stack-frontend-dev: - $(DOCKER_COMPOSE_DEV) --profile api --profile tools up --build -d + $(DOCKER_COMPOSE_DEV) --profile api --profile tools up --build -d .PHONY: all build clean \ build-python \ diff --git a/deployments/seed/src/stitch/seed/__main__.py b/deployments/seed/src/stitch/seed/__main__.py index 6a430674..255feb8e 100644 --- a/deployments/seed/src/stitch/seed/__main__.py +++ b/deployments/seed/src/stitch/seed/__main__.py @@ -1,5 +1,5 @@ import httpx -from .client import post_payloads +from .client import post_payloads, wait_for_api from .config import configure_logging, load_config, logger from .openapi_validate import OpenAPIRequestValidator from .payloads import iter_payloads @@ -13,6 +13,8 @@ def main() -> None: logger.info("API_BASE_URL=%s", cfg.api_base_url) logger.info("FAKER_POST_COUNT=%s", cfg.faker_post_count) + wait_for_api(cfg.api_base_url) + validator = OpenAPIRequestValidator(cfg.api_base_url, openapi_url=cfg.openapi_url) payloads = iter_payloads( static_payload_dir=cfg.static_payload_dir, diff --git a/deployments/seed/src/stitch/seed/client.py b/deployments/seed/src/stitch/seed/client.py index ebce060e..3b93e5d0 100644 --- a/deployments/seed/src/stitch/seed/client.py +++ b/deployments/seed/src/stitch/seed/client.py @@ -5,6 +5,9 @@ from typing import Any, Iterable import httpx +import time + + from .openapi_validate import OpenAPIRequestValidator @@ -41,3 +44,22 @@ def post_payloads( ) resp.raise_for_status() + +def wait_for_api(base_url: str, retries: int = 30, delay: float = 2.0) -> None: + url = f"{base_url.rstrip('/')}/health" + logger.info("url: %s", url) + + for attempt in range(1, retries + 1): + try: + r = httpx.get(url, timeout=2.0) + if 200 <= r.status_code < 300: + logger.info("API ready after %s attempt(s)", attempt) + return + else: + logger.info("API not ready (status %s), attempt %s of %s", r.status_code, attempt, retries) + except Exception as e: + logger.info(f"API not reachable ({e}), attempt {attempt}/{retries}") + + time.sleep(delay) + + raise RuntimeError("API did not become ready in time") diff --git a/docker-compose.local.yml b/docker-compose.local.yml index bcfaf651..188f1828 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -36,6 +36,3 @@ services: - ./deployments/seed/data:/mnt/data:ro restart: "no" profiles: ["seed", "full"] - depends_on: - api: - condition: service_healthy From e9b989c82b4e4b4e56cf1c21ddb3553bf3c7f61c Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Mon, 23 Mar 2026 19:38:38 +0100 Subject: [PATCH 07/26] seed for frontend dev --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4351d8bf..2b362b5d 100644 --- a/Makefile +++ b/Makefile @@ -163,7 +163,7 @@ stack-api-dev: $(DOCKER_COMPOSE_DEV) --profile frontend --profile tools up --build -d stack-frontend-dev: - $(DOCKER_COMPOSE_DEV) --profile api --profile tools up --build -d + $(DOCKER_COMPOSE_DEV) --profile api --profile tools --profile seed up --build -d .PHONY: all build clean \ build-python \ From 96d71c7af5ae376862ca753ffbb0b8d2d74612d9 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Wed, 25 Mar 2026 12:44:57 +0100 Subject: [PATCH 08/26] Sucessfully run API locally, with other services in docker --- Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 2b362b5d..7179d062 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,11 @@ uv-lock-check: $(UV) lock --check api-dev: stack-api-dev - STITCH_DB_USER=stitch_app \ + POSTGRES_HOST=127.0.0.1 \ + POSTGRES_PORT=5432 \ + POSTGRES_DB=stitch \ + POSTGRES_USER=stitch_app \ + POSTGRES_PASSWORD="CHANGE_ME_app123!" \ $(UV) run --env-file .env -- \ uvicorn stitch.api.main:app \ --host 0.0.0.0 \ @@ -160,7 +164,7 @@ reboot-docker: clean-docker $(DOCKER_COMPOSE_DEV) --profile full up --build stack-api-dev: - $(DOCKER_COMPOSE_DEV) --profile frontend --profile tools up --build -d + $(DOCKER_COMPOSE_DEV) --profile frontend --profile tools --profile seed up --build -d stack-frontend-dev: $(DOCKER_COMPOSE_DEV) --profile api --profile tools --profile seed up --build -d From 75181bf65029ed738fe711396d97ab6e5b228528 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Wed, 25 Mar 2026 15:22:04 +0100 Subject: [PATCH 09/26] remove seed mode from db-init --- docker-compose.local.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docker-compose.local.yml b/docker-compose.local.yml index 188f1828..f5e8ed87 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -4,10 +4,6 @@ services: environment: LOG_LEVEL: debug - db-init: - environment: - STITCH_DB_SEED_MODE: if-needed - adminer: image: adminer:latest ports: From 9d0fe9c930cc5b6bd9096e8add0dcd45637afe48 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 10:48:24 +0100 Subject: [PATCH 10/26] Update envvar file, api-dev target works --- Makefile | 4 +--- docker-compose.local.yml | 6 ++---- docker-compose.yml | 29 ++++++++++---------------- env.example | 44 +++++++++++++++++++++++++++++++--------- 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index 7179d062..b6d5dc8a 100644 --- a/Makefile +++ b/Makefile @@ -67,10 +67,7 @@ uv-lock-check: api-dev: stack-api-dev POSTGRES_HOST=127.0.0.1 \ - POSTGRES_PORT=5432 \ - POSTGRES_DB=stitch \ POSTGRES_USER=stitch_app \ - POSTGRES_PASSWORD="CHANGE_ME_app123!" \ $(UV) run --env-file .env -- \ uvicorn stitch.api.main:app \ --host 0.0.0.0 \ @@ -164,6 +161,7 @@ reboot-docker: clean-docker $(DOCKER_COMPOSE_DEV) --profile full up --build stack-api-dev: + SEED_API_BASE_URL=http://host.docker.internal:8000/api/v1 \ $(DOCKER_COMPOSE_DEV) --profile frontend --profile tools --profile seed up --build -d stack-frontend-dev: diff --git a/docker-compose.local.yml b/docker-compose.local.yml index f5e8ed87..5bf1efb4 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -1,9 +1,5 @@ services: - api: - environment: - LOG_LEVEL: debug - adminer: image: adminer:latest ports: @@ -28,6 +24,8 @@ services: SEED_SOURCE: "mixed" NULL_PROBABILITY: 0.3 STATIC_PAYLOAD_DIR: "/mnt/data" + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ./deployments/seed/data:/mnt/data:ro restart: "no" diff --git a/docker-compose.yml b/docker-compose.yml index 567f64af..c60a5f61 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,14 +7,10 @@ services: env_file: - .env environment: - LOG_LEVEL: info - POSTGRES_DB: stitch - POSTGRES_HOST: db - POSTGRES_PORT: 5432 + LOG_LEVEL: ${API_LOG_LEVEL:-info} # API connects as the app role (no DDL) - STITCH_DB_USER: stitch_app - STITCH_DB_PASSWORD: ${STITCH_APP_PASSWORD:?STITCH_APP_PASSWORD must be set in .env} - AUTH_DISABLED: "true" + POSTGRES_USER: stitch_app + POSTGRES_PASSWORD: ${STITCH_APP_PASSWORD:?STITCH_APP_PASSWORD must be set in .env} healthcheck: test: [ @@ -51,8 +47,8 @@ services: env_file: - .env environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres + POSTGRES_USER: ${POSTGRES_SUPERUSER_PASSWORD:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_SUPERUSER_PASSWORD:-postgres} ports: - "5432:5432" volumes: @@ -66,12 +62,9 @@ services: env_file: - .env environment: - STITCH_DB_SCHEMA_MODE: "if-empty" - STITCH_DB_SEED_MODE: "never" - STITCH_DB_SEED_PROFILE: "dev" # db-init connects as the migrator role (DDL + seed) - STITCH_DB_USER: stitch_migrator - STITCH_DB_PASSWORD: ${STITCH_MIGRATOR_PASSWORD} + POSTGRES_USER: stitch_migrator + POSTGRES_PASSWORD: ${STITCH_MIGRATOR_PASSWORD:?STITCH_MIGRATOR_PASSWORD must be set in .env} depends_on: db: condition: service_healthy @@ -83,10 +76,10 @@ services: context: deployments/stitch-frontend dockerfile: Dockerfile args: - VITE_AUTH0_DOMAIN: ${VITE_AUTH0_DOMAIN:-} - VITE_AUTH0_CLIENT_ID: ${VITE_AUTH0_CLIENT_ID:-} - VITE_AUTH0_AUDIENCE: ${VITE_AUTH0_AUDIENCE:-} - VITE_API_URL: ${VITE_API_URL:-http://localhost:8000/api/v1} + VITE_AUTH0_DOMAIN: ${VITE_AUTH0_DOMAIN?} + VITE_AUTH0_CLIENT_ID: ${VITE_AUTH0_CLIENT_ID?} + VITE_AUTH0_AUDIENCE: ${VITE_AUTH0_AUDIENCE?} + VITE_API_URL: ${VITE_API_URL?} ports: - "3000:80" profiles: ["frontend", "full"] diff --git a/env.example b/env.example index a51f749f..0e445bf3 100644 --- a/env.example +++ b/env.example @@ -1,17 +1,41 @@ -LOG_LEVEL=info +# Logging +API_LOG_LEVEL=db +DBINIT_LOG_LEVEL=info +SEED_LOG_LEVEL=debug -POSTGRES_DB=stitch +# ------------------------------ + +# API +AUTH_DISABLED=true + +# ------------------------------ + +# DB Connection details for API: POSTGRES_HOST=db POSTGRES_PORT=5432 +POSTGRES_DB=stitch +POSTGRES_USER=stitch_app +POSTGRES_PASSWORD=SuperSecureApp1! -STITCH_MIGRATOR_PASSWORD=CHANGE_ME_migrator123! -STITCH_APP_PASSWORD=CHANGE_ME_app123! +# DB bootstrap / roles +POSTGRES_SUPERUSER=postgres +POSTGRES_SUPERUSER_PASSWORD=postgres +STITCH_APP_PASSWORD=SuperSecureApp1! +STITCH_MIGRATOR_PASSWORD=SuperSecureMigrator1! +STITCH_DB_SCHEMA_MODE=if-empty -STITCH_DB_SCHEMA_MODE="if-empty" -STITCH_DB_SEED_MODE="if-needed" -STITCH_DB_SEED_PROFILE="dev" +# ------------------------------ -FRONTEND_ORIGIN_URL=http://localhost:3000 +# Frontend (public) +VITE_API_URL=http://localhost:8000/api/v1 +VITE_USE_MOCK_DATA=false +VITE_AUTH0_DOMAIN=https://rmi-spd.us.auth0.com +VITE_AUTH0_CLIENT_ID=TS1V1soQbccAV1sitFFCfUaIlSwHD2S2 +VITE_AUTH0_AUDIENCE=https://stitch-api.local -# Auth (AUTH_DISABLED=true bypasses JWT validation for local dev) -AUTH_DISABLED=true + +# ------------------------------ + +# Seed +SEED_API_BASE_URL=http://localhost:8000/api/v1 +SEED_FAKER_POST_COUNT=5 From 73e49c51dbc1522cc5fe815dae894ca098574d0c Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 11:02:52 +0100 Subject: [PATCH 11/26] cleanup of frontend-dev target --- Makefile | 16 ++++++++++++++-- env.example | 8 ++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index b6d5dc8a..0d42c1a6 100644 --- a/Makefile +++ b/Makefile @@ -144,6 +144,7 @@ frontend-format-check: $(FRONTEND_INSTALL_STAMP) $(NPM) run format:check frontend-dev: $(FRONTEND_INSTALL_STAMP) stack-frontend-dev + VITE_API_URL=http://localhost:8000/api/v1 \ $(NPM) run dev frontend-clean: @@ -162,10 +163,21 @@ reboot-docker: clean-docker stack-api-dev: SEED_API_BASE_URL=http://host.docker.internal:8000/api/v1 \ - $(DOCKER_COMPOSE_DEV) --profile frontend --profile tools --profile seed up --build -d + $(DOCKER_COMPOSE_DEV) \ + --profile frontend \ + --profile tools \ + --profile seed \ + up --build \ + -d stack-frontend-dev: - $(DOCKER_COMPOSE_DEV) --profile api --profile tools --profile seed up --build -d + SEED_API_BASE_URL=http://api:8000/api/v1 \ + $(DOCKER_COMPOSE_DEV) \ + --profile api \ + --profile tools \ + --profile seed \ + up --build \ + -d .PHONY: all build clean \ build-python \ diff --git a/env.example b/env.example index 0e445bf3..4d542f79 100644 --- a/env.example +++ b/env.example @@ -1,7 +1,7 @@ # Logging -API_LOG_LEVEL=db +API_LOG_LEVEL=info DBINIT_LOG_LEVEL=info -SEED_LOG_LEVEL=debug +SEED_LOG_LEVEL=info # ------------------------------ @@ -27,7 +27,7 @@ STITCH_DB_SCHEMA_MODE=if-empty # ------------------------------ # Frontend (public) -VITE_API_URL=http://localhost:8000/api/v1 +VITE_API_URL=http://api:8000/api/v1 VITE_USE_MOCK_DATA=false VITE_AUTH0_DOMAIN=https://rmi-spd.us.auth0.com VITE_AUTH0_CLIENT_ID=TS1V1soQbccAV1sitFFCfUaIlSwHD2S2 @@ -37,5 +37,5 @@ VITE_AUTH0_AUDIENCE=https://stitch-api.local # ------------------------------ # Seed -SEED_API_BASE_URL=http://localhost:8000/api/v1 +SEED_API_BASE_URL=http://api:8000/api/v1 SEED_FAKER_POST_COUNT=5 From b11a86edaa204a54f3447f5c447cc3cf9c442298 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 11:27:57 +0100 Subject: [PATCH 12/26] add target to follow docker logs --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 0d42c1a6..1a452ae5 100644 --- a/Makefile +++ b/Makefile @@ -179,6 +179,9 @@ stack-frontend-dev: up --build \ -d +follow-stack-logs: + $(DOCKER_COMPOSE_DEV) --profile full logs -f + .PHONY: all build clean \ build-python \ check lint test format format-check \ From 99b0ca64173618d1782a6922bae31c053a6e6196 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 11:31:20 +0100 Subject: [PATCH 13/26] style: format --- deployments/seed/src/stitch/seed/client.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/deployments/seed/src/stitch/seed/client.py b/deployments/seed/src/stitch/seed/client.py index 3b93e5d0..6996700b 100644 --- a/deployments/seed/src/stitch/seed/client.py +++ b/deployments/seed/src/stitch/seed/client.py @@ -8,7 +8,6 @@ import time - from .openapi_validate import OpenAPIRequestValidator @@ -45,6 +44,7 @@ def post_payloads( resp.raise_for_status() + def wait_for_api(base_url: str, retries: int = 30, delay: float = 2.0) -> None: url = f"{base_url.rstrip('/')}/health" logger.info("url: %s", url) @@ -56,7 +56,12 @@ def wait_for_api(base_url: str, retries: int = 30, delay: float = 2.0) -> None: logger.info("API ready after %s attempt(s)", attempt) return else: - logger.info("API not ready (status %s), attempt %s of %s", r.status_code, attempt, retries) + logger.info( + "API not ready (status %s), attempt %s of %s", + r.status_code, + attempt, + retries, + ) except Exception as e: logger.info(f"API not reachable ({e}), attempt {attempt}/{retries}") From df4fb0163ad0eefe3a4e691f17080d0cbf914395 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 13:21:28 +0100 Subject: [PATCH 14/26] Update UV testing targets, some reordering Update the PYTEST related targets, to no require an external script. --- Makefile | 129 ++++++++++++++++++++++------------------ scripts/test-package.py | 46 -------------- 2 files changed, 70 insertions(+), 105 deletions(-) delete mode 100755 scripts/test-package.py diff --git a/Makefile b/Makefile index 1a452ae5..996a954a 100644 --- a/Makefile +++ b/Makefile @@ -9,61 +9,83 @@ TEST_PKG := ./scripts/test-package.py check: lint test format-check lock-check @echo "All checks passed." -lint: uv-lint frontend-lint +lint: py-lint frontend-lint +test: py-test frontend-test +format-check: py-format-check frontend-format-check +lock-check: py-lock-check -test: uv-test frontend-test +format: py-format frontend-format +clean: clean-build py-clean-cache frontend-clean clean-docker -format: uv-format frontend-format +clean-build: + rm -rf build dist -format-check: uv-format-check frontend-format-check +# --------------------------------------------------------------------- +# Python (UV) infrasturcture +# --------------------------------------------------------------------- + +uv-dev: uv-sync-dev +uv-sync-dev: + $(UV) sync --group dev --all-packages -lock-check: uv-lock-check -uv-lint: uv-dev +py-lint: uv-dev $(RUFF) check -# All workspace packages with tests -TEST_PACKAGES := stitch-api stitch-models +py-test: api-test pkg-test + +py-format-check: uv-dev + $(RUFF) format --check -define newline +py-lock-check: + $(UV) lock --check +py-format: uv-dev + $(RUFF) format + +py-clean-cache: + rm -rf .ruff_cache .pytest_cache -endef +uv-sync: + $(UV) sync -# --- local: full sync, no --exact (fast, no venv mutation) --- -ifdef pkg -uv-test: uv-dev - $(TEST_PKG) $(pkg) -else -uv-test: uv-dev - $(foreach p,$(TEST_PACKAGES),$(TEST_PKG) $(p)$(newline)) -endif +# Generic helpers +uv-test-target: + $(UV) run --package $(PKG) --active pytest $(PATH) $(ARGS) -# --- isolated (CI): per-package --exact deps only --- -ifdef pkg -uv-test-isolated: - $(TEST_PKG) --exact $(pkg) -else -uv-test-isolated: - $(foreach p,$(TEST_PACKAGES),$(TEST_PKG) --exact $(p)$(newline)) -endif +uv-test-target-exact: + $(UV) run --package $(PKG) --active --exact --group dev pytest $(PATH) $(ARGS) -uv-format: uv-dev - $(RUFF) format +# --------------------------------------------------------------------- +# UV Packages +# --------------------------------------------------------------------- -uv-format-check: uv-dev - $(RUFF) format --check +pkg-test-auth: + $(UV) run --package stitch-auth pytest packages/stitch-auth +pkg-test-exact-auth: + $(UV) run --package stitch-auth pytest packages/stitch-auth -uv-dev: uv-sync-dev +pkg-test-models: + $(UV) run --package stitch-models pytest packages/stitch-models +pkg-test-exact-models: + $(UV) run --package stitch-models pytest packages/stitch-models -uv-sync: - $(UV) sync +pkg-test-ogsi: + $(UV) run --package stitch-ogsi pytest packages/stitch-ogsi +pkg-test-exact-ogsi: + $(UV) run --package stitch-ogsi pytest packages/stitch-ogsi -uv-sync-dev: - $(UV) sync --group dev --all-packages +pkg-test: pkg-test-auth pkg-test-models pkg-test-ogsi +pkg-test-exact: pkg-test-exact-auth pkg-test-exact-models pkg-test-exact-ogsi -uv-lock-check: - $(UV) lock --check +# --------------------------------------------------------------------- +# Deployments +# --------------------------------------------------------------------- + +api-test: + $(MAKE) uv-test-target PKG=stitch-api PATH=deployments/api +api-test-exact: + $(MAKE) uv-test-target-exact PKG=stitch-api PATH=deployments/api api-dev: stack-api-dev POSTGRES_HOST=127.0.0.1 \ @@ -77,18 +99,14 @@ api-dev: stack-api-dev --reload-dir packages \ --reload-exclude '*/tests/*' -# --------------------------------------------------------------------- -# Packages and source discovery -# --------------------------------------------------------------------- -all: build-python frontend -build-python: -clean: clean-build clean-cache frontend-clean clean-docker - -clean-build: - rm -rf build dist -clean-cache: - rm -rf .ruff_cache .pytest_cache - +stack-api-dev: + SEED_API_BASE_URL=http://host.docker.internal:8000/api/v1 \ + $(DOCKER_COMPOSE_DEV) \ + --profile frontend \ + --profile tools \ + --profile seed \ + up --build \ + -d # --------------------------------------------------------------------- # stitch-frontend @@ -151,7 +169,9 @@ frontend-clean: rm -rf $(FRONTEND_DIR)/dist $(FRONTEND_DIR)/node_modules \ $(FRONTEND_INSTALL_STAMP) $(FRONTEND_BUILD_STAMP) -# docker +# --------------------------------------------------------------------- +# Docker +# --------------------------------------------------------------------- clean-docker: $(DOCKER_COMPOSE_DEV) --profile "*" down --volumes --remove-orphans @@ -161,15 +181,6 @@ dev-docker: reboot-docker: clean-docker $(DOCKER_COMPOSE_DEV) --profile full up --build -stack-api-dev: - SEED_API_BASE_URL=http://host.docker.internal:8000/api/v1 \ - $(DOCKER_COMPOSE_DEV) \ - --profile frontend \ - --profile tools \ - --profile seed \ - up --build \ - -d - stack-frontend-dev: SEED_API_BASE_URL=http://api:8000/api/v1 \ $(DOCKER_COMPOSE_DEV) \ diff --git a/scripts/test-package.py b/scripts/test-package.py deleted file mode 100755 index 93d6886b..00000000 --- a/scripts/test-package.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env -S uv run --script -# /// script -# requires-python = ">=3.12" -# /// - -import argparse -import subprocess -import sys -import tomllib -from pathlib import Path - - -def find_package_dir(name: str) -> str: - root = tomllib.loads(Path("pyproject.toml").read_text()) - for member in root["tool"]["uv"]["workspace"]["members"]: - p = Path(member) / "pyproject.toml" - if p.exists() and tomllib.loads(p.read_text())["project"]["name"] == name: - return member - print(f"error: package {name!r} not found in workspace", file=sys.stderr) - sys.exit(1) - - -def main() -> None: - parser = argparse.ArgumentParser( - description="Run pytest for a uv workspace package.", - ) - parser.add_argument("package", help="workspace package name") - parser.add_argument( - "-e", - "--exact", - action="store_true", - help="install only the package's declared deps (CI isolation)", - ) - known, pytest_args = parser.parse_known_args() - - pkg_dir = find_package_dir(known.package) - - cmd = ["uv", "run", "--package", known.package, "--active"] - if known.exact: - cmd += ["--exact", "--group", "dev"] - cmd += ["pytest", pkg_dir, *pytest_args] - - sys.exit(subprocess.call(cmd)) - - -main() From cc4bd35c56b3104eb1c3ec160fe6c5320bee54d3 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 13:45:34 +0100 Subject: [PATCH 15/26] reflow dev stack block --- Makefile | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 996a954a..fffaee8c 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,19 @@ stack-api-dev: up --build \ -d +frontend-dev: $(FRONTEND_INSTALL_STAMP) stack-frontend-dev + VITE_API_URL=http://localhost:8000/api/v1 \ + $(NPM) run dev + +stack-frontend-dev: + SEED_API_BASE_URL=http://api:8000/api/v1 \ + $(DOCKER_COMPOSE_DEV) \ + --profile api \ + --profile tools \ + --profile seed \ + up --build \ + -d + # --------------------------------------------------------------------- # stitch-frontend # --------------------------------------------------------------------- @@ -161,10 +174,6 @@ frontend-format: $(FRONTEND_INSTALL_STAMP) frontend-format-check: $(FRONTEND_INSTALL_STAMP) $(NPM) run format:check -frontend-dev: $(FRONTEND_INSTALL_STAMP) stack-frontend-dev - VITE_API_URL=http://localhost:8000/api/v1 \ - $(NPM) run dev - frontend-clean: rm -rf $(FRONTEND_DIR)/dist $(FRONTEND_DIR)/node_modules \ $(FRONTEND_INSTALL_STAMP) $(FRONTEND_BUILD_STAMP) @@ -181,15 +190,6 @@ dev-docker: reboot-docker: clean-docker $(DOCKER_COMPOSE_DEV) --profile full up --build -stack-frontend-dev: - SEED_API_BASE_URL=http://api:8000/api/v1 \ - $(DOCKER_COMPOSE_DEV) \ - --profile api \ - --profile tools \ - --profile seed \ - up --build \ - -d - follow-stack-logs: $(DOCKER_COMPOSE_DEV) --profile full logs -f From 104b1688aa774e2f08c4ea8724f8acc18bf80d82 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 14:49:01 +0100 Subject: [PATCH 16/26] use actual target definitions for packages --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index fffaee8c..0cea22c9 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ clean-build: rm -rf build dist # --------------------------------------------------------------------- -# Python (UV) infrasturcture +# Python (UV) infrastructure # --------------------------------------------------------------------- uv-dev: uv-sync-dev @@ -61,19 +61,19 @@ uv-test-target-exact: # --------------------------------------------------------------------- pkg-test-auth: - $(UV) run --package stitch-auth pytest packages/stitch-auth + $(MAKE) uv-test-target PKG=stitch-auth PATH=packages/stitch-auth pkg-test-exact-auth: - $(UV) run --package stitch-auth pytest packages/stitch-auth + $(MAKE) uv-test-target-exact PKG=stitch-auth PATH=packages/stitch-auth pkg-test-models: - $(UV) run --package stitch-models pytest packages/stitch-models + $(MAKE) uv-test-target PKG=stitch-models PATH=packages/stitch-models pkg-test-exact-models: - $(UV) run --package stitch-models pytest packages/stitch-models + $(MAKE) uv-test-target-exact PKG=stitch-models PATH=packages/stitch-models pkg-test-ogsi: - $(UV) run --package stitch-ogsi pytest packages/stitch-ogsi + $(MAKE) uv-test-target PKG=stitch-ogsi PATH=packages/stitch-ogsi pkg-test-exact-ogsi: - $(UV) run --package stitch-ogsi pytest packages/stitch-ogsi + $(MAKE) uv-test-target-exact PKG=stitch-ogsi PATH=packages/stitch-ogsi pkg-test: pkg-test-auth pkg-test-models pkg-test-ogsi pkg-test-exact: pkg-test-exact-auth pkg-test-exact-models pkg-test-exact-ogsi From d2c52534ad500e77afd3b48934732d9e57e77b75 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 14:59:58 +0100 Subject: [PATCH 17/26] update PHONY block --- Makefile | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 0cea22c9..e3753527 100644 --- a/Makefile +++ b/Makefile @@ -193,13 +193,30 @@ reboot-docker: clean-docker follow-stack-logs: $(DOCKER_COMPOSE_DEV) --profile full logs -f -.PHONY: all build clean \ - build-python \ - check lint test format format-check \ - uv-lint uv-test uv-test-isolated uv-format uv-format-check \ - uv-sync uv-sync-dev uv-sync-all \ - uv-dev \ - clean-build clean-cache \ - lock-check uv-lock-check \ - clean-docker dev-docker \ - frontend frontend-install frontend-build frontend-test frontend-lint frontend-dev frontend-clean frontend-format frontend-format-check +.PHONY: \ + # Workspace + check lint test format format-check lock-check \ + clean clean-build \ + \ + # Python (uv) + py-lint py-test py-format py-format-check py-lock-check py-clean-cache \ + uv-dev uv-sync uv-sync-dev \ + uv-test-target uv-test-target-exact \ + \ + # Packages + pkg-test pkg-test-exact \ + pkg-test-auth pkg-test-exact-auth \ + pkg-test-models pkg-test-exact-models \ + pkg-test-ogsi pkg-test-exact-ogsi \ + \ + # API + api-test api-test-exact api-dev stack-api-dev \ + \ + # Frontend + frontend frontend-install frontend-build frontend-test frontend-lint \ + frontend-format frontend-format-check \ + frontend-dev frontend-clean \ + \ + # Docker + clean-docker dev-docker reboot-docker \ + stack-frontend-dev follow-stack-logs From 48de3beead353630f73feb37cc13e95a588e3ff9 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 15:19:37 +0100 Subject: [PATCH 18/26] Add python build targets --- Makefile | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index e3753527..90866433 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,8 @@ lock-check: py-lock-check format: py-format frontend-format clean: clean-build py-clean-cache frontend-clean clean-docker +build-all: py-build frontend-build + clean-build: rm -rf build dist @@ -33,6 +35,7 @@ py-lint: uv-dev $(RUFF) check py-test: api-test pkg-test +py-test-exact: api-test pkg-test-exact py-format-check: uv-dev $(RUFF) format --check @@ -46,6 +49,8 @@ py-format: uv-dev py-clean-cache: rm -rf .ruff_cache .pytest_cache +py-build: api-build pkg-build + uv-sync: $(UV) sync @@ -60,21 +65,28 @@ uv-test-target-exact: # UV Packages # --------------------------------------------------------------------- +pkg-build-auth: + $(UV) build --package stitch-auth pkg-test-auth: $(MAKE) uv-test-target PKG=stitch-auth PATH=packages/stitch-auth pkg-test-exact-auth: $(MAKE) uv-test-target-exact PKG=stitch-auth PATH=packages/stitch-auth +pkg-build-models: + $(UV) build --package stitch-models pkg-test-models: $(MAKE) uv-test-target PKG=stitch-models PATH=packages/stitch-models pkg-test-exact-models: $(MAKE) uv-test-target-exact PKG=stitch-models PATH=packages/stitch-models +pkg-build-ogsi: + $(UV) build --package stitch-ogsi pkg-test-ogsi: $(MAKE) uv-test-target PKG=stitch-ogsi PATH=packages/stitch-ogsi pkg-test-exact-ogsi: $(MAKE) uv-test-target-exact PKG=stitch-ogsi PATH=packages/stitch-ogsi +pkg-build: pkg-build-auth pkg-build-models pkg-build-ogsi pkg-test: pkg-test-auth pkg-test-models pkg-test-ogsi pkg-test-exact: pkg-test-exact-auth pkg-test-exact-models pkg-test-exact-ogsi @@ -82,6 +94,8 @@ pkg-test-exact: pkg-test-exact-auth pkg-test-exact-models pkg-test-exact-ogsi # Deployments # --------------------------------------------------------------------- +api-build: + $(UV) build --package stitch-api api-test: $(MAKE) uv-test-target PKG=stitch-api PATH=deployments/api api-test-exact: @@ -196,21 +210,23 @@ follow-stack-logs: .PHONY: \ # Workspace check lint test format format-check lock-check \ + build-all \ clean clean-build \ \ # Python (uv) - py-lint py-test py-format py-format-check py-lock-check py-clean-cache \ + py-lint py-test py-test-exact py-format py-format-check py-lock-check py-clean-cache \ + py-build \ uv-dev uv-sync uv-sync-dev \ uv-test-target uv-test-target-exact \ \ # Packages pkg-test pkg-test-exact \ - pkg-test-auth pkg-test-exact-auth \ - pkg-test-models pkg-test-exact-models \ - pkg-test-ogsi pkg-test-exact-ogsi \ + pkg-build-auth pkg-test-auth pkg-test-exact-auth \ + pkg-build-models pkg-test-models pkg-test-exact-models \ + pkg-build-ogsi pkg-test-ogsi pkg-test-exact-ogsi \ \ # API - api-test api-test-exact api-dev stack-api-dev \ + api-build api-test api-test-exact api-dev stack-api-dev \ \ # Frontend frontend frontend-install frontend-build frontend-test frontend-lint \ From 5fd2d3a1997d9c1e5c88f3c862cf172c737a77fb Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 15:20:12 +0100 Subject: [PATCH 19/26] update target names in CI checks --- .github/workflows/python-build.yml | 2 +- .github/workflows/python-format.yml | 3 +-- .github/workflows/python-lint.yml | 2 +- .github/workflows/python-lock-check.yml | 2 +- .github/workflows/python-test.yml | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-build.yml b/.github/workflows/python-build.yml index 46cd9ac8..c6ca602d 100644 --- a/.github/workflows/python-build.yml +++ b/.github/workflows/python-build.yml @@ -18,4 +18,4 @@ jobs: python-version-file: ".python-version" - name: Build - run: make build-python + run: make py-build diff --git a/.github/workflows/python-format.yml b/.github/workflows/python-format.yml index 5644375f..979ce69c 100644 --- a/.github/workflows/python-format.yml +++ b/.github/workflows/python-format.yml @@ -18,5 +18,4 @@ jobs: python-version-file: ".python-version" - name: Run format check - run: make uv-format-check - + run: make py-format-check diff --git a/.github/workflows/python-lint.yml b/.github/workflows/python-lint.yml index 9826cb34..69eec0dc 100644 --- a/.github/workflows/python-lint.yml +++ b/.github/workflows/python-lint.yml @@ -18,4 +18,4 @@ jobs: python-version-file: ".python-version" - name: Run Linter - run: make uv-lint + run: make py-lint diff --git a/.github/workflows/python-lock-check.yml b/.github/workflows/python-lock-check.yml index 82c4e5f5..6abe6fe9 100644 --- a/.github/workflows/python-lock-check.yml +++ b/.github/workflows/python-lock-check.yml @@ -18,4 +18,4 @@ jobs: python-version-file: ".python-version" - name: Lock check - run: make uv-lock-check + run: make py-lock-check diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 04753097..fab2eefd 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -18,4 +18,4 @@ jobs: python-version-file: ".python-version" - name: Run Tests - run: make uv-test-isolated + run: make py-test-exact From 778d5fb07ec6be6ddf7e298c78e8519cb6b99f13 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 15:26:02 +0100 Subject: [PATCH 20/26] Use different var name than `PATH` was overwriting the actual `PATH` var --- Makefile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 90866433..a57a165f 100644 --- a/Makefile +++ b/Makefile @@ -56,10 +56,10 @@ uv-sync: # Generic helpers uv-test-target: - $(UV) run --package $(PKG) --active pytest $(PATH) $(ARGS) + $(UV) run --package $(PKG) --active pytest $(TEST_PATH) $(ARGS) uv-test-target-exact: - $(UV) run --package $(PKG) --active --exact --group dev pytest $(PATH) $(ARGS) + $(UV) run --package $(PKG) --active --exact --group dev pytest $(TEST_PATH) $(ARGS) # --------------------------------------------------------------------- # UV Packages @@ -68,23 +68,23 @@ uv-test-target-exact: pkg-build-auth: $(UV) build --package stitch-auth pkg-test-auth: - $(MAKE) uv-test-target PKG=stitch-auth PATH=packages/stitch-auth + $(MAKE) uv-test-target PKG=stitch-auth TEST_PATH=packages/stitch-auth pkg-test-exact-auth: - $(MAKE) uv-test-target-exact PKG=stitch-auth PATH=packages/stitch-auth + $(MAKE) uv-test-target-exact PKG=stitch-auth TEST_PATH=packages/stitch-auth pkg-build-models: $(UV) build --package stitch-models pkg-test-models: - $(MAKE) uv-test-target PKG=stitch-models PATH=packages/stitch-models + $(MAKE) uv-test-target PKG=stitch-models TEST_PATH=packages/stitch-models pkg-test-exact-models: - $(MAKE) uv-test-target-exact PKG=stitch-models PATH=packages/stitch-models + $(MAKE) uv-test-target-exact PKG=stitch-models TEST_PATH=packages/stitch-models pkg-build-ogsi: $(UV) build --package stitch-ogsi pkg-test-ogsi: - $(MAKE) uv-test-target PKG=stitch-ogsi PATH=packages/stitch-ogsi + $(MAKE) uv-test-target PKG=stitch-ogsi TEST_PATH=packages/stitch-ogsi pkg-test-exact-ogsi: - $(MAKE) uv-test-target-exact PKG=stitch-ogsi PATH=packages/stitch-ogsi + $(MAKE) uv-test-target-exact PKG=stitch-ogsi TEST_PATH=packages/stitch-ogsi pkg-build: pkg-build-auth pkg-build-models pkg-build-ogsi pkg-test: pkg-test-auth pkg-test-models pkg-test-ogsi @@ -97,9 +97,9 @@ pkg-test-exact: pkg-test-exact-auth pkg-test-exact-models pkg-test-exact-ogsi api-build: $(UV) build --package stitch-api api-test: - $(MAKE) uv-test-target PKG=stitch-api PATH=deployments/api + $(MAKE) uv-test-target PKG=stitch-api TEST_PATH=deployments/api api-test-exact: - $(MAKE) uv-test-target-exact PKG=stitch-api PATH=deployments/api + $(MAKE) uv-test-target-exact PKG=stitch-api TEST_PATH=deployments/api api-dev: stack-api-dev POSTGRES_HOST=127.0.0.1 \ From a6a63a1d750ab055af149e7529049cbc1bc83bb4 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 15:37:25 +0100 Subject: [PATCH 21/26] Update test to use new resource signatures --- packages/stitch-ogsi/tests/test_og_field.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/stitch-ogsi/tests/test_og_field.py b/packages/stitch-ogsi/tests/test_og_field.py index 70f16578..11369d23 100644 --- a/packages/stitch-ogsi/tests/test_og_field.py +++ b/packages/stitch-ogsi/tests/test_og_field.py @@ -61,14 +61,8 @@ class TestOGFieldResource: def test_has_both_base_class_fields(self, og_payload: Sequence[OGFieldSource]): resource = OGFieldResource( id=1, - name="Merged Field", - country="USA", source_data=og_payload, - location_type="Onshore", ) - # OilAndGasFieldBase fields - assert resource.name == "Merged Field" - assert resource.location_type == "Onshore" # Resource fields assert resource.id == 1 assert resource.source_data == og_payload @@ -79,8 +73,6 @@ def test_self_reference_rejected(self, og_payload: Sequence[OGFieldSource]): with pytest.raises(ValidationError, match="constituent of itself"): OGFieldResource( id=1, - name="Bad", - country="USA", source_data=og_payload, constituents=[1], ) From 5541a943c0e497804fc68620ef2f3c1fbe2badac Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 15:48:29 +0100 Subject: [PATCH 22/26] update HACKING.md with new startup procedures --- HACKING.md | 162 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 125 insertions(+), 37 deletions(-) diff --git a/HACKING.md b/HACKING.md index e441c58c..a8be3702 100644 --- a/HACKING.md +++ b/HACKING.md @@ -1,85 +1,173 @@ # Hacking on Stitch -This guide covers day-to-day development in the current Stitch monorepo. +This guide covers the day-to-day development workflow in the Stitch monorepo. ## Monorepo layout -- `packages/stitch-auth`: auth/claims/validation package -- `deployments/api`: FastAPI service (`stitch-api`) -- `deployments/stitch-frontend`: React + Vite frontend -- `deployments/db`: DB bootstrap/role scripts +* `deployments/api` — FastAPI service (`stitch-api`) +* `deployments/stitch-frontend` — React + Vite frontend +* `deployments/db` — database bootstrap and role scripts +* `deployments/seed` — local seed data tooling +* `packages/` — shared Python packages ## Prerequisites -- Docker Desktop (`docker`, `docker compose`) -- `uv` for Python dependency/workspace management -- Node.js + npm (for frontend-only workflows) +* Docker Desktop (`docker`, `docker compose`) +* `uv` for Python dependency and workspace management +* Node.js + npm for frontend development ## First-time setup +From the repo root: + ```bash cp env.example .env +make uv-sync-dev +``` + +You can also run the equivalent `uv` command directly: + +```bash uv sync --group dev --all-packages ``` -If you are running the full stack via Docker, `uv sync` is optional unless you also run tests/tools on host. +## The main entrypoints + +In most cases, start with one of these three commands: + +* `make frontend-dev` +* `make api-dev` +* `make dev-docker` (or `make reboot-docker`) + +### `make frontend-dev` + +Use this when you are primarily working on the frontend. + +This target: + +* installs frontend dependencies if needed +* starts the supporting local services in Docker +* runs the Vite dev server on the host + +The API and supporting services run in Docker, while the frontend runs locally with fast rebuilds. + +```bash +make frontend-dev +``` + +### `make api-dev` + +Use this when you are primarily working on the API. + +This target: -## Run the stack (recommended) +* starts the supporting local services in Docker +* runs the FastAPI app on the host with reload enabled + +The frontend and supporting services run in Docker, while the API runs locally for a tighter backend loop. ```bash -docker compose up --build +make api-dev ``` -Or: +### `make dev-docker` + +Use this when you want the whole local stack running in Docker. + +This is the best choice when you want the most production-like local setup or do not need to run either app directly on the host. ```bash make dev-docker ``` -Useful local URLs: +## Which one should I use? + +A simple rule of thumb: + +* changing React/UI code: `make frontend-dev` +* changing FastAPI/backend code: `make api-dev` +* validating the whole stack together: `make dev-docker` + +## Useful local URLs + +Depending on which entrypoint you use, these are the main local endpoints: + +* Frontend: `http://localhost:3000` +* API docs: `http://localhost:8000/docs` +* Adminer: `http://localhost:8081` + +## Other useful targets + +You do not need to memorize the whole Makefile, but these are worth knowing. -- Frontend: http://localhost:3000 -- API docs: http://localhost:8000/docs -- Adminer: http://localhost:8081 +### `make check` -## Common dev commands +Runs the main verification suite in one command: -Run from repo root. +* lint +* tests +* format checks +* lockfile checks + +Use this before pushing or when you want a quick confidence pass. ```bash -make lint -make test -make format -make format-check make check ``` -Python-only: +### `make clean` + +Resets local build artifacts, caches, frontend install/build outputs, and Docker state. + +⚠️ **Warning:** this target includes `clean-docker`, which removes Docker containers **and volumes**. This will delete your local database data. + +Use this when you want a completely fresh environment. ```bash -uv run ruff check -uv run ruff format -uv run pytest deployments/api +make clean ``` -Frontend-only: +### `make reboot-docker` + +Performs a clean Docker reset and immediately brings the full stack back up with builds. + +This is a convenience target for the common “wipe it and restart everything” workflow. ```bash -npm --prefix deployments/stitch-frontend ci -npm --prefix deployments/stitch-frontend run dev -npm --prefix deployments/stitch-frontend run lint -npm --prefix deployments/stitch-frontend run test:run +make reboot-docker ``` -## Reset local DB data + +### `make follow-stack-logs` + +Follows logs for the full Docker-based local stack. + +Useful when debugging service startup or cross-service interactions. ```bash -docker compose down -v -docker compose up db api frontend +make follow-stack-logs ``` -Or: +## Common quality commands + +From the repo root: ```bash -make clean-docker -make dev-docker +make lint +make test +make format +make format-check +make lock-check +make check ``` + +## When things get weird + +A good escalation path is: + +```bash +make check +make clean +make reboot-docker +``` + +That sequence catches most local issues caused by stale caches, stale frontend installs, or stale Docker volumes. From 5e324c82e84a02fc40149aab8288e027ac504c34 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 15:54:13 +0100 Subject: [PATCH 23/26] pass log level to init container --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index c60a5f61..2f00586c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -62,6 +62,7 @@ services: env_file: - .env environment: + LOG_LEVEL: ${DBINIT_LOG_LEVEL:-info} # db-init connects as the migrator role (DDL + seed) POSTGRES_USER: stitch_migrator POSTGRES_PASSWORD: ${STITCH_MIGRATOR_PASSWORD:?STITCH_MIGRATOR_PASSWORD must be set in .env} From f3c841fcb39eac57ec1060d9a178854e90e577f1 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 15:56:34 +0100 Subject: [PATCH 24/26] Use correct envvar for super user --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2f00586c..f5257c2b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -47,7 +47,7 @@ services: env_file: - .env environment: - POSTGRES_USER: ${POSTGRES_SUPERUSER_PASSWORD:-postgres} + POSTGRES_USER: ${POSTGRES_SUPERUSER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_SUPERUSER_PASSWORD:-postgres} ports: - "5432:5432" From f40132bc18315b245c007f81898922459367d095 Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 15:59:03 +0100 Subject: [PATCH 25/26] Update Makefile Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a57a165f..2385d52b 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ py-lint: uv-dev $(RUFF) check py-test: api-test pkg-test -py-test-exact: api-test pkg-test-exact +py-test-exact: api-test-exact pkg-test-exact py-format-check: uv-dev $(RUFF) format --check From 7ad279d39eb500cf35bf8a976c5d9cdfbe45d2ef Mon Sep 17 00:00:00 2001 From: Alex Axthelm Date: Thu, 26 Mar 2026 15:59:33 +0100 Subject: [PATCH 26/26] Better error handling Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- deployments/seed/src/stitch/seed/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployments/seed/src/stitch/seed/client.py b/deployments/seed/src/stitch/seed/client.py index 6996700b..f2d2348f 100644 --- a/deployments/seed/src/stitch/seed/client.py +++ b/deployments/seed/src/stitch/seed/client.py @@ -62,8 +62,8 @@ def wait_for_api(base_url: str, retries: int = 30, delay: float = 2.0) -> None: attempt, retries, ) - except Exception as e: - logger.info(f"API not reachable ({e}), attempt {attempt}/{retries}") + except (httpx.HTTPError, OSError) as e: + logger.info("API not reachable (%s), attempt %s/%s", e, attempt, retries) time.sleep(delay)