Lockfile-only bump from 7.14.0 -> 7.16.0. The ^7.0.0 range in
package.json already permits 7.16.0, so no source changes.
Clears three high-severity advisories that block the audit CI gate:
- GHSA-49rj-9fvp-4h2h (turbo-stream arbitrary constructor invocation)
- GHSA-2j2x-hqr9-3h42 (protocol-relative URL open redirect)
- GHSA-8x6r-g9mw-2r78 (DoS via unbounded path expansion)
No runtime behavior change; react-router stays on 7.x. npm audit
--audit-level=high exits clean (0 high/critical) locally.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per the spec for CAR-1212 (CAR-1195 follow-up):
- deploy-dev and deploy-uat now request cs_savannah as a reviewer on the
cartsnitch/infra PR (best-effort, log on non-2xx, never fail the job).
- After the merge attempt, classify the response:
* .merged == true -> success notice
* 'Does not have enough approvals' -> ::notice:: + exit 0
(GitOps approval gate, not a
failure; the PR is correctly
opened and surfaces in the CTO
queue)
* anything else -> keep the existing ::error::
and exit 1 (genuine unexpected
failure)
This unblocks the deploy jobs that were hard-failing on the branch-protection
approvals requirement, which a CI bot cannot self-satisfy. The CTO (cs_savannah)
already backstop-approves+merges these infra PRs by hand (e.g. #321, #322).
- 'No image changes to deploy' early-exit preserved.
- Still uses secrets.CI_GITEA_TOKEN for the PR/reviewer/merge API calls.
- No git push origin main: only the API path is used.
Refs CAR-1195, CAR-1194.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Set delete_branch_after_merge:true on the auto-merge POST in both
deploy-dev and deploy-uat so the per-deploy branches in
cartsnitch/infra (ci/deploy-{dev,uat}-${GITHUB_SHA}) are removed
once their overlay image-tag bump lands on main. Without this flag
every successful deploy would leave a branch behind, accumulating
in cartsnitch/infra and making future re-runs of the same SHA
un-actionable from the existing branch name.
Refs CAR-1195 (CTO fix#2).
deploy-dev and deploy-uat had CI_GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
which is the package-scoped container-registry token. PR creation and
auto-merge against cartsnitch/infra would 403 on the first real push.
Bind to secrets.CI_GITEA_TOKEN (the token the infra checkout already
uses for branch push) so the Gitea API calls have repo-write scope.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Runner pod gitea-act-runner-cartsnitch-85b5984bb-527xw has a corrupt
/root/.cache/act clone of actions/setup-node (missing dist/setup/index.js).
SHA-pinning changed the cache hash but the fresh clone on that pod still
ends up missing the dist directory.
catthehacker/ubuntu:act-latest ships Node pre-installed; the lint job only
needs ESLint + tsc, both of which are devDependencies installed by npm ci.
Removing actions/setup-node from lint bypasses the corrupt pod cache entirely
without affecting other jobs.
Refs CAR-1162
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The CI's npm audit (10.8.2) flagged three transitive vulnerabilities
that local newer-npm runs (11.x) miss due to advisory-DB divergence:
- @babel/plugin-transform-modules-systemjs: 7.29.0 -> ^7.29.4
(CVE-2026-44728: arbitrary code generation, fixed in 7.29.4)
- fast-uri: 3.1.0 -> ^3.1.2
(path traversal / host confusion via percent-encoded segments)
- brace-expansion: 5.0.5 -> >=5.0.6
(DoS via large numeric range defeating max protection)
These are non-breaking transitive updates within the same major
version. The previous override for brace-expansion (>=1.1.13) was
too loose to exclude 5.0.2-5.0.5; tightening it to >=5.0.6.
Ref CAR-1162, CAR-1122, CAR-1078
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Remove .mcp.json (scope creep, unrelated to CAR-1078)
- Bump vitest to ^4.1.8 (fixes GHSA-5xrq-8626-4rwp critical)
- Run npm audit fix for non-breaking vulns
- Pin actions/checkout and actions/setup-node to commit SHAs
in .gitea/workflows/ci.yml to force a clean cache fetch on
the act runner (workaround for corrupted /root/.cache/act cache)
Refs CAR-1162, CAR-1122, CAR-1078
email_worker calls get_async_session_factory() inside every resolve_user()
call, which creates a brand-new async engine (and thus a brand-new
connection pool) on every message. In a tight consumer loop processing
5 messages per batch, this rapidly exhausts DragonflyDB/Postgres
connection limits and manifests as ConnectionResetError.
Fix: cache the async engine in a module-level dict keyed by URL in
cartsnitch_common.database:get_async_engine(), matching the pattern
already used in receiptwitness:events.py for the Redis connection pool.
Also add pool_size=10, max_overflow=20, pool_pre_ping=True for
健壮连接管理.
Similarly, receiptwitness/queue/email.py:get_redis() was creating a new
Redis connection on every call with no pooling. Share a
ConnectionPool (max_connections=30) across all get_redis() callers.
Fixes CAR-1078
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Update deploy-dev and deploy-uat jobs to use CI_GITEA_TOKEN for
checking out the cartsnitch/infra repository instead of REGISTRY_TOKEN.
CI_GITEA_TOKEN is the org-level Actions secret configured for cross-repo
access, while REGISTRY_TOKEN continues to be used for Docker registry login.
This resolves CAR-986 by enabling CI to commit image tag updates to
the private infra repository.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Merge PR #266: Fix API crash — remove dead dispose_engine import
Removes non-existent dispose_engine import from main.py that caused ImportError and CrashLoopBackOff on API pods.
Reviewed-by: Checkout Charlie (QA PASS)
Approved-by: Savannah Savings (CTO)
ImportError: cannot import name 'dispose_engine' from 'cartsnitch_api.database'
The function does not exist and is unused - lifespan already calls close_db() directly.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
cpfarhood confirmed the Gitea registry token is configured as REGISTRY_TOKEN
(not GITEA_TOKEN). This applies to both the registry docker login steps
and the infra repo checkout steps in deploy-dev/deploy-uat.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Replace hardcoded 'cs_carl' Gitea registry username with '${{ github.actor }}' in all 5 login steps
- Use kustomize 'OLD=NEW:TAG' rename syntax so existing ghcr.io image entries are updated instead of duplicated
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Gitea's GITHUB_TOKEN authenticates against git.farh.net, not ghcr.io.
Use explicit GHCR_USERNAME and GHCR_TOKEN secrets instead.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Replace all runs-on: runners-cartsnitch with ubuntu-latest
- Remove SARIF upload steps (no Gitea Security tab)
- Replace GitHub App token with secrets.GITEA_TOKEN in deploy-dev and deploy-uat
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Exclude src/__tests__ from tsconfig to prevent test files from being
compiled during Docker build. Fixes build-and-push-auth CI failure.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Add build-and-push-auth job and update deploy-dev/uat to include auth image.
- Add AUTH_IMAGE_NAME env var
- Add build-and-push-auth job (modeled on build-and-push-api)
- Add build-and-push-auth to deploy-dev and deploy-uat needs
- Add auth image tag determination and update steps in both deploy jobs
- Update commit messages to include auth
UAT PASS (Deal Dottie, 2026-05-04) + Security PASS (Stockboy Steve, 2026-05-04)
Merged with admin privileges due to 1-commit divergence (README/UI-only release commit from PR #245 with no file overlap with uat changes). No functional conflict.
Refs: CAR-842, CAR-812
- docs: fix email address format to receipts+<token>@receipts.cartsnitch.com
(per Settings → Receipt Email UI, not the old farh.net domain format)
- docs: fix UI section label from 'Account' to 'Receipt Email'
- scripts/seed-env.sh: fix --env flag parser when called as './seed-env.sh --env uat'
positional form was already correct; flag form was consuming --env as ENV value
Co-Authored-By: Paperclip <noreply@paperclip.ing>