From 03a16c842662ba9cd44aba0dd409e8fd402d79f2 Mon Sep 17 00:00:00 2001 From: Fluory Date: Mon, 28 Sep 2026 22:24:23 +0200 Subject: [PATCH 1/2] fix(deploy): build the AI service on Vercel only when services/ai changed (#98) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every push – main and every PR – built and pushed a new AI image, also for web-only changes, until the Hobby container registry hit its image limit and the production build of #95 failed. An ignoreCommand now skips the build unless services/ai changed since the last successful deployment (else the parent commit; if git cannot compare, it builds). The runbook names the registry limit and how to prune it. Co-Authored-By: Claude Opus 5.5 (1M context) --- CHANGELOG.md | 2 ++ docs/technical/deployment-vercel.md | 8 ++++++++ services/ai/vercel.json | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b871ada..9bb4a11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ This file records what changes **in the product** – process and session state ## [Unreleased] ### Changed +- The AI service's Vercel project builds only when something under `services/ai/` changed: fewer images in its + container registry and fewer deployments per push (#98). - A unit correction is stored like the extraction stores units: „Stk.“, „Stück“ or „Meter“ become the ERP units `pcs` and `m`; other units stay as typed. The correction field shows „Stk.“, and the audit event keeps what was typed (#96). diff --git a/docs/technical/deployment-vercel.md b/docs/technical/deployment-vercel.md index 764d012..8928eea 100644 --- a/docs/technical/deployment-vercel.md +++ b/docs/technical/deployment-vercel.md @@ -73,6 +73,14 @@ creation). The script is all-or-nothing; running it twice fails on "role already 5. `GET /healthz` → 200. The production URL → `AI_SERVICE_URL` of the web app (§4). Instances scale to zero after 5 minutes without traffic (vercel.com/docs/functions/container-images, verified 2026-09-27); the first call after that pays a cold start (measured about 5.6 s). +6. **Builds only when the service changed (#98):** `services/ai/vercel.json` sets an `ignoreCommand` that + skips the build unless something under `services/ai/` changed since the last successful deployment + (`VERCEL_GIT_PREVIOUS_SHA`, else the parent commit; if git cannot compare, it builds). Every build pushes + an image to the project's container registry, which has a maximum number of images on the Hobby plan – + when a build fails with `repository has reached the maximum allowed number of images`, prune old images + (dashboard: project `requestflow-ai` → Sandboxes → Container Registry, or `vercel vcr image ls dockerfile` + and `vercel vcr image rm dockerfile `), keeping the image of the current production deployment + and one rollback candidate. Deleting an image is permanent. ## 4. Vercel project diff --git a/services/ai/vercel.json b/services/ai/vercel.json index 2c12ed8..0f04c79 100644 --- a/services/ai/vercel.json +++ b/services/ai/vercel.json @@ -1,4 +1,5 @@ { "$schema": "https://openapi.vercel.sh/vercel.json", - "regions": ["fra1"] + "regions": ["fra1"], + "ignoreCommand": "git diff --quiet \"${VERCEL_GIT_PREVIOUS_SHA:-HEAD^}\" HEAD -- ./" } From 22b3adaf0419d7bf700ed5011d7ac37274e01cf3 Mon Sep 17 00:00:00 2001 From: Fluory Date: Mon, 28 Sep 2026 22:42:14 +0200 Subject: [PATCH 2/2] =?UTF-8?q?docs(deploy):=20address=20the=20#102=20revi?= =?UTF-8?q?ew=20=E2=80=93=20redeploy=20must=20reach=20Ready,=20honest=20sc?= =?UTF-8?q?ope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - a redeploy runs the Ignored Build Step too: after rotating a secret or the Gemini switch, redeploy without it and check Ready (CANCELED = not active) - skipped builds may still count against deployment limits: the CHANGELOG no longer promises fewer deployments - first build of a new branch compares only its last commit (AI preview may be missing); vcr commands name --project Co-Authored-By: Claude Opus 5.5 (1M context) --- CHANGELOG.md | 2 +- docs/technical/deployment-vercel.md | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bb4a11..043f339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ This file records what changes **in the product** – process and session state ### Changed - The AI service's Vercel project builds only when something under `services/ai/` changed: fewer images in its - container registry and fewer deployments per push (#98). + container registry and fewer builds. A redeploy after changing its variables must not be skipped (runbook §3.6) (#98). - A unit correction is stored like the extraction stores units: „Stk.“, „Stück“ or „Meter“ become the ERP units `pcs` and `m`; other units stay as typed. The correction field shows „Stk.“, and the audit event keeps what was typed (#96). diff --git a/docs/technical/deployment-vercel.md b/docs/technical/deployment-vercel.md index 8928eea..17dce06 100644 --- a/docs/technical/deployment-vercel.md +++ b/docs/technical/deployment-vercel.md @@ -75,12 +75,18 @@ creation). The script is all-or-nothing; running it twice fails on "role already verified 2026-09-27); the first call after that pays a cold start (measured about 5.6 s). 6. **Builds only when the service changed (#98):** `services/ai/vercel.json` sets an `ignoreCommand` that skips the build unless something under `services/ai/` changed since the last successful deployment - (`VERCEL_GIT_PREVIOUS_SHA`, else the parent commit; if git cannot compare, it builds). Every build pushes - an image to the project's container registry, which has a maximum number of images on the Hobby plan – - when a build fails with `repository has reached the maximum allowed number of images`, prune old images - (dashboard: project `requestflow-ai` → Sandboxes → Container Registry, or `vercel vcr image ls dockerfile` - and `vercel vcr image rm dockerfile `), keeping the image of the current production deployment - and one rollback candidate. Deleting an image is permanent. + (`VERCEL_GIT_PREVIOUS_SHA`, else the parent commit; if git cannot compare, it builds). A skipped build + ends as `CANCELED`; skipped builds may still count against the plan's deployment limits. A new branch + without a successful AI deployment compares only its last commit, so an AI preview may be missing there + (production is not affected). **A redeploy runs the same step:** after changing a variable of + `requestflow-ai` (§9), redeploy without the Ignored Build Step (untick it in the Redeploy dialog if offered) + and check that the deployment reaches **Ready** – `CANCELED` means the new value is not active. + Every build pushes an image to the project's container registry, which has a maximum number of images on + the Hobby plan – when a build fails with `repository has reached the maximum allowed number of images`, + prune old images (dashboard: project `requestflow-ai` → Sandboxes → Container Registry, or + `vercel vcr image ls dockerfile --project requestflow-ai` and + `vercel vcr image rm dockerfile --project requestflow-ai`), keeping the image of the current + production deployment and one rollback candidate. Deleting an image is permanent. ## 4. Vercel project @@ -173,12 +179,14 @@ run started meanwhile waits for the first and then finds the samples in place; a pause the Supabase project. - Code: Vercel "Instant Rollback" to the previous deployment. Migrations are forward-only (`docs/technical/operations.md` → Rollback); roll back code only to a version that knows the schema. -- Rotate a leaked secret in its settings page, then redeploy (Vercel reads variables at deploy time). +- Rotate a leaked secret in its settings page, then redeploy (Vercel reads variables at deploy time). For + `requestflow-ai` the redeploy must not be skipped by the Ignored Build Step (§3 step 6): check it is **Ready**. - Pause the AI service: pause the Vercel project `requestflow-ai`; uploads then end in a visible processing error with retries instead of reaching the model. - When the Gemini free-tier exception expires (ADR-0001 D11 amendment 2026-09-26, at the latest 2026-10-31): delete the key in Google AI Studio, remove `GEMINI_API_KEY` and `AI_ALLOW_GEMINI_API_DEV` - from `requestflow-ai`, then switch to the paid tier or Vertex `eu` (§3 step 4) and redeploy. + from `requestflow-ai`, then switch to the paid tier or Vertex `eu` (§3 step 4) and redeploy – **Ready**, not + skipped (§3 step 6). - Remove the showcase completely: delete both Vercel projects (`requestflow`, `requestflow-ai`) and the Supabase project – all data is synthetic, nothing has to be kept.