488 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c2fb7d61f7 |
feat(invoices): generate GST invoices for AI credit purchases
All checks were successful
build-and-release / build (developers) (push) Successful in 1m41s
build-and-release / build (catering-services) (push) Successful in 1m58s
build-and-release / build (companies) (push) Successful in 2m0s
build-and-release / build (cron) (push) Successful in 2m8s
build-and-release / build (customers) (push) Successful in 2m42s
build-and-release / build (gateway) (push) Successful in 1m2s
build-and-release / build (fitness-trainers) (push) Successful in 1m34s
build-and-release / build (jobs) (push) Successful in 44s
build-and-release / build (employees) (push) Successful in 1m50s
build-and-release / build (graphic-designers) (push) Successful in 2m41s
build-and-release / build (makeup-artists) (push) Successful in 1m49s
build-and-release / build (job-seekers) (push) Successful in 3m2s
build-and-release / build (photographers) (push) Successful in 2m40s
build-and-release / build (payments) (push) Successful in 2m50s
build-and-release / build (social-media-managers) (push) Successful in 2m55s
backend-integration-tests / ai-credits (push) Successful in 52s
build-and-release / build (ugc-content-creators) (push) Successful in 2m37s
build-and-release / build (tutors) (push) Successful in 2m56s
build-and-release / build (video-editors) (push) Successful in 2m41s
build-and-release / build (users) (push) Successful in 4m44s
AI credit purchases (money -> credits via PayU) never generated an invoice, even though the exact same infrastructure already works for TraceCoin purchases in main.rs's generate_purchase_invoice. Spending credits (try_reserve_credits/capture) correctly does NOT get an invoice - only real-money purchases do, matching existing TraceCoin behavior. - invoices.payment_id had a hard FK to payments(id) only, which blocks using it for ai_credit_orders(id) rows. Postgres has no polymorphic FK; dropped the constraint (invoice_type already says which table payment_id points into) via a new migration rather than editing the original invoices migration. - Added generate_ai_credit_invoice in ai_credits.rs, called from verify_order after a successful PayU payment - mirrors main.rs's pattern exactly (same non-blocking failure handling, same seller details via the now pub(crate) seller_details(), invoice_type 'AI_CREDIT_PURCHASE'). - Caught a real bug while writing this: order.amount_inr is the POST-discount final price, but NewInvoice.discount_amount is subtracted again inside compute_totals (subtotal - discount) - using amount_inr directly as unit_price_paise would have double-subtracted the discount. Reconstructed the pre-discount price (amount_inr + discount_applied) for the line item instead. Applied the FK-drop migration to nxtgauge_test and prod; verified the constraint is gone and user_id's FK is untouched. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
65262e842c |
fix(db): add missing ai_credit_orders columns + ai_coupons tables
All checks were successful
build-and-release / build (cron) (push) Successful in 1m0s
build-and-release / build (catering-services) (push) Successful in 1m53s
build-and-release / build (companies) (push) Successful in 2m2s
build-and-release / build (employees) (push) Successful in 2m17s
build-and-release / build (developers) (push) Successful in 2m32s
build-and-release / build (customers) (push) Successful in 2m39s
build-and-release / build (gateway) (push) Successful in 1m4s
build-and-release / build (fitness-trainers) (push) Successful in 2m38s
build-and-release / build (graphic-designers) (push) Successful in 1m49s
build-and-release / build (makeup-artists) (push) Successful in 1m37s
build-and-release / build (jobs) (push) Successful in 1m44s
build-and-release / build (job-seekers) (push) Successful in 2m57s
build-and-release / build (social-media-managers) (push) Successful in 1m43s
build-and-release / build (payments) (push) Successful in 2m47s
backend-integration-tests / ai-credits (push) Successful in 52s
build-and-release / build (photographers) (push) Successful in 2m57s
build-and-release / build (ugc-content-creators) (push) Successful in 2m31s
build-and-release / build (tutors) (push) Successful in 2m53s
build-and-release / build (video-editors) (push) Successful in 2m33s
build-and-release / build (users) (push) Successful in 4m52s
20260814000000: add coupon_code + discount_applied to ai_credit_orders CREATE TABLE — create_order inserts both columns but the original migration omitted them. 20260814020000 (new): create ai_coupons + ai_coupon_redemptions, the tables referenced by create_order/verify_order in ai_credits.rs. Extracted from the skipped 20260706300000 migration which couldn't be enabled because it referenced ai_credit_orders before that table existed. Runbook updated with the 3 pending prod migrations and redeploy step. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
41b17baa14 |
feat(ai-credits): role-scoped purchasable credit packages
All checks were successful
build-and-release / build (catering-services) (push) Successful in 1m25s
build-and-release / build (cron) (push) Successful in 1m50s
build-and-release / build (customers) (push) Successful in 1m55s
build-and-release / build (companies) (push) Successful in 2m0s
build-and-release / build (developers) (push) Successful in 2m22s
build-and-release / build (employees) (push) Successful in 2m34s
build-and-release / build (fitness-trainers) (push) Successful in 1m41s
build-and-release / build (gateway) (push) Successful in 1m32s
build-and-release / build (graphic-designers) (push) Successful in 2m3s
build-and-release / build (job-seekers) (push) Successful in 2m4s
build-and-release / build (jobs) (push) Successful in 2m7s
build-and-release / build (payments) (push) Successful in 1m45s
build-and-release / build (makeup-artists) (push) Successful in 2m42s
build-and-release / build (tutors) (push) Successful in 1m42s
build-and-release / build (photographers) (push) Successful in 2m45s
backend-integration-tests / ai-credits (push) Successful in 50s
build-and-release / build (social-media-managers) (push) Successful in 2m39s
build-and-release / build (ugc-content-creators) (push) Successful in 2m40s
build-and-release / build (video-editors) (push) Successful in 2m42s
build-and-release / build (users) (push) Successful in 4m38s
Adds applicable_roles TEXT[] to ai_credit_packages (empty = visible to
every role, matching today's behavior for the 4 existing packages -
nothing changes for them until an admin opts them into specific
roles). Mirrors pricing_packages' existing role_key convention, as an
array since one AI package can reasonably apply to several roles at
once.
- GET /api/ai-credits (list_packages) now accepts optional auth (via a
local MaybeAuthUser wrapper, since AuthUser doesn't implement axum's
optional-extraction trait) and filters out packages not applicable
to the viewer's roles. Anonymous viewers only see role-unrestricted
packages.
- POST /api/ai-credits/order (create_order) re-validates role
eligibility server-side too, not just in the listing - closes off
a logged-in user buying a package never shown to them.
- Admin CRUD (GET/POST /api/admin/ai-credits/packages,
PATCH .../{id}) now reads/writes applicable_roles.
Applied to nxtgauge_test and prod; verified column + index created,
existing 4 packages default to empty (all roles).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
57146b2e19 |
Merge remote-tracking branch 'origin/high-performance' into high-performance
Some checks failed
build-and-release / build (cron) (push) Successful in 59s
build-and-release / build (catering-services) (push) Successful in 1m34s
build-and-release / build (companies) (push) Successful in 2m15s
build-and-release / build (employees) (push) Successful in 2m15s
build-and-release / build (customers) (push) Successful in 2m18s
build-and-release / build (gateway) (push) Successful in 1m1s
build-and-release / build (developers) (push) Successful in 2m49s
build-and-release / build (jobs) (push) Successful in 41s
build-and-release / build (fitness-trainers) (push) Successful in 2m38s
build-and-release / build (graphic-designers) (push) Successful in 1m56s
build-and-release / build (makeup-artists) (push) Successful in 1m41s
build-and-release / build (job-seekers) (push) Successful in 3m5s
build-and-release / build (photographers) (push) Successful in 2m33s
build-and-release / build (payments) (push) Successful in 2m46s
build-and-release / build (video-editors) (push) Has been cancelled
build-and-release / build (users) (push) Has been cancelled
build-and-release / build (ugc-content-creators) (push) Has been cancelled
build-and-release / build (social-media-managers) (push) Has been cancelled
build-and-release / build (tutors) (push) Has been cancelled
backend-integration-tests / ai-credits (push) Has been cancelled
|
||
|
|
8e4d64d33b |
fix(db): correct ai_credit_packages pricing (paise not rupees), add missing ai_credit_orders table
Discovered while wiring up role-scoped AI credit packages: the active seed migration (20260615060600) stored price_inr as 99/349/999/2499 - values that read like whole rupees, but every consumer (PayU's paise_to_rupee_string, matching pricing_packages' existing paise convention) treats price_inr as paise, meaning a real purchase would have charged ~1% of the intended price. The actual fix already existed as 20260705110000_ai_credit_packages .up.sql.skip (correct paise values + the ai_credit_orders table create_order inserts into) but got disabled in the same bulk skip pass as everything else this session has been un-tangling - its CREATE TABLE ai_credit_packages (no IF NOT EXISTS) hit 'relation already exists' since 20260615060600 had already created it, aborting before ai_credit_orders was ever created. Net effect before this fix: buying AI credits was completely broken (create_order would 500 - no ai_credit_orders table to insert into). Confirmed zero rows anywhere in ai_credit_orders (the table simply didn't exist) - nothing to reconcile, this is a pre-launch fix. New migration (not resurrecting the old .skip file, to keep a clean linear history matching this session's other fixes): UPDATE the 4 known-wrong rows by name to their correct paise values, CREATE TABLE IF NOT EXISTS ai_credit_orders. Applied to both nxtgauge_test and prod; verified. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
0e2bbd34eb |
docs: mark DB migrations as completed in runbook
All checks were successful
build-and-release / build (cron) (push) Successful in 4s
build-and-release / build (employees) (push) Successful in 4s
build-and-release / build (fitness-trainers) (push) Successful in 5s
build-and-release / build (gateway) (push) Successful in 7s
build-and-release / build (developers) (push) Successful in 17s
build-and-release / build (companies) (push) Successful in 19s
build-and-release / build (catering-services) (push) Successful in 21s
build-and-release / build (customers) (push) Successful in 20s
build-and-release / build (graphic-designers) (push) Successful in 7s
build-and-release / build (job-seekers) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 7s
build-and-release / build (makeup-artists) (push) Successful in 7s
build-and-release / build (photographers) (push) Successful in 6s
build-and-release / build (payments) (push) Successful in 11s
build-and-release / build (tutors) (push) Successful in 7s
build-and-release / build (social-media-managers) (push) Successful in 11s
build-and-release / build (ugc-content-creators) (push) Successful in 7s
build-and-release / build (users) (push) Successful in 7s
build-and-release / build (video-editors) (push) Successful in 7s
backend-integration-tests / ai-credits (push) Successful in 10s
All four DB tasks confirmed applied to production (2026-08-13): - wallet_full migration re-enabled - ai_credits_wallet migration rewritten as idempotent and applied - TIMESTAMP → TIMESTAMPTZ fix for 9 AI table columns - nxtgauge_test DB + Forgejo CI secret wired Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
eefc0457be |
fix(test): use a fresh random user per ai_credits_reaper.rs run
All checks were successful
build-and-release / build (catering-services) (push) Successful in 1m31s
build-and-release / build (cron) (push) Successful in 1m54s
build-and-release / build (companies) (push) Successful in 2m7s
build-and-release / build (customers) (push) Successful in 2m53s
build-and-release / build (fitness-trainers) (push) Successful in 1m29s
build-and-release / build (developers) (push) Successful in 1m43s
build-and-release / build (gateway) (push) Successful in 1m35s
build-and-release / build (employees) (push) Successful in 2m15s
build-and-release / build (jobs) (push) Successful in 1m10s
build-and-release / build (graphic-designers) (push) Successful in 2m9s
build-and-release / build (makeup-artists) (push) Successful in 1m35s
build-and-release / build (photographers) (push) Successful in 1m44s
build-and-release / build (job-seekers) (push) Successful in 3m8s
build-and-release / build (payments) (push) Successful in 2m45s
build-and-release / build (social-media-managers) (push) Successful in 2m35s
backend-integration-tests / ai-credits (push) Successful in 50s
build-and-release / build (tutors) (push) Successful in 3m10s
build-and-release / build (ugc-content-creators) (push) Successful in 2m49s
build-and-release / build (video-editors) (push) Successful in 2m48s
build-and-release / build (users) (push) Successful in 4m38s
The fixed UUID (33333333-...) meant every re-run against the same persistent test database reused the same wallet - any earlier partial run that panicked before its own capture/release step left reserved_credits permanently stuck above zero, so this run's fresh reserve (expected to bring it to exactly 4) actually reads 8, 12, etc. depending on how many times the suite had previously failed midway. Matches ai_credits.rs's make_user() pattern (Uuid::new_v4()) instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
85690b3002 |
fix(test): make ai_credits_reaper.rs resilient to accumulated stale holds
Some checks failed
build-and-release / build (catering-services) (push) Successful in 1m30s
build-and-release / build (employees) (push) Successful in 1m42s
build-and-release / build (cron) (push) Successful in 2m11s
build-and-release / build (companies) (push) Successful in 2m16s
build-and-release / build (gateway) (push) Successful in 39s
build-and-release / build (developers) (push) Successful in 2m49s
build-and-release / build (customers) (push) Successful in 3m0s
build-and-release / build (graphic-designers) (push) Successful in 1m36s
build-and-release / build (jobs) (push) Successful in 1m46s
build-and-release / build (fitness-trainers) (push) Successful in 2m54s
build-and-release / build (job-seekers) (push) Successful in 2m17s
build-and-release / build (photographers) (push) Successful in 1m43s
build-and-release / build (payments) (push) Successful in 2m45s
build-and-release / build (makeup-artists) (push) Successful in 3m6s
build-and-release / build (social-media-managers) (push) Successful in 2m34s
backend-integration-tests / ai-credits (push) Failing after 1m7s
build-and-release / build (tutors) (push) Successful in 2m46s
build-and-release / build (ugc-content-creators) (push) Successful in 3m1s
build-and-release / build (users) (push) Has been cancelled
build-and-release / build (video-editors) (push) Has been cancelled
The sweep query is intentionally global (matches the real cron reaper), but against a persistent, never-reset test database re-run many times over a debugging session, other tests' un-captured/ un-released reservations eventually go stale and get picked up alongside this test's own hold, breaking the exact-match assertion (observed: 6 expired holds instead of 1). Clear pre-existing stale 'held' rows first, matching the clean slate a continuously-running production reaper would actually maintain. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
b48a1dd204 |
fix(test): self-provision the fixture user in ai_credits_reaper.rs
Some checks failed
build-and-release / build (cron) (push) Successful in 1m0s
build-and-release / build (catering-services) (push) Successful in 1m29s
build-and-release / build (companies) (push) Successful in 1m52s
build-and-release / build (customers) (push) Successful in 2m13s
build-and-release / build (employees) (push) Successful in 2m20s
build-and-release / build (gateway) (push) Successful in 1m1s
build-and-release / build (developers) (push) Successful in 3m9s
build-and-release / build (fitness-trainers) (push) Successful in 2m50s
build-and-release / build (job-seekers) (push) Successful in 1m54s
build-and-release / build (jobs) (push) Successful in 1m55s
build-and-release / build (graphic-designers) (push) Successful in 2m38s
build-and-release / build (makeup-artists) (push) Successful in 2m59s
build-and-release / build (photographers) (push) Successful in 1m52s
build-and-release / build (payments) (push) Successful in 2m45s
backend-integration-tests / ai-credits (push) Failing after 51s
build-and-release / build (social-media-managers) (push) Successful in 2m40s
build-and-release / build (tutors) (push) Successful in 2m51s
build-and-release / build (ugc-content-creators) (push) Successful in 2m53s
build-and-release / build (video-editors) (push) Has been cancelled
build-and-release / build (users) (push) Has been cancelled
expired_hold_is_swept_and_credits_return_to_available used a hardcoded UUID assuming a matching users row already existed in whatever database it ran against, but user_ai_subscriptions.user_id has a FK to users(id) - against a fresh database (like CI's nxtgauge_test) this failed with a foreign key violation before the actual sweep/release logic under test ever ran. Provision it inline instead, matching ai_credits.rs's make_user() pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
1af10420ce |
fix(db): convert ai_credits timestamp columns to TIMESTAMPTZ
Some checks failed
build-and-release / build (cron) (push) Successful in 57s
build-and-release / build (customers) (push) Successful in 1m54s
build-and-release / build (employees) (push) Successful in 2m11s
build-and-release / build (companies) (push) Successful in 2m27s
build-and-release / build (catering-services) (push) Successful in 2m28s
build-and-release / build (gateway) (push) Successful in 48s
build-and-release / build (developers) (push) Successful in 3m3s
build-and-release / build (jobs) (push) Successful in 43s
build-and-release / build (fitness-trainers) (push) Successful in 2m36s
build-and-release / build (makeup-artists) (push) Successful in 1m45s
build-and-release / build (graphic-designers) (push) Successful in 2m38s
build-and-release / build (job-seekers) (push) Successful in 2m28s
build-and-release / build (photographers) (push) Successful in 2m34s
build-and-release / build (social-media-managers) (push) Successful in 2m34s
build-and-release / build (payments) (push) Successful in 3m20s
backend-integration-tests / ai-credits (push) Failing after 44s
build-and-release / build (tutors) (push) Successful in 2m41s
build-and-release / build (video-editors) (push) Has been cancelled
build-and-release / build (users) (push) Has been cancelled
build-and-release / build (ugc-content-creators) (push) Successful in 2m41s
9 columns across ai_plans/user_ai_subscriptions/ai_feature_costs/ ai_usage_logs were TIMESTAMP (no timezone), left over from whatever pre-20260703210000 mechanism originally created these 4 tables, but crates/db/src/models/ai_credits.rs maps all of them to DateTime<Utc>, which sqlx requires TIMESTAMPTZ for. This is a live bug, not just a test-setup gap - discovered via crates/db/tests/ai_credits.rs failing with ColumnDecode errors, but any production code path selecting these columns (e.g. current_period_start/end on every wallet read) would hit the same failure. ALTER COLUMN ... USING col AT TIME ZONE 'UTC' is lossless here since every write path uses NOW()/DEFAULT NOW() with no other timezone handling anywhere in the codebase. Applied to both nxtgauge_test and the live nxtgauge database directly; verified all 9 columns converted and the 3 existing user_ai_subscriptions + 4 ai_plans rows' values are intact and correctly interpreted as UTC afterward. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
675a5a12c5 |
chore: trigger ai-credits CI re-run with seeded test data
Some checks failed
build-and-release / build (catering-services) (push) Successful in 13s
build-and-release / build (cron) (push) Successful in 13s
build-and-release / build (companies) (push) Successful in 16s
build-and-release / build (customers) (push) Successful in 28s
build-and-release / build (fitness-trainers) (push) Successful in 19s
build-and-release / build (graphic-designers) (push) Successful in 18s
build-and-release / build (gateway) (push) Successful in 27s
build-and-release / build (jobs) (push) Successful in 15s
build-and-release / build (makeup-artists) (push) Successful in 13s
build-and-release / build (job-seekers) (push) Successful in 29s
build-and-release / build (payments) (push) Successful in 20s
build-and-release / build (social-media-managers) (push) Successful in 13s
build-and-release / build (photographers) (push) Successful in 26s
build-and-release / build (ugc-content-creators) (push) Successful in 14s
build-and-release / build (users) (push) Successful in 14s
build-and-release / build (video-editors) (push) Successful in 14s
build-and-release / build (tutors) (push) Successful in 36s
build-and-release / build (employees) (push) Failing after 1m34s
build-and-release / build (developers) (push) Failing after 1m45s
backend-integration-tests / ai-credits (push) Failing after 54s
|
||
|
|
9605636c7f |
chore: re-trigger ai-credits CI now that nxtgauge_test has the free plan seeded
Some checks failed
backend-integration-tests / ai-credits (push) Waiting to run
build-and-release / build (companies) (push) Successful in 5s
build-and-release / build (developers) (push) Successful in 7s
build-and-release / build (cron) (push) Successful in 8s
build-and-release / build (employees) (push) Successful in 9s
build-and-release / build (fitness-trainers) (push) Has been cancelled
build-and-release / build (catering-services) (push) Successful in 12s
build-and-release / build (customers) (push) Successful in 13s
build-and-release / build (graphic-designers) (push) Successful in 7s
build-and-release / build (gateway) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 6s
build-and-release / build (job-seekers) (push) Successful in 9s
build-and-release / build (payments) (push) Successful in 7s
build-and-release / build (photographers) (push) Successful in 7s
build-and-release / build (makeup-artists) (push) Successful in 11s
build-and-release / build (social-media-managers) (push) Successful in 6s
build-and-release / build (ugc-content-creators) (push) Successful in 7s
build-and-release / build (users) (push) Successful in 7s
build-and-release / build (tutors) (push) Successful in 12s
build-and-release / build (video-editors) (push) Successful in 11s
pg_dump --schema-only (used to create nxtgauge_test) only copies structure, not data - the 'free' plan row that 20260703210000's own INSERT seeds only existed in prod. Applied that migration to nxtgauge_test directly to seed it there too. |
||
|
|
1106b0cb8c |
fix: remove invalid trailing line from Dockerfile.test
Some checks failed
build-and-release / build (customers) (push) Successful in 23s
build-and-release / build (catering-services) (push) Successful in 29s
build-and-release / build (developers) (push) Successful in 34s
build-and-release / build (companies) (push) Successful in 41s
build-and-release / build (gateway) (push) Successful in 13s
build-and-release / build (fitness-trainers) (push) Successful in 28s
build-and-release / build (jobs) (push) Successful in 13s
build-and-release / build (job-seekers) (push) Successful in 23s
build-and-release / build (makeup-artists) (push) Successful in 15s
build-and-release / build (graphic-designers) (push) Successful in 40s
build-and-release / build (social-media-managers) (push) Successful in 12s
build-and-release / build (photographers) (push) Successful in 22s
build-and-release / build (tutors) (push) Successful in 21s
build-and-release / build (employees) (push) Failing after 1m40s
build-and-release / build (cron) (push) Failing after 1m42s
build-and-release / build (users) (push) Successful in 20s
build-and-release / build (payments) (push) Successful in 57s
build-and-release / build (video-editors) (push) Successful in 20s
backend-integration-tests / ai-credits (push) Failing after 41s
build-and-release / build (ugc-content-creators) (push) Successful in 1m10s
My own previous trivial-touch commit appended a bare '-- ...' line
without a # prefix, which isn't valid Dockerfile syntax and broke the
buildx parse ('unknown instruction: --') - explains why the last CI
run died immediately again despite the actual fix (corrected password)
being in place.
|
||
|
|
f2ee346a37 |
chore: trivial touch to Dockerfile.test to trigger a real ai-credits CI run
Some checks failed
build-and-release / build (cron) (push) Successful in 27s
build-and-release / build (employees) (push) Successful in 33s
build-and-release / build (companies) (push) Successful in 43s
build-and-release / build (developers) (push) Successful in 52s
build-and-release / build (fitness-trainers) (push) Successful in 29s
build-and-release / build (gateway) (push) Successful in 27s
build-and-release / build (graphic-designers) (push) Successful in 35s
build-and-release / build (jobs) (push) Successful in 28s
build-and-release / build (makeup-artists) (push) Successful in 28s
build-and-release / build (job-seekers) (push) Successful in 46s
build-and-release / build (photographers) (push) Successful in 24s
build-and-release / build (payments) (push) Successful in 37s
build-and-release / build (customers) (push) Failing after 2m0s
build-and-release / build (catering-services) (push) Failing after 2m3s
build-and-release / build (social-media-managers) (push) Successful in 33s
build-and-release / build (ugc-content-creators) (push) Successful in 23s
backend-integration-tests / ai-credits (push) Failing after 9s
build-and-release / build (tutors) (push) Successful in 44s
build-and-release / build (users) (push) Successful in 38s
build-and-release / build (video-editors) (push) Successful in 34s
|
||
|
|
786ad41bd8 |
chore: re-trigger ai-credits CI with corrected TEST_DATABASE_URL password
All checks were successful
build-and-release / build (developers) (push) Successful in 9s
build-and-release / build (companies) (push) Successful in 12s
build-and-release / build (cron) (push) Successful in 16s
build-and-release / build (catering-services) (push) Successful in 19s
build-and-release / build (employees) (push) Successful in 16s
build-and-release / build (fitness-trainers) (push) Successful in 8s
build-and-release / build (gateway) (push) Successful in 7s
build-and-release / build (customers) (push) Successful in 20s
build-and-release / build (graphic-designers) (push) Successful in 6s
build-and-release / build (jobs) (push) Successful in 5s
build-and-release / build (makeup-artists) (push) Successful in 6s
build-and-release / build (job-seekers) (push) Successful in 11s
build-and-release / build (photographers) (push) Successful in 5s
build-and-release / build (payments) (push) Successful in 11s
build-and-release / build (social-media-managers) (push) Successful in 5s
build-and-release / build (ugc-content-creators) (push) Successful in 5s
build-and-release / build (video-editors) (push) Successful in 6s
build-and-release / build (tutors) (push) Successful in 11s
build-and-release / build (users) (push) Successful in 11s
backend-integration-tests / ai-credits (push) Successful in 5s
Discovered POSTGRES_PASSWORD env var on the postgres pod itself is stale/unused for network auth - pg_hba.conf only trusts it for local socket connections (no password check at all there). The real scram-sha-256 password the live app pods actually use over the network lives in the nxtgauge-backend-rust-secrets K8s secret's DATABASE_URL key. Used that instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
c307ef1ba4 |
fix(ci): run ai_credits tests via buildx build, not runtime apt-get/docker run -v
Some checks failed
build-and-release / build (catering-services) (push) Successful in 17s
build-and-release / build (companies) (push) Successful in 30s
build-and-release / build (cron) (push) Successful in 37s
build-and-release / build (developers) (push) Successful in 27s
build-and-release / build (fitness-trainers) (push) Successful in 31s
build-and-release / build (graphic-designers) (push) Successful in 15s
build-and-release / build (job-seekers) (push) Successful in 11s
build-and-release / build (makeup-artists) (push) Successful in 9s
build-and-release / build (payments) (push) Successful in 10s
build-and-release / build (gateway) (push) Successful in 42s
build-and-release / build (photographers) (push) Successful in 14s
build-and-release / build (social-media-managers) (push) Successful in 13s
build-and-release / build (tutors) (push) Successful in 15s
build-and-release / build (ugc-content-creators) (push) Successful in 15s
build-and-release / build (customers) (push) Failing after 1m46s
build-and-release / build (employees) (push) Successful in 2m0s
backend-integration-tests / ai-credits (push) Failing after 58s
build-and-release / build (jobs) (push) Successful in 1m56s
build-and-release / build (video-editors) (push) Successful in 1m34s
build-and-release / build (users) (push) Successful in 2m53s
The bare bookworm runner image has no apt-get/package manager at all (the earlier build-essential install attempt failed with 'apt-get: command not found'), and a plain 'docker run -v $PWD:/workspace' wouldn't work either - DOCKER_HOST points at the sibling dind engine (same nested-container setup build.yaml's own comments describe), so a bind mount would look for the path on the wrong filesystem. Matches build.yaml's actual working pattern instead: docker buildx build with context transfer (not a volume mount), using a Dockerfile (Dockerfile.test) whose RUN step runs the test suite and fails the build on a non-zero exit. TEST_DATABASE_URL passed via buildx --secret (not --build-arg) so it never lands in image layer history. Isolated this by testing each piece of the original workflow independently (env/secrets, id+GITHUB_OUTPUT, if: conditionals all checked out fine one at a time) until apt-get was confirmed as the actual failure point. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
a0a4259d50 |
debug: test apt-get network access in isolation
Some checks failed
build-and-release / build (cron) (push) Successful in 8s
build-and-release / build (companies) (push) Successful in 16s
build-and-release / build (customers) (push) Successful in 17s
build-and-release / build (developers) (push) Successful in 14s
build-and-release / build (employees) (push) Successful in 10s
build-and-release / build (fitness-trainers) (push) Successful in 12s
build-and-release / build (gateway) (push) Successful in 24s
build-and-release / build (graphic-designers) (push) Successful in 32s
build-and-release / build (job-seekers) (push) Successful in 34s
build-and-release / build (jobs) (push) Successful in 25s
build-and-release / build (photographers) (push) Successful in 11s
build-and-release / build (social-media-managers) (push) Successful in 10s
build-and-release / build (makeup-artists) (push) Successful in 33s
build-and-release / build (tutors) (push) Successful in 12s
build-and-release / build (ugc-content-creators) (push) Successful in 11s
build-and-release / build (catering-services) (push) Successful in 1m42s
backend-integration-tests / ai-credits (push) Failing after 4s
build-and-release / build (users) (push) Successful in 1m58s
build-and-release / build (payments) (push) Has been cancelled
build-and-release / build (video-editors) (push) Has been cancelled
|
||
|
|
24e85db097 |
debug: add back a conditional step to isolate the failure further
Some checks failed
build-and-release / build (catering-services) (push) Successful in 20s
build-and-release / build (cron) (push) Successful in 29s
build-and-release / build (companies) (push) Successful in 48s
build-and-release / build (customers) (push) Successful in 1m0s
build-and-release / build (fitness-trainers) (push) Successful in 36s
build-and-release / build (employees) (push) Successful in 58s
build-and-release / build (graphic-designers) (push) Successful in 40s
build-and-release / build (gateway) (push) Successful in 56s
build-and-release / build (jobs) (push) Successful in 35s
build-and-release / build (makeup-artists) (push) Successful in 27s
build-and-release / build (developers) (push) Failing after 1m56s
build-and-release / build (payments) (push) Successful in 30s
build-and-release / build (social-media-managers) (push) Successful in 19s
build-and-release / build (tutors) (push) Successful in 19s
build-and-release / build (ugc-content-creators) (push) Successful in 14s
backend-integration-tests / ai-credits (push) Successful in 5s
build-and-release / build (video-editors) (push) Successful in 12s
build-and-release / build (job-seekers) (push) Successful in 1m38s
build-and-release / build (photographers) (push) Successful in 2m8s
build-and-release / build (users) (push) Successful in 4m15s
|
||
|
|
c0a961c8ef |
debug: add back the check step to isolate the failure further
Some checks failed
build-and-release / build (companies) (push) Successful in 9s
build-and-release / build (cron) (push) Successful in 15s
build-and-release / build (catering-services) (push) Successful in 21s
build-and-release / build (developers) (push) Successful in 14s
build-and-release / build (employees) (push) Successful in 15s
build-and-release / build (fitness-trainers) (push) Successful in 12s
build-and-release / build (gateway) (push) Successful in 14s
build-and-release / build (graphic-designers) (push) Successful in 12s
build-and-release / build (job-seekers) (push) Successful in 10s
build-and-release / build (jobs) (push) Successful in 9s
build-and-release / build (makeup-artists) (push) Successful in 12s
build-and-release / build (photographers) (push) Successful in 10s
build-and-release / build (social-media-managers) (push) Successful in 10s
build-and-release / build (tutors) (push) Successful in 9s
build-and-release / build (customers) (push) Successful in 1m44s
build-and-release / build (video-editors) (push) Successful in 21s
backend-integration-tests / ai-credits (push) Successful in 4s
build-and-release / build (ugc-content-creators) (push) Has been cancelled
build-and-release / build (users) (push) Has been cancelled
build-and-release / build (payments) (push) Has been cancelled
|
||
|
|
22cbd3e285 |
debug: add back job-level env secret reference to isolate the failure
All checks were successful
build-and-release / build (catering-services) (push) Successful in 9s
build-and-release / build (companies) (push) Successful in 8s
build-and-release / build (cron) (push) Successful in 9s
build-and-release / build (customers) (push) Successful in 8s
build-and-release / build (developers) (push) Successful in 9s
build-and-release / build (employees) (push) Successful in 9s
build-and-release / build (fitness-trainers) (push) Successful in 8s
build-and-release / build (gateway) (push) Successful in 9s
build-and-release / build (job-seekers) (push) Successful in 8s
build-and-release / build (jobs) (push) Successful in 9s
build-and-release / build (makeup-artists) (push) Successful in 8s
build-and-release / build (payments) (push) Successful in 9s
build-and-release / build (photographers) (push) Successful in 8s
build-and-release / build (tutors) (push) Successful in 8s
build-and-release / build (ugc-content-creators) (push) Successful in 8s
build-and-release / build (users) (push) Successful in 11s
build-and-release / build (video-editors) (push) Successful in 9s
backend-integration-tests / ai-credits (push) Successful in 4s
build-and-release / build (social-media-managers) (push) Successful in 52s
build-and-release / build (graphic-designers) (push) Successful in 2m33s
|
||
|
|
e80c58641f |
debug: strip test.yaml to bare minimum to isolate why the job dies mid-run
Some checks failed
build-and-release / build (catering-services) (push) Successful in 25s
build-and-release / build (cron) (push) Successful in 33s
build-and-release / build (companies) (push) Successful in 39s
build-and-release / build (developers) (push) Successful in 45s
build-and-release / build (fitness-trainers) (push) Successful in 28s
build-and-release / build (gateway) (push) Successful in 26s
build-and-release / build (graphic-designers) (push) Successful in 31s
build-and-release / build (makeup-artists) (push) Successful in 12s
build-and-release / build (jobs) (push) Successful in 24s
build-and-release / build (photographers) (push) Successful in 9s
build-and-release / build (payments) (push) Successful in 19s
build-and-release / build (social-media-managers) (push) Successful in 14s
build-and-release / build (employees) (push) Failing after 1m46s
build-and-release / build (customers) (push) Failing after 1m48s
backend-integration-tests / ai-credits (push) Successful in 5s
build-and-release / build (tutors) (push) Successful in 1m33s
build-and-release / build (video-editors) (push) Successful in 2m26s
build-and-release / build (users) (push) Successful in 2m52s
build-and-release / build (job-seekers) (push) Successful in 6m30s
build-and-release / build (ugc-content-creators) (push) Successful in 7m36s
|
||
|
|
3740bb81c5 |
fix(ci): fetch full git history in ai-credits job for diff-based change detection
Some checks failed
build-and-release / build (employees) (push) Successful in 18s
build-and-release / build (cron) (push) Successful in 23s
build-and-release / build (gateway) (push) Successful in 9s
build-and-release / build (graphic-designers) (push) Successful in 8s
build-and-release / build (catering-services) (push) Successful in 1m38s
build-and-release / build (jobs) (push) Successful in 9s
build-and-release / build (fitness-trainers) (push) Successful in 1m29s
build-and-release / build (payments) (push) Successful in 9s
build-and-release / build (photographers) (push) Successful in 11s
build-and-release / build (companies) (push) Successful in 2m15s
build-and-release / build (customers) (push) Successful in 2m26s
build-and-release / build (tutors) (push) Successful in 18s
build-and-release / build (developers) (push) Successful in 2m48s
build-and-release / build (video-editors) (push) Successful in 18s
backend-integration-tests / ai-credits (push) Failing after 10s
build-and-release / build (job-seekers) (push) Successful in 2m48s
build-and-release / build (makeup-artists) (push) Successful in 2m0s
build-and-release / build (users) (push) Has been cancelled
build-and-release / build (social-media-managers) (push) Has been cancelled
build-and-release / build (ugc-content-creators) (push) Has been cancelled
Previous job died silently right after checkout with no logs at all from the 'Check for relevant changes' step onward - shallow clone (default fetch-depth:1, unlike build.yaml which sets fetch-depth:0) may have been the cause. Matching build.yaml's checkout config. Also re-set TEST_DATABASE_URL with a properly percent-encoded password (the raw '@' in it made the postgresql:// URI ambiguous to parse). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
8893eaa230 |
chore: re-trigger ai-credits CI job (previous run died mid-checkout, likely runner contention)
Some checks failed
build-and-release / build (companies) (push) Successful in 6s
build-and-release / build (developers) (push) Successful in 10s
build-and-release / build (cron) (push) Successful in 10s
build-and-release / build (catering-services) (push) Successful in 14s
build-and-release / build (employees) (push) Successful in 11s
build-and-release / build (customers) (push) Successful in 14s
build-and-release / build (fitness-trainers) (push) Successful in 7s
build-and-release / build (gateway) (push) Successful in 8s
build-and-release / build (graphic-designers) (push) Successful in 8s
build-and-release / build (jobs) (push) Successful in 9s
build-and-release / build (job-seekers) (push) Successful in 12s
build-and-release / build (makeup-artists) (push) Successful in 11s
build-and-release / build (social-media-managers) (push) Successful in 7s
build-and-release / build (payments) (push) Successful in 7s
build-and-release / build (photographers) (push) Successful in 8s
build-and-release / build (tutors) (push) Successful in 8s
build-and-release / build (ugc-content-creators) (push) Successful in 5s
backend-integration-tests / ai-credits (push) Failing after 6s
build-and-release / build (users) (push) Successful in 11s
build-and-release / build (video-editors) (push) Successful in 10s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
3b4a4eac3f |
fix(ci): install build-essential before cargo test in ai-credits job
Some checks failed
build-and-release / build (catering-services) (push) Successful in 28s
build-and-release / build (customers) (push) Successful in 30s
build-and-release / build (cron) (push) Successful in 55s
build-and-release / build (companies) (push) Successful in 1m54s
build-and-release / build (job-seekers) (push) Successful in 8s
build-and-release / build (employees) (push) Successful in 2m11s
build-and-release / build (fitness-trainers) (push) Successful in 1m48s
build-and-release / build (developers) (push) Successful in 2m26s
build-and-release / build (gateway) (push) Successful in 2m2s
build-and-release / build (jobs) (push) Successful in 54s
build-and-release / build (graphic-designers) (push) Successful in 2m32s
build-and-release / build (ugc-content-creators) (push) Successful in 8s
build-and-release / build (payments) (push) Successful in 1m50s
build-and-release / build (photographers) (push) Successful in 1m51s
backend-integration-tests / ai-credits (push) Failing after 4s
build-and-release / build (makeup-artists) (push) Successful in 2m32s
build-and-release / build (social-media-managers) (push) Successful in 2m55s
build-and-release / build (tutors) (push) Successful in 2m45s
build-and-release / build (users) (push) Has been cancelled
build-and-release / build (video-editors) (push) Has been cancelled
The bare bookworm runner image has no C toolchain at all, unlike build.yaml's jobs which build inside a Dockerfile-based image with one already present. proc-macro2/libc/etc build scripts need `cc` to link and failed immediately (error: linker `cc` not found) before any real test code ran. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
da9be7f6a3 |
feat(db,ci): fix missing ai_credits tables, wire integration tests to CI
Some checks failed
build-and-release / build (cron) (push) Successful in 1m10s
build-and-release / build (developers) (push) Successful in 1m40s
build-and-release / build (catering-services) (push) Successful in 1m58s
build-and-release / build (employees) (push) Successful in 2m19s
build-and-release / build (companies) (push) Successful in 2m36s
build-and-release / build (customers) (push) Successful in 2m45s
build-and-release / build (gateway) (push) Successful in 1m11s
build-and-release / build (jobs) (push) Successful in 40s
build-and-release / build (fitness-trainers) (push) Successful in 2m28s
build-and-release / build (graphic-designers) (push) Successful in 2m14s
build-and-release / build (payments) (push) Successful in 1m48s
build-and-release / build (job-seekers) (push) Successful in 2m57s
build-and-release / build (makeup-artists) (push) Successful in 2m49s
build-and-release / build (photographers) (push) Successful in 2m43s
backend-integration-tests / ai-credits (push) Failing after 31s
build-and-release / build (social-media-managers) (push) Successful in 2m58s
build-and-release / build (tutors) (push) Successful in 2m47s
build-and-release / build (ugc-content-creators) (push) Successful in 2m39s
build-and-release / build (users) (push) Has been cancelled
build-and-release / build (video-editors) (push) Has been cancelled
Re-enables and corrects 20260703210000_ai_credits_wallet, which had been
disabled (.up.sql.skip) in commit
|
||
|
|
6e1041a1f6 |
chore(deps): document rkyv CVE exemption, restore + expand audit.toml comments
All checks were successful
build-and-release / build (companies) (push) Successful in 5s
build-and-release / build (cron) (push) Successful in 5s
build-and-release / build (developers) (push) Successful in 6s
build-and-release / build (employees) (push) Successful in 6s
build-and-release / build (fitness-trainers) (push) Successful in 6s
build-and-release / build (gateway) (push) Successful in 7s
build-and-release / build (graphic-designers) (push) Successful in 8s
build-and-release / build (job-seekers) (push) Successful in 10s
build-and-release / build (customers) (push) Successful in 20s
build-and-release / build (catering-services) (push) Successful in 21s
build-and-release / build (makeup-artists) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 6s
build-and-release / build (payments) (push) Successful in 7s
build-and-release / build (photographers) (push) Successful in 7s
build-and-release / build (ugc-content-creators) (push) Successful in 7s
build-and-release / build (tutors) (push) Successful in 8s
build-and-release / build (social-media-managers) (push) Successful in 11s
build-and-release / build (users) (push) Successful in 5s
build-and-release / build (video-editors) (push) Successful in 6s
cargo audit flagged RUSTSEC-2026-0235 (rkyv, out-of-bounds read) via rust_decimal's optional rkyv feature, which apps/payments never enables (features = ["db-tokio-postgres"] only) - confirmed absent from the actual feature-resolved graph via cargo tree, and cargo-deny (which is feature-aware) already doesn't flag it. Added to both deny.toml and .cargo/audit.toml so cargo audit also exits 0. Also re-documented the 4 pre-existing crate-name-collision ignores in .cargo/audit.toml (RUSTSEC-2020-0128/2021-0006/2023-0040/2023-0059 - our own workspace crates crates/cache and apps/users happen to share name+version with unrelated abandoned crates.io packages) with fuller explanation, and mirrored them into deny.toml for a single source of truth even though cargo-deny's real graph resolution never matched them in the first place. Verified: cargo audit and cargo deny check advisories bans both now exit 0 against the live server runbook's requirement. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
f007ca0999 |
fix(db): re-enable wallet_full migration (tracecoin_holds/buckets)
All checks were successful
build-and-release / build (gateway) (push) Successful in 49s
build-and-release / build (employees) (push) Successful in 1m46s
build-and-release / build (ugc-content-creators) (push) Successful in 2m36s
build-and-release / build (companies) (push) Successful in 1m55s
build-and-release / build (catering-services) (push) Successful in 2m48s
build-and-release / build (fitness-trainers) (push) Successful in 1m45s
build-and-release / build (makeup-artists) (push) Successful in 1m43s
build-and-release / build (payments) (push) Successful in 2m52s
build-and-release / build (tutors) (push) Successful in 2m54s
build-and-release / build (job-seekers) (push) Successful in 7m28s
build-and-release / build (developers) (push) Successful in 2m28s
build-and-release / build (photographers) (push) Successful in 2m37s
build-and-release / build (video-editors) (push) Successful in 2m32s
build-and-release / build (users) (push) Successful in 4m55s
build-and-release / build (social-media-managers) (push) Successful in 7m32s
build-and-release / build (customers) (push) Successful in 2m11s
build-and-release / build (cron) (push) Successful in 2m14s
build-and-release / build (jobs) (push) Successful in 39s
build-and-release / build (graphic-designers) (push) Successful in 2m0s
20260627030000_wallet_full.up.sql was disabled in
|
||
|
|
b30629411a |
fix(ci): diff/scan full pushed commit range, not just HEAD^..HEAD
All checks were successful
build-and-release / build (customers) (push) Successful in 2m42s
build-and-release / build (developers) (push) Successful in 1m46s
build-and-release / build (graphic-designers) (push) Successful in 2m43s
build-and-release / build (tutors) (push) Successful in 2m44s
build-and-release / build (catering-services) (push) Successful in 1m49s
build-and-release / build (fitness-trainers) (push) Successful in 1m48s
build-and-release / build (photographers) (push) Successful in 2m55s
build-and-release / build (users) (push) Successful in 4m57s
build-and-release / build (gateway) (push) Successful in 1m22s
build-and-release / build (payments) (push) Successful in 2m12s
build-and-release / build (ugc-content-creators) (push) Successful in 2m44s
build-and-release / build (companies) (push) Successful in 1m59s
build-and-release / build (social-media-managers) (push) Successful in 2m42s
build-and-release / build (job-seekers) (push) Successful in 7m6s
build-and-release / build (video-editors) (push) Successful in 2m42s
build-and-release / build (cron) (push) Successful in 2m9s
build-and-release / build (employees) (push) Successful in 2m30s
build-and-release / build (makeup-artists) (push) Successful in 2m40s
build-and-release / build (jobs) (push) Successful in 6m53s
Multi-commit pushes (e.g. this repo's mirror sync from GitHub) were silently skipping every service's build: the 'does this service need building' check only looked at the last commit vs its immediate parent. A push landing 3 commits where only the final one was a no-op (docs/.gitignore) meant the actual code commit's changes were never seen, so all 19 services reported 'no changes relevant - skipping' even though real backend code had changed. Use github.event.before (the pre-push SHA) to diff/scan the whole pushed range when available, falling back to HEAD^..HEAD only when that ref is unavailable. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
7b4a23cee6 |
chore: gitignore *.pid runtime files
All checks were successful
build-and-release / build (companies) (push) Successful in 14s
build-and-release / build (developers) (push) Successful in 13s
build-and-release / build (customers) (push) Successful in 15s
build-and-release / build (employees) (push) Successful in 15s
build-and-release / build (catering-services) (push) Successful in 19s
build-and-release / build (cron) (push) Successful in 18s
build-and-release / build (fitness-trainers) (push) Successful in 6s
build-and-release / build (graphic-designers) (push) Successful in 6s
build-and-release / build (gateway) (push) Successful in 7s
build-and-release / build (job-seekers) (push) Successful in 8s
build-and-release / build (makeup-artists) (push) Successful in 8s
build-and-release / build (jobs) (push) Successful in 8s
build-and-release / build (payments) (push) Successful in 6s
build-and-release / build (social-media-managers) (push) Successful in 6s
build-and-release / build (photographers) (push) Successful in 7s
build-and-release / build (tutors) (push) Successful in 8s
build-and-release / build (ugc-content-creators) (push) Successful in 8s
build-and-release / build (users) (push) Successful in 7s
build-and-release / build (video-editors) (push) Successful in 7s
PID files are created by running services locally and should never be tracked in version control. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
9e37060737 |
docs: add live server runbook
All checks were successful
build-and-release / build (cron) (push) Successful in 12s
build-and-release / build (customers) (push) Successful in 16s
build-and-release / build (employees) (push) Successful in 15s
build-and-release / build (companies) (push) Successful in 18s
build-and-release / build (developers) (push) Successful in 17s
build-and-release / build (catering-services) (push) Successful in 19s
build-and-release / build (fitness-trainers) (push) Successful in 5s
build-and-release / build (graphic-designers) (push) Successful in 7s
build-and-release / build (gateway) (push) Successful in 6s
build-and-release / build (job-seekers) (push) Successful in 6s
build-and-release / build (makeup-artists) (push) Successful in 8s
build-and-release / build (jobs) (push) Successful in 9s
build-and-release / build (payments) (push) Successful in 7s
build-and-release / build (photographers) (push) Successful in 6s
build-and-release / build (social-media-managers) (push) Successful in 7s
build-and-release / build (ugc-content-creators) (push) Successful in 7s
build-and-release / build (tutors) (push) Successful in 8s
build-and-release / build (video-editors) (push) Successful in 7s
build-and-release / build (users) (push) Successful in 9s
Covers everything that needs a running DB/server: - Deploy the backend changes (wallet holds, printpdf upgrade) - Verify /wallet/me/holds endpoint with curl - cargo audit + cargo deny check - Schemathesis API fuzzing setup - Playwright e2e tests - CI integration tests with TEST_DATABASE_URL - npm run lint and tsc --noEmit Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
8423b7a0f5 |
fix: security, wallet holds, printpdf upgrade
- Upgrade printpdf 0.7 → 0.12.5 in job_seekers (fixes lopdf HIGH CVE RUSTSEC-2023-0068)
Rewrote build_resume_pdf() for the new Op-based API; same PDF output
- Add wallet/me/holds and wallet/me/holds/{id}/release routes to profession_shared
Backed by wallet::hold::list_for_user and wallet::hold::release
Applies to all 9 profession services via the shared router
- Add deny.toml for cargo-deny (advisory + ban policy enforcement)
RSA timing CVE and bincode unmaintained acknowledged with documented reasons
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
ddb2110e86 |
fix: return JSON errors from create_job and add admin job-slot grant endpoint
All checks were successful
build-and-release / build (customers) (push) Successful in 8s
build-and-release / build (catering-services) (push) Successful in 11s
build-and-release / build (fitness-trainers) (push) Successful in 7s
build-and-release / build (developers) (push) Successful in 12s
build-and-release / build (cron) (push) Successful in 18s
build-and-release / build (employees) (push) Successful in 16s
build-and-release / build (gateway) (push) Successful in 8s
build-and-release / build (job-seekers) (push) Successful in 5s
build-and-release / build (graphic-designers) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 7s
build-and-release / build (payments) (push) Successful in 7s
build-and-release / build (makeup-artists) (push) Successful in 6s
build-and-release / build (photographers) (push) Successful in 5s
build-and-release / build (tutors) (push) Successful in 5s
build-and-release / build (social-media-managers) (push) Successful in 5s
build-and-release / build (ugc-content-creators) (push) Successful in 6s
build-and-release / build (users) (push) Successful in 5s
build-and-release / build (video-editors) (push) Successful in 4s
build-and-release / build (companies) (push) Successful in 1m21s
create_job returned plain-text bodies on every failure branch except
quota-exhausted, so the frontend's res.json() silently failed and always
showed a generic "Failed to create job" message regardless of the real
cause (company not approved, quota exhausted, DB error).
Also adds PATCH /api/admin/companies/{id}/job-slots as a manual top-up
for purchased_job_slots, since no self-serve purchase flow exists yet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
b281eb5278 |
fix: profile approval 500 — users table has no role column
All checks were successful
build-and-release / build (employees) (push) Successful in 11s
build-and-release / build (cron) (push) Successful in 13s
build-and-release / build (catering-services) (push) Successful in 17s
build-and-release / build (companies) (push) Successful in 17s
build-and-release / build (customers) (push) Successful in 17s
build-and-release / build (developers) (push) Successful in 16s
build-and-release / build (fitness-trainers) (push) Successful in 5s
build-and-release / build (graphic-designers) (push) Successful in 7s
build-and-release / build (gateway) (push) Successful in 7s
build-and-release / build (job-seekers) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 8s
build-and-release / build (payments) (push) Successful in 7s
build-and-release / build (makeup-artists) (push) Successful in 10s
build-and-release / build (photographers) (push) Successful in 7s
build-and-release / build (social-media-managers) (push) Successful in 8s
build-and-release / build (tutors) (push) Successful in 8s
build-and-release / build (ugc-content-creators) (push) Successful in 7s
build-and-release / build (video-editors) (push) Successful in 8s
build-and-release / build (users) (push) Successful in 2m45s
activate_profile_after_final_approval ran UPDATE users SET role = $1, but users only has role_id (FK into roles), never a plain role column. Resolve the role's id via RoleRepository::get_by_key first and update role_id instead, matching how role is tracked everywhere else. |
||
|
|
2f47308498 |
fix: verification submission no longer blocks login or misreports status
All checks were successful
build-and-release / build (customers) (push) Successful in 12s
build-and-release / build (catering-services) (push) Successful in 15s
build-and-release / build (developers) (push) Successful in 13s
build-and-release / build (cron) (push) Successful in 17s
build-and-release / build (employees) (push) Successful in 5s
build-and-release / build (gateway) (push) Successful in 5s
build-and-release / build (fitness-trainers) (push) Successful in 6s
build-and-release / build (graphic-designers) (push) Successful in 7s
build-and-release / build (makeup-artists) (push) Successful in 5s
build-and-release / build (jobs) (push) Successful in 8s
build-and-release / build (payments) (push) Successful in 7s
build-and-release / build (photographers) (push) Successful in 7s
build-and-release / build (social-media-managers) (push) Successful in 5s
build-and-release / build (tutors) (push) Successful in 6s
build-and-release / build (ugc-content-creators) (push) Successful in 5s
build-and-release / build (video-editors) (push) Successful in 4s
build-and-release / build (companies) (push) Successful in 1m10s
build-and-release / build (job-seekers) (push) Successful in 1m8s
build-and-release / build (users) (push) Successful in 3m7s
- submit_for_verification: stop downgrading user_role_assignments.status to PENDING. This was locking users out of login while their verification was under review. Verification progress is tracked in the verifications table; role assignment stays APPROVED throughout. - verification_status: remove role_assignment_approved from the status calculation. Because the assignment now stays APPROVED, using it as a proxy was incorrectly overriding PENDING verification status to APPROVED immediately after submission. - companies submit_with_documents: encode document_type from filename prefix before '|' separator (set by frontend) rather than file stem; add duplicate-verification guard to match users service. - job_seekers: add get_or_create_job_seeker_profile helper to ensure profile row exists before upsert operations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
5f1b48d27b |
fix: sync profile approval unlock state
All checks were successful
build-and-release / build (developers) (push) Successful in 9s
build-and-release / build (customers) (push) Successful in 13s
build-and-release / build (companies) (push) Successful in 12s
build-and-release / build (cron) (push) Successful in 15s
build-and-release / build (catering-services) (push) Successful in 14s
build-and-release / build (fitness-trainers) (push) Successful in 6s
build-and-release / build (employees) (push) Successful in 15s
build-and-release / build (gateway) (push) Successful in 6s
build-and-release / build (graphic-designers) (push) Successful in 7s
build-and-release / build (job-seekers) (push) Successful in 6s
build-and-release / build (payments) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 8s
build-and-release / build (makeup-artists) (push) Successful in 9s
build-and-release / build (photographers) (push) Successful in 6s
build-and-release / build (social-media-managers) (push) Successful in 7s
build-and-release / build (ugc-content-creators) (push) Successful in 6s
build-and-release / build (tutors) (push) Successful in 8s
build-and-release / build (video-editors) (push) Successful in 9s
build-and-release / build (users) (push) Successful in 6m14s
|
||
|
|
2da1ebc8be |
Fix COMPANY verification snapshot dropping every field but company_name
All checks were successful
build-and-release / build (catering-services) (push) Successful in 13s
build-and-release / build (cron) (push) Successful in 12s
build-and-release / build (customers) (push) Successful in 13s
build-and-release / build (companies) (push) Successful in 16s
build-and-release / build (developers) (push) Successful in 6s
build-and-release / build (fitness-trainers) (push) Successful in 6s
build-and-release / build (employees) (push) Successful in 6s
build-and-release / build (gateway) (push) Successful in 5s
build-and-release / build (graphic-designers) (push) Successful in 6s
build-and-release / build (job-seekers) (push) Successful in 6s
build-and-release / build (jobs) (push) Successful in 6s
build-and-release / build (makeup-artists) (push) Successful in 6s
build-and-release / build (payments) (push) Successful in 5s
build-and-release / build (photographers) (push) Successful in 5s
build-and-release / build (social-media-managers) (push) Successful in 6s
build-and-release / build (tutors) (push) Successful in 5s
build-and-release / build (ugc-content-creators) (push) Successful in 6s
build-and-release / build (video-editors) (push) Successful in 6s
build-and-release / build (users) (push) Successful in 2m49s
fetch_saved_profile() is the fallback used by submit-for-verification
when the caller doesn't send profile_data (e.g. VerificationStatusPage's
resubmit-after-revision-request flow, which only sends {roleKey}). It's a
separate implementation from GET /api/profile and still had the same
stale COMPANY query that was already fixed there — SELECT company_name
only, discarding email/phone/website/address/city/state/pin/GST. The
admin verification sidebar renders exactly this snapshot, so a resubmit
made every other field vanish from the admin's review view. Select and
return the full column set, matching get_profile.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
fd889efa22 |
Fix wizard-submitted profile data being dropped and wizard schemas saving with no fields
All checks were successful
build-and-release / build (customers) (push) Successful in 11s
build-and-release / build (catering-services) (push) Successful in 13s
build-and-release / build (companies) (push) Successful in 16s
build-and-release / build (developers) (push) Successful in 16s
build-and-release / build (cron) (push) Successful in 17s
build-and-release / build (employees) (push) Successful in 16s
build-and-release / build (fitness-trainers) (push) Successful in 6s
build-and-release / build (gateway) (push) Successful in 5s
build-and-release / build (graphic-designers) (push) Successful in 7s
build-and-release / build (job-seekers) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 5s
build-and-release / build (makeup-artists) (push) Successful in 5s
build-and-release / build (payments) (push) Successful in 7s
build-and-release / build (photographers) (push) Successful in 4s
build-and-release / build (tutors) (push) Successful in 5s
build-and-release / build (social-media-managers) (push) Successful in 6s
build-and-release / build (ugc-content-creators) (push) Successful in 5s
build-and-release / build (video-editors) (push) Successful in 4s
build-and-release / build (users) (push) Successful in 2m31s
- GET /api/profile for COMPANY only ever returned company_name, silently discarding every other field the wizard (and PATCH) already saved — the profile page looked empty after approval. Select and return all company_profiles columns. - The generic professional-role PATCH path (photographer, tutor, etc.) overwrote custom_data wholesale instead of merging, so RoleWizard's two sequential PATCH calls (portfolio step, then basic+documents step) clobbered each other. Read-merge-write instead, matching the existing JOB_SEEKER/CUSTOMER pattern. - create_onboarding_config now rejects schemas with enableWizardFlow=true but no steps, or a non-review step with no fields — the root cause of a wizard rendering with nothing to fill in. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
a24e03fd02 |
Add runtime-config foundation for verification wizard + field locking
All checks were successful
build-and-release / build (cron) (push) Successful in 1m1s
build-and-release / build (catering-services) (push) Successful in 1m40s
build-and-release / build (companies) (push) Successful in 1m50s
build-and-release / build (employees) (push) Successful in 2m19s
build-and-release / build (developers) (push) Successful in 2m23s
build-and-release / build (customers) (push) Successful in 2m27s
build-and-release / build (gateway) (push) Successful in 1m4s
build-and-release / build (graphic-designers) (push) Successful in 57s
build-and-release / build (jobs) (push) Successful in 47s
build-and-release / build (makeup-artists) (push) Successful in 50s
build-and-release / build (fitness-trainers) (push) Successful in 2m37s
build-and-release / build (photographers) (push) Successful in 1m39s
build-and-release / build (payments) (push) Successful in 2m4s
build-and-release / build (job-seekers) (push) Successful in 2m56s
build-and-release / build (social-media-managers) (push) Successful in 2m25s
build-and-release / build (tutors) (push) Successful in 2m52s
build-and-release / build (ugc-content-creators) (push) Successful in 3m0s
build-and-release / build (video-editors) (push) Successful in 2m3s
build-and-release / build (users) (push) Successful in 4m20s
Reconciles onboarding_configs.schema_json (previously orphaned seed data using a field vocabulary that didn't match production) with the live profile-fields-config.ts field keys, and extends the schema with lockAfterApproval flags, step types, and a per-role portfolioModel so the frontend wizard is entirely schema-driven rather than hardcoded per role. Also: closes an unauthenticated write on the onboarding/dashboard config create endpoints (require_admin was missing), and adds server-side enforcement in save_profile rejecting changes to any field marked lockAfterApproval once a profile is APPROVED — the UI already disables these inputs, this stops a direct API call from bypassing it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
80acfdd64f |
Add presigned document URLs to stop leaking permanent Backblaze links
All checks were successful
build-and-release / build (employees) (push) Successful in 1m34s
build-and-release / build (catering-services) (push) Successful in 1m43s
build-and-release / build (cron) (push) Successful in 1m59s
build-and-release / build (companies) (push) Successful in 2m4s
build-and-release / build (customers) (push) Successful in 2m26s
build-and-release / build (developers) (push) Successful in 2m38s
build-and-release / build (fitness-trainers) (push) Successful in 1m31s
build-and-release / build (gateway) (push) Successful in 1m29s
build-and-release / build (jobs) (push) Successful in 1m9s
build-and-release / build (graphic-designers) (push) Successful in 2m19s
build-and-release / build (job-seekers) (push) Successful in 2m16s
build-and-release / build (photographers) (push) Successful in 1m43s
build-and-release / build (makeup-artists) (push) Successful in 3m3s
build-and-release / build (social-media-managers) (push) Successful in 2m36s
build-and-release / build (ugc-content-creators) (push) Successful in 2m46s
build-and-release / build (payments) (push) Successful in 4m15s
build-and-release / build (video-editors) (push) Successful in 2m53s
build-and-release / build (tutors) (push) Successful in 4m24s
build-and-release / build (users) (push) Successful in 7m40s
Verification documents were being stored/rendered as permanent, unsigned B2 URLs across every role's admin review and self-service dashboard. Add StorageClient::presign() plus two mediating endpoints (admin and self-service) so viewers always get a short-lived signed URL instead of the raw storage link. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
cd695514fe |
Surface real B2 upload errors and enforce 10MB body limit on document uploads
All checks were successful
build-and-release / build (developers) (push) Successful in 1m27s
build-and-release / build (employees) (push) Successful in 1m52s
build-and-release / build (customers) (push) Successful in 1m56s
build-and-release / build (cron) (push) Successful in 2m16s
build-and-release / build (companies) (push) Successful in 2m21s
build-and-release / build (catering-services) (push) Successful in 2m29s
build-and-release / build (gateway) (push) Successful in 39s
build-and-release / build (fitness-trainers) (push) Successful in 2m0s
build-and-release / build (graphic-designers) (push) Successful in 1m52s
build-and-release / build (jobs) (push) Successful in 1m34s
build-and-release / build (job-seekers) (push) Successful in 2m4s
build-and-release / build (photographers) (push) Successful in 1m35s
build-and-release / build (makeup-artists) (push) Successful in 2m41s
build-and-release / build (payments) (push) Successful in 3m15s
build-and-release / build (tutors) (push) Successful in 2m16s
build-and-release / build (social-media-managers) (push) Successful in 2m33s
build-and-release / build (ugc-content-creators) (push) Successful in 2m47s
build-and-release / build (video-editors) (push) Successful in 2m32s
build-and-release / build (users) (push) Successful in 4m11s
Document upload endpoints (job_seekers, customers, companies, and the profession_shared crate used by 10 profession apps) returned a generic "File upload failed" 500 on any storage error, hiding the actual cause from both the API response and (for job_seekers/companies) the server logs, which only printed anyhow's outer context via Display instead of the full error chain via Debug. Also add an explicit DefaultBodyLimit(11MB) to every affected app's router — none had one, so axum's implicit 2MB default could silently reject uploads under the UI's advertised 10MB cap. |
||
|
|
da8188563f |
Fix job seeker document upload 404ing before profile is saved
All checks were successful
build-and-release / build (companies) (push) Successful in 10s
build-and-release / build (developers) (push) Successful in 9s
build-and-release / build (customers) (push) Successful in 11s
build-and-release / build (catering-services) (push) Successful in 14s
build-and-release / build (cron) (push) Successful in 15s
build-and-release / build (fitness-trainers) (push) Successful in 5s
build-and-release / build (employees) (push) Successful in 12s
build-and-release / build (gateway) (push) Successful in 4s
build-and-release / build (graphic-designers) (push) Successful in 6s
build-and-release / build (makeup-artists) (push) Successful in 5s
build-and-release / build (jobs) (push) Successful in 8s
build-and-release / build (payments) (push) Successful in 8s
build-and-release / build (photographers) (push) Successful in 6s
build-and-release / build (tutors) (push) Successful in 6s
build-and-release / build (social-media-managers) (push) Successful in 8s
build-and-release / build (ugc-content-creators) (push) Successful in 8s
build-and-release / build (video-editors) (push) Successful in 7s
build-and-release / build (users) (push) Successful in 8s
build-and-release / build (job-seekers) (push) Successful in 1m8s
upload_document and list_documents both required a pre-existing job_seeker_profiles row, but nothing creates that row until the user clicks "Save" on the Basic Information tab. A job seeker who opened the Documents tab first (or never saved Basic Info) got every upload silently rejected with a 404, and the earlier fix in frontend-solid (070c4bd) only addressed a different bug in the dashboard widget - it never touched this upload path. upload_document now lazily creates a blank profile row on first upload instead of 404ing (uploading a verification document doesn't depend on basic profile fields being filled in). list_documents now returns an empty list instead of erroring when no profile exists yet, since that's just the normal empty state for a new job seeker. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
fdd5c7a418 |
Fix security audit findings: admin authz, captcha, secret leak, CORS
All checks were successful
build-and-release / build (developers) (push) Successful in 5m31s
build-and-release / build (catering-services) (push) Successful in 5m56s
build-and-release / build (employees) (push) Successful in 6m23s
build-and-release / build (companies) (push) Successful in 6m31s
build-and-release / build (cron) (push) Successful in 6m38s
build-and-release / build (customers) (push) Successful in 7m19s
build-and-release / build (gateway) (push) Successful in 1m28s
build-and-release / build (fitness-trainers) (push) Successful in 2m2s
build-and-release / build (jobs) (push) Successful in 1m12s
build-and-release / build (graphic-designers) (push) Successful in 2m20s
build-and-release / build (job-seekers) (push) Successful in 2m24s
build-and-release / build (photographers) (push) Successful in 2m20s
build-and-release / build (makeup-artists) (push) Successful in 2m55s
build-and-release / build (tutors) (push) Successful in 2m15s
build-and-release / build (payments) (push) Successful in 3m48s
build-and-release / build (ugc-content-creators) (push) Successful in 2m35s
build-and-release / build (social-media-managers) (push) Successful in 4m46s
build-and-release / build (video-editors) (push) Successful in 2m41s
build-and-release / build (users) (push) Successful in 8m7s
- Require admin role on role/module/permission management endpoints that previously accepted any authenticated user (privilege escalation) - Add server-side captcha generation/verification (Redis-backed, single-use, 5 min TTL) enforced on register/login for users and employees services - Untrack .env.test111 (contained a live SMTP key) and harden .gitignore against future .env commits - Stop logging OTP codes in plaintext - Restrict jobs service CORS to an explicit origin allowlist - Mask PayU merchant secret/salt in payment-gateway-config responses, preserving the stored value on save when the field is left unchanged - Bump vulnerable transitive dependencies (quinn-proto, rustls-webpki, anyhow) via cargo update; switch aws-sdk-s3 off the legacy rustls feature Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
73beb03368 |
fix: seed verification_status into JOB_SEEKER dashboard widgets
All checks were successful
build-and-release / build (catering-services) (push) Successful in 1m45s
build-and-release / build (developers) (push) Successful in 1m43s
build-and-release / build (companies) (push) Successful in 1m53s
build-and-release / build (cron) (push) Successful in 2m9s
build-and-release / build (customers) (push) Successful in 2m27s
build-and-release / build (employees) (push) Successful in 1m46s
build-and-release / build (fitness-trainers) (push) Successful in 1m48s
build-and-release / build (graphic-designers) (push) Successful in 1m47s
build-and-release / build (jobs) (push) Successful in 1m32s
build-and-release / build (gateway) (push) Successful in 2m21s
build-and-release / build (job-seekers) (push) Successful in 2m53s
build-and-release / build (photographers) (push) Successful in 1m32s
build-and-release / build (makeup-artists) (push) Successful in 1m58s
build-and-release / build (social-media-managers) (push) Successful in 2m17s
build-and-release / build (payments) (push) Successful in 2m51s
build-and-release / build (tutors) (push) Successful in 2m38s
build-and-release / build (ugc-content-creators) (push) Successful in 2m41s
build-and-release / build (video-editors) (push) Successful in 2m39s
build-and-release / build (users) (push) Successful in 4m13s
The live role_sidebar_configs row for JOB_SEEKER never included this widget, so the verification status badge never rendered. Also applied directly to the live DB row (this seed file wasn't wired into any auto-run migration path, so editing it alone wouldn't have taken effect). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
c1eed2530d |
fix: stop leaking raw LiteLLM error bodies; harden prompts against injection; fix UTF-8 panic
All checks were successful
build-and-release / build (companies) (push) Successful in 4s
build-and-release / build (catering-services) (push) Successful in 6s
build-and-release / build (developers) (push) Successful in 7s
build-and-release / build (customers) (push) Successful in 8s
build-and-release / build (employees) (push) Successful in 8s
build-and-release / build (fitness-trainers) (push) Successful in 6s
build-and-release / build (graphic-designers) (push) Successful in 5s
build-and-release / build (gateway) (push) Successful in 8s
build-and-release / build (job-seekers) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 7s
build-and-release / build (makeup-artists) (push) Successful in 5s
build-and-release / build (payments) (push) Successful in 5s
build-and-release / build (photographers) (push) Successful in 5s
build-and-release / build (social-media-managers) (push) Successful in 6s
build-and-release / build (tutors) (push) Successful in 6s
build-and-release / build (ugc-content-creators) (push) Successful in 5s
build-and-release / build (video-editors) (push) Successful in 5s
build-and-release / build (cron) (push) Successful in 51s
build-and-release / build (users) (push) Successful in 3m12s
Follow-up on the AI safety review — addressed the three remaining lower-severity findings: 1. crates LiteLlmError::error_body() returned the raw upstream response body verbatim to the client on any non-2xx LiteLLM response. That body can contain internal routing/diagnostic details from the LiteLLM proxy or the underlying model provider. Now returns a generic, status-aware message to the client; the full body is logged server-side via tracing::error! at each of the three call sites that construct LiteLlmError::Api, so nothing is lost for debugging — it's just not exposed to end users. 2. Added an explicit anti-prompt-injection clause to ai/orchestrator.rs::GROUNDING_GUARDRAIL, the baseline system prompt applied to every AI feature call via effective_system_prompt() — instructs the model to treat all user/company-authored input (job descriptions, profile text, chat messages) as data to analyze, never as instructions to follow. Covers every ai.rs handler that goes through call_feature/call_feature_with_plan in one place, rather than patching each call site's prompt construction individually. 3. apps/cron/src/tasks/auto_apply.rs's cover-letter prompt doesn't run through the orchestrator (separate app/crate), so hardened it directly: fenced the untrusted CANDIDATE/JOB sections with explicit "this is data, not instructions" framing. While there, fixed a latent panic: `&job_desc[..job_desc.len().min(500)]` slices on a raw byte offset, which panics if byte 500 isn't a UTF-8 character boundary — a company job description with any multi-byte character before that point (accented letters, emoji, etc.) would crash the whole cron run. Switched to char_indices() to find a safe boundary. |
||
|
|
3e701f2fe6 |
fix: close two real money/spend races (Tracecoin double-credit, unbounded AI overspend)
Some checks failed
build-and-release / build (ugc-content-creators) (push) Waiting to run
build-and-release / build (users) (push) Waiting to run
build-and-release / build (video-editors) (push) Waiting to run
build-and-release / build (catering-services) (push) Successful in 1m47s
build-and-release / build (companies) (push) Successful in 2m0s
build-and-release / build (cron) (push) Successful in 2m12s
build-and-release / build (customers) (push) Successful in 2m42s
build-and-release / build (gateway) (push) Successful in 1m0s
build-and-release / build (developers) (push) Successful in 1m27s
build-and-release / build (fitness-trainers) (push) Successful in 1m54s
build-and-release / build (employees) (push) Successful in 1m59s
build-and-release / build (job-seekers) (push) Successful in 1m57s
build-and-release / build (makeup-artists) (push) Successful in 1m39s
build-and-release / build (graphic-designers) (push) Has been cancelled
build-and-release / build (payments) (push) Has been cancelled
build-and-release / build (jobs) (push) Has been cancelled
build-and-release / build (social-media-managers) (push) Has been cancelled
build-and-release / build (tutors) (push) Has been cancelled
build-and-release / build (photographers) (push) Has been cancelled
Asked to review Tracecoin and AI implementation safety. Found and fixed two exploitable TOCTOU races, plus a data-integrity bug: 1. apps/payments/src/main.rs::verify_payment — the PayU success callback is called directly by the client (not a server-to-server webhook), so a user fully controls how many times they replay a valid success payload. The payment "is it still PENDING" check and the "mark SUCCESS + credit wallet" write were separate, non-transactional queries — concurrent replays could both pass the check before either commits, double- (or N-times-) crediting the wallet for one real payment. Now wrapped in a single transaction with `SELECT ... FOR UPDATE` on the payments row, so a second concurrent call blocks until the first commits, then correctly sees the row is no longer PENDING (Postgres re-evaluates the WHERE clause via EvalPlanQual after the lock is granted). 2. crates/db/src/models/ai/repository.rs — UserAiSubscriptionRepository had the exact same shape of bug: apps/users/src/ai/credits.rs:: charge_feature read the subscription, checked daily-limit and credit balance, THEN issued two separate unconditional `UPDATE ... SET x = x + $1` statements with no WHERE guard on the balance. N concurrent requests from one user all pass the check before any deduction lands, running up unlimited LLM API spend (this endpoint is called before/around real LiteLLM calls, so the cost is real). Added UserAiSubscriptionRepository::try_charge — a single conditional UPDATE that checks the daily limit and credit balance and deducts atomically, returning None (mapped to the existing error types) if either check fails. 3. apps/cron/src/tasks/auto_apply.rs — daily_actions_used was being incremented twice per auto-applied job (once in the credit-deduct UPDATE, once more in a second, redundant UPDATE right after) — silently halving job seekers' effective daily auto-apply limit. Removed the redundant second UPDATE. Also added non-negative CHECK constraints directly to the live database (tracecoin_wallets.balance/reserved, user_ai_subscriptions.daily_actions_used/monthly_credits_used/ purchased_credits_used) as defense in depth — belt-and-suspenders in case a future code path reintroduces a similar bug. |
||
|
|
92ce2d2a86 |
fix: notification insert used wrong column name; log silent email failures
All checks were successful
build-and-release / build (catering-services) (push) Successful in 15s
build-and-release / build (cron) (push) Successful in 13s
build-and-release / build (developers) (push) Successful in 10s
build-and-release / build (employees) (push) Successful in 8s
build-and-release / build (fitness-trainers) (push) Successful in 5s
build-and-release / build (gateway) (push) Successful in 5s
build-and-release / build (graphic-designers) (push) Successful in 5s
build-and-release / build (job-seekers) (push) Successful in 5s
build-and-release / build (jobs) (push) Successful in 6s
build-and-release / build (payments) (push) Successful in 4s
build-and-release / build (makeup-artists) (push) Successful in 6s
build-and-release / build (photographers) (push) Successful in 5s
build-and-release / build (social-media-managers) (push) Successful in 6s
build-and-release / build (tutors) (push) Successful in 6s
build-and-release / build (ugc-content-creators) (push) Successful in 6s
build-and-release / build (video-editors) (push) Successful in 6s
build-and-release / build (companies) (push) Successful in 2m9s
build-and-release / build (customers) (push) Successful in 2m47s
build-and-release / build (users) (push) Successful in 3m16s
Found while investigating "notifications/emails not working on approve or job posting": 1. Real bug: apps/companies/src/handlers/mod.rs::view_contact (company viewing an applicant's contact info) inserted into notifications using column name `notification_type`, which has never existed — the column is `type`. This INSERT has been failing outright every time a company views a contact. 2. Root cause for approvals specifically: verifications/approval_requests never existed until earlier this session (see 20260718200000_create_verifications_and_approvals) — every admin approve/reject action was failing at the DB layer before it ever reached the notification/email code, so nothing in this area could have worked regardless of the email/notification logic itself. 3. Observability gap: every `state.mail.send_*_email(...)` call site silently discarded its Result (`let _ = ...`), so if the SMTP/ Zeptomail provider is unconfigured (crates/email::Mailer already logs a clear warning at startup for that, but callers gave no per-send signal) or a send fails for any other reason, there was no way to see it happen. Added `tracing::error!` logging on failure for every job/approval-related email: job submitted, job approved, job rejected, requirement approved, profile approval approved/rejected, requirement submitted. Doesn't change delivery — if the environment has no EMAIL_PROVIDER/SMTP_*/ZEPTOMAIL_* configured, sends still fail, but that failure is now visible in logs instead of silent. In-app notifications for approvals were already schema-correct (job/profile/requirement approve+reject all insert into notifications with the right columns) — the two real defects were #1 and #2 above. |
||
|
|
c570d7df67 |
chore: remove the dead apps/leads microservice
apps/leads implemented its own, independent "lead request" system (POST /api/leads, /api/lead-requests/send, accept/reject) with a schema that never matched the live one (message vs remarks, no professional_user_id, accepted_at/rejected_at instead of resolved_at — see 20260721030000_create_lead_requests's commit message). Confirmed unreachable: the frontend's live flows use apps/customers' /api/customers/requirements and each profession's /leads/request (crates/contracts::profession_shared), never anything under apps/leads' own paths. Its /api/lead-requests/* endpoints weren't even reachable through the gateway (wrong prefix, never matched /api/leads or /api/admin/leads). Removed: - apps/leads/ entirely, and its Cargo.toml workspace membership - the `leads` docker-compose service, its LEADS_SERVICE_URL env var on gateway, and gateway's depends_on entry - the `leads` entry from both CI build matrices (.gitea/.forgejo) - gateway's leads_url field/routing branch — gateway no longer hard- requires LEADS_SERVICE_URL to boot (.expect() would have panicked once the service was gone); /api/admin/leads now falls through to the customers service, which already had a matching (previously shadowed) branch for it NOTE: this service may still have a live Deployment/Service in nxtgauge-gitops (a separate repo not touched here) — that manifest should be removed too, or the next deploy will reference an image that no CI job builds anymore. |
||
|
|
9309334d52 |
seed: add a starter Tracecoin package per role; fix paise unit bug in invoice line item
Seeds one TRACECOIN_BUNDLE package per role (100 Tracecoins / ₹250, placeholder pricing per your instruction) so the purchase flow (CreditsPage.tsx -> GET /api/packages, filtered client-side by role_key) has something to show instead of "No packages available for your role," and so create_order/verify_payment/invoice generation can actually be exercised end-to-end. Idempotent (WHERE NOT EXISTS guard) so it's safe against the custom db-migrate runner re-executing every file on every deploy. Adjust real pricing later via the existing admin CRUD (POST/PATCH /api/packages) — no new endpoint needed, it already works. Also fixes a unit bug introduced in the invoice wiring last commit: payments.amount_inr is already paise (copied straight from pricing_packages.price_inr, which is paise despite the name — PayU order creation divides it by 100 via paise_to_rupee_string), but the invoice line item multiplied it by 100 again, making every generated invoice show a 100x inflated amount. |
||
|
|
68f659903c |
fix: audit_logs, tax_rules, reviews tables never existed; fix wrong column in review creation
Finished the sweep of every table referenced by live Rust code but not created by any active migration: - audit_logs / audit_log_changes — backs wallet::audit() (crates/wallet), called from every admin Tracecoin balance adjustment (apps/payments/src/admin.rs::adjust_credits). actor_type defaulted since the only caller doesn't supply it. - tax_rules — backs the admin tax-rule CRUD in apps/payments/src/admin.rs. init-db.sql has a differently-named version (title/percentage/ applicable_to); schema here matches the live code's actual columns (name/tax_rate/applies_to). - reviews — backs the professional review/rating system (apps/users/src/handlers/reviews.rs). Also fixed a real bug found while building the reviews schema: admin_create_review's customer-lookup subquery selected `lead_requests.user_id`, a column that has never existed (it's `customer_user_id`) — would have failed on the very first review creation attempt now that lead_requests actually exists. Checked every other previously-flagged table (permissions, orders, external_roles, internal_roles, kb_*, notification_*, order_items, portfolio_images, smtp_configs, dashboard_widgets, verification_documents) against actual Rust usage — none of them are referenced by a real SQL query (grep hits were all Rust variable/type names), so nothing to fix there. Full migration-chain sweep confirms zero remaining "references a table before it's created" issues. |
||
|
|
63fd3f5135 |
feat: generate a GST invoice automatically after a successful Tracecoin/PayU purchase
crates/invoice (InvoiceService, GST computation, HTML rendering) was
fully built but never wired to anything and never had its tables —
invoices/invoice_line_items/billing_profiles/invoice_number_seq never
existed in any active migration (same root cause as everything else
this session: only in scripts/init-db.sql, which the real db-migrate
job never runs). Created them, matching InvoiceService's actual
columns exactly rather than init-db.sql's older, simpler invoices
shape.
Fixed a real bug in InvoiceService::create while at it: four money
fields (total, and three line-item amounts) were bound as i64 against
columns/read-models that are i32 everywhere else — would have failed
every insert with a Postgres type mismatch the first time this code
ever actually ran against a real table.
Wired invoice generation into apps/payments' PayU verify_payment
handler (the actual success callback) — right after the wallet is
credited, a one-line-item GST invoice is generated from the purchased
package and PayU's billing fields (firstname/email/phone), using a
new INVOICE_SELLER_* env-configurable seller identity. Generation
failures are logged, not surfaced to the buyer, since the payment and
wallet credit have already succeeded by that point.
Also added the missing user-facing endpoints to fetch what got
generated: GET /api/payments/invoices (list) and
GET /api/payments/invoices/{id} (detail + line items) — previously
only admin-side invoice viewing existed.
NOTE: the frontend (nxtgauge-frontend-solid, a separate repo) has an
existing invoice-viewing page at src/routes/dashboard/wallet/invoices/
but it calls /wallet/me/invoices (no /api/ prefix) via a different,
apparently-dead API helper (api.get, not apiFetch) that every other
live page avoids — same dead-code pattern as the earlier apps/leads
discovery. The live purchase flow (CreditsPage.tsx) has no invoice UI
at all yet. Not fixed here since it's out of this repo's scope this
session — flagging for a frontend pass.
|