docs: sync from backend e8cb64c — DB audit bounded high cleanup
This commit is contained in:
@@ -12,6 +12,16 @@ entries on top. Maintained by agents per the rule in `../AGENTS.md`.
|
||||
|
||||
---
|
||||
|
||||
### 2026-06-07 — backend@e8cb64c, frontend@05e9bcd — DB audit bounded high cleanup and blog status enum
|
||||
|
||||
**Commits:** `e8cb64c` `05e9bcd`
|
||||
**Touched:** backend `src/services/blog/blogPostgresSchema.ts`, `src/db/migrations/0027_blog_post_status_enum.sql`, `src/db/backfill/backfill-users.ts`, `src/db/repositories/drizzle/DrizzleUserRepo.ts`, `src/db/repositories/drizzle/DrizzleMarketplaceRepo.ts`, targeted regression tests, `package.json`, `package-lock.json`; frontend `package.json`, `Dockerfile`; docs `09 - Audits/DB Query & Schema Audit - 2026-06-06.md`, `09 - Audits/Activity Log.md`, `RTK.md`
|
||||
**Why:** Normalize the audit fixed table so early C/H closures are keyed by issue ID, close H38 by enforcing `blog_post_status` in runtime schema and migration, and keep residual H1/H30-H33-style paths bounded with regression coverage. Added the CI/build freeze rule to the canonical docs RTK so agents diagnose CI before changing build procedure.
|
||||
**Verification:** backend `npm test -- --runInBand __tests__/blog-postgres-schema.test.ts __tests__/drizzle-payment-repo-export.test.ts __tests__/drizzle-user-repo.test.ts __tests__/drizzle-marketplace-repo-batch.test.ts __tests__/payment-migration.service.test.ts __tests__/auth-store-pg-query.test.ts __tests__/backfill-guard.test.ts` (7 suites / 52 tests), backend `npm run typecheck`, backend/frontend scoped `git diff --check`; frontend/backend version metadata confirmed at v2.9.43.
|
||||
**Linked docs updated:** [[09 - Audits/DB Query & Schema Audit - 2026-06-06]]
|
||||
|
||||
---
|
||||
|
||||
### 2026-06-07 — backend@55321c0, frontend@525d50a — restore last-green Woodpecker build procedure
|
||||
|
||||
**Commits:** `55321c0` `525d50a`
|
||||
|
||||
@@ -17,25 +17,25 @@ updated: 2026-06-07
|
||||
| Stats endpoint: 10 serial `findPurchaseRequests` queries → 1 `GROUP BY status` | `2484150` v2.9.13 |
|
||||
| Offer filter: per-offer `sameUser()` calls (N×2 queries) → resolve-once + in-memory filter | `2484150` v2.9.13 |
|
||||
| Seller notification fan-out: in-JS filter + 100-row hard cap → SQL `watchedCategory` filter, no limit | `2484150` v2.9.13 |
|
||||
| Auth user hydration: `rowToUser` child lookups per row → batched token/passkey/referrer hydration per result set | `4aa6ccb` v2.9.14 |
|
||||
| Auth user save: users/tokens/passkeys independent writes → single `BEGIN`/`COMMIT` transaction with rollback | `4aa6ccb` v2.9.14 |
|
||||
| Auth token/passkey save loops: one INSERT per child row → bulk token/passkey inserts inside the transaction | `4aa6ccb` v2.9.14 |
|
||||
| Bulk notification canonicalization: one UUID→legacy lookup per notification → one batched lookup per bulk call | `2a56f98` v2.9.15 |
|
||||
| Offer acceptance loser notifications: sequential per-offer INSERTs → one `createNotificationsBulk` call | `2a56f98` v2.9.15 |
|
||||
| Template batch conversion: first-seller templates fetched twice → first-pass template cache reused | `2a56f98` v2.9.15 |
|
||||
| Dispute statistics: four repeated status count scans → one status `GROUP BY` query | `2a56f98` v2.9.15 |
|
||||
| C1: Auth user hydration `rowToUser` child lookups per row → batched token/passkey/referrer hydration per result set | `4aa6ccb` v2.9.14 |
|
||||
| C8: Auth user save users/tokens/passkeys independent writes → single `BEGIN`/`COMMIT` transaction with rollback | `4aa6ccb` v2.9.14 |
|
||||
| H1: Auth token/passkey save loops one INSERT per child row → bulk token/passkey inserts inside the transaction | `4aa6ccb` v2.9.14 |
|
||||
| H2: Bulk notification canonicalization one UUID→legacy lookup per notification → one batched lookup per bulk call | `2a56f98` v2.9.15 |
|
||||
| H6: Offer acceptance loser notifications sequential per-offer INSERTs → one `createNotificationsBulk` call | `2a56f98` v2.9.15 |
|
||||
| H5: Template batch conversion first-seller templates fetched twice → first-pass template cache reused | `2a56f98` v2.9.15 |
|
||||
| H9: Dispute statistics four repeated status count scans → one status `GROUP BY` query | `2a56f98` v2.9.15 |
|
||||
| Chat query reads: full-table `findRows()` scan → SQL pushdown for participant/archive/unread filters with in-memory fallback only for unsupported predicates | `3ad3bbe` v2.9.16 |
|
||||
| Chat JSONB filters: missing `participants`/`unread_counts` GIN indexes → added schema indexes and migration `0020_chat_jsonb_indexes.sql` | `3ad3bbe` v2.9.16 |
|
||||
| Buyer purchase request list: per-request latest-payment lookup → one `DISTINCT ON (purchase_request_id)` payment query per page | `3ad3bbe` v2.9.16 |
|
||||
| Notification bulk mark/delete: serial per-id writes with no cap → set-based repo operations plus 100-id API cap | `3ad3bbe` v2.9.16 |
|
||||
| Payments admin list: unbounded `findAllPayments` plus per-row buyer/seller lookups → single joined payment/user query | `0835be9` v2.9.17 |
|
||||
| Seller template list: per-template seller/category lookups → batched seller/category page lookups | `0835be9` v2.9.17 |
|
||||
| Payment coordinator rejected-seller notifications: per-seller notification loop → one `createNotificationsBulk` call | `0835be9` v2.9.17 |
|
||||
| Category path lookup: one query per ancestor level → one recursive CTE returning root-to-leaf path | `0835be9` v2.9.17 |
|
||||
| Payment export: `listForExport` fetched all matching payments → bounded export query with default/max limits | `5ff0013` v2.9.18 |
|
||||
| Seller lookup: `findSellers` without input limit loaded all sellers → safe default cap while preserving explicit limits | `5ff0013` v2.9.18 |
|
||||
| Active template seller list/detail: full seller/template table scans → capped list query and scoped single-seller detail query | `5ff0013` v2.9.18 |
|
||||
| SHKeeper migration report: loaded all SHKeeper payments → bounded sorted scan with explicit `maxRecords` cap | `5ff0013` v2.9.18 |
|
||||
| C3: Chat JSONB filters missing `participants`/`unread_counts` GIN indexes → added schema indexes and migration `0020_chat_jsonb_indexes.sql` | `3ad3bbe` v2.9.16 |
|
||||
| C5: Buyer purchase request list per-request latest-payment lookup → one `DISTINCT ON (purchase_request_id)` payment query per page | `3ad3bbe` v2.9.16 |
|
||||
| H3: Notification bulk mark/delete serial per-id writes with no cap → set-based repo operations plus 100-id API cap | `3ad3bbe` v2.9.16 |
|
||||
| C4: Payments admin list unbounded `findAllPayments` plus per-row buyer/seller lookups → single joined payment/user query | `0835be9` v2.9.17 |
|
||||
| H4: Seller template list per-template seller/category lookups → batched seller/category page lookups | `0835be9` v2.9.17 |
|
||||
| H7: Payment coordinator rejected-seller notifications per-seller notification loop → one `createNotificationsBulk` call | `0835be9` v2.9.17 |
|
||||
| H8: Category path lookup one query per ancestor level → one recursive CTE returning root-to-leaf path | `0835be9` v2.9.17 |
|
||||
| H30: Payment export `listForExport` fetched all matching payments → bounded export query with default/max limits | `5ff0013` v2.9.18 |
|
||||
| H31: Seller lookup `findSellers` without input limit loaded all sellers → safe default cap while preserving explicit limits | `5ff0013` v2.9.18 |
|
||||
| H32: Active template seller list/detail full seller/template table scans → capped list query and scoped single-seller detail query | `5ff0013` v2.9.18 |
|
||||
| H33: SHKeeper migration report loaded all SHKeeper payments → bounded sorted scan with explicit `maxRecords` cap | `5ff0013` v2.9.18 |
|
||||
| M2: `updatePurchaseRequestStatus` 3rd redundant read → reuse first `currentRequest` with status override | `2abba67` v2.9.19 |
|
||||
| M5: `createOffer` fetched PR twice → cached first `requestForOffer` reused for notification path | `2abba67` v2.9.19 |
|
||||
| M7: `createReviewRecord` sequential `resolveUserUuid` → `Promise.all` parallel | `2abba67` v2.9.19 |
|
||||
@@ -90,6 +90,7 @@ updated: 2026-06-07
|
||||
| H16: batch template conversion request/offer/status writes split across service calls → proposal conversions use one serializable vital transaction; template usage remains explicitly non-vital | `957c356` v2.9.38 |
|
||||
| H17: template payment completion per-request status loop → one serializable bulk status update with an all-rows-updated guard | `957c356` v2.9.38 |
|
||||
| H18: email-code registration split referrer/user/temp writes → one serializable auth-store registration transaction, with referral bonus left post-commit best-effort | `957c356` v2.9.38 |
|
||||
| H38: `blog_posts.status` stored as text instead of pgEnum → runtime schema and migration `0027_blog_post_status_enum.sql` enforce `blog_post_status` | `e8cb64c` v2.9.43 |
|
||||
|
||||
---
|
||||
|
||||
@@ -559,13 +560,13 @@ status, priority, and category are `text` with TypeScript-only `$type<>` casts.
|
||||
|
||||
---
|
||||
|
||||
### 38. blogPosts.status stored as text instead of pgEnum
|
||||
### 38. blogPosts.status stored as text instead of pgEnum | **FIXED** `e8cb64c` v2.9.43
|
||||
|
||||
> **Category:** Wrong Schema | **File:** `src/db/schema/blogPost.ts:50`
|
||||
|
||||
`status` is declared as `text` with a `$type<BlogPostStatus>` cast only. Postgres accepts any string. The composite indexes `blog_posts_status_published_idx`, `blog_posts_category_status_idx`, and `blog_posts_featured_status_idx` all rely on this column and return incorrect results for mistyped values.
|
||||
|
||||
**Fix:** Create a `blog_post_status` pgEnum with values `('draft', 'published', 'archived')` and use it as the column type.
|
||||
**Fix:** `e8cb64c` adds `blog_post_status`, updates the runtime schema initializer so new tables use the enum, and adds migration `0027_blog_post_status_enum.sql` to normalize existing rows and convert `blog_posts.status` from text to the enum.
|
||||
|
||||
---
|
||||
|
||||
|
||||
8
RTK.md
8
RTK.md
@@ -18,6 +18,14 @@ Repository rules agents must follow for Amanat escrow work.
|
||||
- Do not bump versions for docs-only changes unless the user asks for a release/build number.
|
||||
- Mention the resulting frontend and backend version numbers in the final response.
|
||||
|
||||
## CI/Build Freeze
|
||||
|
||||
- During CI incident diagnosis, do not change Woodpecker pipeline files, Dockerfiles, build scripts, deploy commands, clone strategy, cache behavior, prune behavior, or the production build procedure unless the user explicitly asks for that exact change.
|
||||
- Diagnose and report the failure first. Classify it as clone/auth, Docker host storage, app build, deploy/compose, notification, or infrastructure before proposing any build-procedure edits.
|
||||
- Last-known-good build references are backend `5d7d2af1b35d4a595eefc2317a345ba5156fa833` and frontend `ade735281fdb712c026a45947ea52e17a3f8ecdf`.
|
||||
- Do not add Docker prune, cache cleanup, dependency-install rewrites, or host cleanup blocks to production pipelines without explicit approval. Treat host disk cleanup as an operational action by default.
|
||||
- Any CI/build change must have explicit user approval, a narrow stated scope, a verification plan, and the required version bump if it will trigger a build or deploy.
|
||||
|
||||
## Pre-Deploy CLI Verification
|
||||
|
||||
- For any backend or frontend change, run the focused CLI smoke test for the touched area **before pushing a commit that would trigger a build**. The image tracker patch-bumps per build, so a failed build still consumes a version slot.
|
||||
|
||||
Reference in New Issue
Block a user