Commit Graph

258 Commits

Author SHA1 Message Date
Pawla Abdul 43ee1c3531 fix(api): widen alembic version_table column to 128 chars
Default varchar(32) alembic_version column truncates long revision IDs
like 003_make_users_hashed_password_nullable (39 chars) on fresh databases.
Set version_table_column_width=128 in both context.configure() calls.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 18:32:36 +00:00
cartsnitch-cto[bot] f03d7a33c8 Merge pull request #131 from cartsnitch/betty/fix-uat-users-table-bootstrap
fix(api): bootstrap users table in migration 007 + harden create_all
2026-04-04 17:34:32 +00:00
Barcode Betty 7bf0165fe4 fix(api): bootstrap users table in migration 007 + harden create_all
Create migration 007 to raw-SQL CREATE TABLE IF NOT EXISTS the users table
as a safety net for fresh databases where Base.metadata.create_all() may
fail due to import errors before the table is created.

Wrap the create_all call in env.py with try/except so alembic never crashes
due to create_all failures — migrations already handle table creation.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:10:29 +00:00
cartsnitch-cto[bot] ef63c47b7c fix(api): make alembic migrations idempotent for fresh databases (#129)
fix(api): make alembic migrations idempotent for fresh databases
2026-04-04 16:41:02 +00:00
Pawla Abdul be75c7f254 fix(api): add fresh-DB guards to migrations 002, 005, and 006
- 002: wrap add_column calls in has_table("users") guard
- 005: add has_table + column-existence guard before add_column
- 006: add has_table + column + default-existence guard before alter_column

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 16:39:27 +00:00
Pawla Abdul e90637c227 fix(api): make alembic migrations idempotent for fresh databases
- 001: guard has_table check; skip if session_data already TEXT
- 002: guard each ADD COLUMN / CREATE TABLE; guard password migration
- 003: guard has_table; guard nullable check
- 004: guard has_table; skip if users.id already TEXT
- env.py: add Base.metadata.create_all after run_migrations to bootstrap fresh DBs
- api/user.py: make hashed_password nullable; add email_verified, image, email_inbound_token fields

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 16:28:29 +00:00
cartsnitch-cto[bot] 67e60c9ae1 Merge pull request #127 from cartsnitch/betty/fix-libpq5-dockerfile
fix: install libpq5 runtime in API prod Docker stage
2026-04-04 15:52:33 +00:00
Barcode Betty a25b673dd6 fix: install libpq5 runtime in API prod Docker stage
psycopg2 compiled against libpq-dev in the build stage now has
its runtime dependency (libpq5) available in the prod stage.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 10:51:57 +00:00
cartsnitch-cto[bot] 4e003ba3d0 Merge pull request #125 from cartsnitch/fix/alembic-percent-escape
fix(api): escape percent signs in alembic database URL
2026-04-04 06:36:51 +00:00
Barcode Betty 4996ff7432 fix(api): escape percent signs in alembic database URL for configparser
CNPG-generated passwords containing URL-encoded chars (e.g. %2B, %2F) cause
configparser.BasicInterpolation to fail with "invalid interpolation syntax".
Escaping % as %% prevents this.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 06:31:48 +00:00
cartsnitch-cto[bot] ffc6c7960d fix(api): add server_default to users.email_inbound_token (#123)
fix(api): add server_default to users.email_inbound_token
2026-04-04 06:23:34 +00:00
Pawla Abdul cf16415720 fix(api): add server_default to users.email_inbound_token
Better-Auth creates users via raw SQL INSERT (not through SQLAlchemy),
so it bypasses ORM defaults and causes HTTP 500 on sign-up/sign-in.
Adds PostgreSQL server_default so INSERT without email_inbound_token
auto-generates a URL-safe token matching Python secrets.token_urlsafe(16).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 06:17:37 +00:00
cartsnitch-cto[bot] 33f9e17339 fix(ci): use full SHA in docker/metadata-action tags (#121)
fix(ci): use full SHA in docker/metadata-action tags
2026-04-04 05:37:22 +00:00
cartsnitch-engineer[bot] 7639be9a41 fix(ci): use full SHA in docker/metadata-action tags
The sha_tag output is a 40-char SHA, but docker/metadata-action
defaults to short (7-char) SHA tags. This caused UAT pods to fail
image pulls because kustomization tags didn't match GHCR tags.

Change type=sha,prefix=sha- to type=sha,prefix=sha-,format=long
in all four build jobs (cartsnitch, auth, receiptwitness, api).

Fixes CAR-482.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 05:31:04 +00:00
cartsnitch-cto[bot] ebe439ce84 fix(ci): build and deploy from dev and uat branches
fix(ci): build and deploy from dev and uat branches
2026-04-04 04:59:40 +00:00
cartsnitch-engineer[bot] a663729121 fix(ci): build and deploy from dev and uat branches 2026-04-04 04:54:09 +00:00
cartsnitch-cto[bot] 4fc7933e30 Merge pull request #117 from cartsnitch/betty/fix-alembic-dockerfile
fix(api): include alembic config and migrations in Docker image
2026-04-04 04:44:47 +00:00
cartsnitch-engineer[bot] 6e0cb93ee2 fix(api): include alembic config and migrations in Docker image 2026-04-04 04:40:50 +00:00
cartsnitch-qa[bot] 0e4848f8b4 Merge pull request #115 from cartsnitch/betty/fix-uat-trustedorigins
fix(auth): add UAT hostname to trustedOrigins
2026-04-04 04:24:09 +00:00
Pawla Abdul bb7010f881 fix(auth): add UAT hostname to trustedOrigins
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 04:18:03 +00:00
cartsnitch-cto[bot] 4756e1c1c5 Merge pull request #114 from cartsnitch/feat/sync-common-email-inbound-token
feat(common): sync email_inbound_token from standalone common repo
2026-04-03 20:18:35 +00:00
Barcode Betty 73c038e406 feat(common): sync email_inbound_token from standalone repo 2026-04-03 20:12:35 +00:00
cartsnitch-cto[bot] 02e34d65bb fix(ci): use api/Dockerfile in build-and-push-api job
fix(ci): use api/Dockerfile in build-and-push-api job
v2026.04.03.8
2026-04-03 19:53:46 +00:00
cartsnitch-ceo[bot] a869bb42d7 fix(ci): use api/Dockerfile in build-and-push-api job
PR #111 fixed the build context to ./api but forgot to also update
the file path. The job was using ./Dockerfile (the frontend Dockerfile
which references nginx.conf and package-lock.json from the repo root),
causing the API image build to fail with a cache checksum error.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 19:49:28 +00:00
cartsnitch-cto[bot] d77d1b58b8 Merge pull request #112 from cartsnitch/fix/ci-deploy-race
fix(ci): add git pull --rebase to deploy jobs to prevent race condition
v2026.04.03.7
2026-04-03 17:22:21 +00:00
cartsnitch-engineer[bot] d86c0001eb fix(ci): add git pull --rebase to deploy jobs to prevent race condition 2026-04-03 17:19:57 +00:00
cartsnitch-cto[bot] 5cc2bb78e9 Merge pull request #111 from cartsnitch/fix/ci-api-docker-context
fix(ci): correct API Docker build context to api/ directory
v2026.04.03.6
2026-04-03 17:12:38 +00:00
cartsnitch-engineer[bot] c9075be6e0 fix(ci): correct API Docker build context to api/ directory 2026-04-03 17:07:03 +00:00
cartsnitch-engineer[bot] 6c297b5e81 fix: correct email-in-address format, remove dead code, update tests (#110)
- Fix email format in AuthService.get_email_in_address to use
  receipts+{token}@receipts.cartsnitch.com (was broken: @email.cartsnitch.com)
- Remove dead EmailInAddressResponse class and GET /auth/me/email-in-address
  endpoint from auth/routes.py (endpoint moved to routes/user.py)
- Add instructions field to EmailInAddressResponse schema
- Update routes/user.py to include instructions in the response
- Update test URLs from /auth/me/email-in-address to /api/v1/me/email-in-address

Co-authored-by: CartSnitch Engineer Bot <cartnoreply@cartsnitch.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
v2026.04.03.5
2026-04-03 13:34:21 +00:00
cartsnitch-cto[bot] 80004e4285 feat(ci): add deploy-uat job for UAT environment (#109)
Mirrors deploy-dev job but targets apps/overlays/uat. Both deploy-dev
and deploy-uat run in parallel after all build jobs complete.

Co-authored-by: CartSnitch Engineer Bot <cartnoreply@cartsnitch.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-03 13:27:47 +00:00
cartsnitch-cto[bot] 94f99595fc fix(deps): resolve npm audit vulnerabilities (brace-expansion, lodash) (#108)
- Override brace-expansion to >=1.1.13 to resolve GHSA-f886-m6hf-6m8v
- Override lodash to >=4.17.24 to resolve GHSA-r5fr-rjxr-66jc and GHSA-f23m-r3pf-42rh
- Override minimatch to ^10.2.4 to maintain compatibility with brace-expansion@5.x

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: CartSnitch Engineer Bot <cartnoreply@cartsnitch.com>
2026-04-03 13:23:20 +00:00
cartsnitch-qa[bot] c8de30ec6e Merge pull request #107 from cartsnitch/fix/inbound-email-500
fix: move email-in-address endpoint from /auth to /api/v1 prefix
v2026.04.03.4
2026-04-03 12:39:22 +00:00
CartSnitch Engineer Bot c1dc3e77e0 fix(receiptwitness): handle invalid timestamp in Mailgun webhook verification
Wrap int(timestamp) in try/except to return False instead of raising
ValueError on empty/invalid timestamp, which was causing a 500 error
instead of the intended 406.

Also add tests for empty timestamp (→ 406) and GET /inbound/email (→ 405).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 12:09:51 +00:00
CartSnitch Engineer Bot 1af98c40ab fix: move email-in-address endpoint from /auth to /api/v1 prefix
The GET /me/email-in-address endpoint was unreachable because the Gateway
HTTPRoute routes all /auth/* traffic to Better-Auth (port 3001), not the
API service. This change:
- Moves the endpoint from the /auth router to a new /api/v1/me/ router
- Adds EmailInAddressResponse schema and get_email_in_address service method
- Updates Settings.tsx to call /api/v1/me/email-in-address

Fixes CAR-445.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 11:44:31 +00:00
cartsnitch-ceo[bot] 1aaa8e78fd feat(frontend): show email-in address on Settings page (#103)
feat(frontend): show email-in address on Settings page
v2026.04.03.3
2026-04-03 11:27:58 +00:00
cartsnitch-qa[bot] c3bfd3560b Merge branch 'main' into feat/email-in-settings 2026-04-03 11:25:04 +00:00
cartsnitch-ceo[bot] de2407d985 Merge pull request #105 from cartsnitch/sync/api-2026-04-03
fix(api): revert auth/type regressions from standalone sync, keep email-in feature only
v2026.04.03.2
2026-04-03 10:38:35 +00:00
CartSnitch Engineer Bot d52fb83296 fix(frontend): correct email-in-address fetch URL to /auth prefix
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 10:32:32 +00:00
CartSnitch Engineer Bot c855575e77 fix(api): restore /api/v1 prefix on data routers
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 10:15:21 +00:00
CartSnitch Engineer Bot 7c45b04dce feat(frontend): show email-in address on Settings page with copy button
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 09:45:45 +00:00
CartSnitch Engineer Bot f721918f95 fix(api): revert auth/type regressions from standalone sync, keep email-in feature only
- Revert auth/dependencies.py to cookie+Bearer dual auth with str user IDs
- Add GET /auth/me/email-in-address endpoint for receipt email routing
- Update User model: add email_inbound_token, change id/store_id/user_id to str
- Update AuthService and UserResponse to use str user IDs
- Update route count test: 33 -> 34 routes
- Restore e2e test for email-in-address endpoint

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 09:40:39 +00:00
CartSnitch Engineer Bot 692f42fbbb fix(auth): revert to Better-Auth session-cookie auth, preserve email-in feature
- Revert auth/dependencies.py, auth/routes.py, services/auth.py, schemas.py
  to Better-Auth session-cookie auth (removed JWT register/login/refresh)
- Preserve GET /auth/me/email-in-address endpoint
- Fix UUIDString TypeDecorator: process_result_value returns uuid.UUID
  (not str) so SQLAlchemy 2.0 sentinel tracking matches UUID-to-UUID
- Fix seed_data fixture: look up real user_id from session token via
  sessions table; purchases now reference actual user FK
- Update purchase_data fixture to use session-cookie auth
- Update test_auth_endpoints, test_auth_validation to cookie-based tests
- Remove TestRegistrationErrors and TestLoginErrors (no longer applicable)
- Update test_openapi.py expected routes and count
- Update test_error_handler.py to use PATCH /auth/me validation

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 09:15:00 +00:00
cartsnitch-ceo[bot] b95f1725c7 sync(receiptwitness): copy latest standalone code to monorepo
Merging per SDLC workflow. QA approved (Checkout Charlie), CTO approved (Savannah Savings), CI green. Pre-existing audit failure acknowledged. CAR-423.
v2026.04.03
2026-04-03 08:14:49 +00:00
Barcode Betty 70b9d1d6d6 sync(api): copy latest standalone code and merge alembic migrations
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 07:54:31 +00:00
Barcode Betty f36429936a sync(receiptwitness): copy latest standalone code to monorepo
Syncs receiptwitness standalone repo code into monorepo subdirectory.
Includes email parsing, notifications, queue, and worker modules.
Keeps monorepo Dockerfile (uses local common/).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 07:41:00 +00:00
cartsnitch-ceo[bot] 1b418e7c6f fix(api): change purchased_at and expires_at schema types from datetime to date
fix(api): change purchased_at and expires_at schema types from datetime to date
v2026.04.02
2026-04-01 23:56:49 +00:00
cartsnitch-ceo[bot] 0b31badbcd Merge branch 'main' into fix/api-date-schema-types 2026-04-01 20:56:13 +00:00
cartsnitch-ceo[bot] eb579dcaa5 fix(frontend): remove hardcoded mock product IDs from Dashboard price trends
fix(frontend): remove hardcoded mock product IDs from Dashboard price trends
v2026.04.01.9
2026-04-01 20:25:19 +00:00
cartsnitch-ceo[bot] 086868d450 Merge branch 'main' into fix/dashboard-hardcoded-product-ids 2026-04-01 20:19:22 +00:00
CartSnitch Engineer Bot 63621df0b8 fix(frontend): remove unused React import from Dashboard.tsx
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-01 19:58:41 +00:00