diff --git a/09 - Audits/Activity Log.md b/09 - Audits/Activity Log.md index d89c7c0..684163f 100644 --- a/09 - Audits/Activity Log.md +++ b/09 - Audits/Activity Log.md @@ -12,6 +12,16 @@ entries on top. Maintained by agents per the rule in `../AGENTS.md`. --- +### 2026-06-07 — backend@4766eba, frontend@fccccbc — DB audit H22/H23/H28/H37 dispute integrity closeout + +**Commits:** `8fc2309` `f5e53cb` `4766eba` `fccccbc` +**Touched:** backend `src/services/dispute/DisputeService.ts`, `src/db/repositories/drizzle/DrizzleDisputeRepo.ts`, `src/db/repositories/drizzle/DrizzleReleaseHoldRepo.ts`, `src/db/repositories/drizzle/DrizzleChatRepo.ts`, `src/services/admin/dataCleanupService.ts`, `src/services/admin/ttlCleanupJob.ts`, `src/db/schema/dispute.ts`, `src/db/migrations/0025_dispute_enums.sql`, `__tests__/db-audit-dispute-integrity.test.ts`, `scripts/smoke/db-audit-service-regressions.sh`, `package.json`, `package-lock.json`; frontend `Dockerfile`, `package.json`; docs `09 - Audits/DB Query & Schema Audit - 2026-06-06.md`, `09 - Audits/Activity Log.md` +**Why:** Close High H22/H23/H28/H37. Dispute create now uses a serializable vital transaction for the dispute insert, immediate chat cleanup on rollback, and a TTL orphan-dispute-chat sweep for crash recovery across the split vital/non-vital pools. Dispute resolution and release-hold clearing run in one serializable vital transaction. Dispute timeline/evidence updates use atomic JSONB append expressions. Dispute status/priority/category are pgEnums. +**Verification:** backend `npm run typecheck`, `npm test -- --runTestsByPath __tests__/db-audit-dispute-integrity.test.ts --runInBand`, `scripts/smoke/db-audit-service-regressions.sh` (17 suites / 58 tests), scoped `git diff --check`; frontend scoped `git diff --check -- package.json Dockerfile`. Pushed to Forgejo. +**Linked docs updated:** [[09 - Audits/DB Query & Schema Audit - 2026-06-06]] + +--- + ### 2026-06-07 — backend@f5e53cb — DB audit medium batch M24/M30/M39 **Commits:** `f5e53cb` @@ -26,7 +36,7 @@ entries on top. Maintained by agents per the rule in `../AGENTS.md`. **Commits:** `8fc2309` **Touched:** backend `src/db/schema/purchaseRequest.ts`, `src/db/schema/dispute.ts`, `src/services/dispute/DisputeService.ts`, `src/db/repositories/drizzle/DrizzleDisputeRepo.ts`, `src/db/repositories/drizzle/DrizzleReleaseHoldRepo.ts`, `src/db/migrations/0020_luxuriant_queen_noir.sql`, `src/db/migrations/0025_dispute_enums.sql`, `package.json`; docs `09 - Audits/DB Query & Schema Audit - 2026-06-06.md`, `09 - Audits/Activity Log.md` -**Why:** Close Medium M43/M44 by adding FK constraints to purchase_requests and child tables (categoryId, selectedOfferId, deliveryInfo, deliveryAddress, sellerDeliveryInfo, deliveryAttempts, serviceInfo, specifications, preferredSellers). Also close High H37 by converting disputes status/priority/category from plain text to pgEnum. DisputeService now wraps chat+dispute creation in a db.transaction for atomicity. +**Why:** Close Medium M43/M44 by adding FK constraints to purchase_requests and child tables (categoryId, selectedOfferId, deliveryInfo, deliveryAddress, sellerDeliveryInfo, deliveryAttempts, serviceInfo, specifications, preferredSellers). Also close High H37 by converting disputes status/priority/category from plain text to pgEnum. DisputeService now creates disputes through the transaction-bound Drizzle repo while preserving legacy chat compatibility. **Verification:** backend `npm run typecheck` (clean), `npm test -- --runTestsByPath __tests__/db-audit-critical-fks.test.ts __tests__/drizzle-marketplace-repo-batch.test.ts --runInBand` (2 suites / 8 tests passed). Pushed to Forgejo. **Linked docs updated:** [[09 - Audits/DB Query & Schema Audit - 2026-06-06]] diff --git a/09 - Audits/DB Query & Schema Audit - 2026-06-06.md b/09 - Audits/DB Query & Schema Audit - 2026-06-06.md index 9f96709..e6ef5e0 100644 --- a/09 - Audits/DB Query & Schema Audit - 2026-06-06.md +++ b/09 - Audits/DB Query & Schema Audit - 2026-06-06.md @@ -73,6 +73,10 @@ updated: 2026-06-07 | M16: `releaseDeletedUserEmail` read-then-write release race → one conditional `UPDATE ... WHERE email/status ... RETURNING` atomically releases deleted-user emails | `fcee958` v2.9.25 | | C6: `notifications.user_id` text recipient key → UUID FK to `users(id)` with legacy/UUID repo resolution and migration backfill | `38d0e76` v2.9.26 | | C7: `disputes` purchase-request/user relationship columns text → UUID FKs with legacy/UUID repo resolution and migration backfill | `b743b5e` v2.9.28 | +| H22: `DisputeService.createDispute` split chat/dispute writes → serializable dispute transaction, immediate chat cleanup on rollback, and TTL orphan-dispute-chat sweep | `8fc2309` / `4766eba` v2.9.32 | +| H23: `DisputeService.resolveDispute` dispute update + releaseHold separate writes → one serializable transaction with transaction-bound dispute/release-hold repos | `8fc2309` v2.9.30 | +| H28: dispute timeline/evidence read-modify-write arrays → atomic SQL JSONB append expressions | `8fc2309` v2.9.30 | +| H37: disputes status/priority/category plain text → pgEnum columns plus data-normalizing migration | `8fc2309` v2.9.30 | --- @@ -382,7 +386,7 @@ The login handler calls `user.save()` twice: once for `lastLoginAt` (line 407) a --- -### 22. DisputeService.createDispute: chat creation and dispute creation are not atomic +### 22. DisputeService.createDispute: chat creation and dispute creation are not atomic | **FIXED** `4766eba` v2.9.32 > **Category:** Missing Transaction | **File:** `src/services/dispute/DisputeService.ts:91-176` @@ -392,7 +396,7 @@ The service creates a chat (step 1, line 112) and then creates the dispute (step --- -### 23. DisputeService.resolveDispute: dispute update and releaseHold are not atomic +### 23. DisputeService.resolveDispute: dispute update and releaseHold are not atomic | **FIXED** `8fc2309` v2.9.30 > **Category:** Missing Transaction | **File:** `src/services/dispute/DisputeService.ts:307-341` @@ -442,7 +446,7 @@ The method reads the delivery code row at line 1377, checks `isUsed`/expired/cod --- -### 28. DrizzleDisputeRepo read-modify-write on timeline/evidence arrays has no transaction — concurrent writes silently overwrite each other +### 28. DrizzleDisputeRepo read-modify-write on timeline/evidence arrays has no transaction — concurrent writes silently overwrite each other | **FIXED** `8fc2309` v2.9.30 > **Category:** Missing Transaction | **File:** `src/db/repositories/drizzle/DrizzleDisputeRepo.ts:209-265, 304-336`