Author SHA1 Message Date
jjbruntonandClaude Opus 5 3a019e62d3 fix(api): allow the admin console origin through CORS
The production allowlist held only https://sauci.app, so every
/v1/admin/* preflight from https://manage.sauci.app returned 204 with no
Access-Control-Allow-Origin and the browser blocked the request. Login
then reported "Access denied. You are not an administrator." because the
admin app treats any /v1/admin/me failure as a permissions failure.

Add the admin console origin and record in the README that new admin
hosts belong in the Compose contract rather than a Dokploy override.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 18:17:26 +01:00
jjbrunton 84712a950e Merge pull request #26 from jjbrunton/hotfix/admin-docker-context
fix(admin): restore admin docker build context, allow hotfix branches into main
2026-08-31 18:08:31 +01:00
jjbruntonandClaude Opus 5 d14869d745 ci(branch-policy): allow hotfix and release branches into main
The policy accepted only `staging` as a head for main, so any change
production needed before the next promotion had nowhere to go: the PR was
unmergeable by CI and branch protection blocks direct pushes.

Accept `hotfix/*` and `release/*` heads as well. The naming requirement
keeps a direct-to-main change deliberate and visible, and the master
freeze plus the "features target staging" rule are unchanged. Document
the escape hatch and the need to land the same commit on staging.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 18:03:48 +01:00
jjbruntonandClaude Opus 5 f1573f4906 fix(admin): keep admin app in the docker build context
The root .dockerignore excluded apps/admin, so the monorepo build context
dropped that workspace entirely: npm ci skipped it and
`npm run build -w @sauci/admin` failed with "No workspaces found".
The ignore file was authored for the mcp image and later extended with
re-includes for web; admin never got the same treatment.

Re-include apps/admin, and re-exclude node_modules/dist last so the
re-includes cannot pull host build artefacts into any image context.

Verified with `docker build -f apps/admin/Dockerfile .`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 18:03:48 +01:00
jjbrunton 83df3b45f8 Merge pull request #23 from jjbrunton/staging
Release v1.0.8: Expo SDK 56 and EAS Observe
2026-08-31 15:47:29 +01:00
5 changed files with 31 additions and 10 deletions

No files matched your search

+8
View File
@@ -39,3 +39,11 @@ terraform
.claude
.codex
.ralph
# The admin app builds from this same monorepo context (apps/admin/Dockerfile).
!apps/admin
!apps/admin/**
# Host build artefacts must never leak into any image context.
**/node_modules
**/dist
+7 -2
View File
@@ -24,9 +24,14 @@ jobs:
echo "master is frozen; target staging or main" >&2
exit 1
fi
if [ "$BASE_BRANCH" = "main" ] && [ "$HEAD_BRANCH" != "staging" ]; then
echo "Only staging may be promoted to main" >&2
if [ "$BASE_BRANCH" = "main" ]; then
case "$HEAD_BRANCH" in
staging|hotfix/*|release/*) ;;
*)
echo "main takes staging promotions, or a hotfix/* or release/* branch for direct work" >&2
exit 1
;;
esac
fi
if [ "$BASE_BRANCH" != "staging" ] && [ "$BASE_BRANCH" != "main" ]; then
echo "Feature pull requests target staging; promotions target main" >&2
+8 -4
View File
@@ -14,10 +14,14 @@ not deploy the retired Supabase data plane.
| `master` | frozen legacy default | none | none |
Normal feature pull requests target `staging`. After CI and authenticated staging
acceptance pass, open a promotion pull request from `staging` to `main`. Do not
add production-only commits to `main`: production should run the exact commit
already exercised in staging. Direct pushes to either deployment branch are for
explicit incident recovery only.
acceptance pass, open a promotion pull request from `staging` to `main`. Prefer
that route: production then runs the exact commit already exercised in staging.
When production needs a change that cannot wait for the next promotion, open a
pull request into `main` from a `hotfix/*` or `release/*` branch. CI enforces
that naming so a direct-to-main change is always deliberate and visible. Land
the same commit on `staging` too, or the next promotion will revert it. Direct
pushes to either deployment branch remain blocked by branch protection.
Each Dokploy Compose application is connected to `jjbrunton/Sauci`, watches its
single branch with push-triggered automatic deployment, and uses
+6 -3
View File
@@ -87,9 +87,12 @@ Before the first deployment, provide:
5. A rollback and restore point before any migrated production data is imported.
6. A separately generated `MEDIA_SIGNING_SECRET` (at least 32 characters) and
the HTTPS API origin as `MEDIA_PUBLIC_BASE_URL`.
7. The public web origin is fixed to `https://sauci.app` by
`CORS_ALLOWED_ORIGINS` in the Compose contract. Do not broaden it without a
reviewed browser client requirement.
7. Browser origins are fixed by `CORS_ALLOWED_ORIGINS` in the Compose contract:
`https://sauci.app` (public web) and `https://manage.sauci.app` (admin
console, which calls `/v1/admin/*` with a bearer token). Do not broaden the
list without a reviewed browser client requirement, and add any new admin
host here rather than as a Dokploy override, so the allowlist stays
reviewable in git.
8. A non-production hosted Auth project and disposable, onboarding-complete test
identities mapped into the staging database for authenticated mobile acceptance.
+2 -1
View File
@@ -8,7 +8,8 @@ x-common-environment: &common-environment
x-api-environment: &api-environment
<<: *common-environment
PORT: 3003
CORS_ALLOWED_ORIGINS: https://sauci.app
# https://manage.sauci.app is the admin console; it calls /v1/admin/* from the browser.
CORS_ALLOWED_ORIGINS: https://sauci.app,https://manage.sauci.app
DATABASE_POOL_MAX: ${API_DATABASE_POOL_MAX:-10}
DATABASE_POOL_IDLE_TIMEOUT_MS: ${DATABASE_POOL_IDLE_TIMEOUT_MS:-30000}
DATABASE_POOL_CONNECTION_TIMEOUT_MS: ${DATABASE_POOL_CONNECTION_TIMEOUT_MS:-10000}