72 KiB
title, tags, created
| title | tags | created | |||
|---|---|---|---|---|---|
| Activity Log |
|
2026-05-28 |
Activity Log
Append-only log of every git push from backend and frontend. Newest
entries on top. Maintained by agents per the rule in ../AGENTS.md.
2026-06-03 — frontend@9bafbbb — Telegram Mini App: full in-shell shop, account tab parity, and shopping cart (v2.8.57–v2.8.59)
Commits: a8ae1e3 (v2.8.57), 6dc3918 (v2.8.58), 9bafbbb (v2.8.59) — frontend only; backend stays at v2.8.56
Touched: telegram-mini-app-view.tsx (shell nav: openSellerId, overlayScreen='cart', BackButton dismissal chain), telegram-shop-view.tsx (cart badge header button, TelegramShopRow converted from <a href> to in-shell onOpen), telegram-seller-shop-view.tsx (new — seller header, active templates with budget/usage, add/remove-to-cart buttons, floating cart CTA), telegram-cart-view.tsx (new — qty stepper, remove, USDT total, "Continue to payment" → web checkout), telegram-account-view.tsx (new — profile header, preferences section, help section, sign-out with bottom-sheet confirm), hooks/use-telegram-seller-shop.ts (new — SWR over getSellerWithTemplates), hooks/use-telegram-cart.ts (new — localStorage app-request-template-checkout, custom tg-cart-changed event), hooks/use-telegram-shops.ts (new — SWR over getTemplateSellers), telegram locales (fa/en/types)
Why: Three sequential buyer-parity milestones shipped in one session. (1) v2.8.57: tapping a seller in فروشگاه previously opened the web dashboard inside the webview; the seller store now renders entirely in-shell with TelegramSellerShopView — seller header, active templates, budget/usage count — and template ordering hands off to the web from-template checkout where the wallet stack lives. (2) v2.8.58: the web account menu (تنظیمات عمومی، اعلانها، کیف پول، آدرسهای تحویل، Passkey) had no Mini App counterpart; all five are now accessible from the account tab — notifications open the existing in-shell overlay, the other four deep-link to web dashboard pages (labeled «در داشبورد وب باز میشود») because passkey and wallet require browser-context APIs unavailable in Telegram. (3) v2.8.59: phase 1 of full buyer parity — new useTelegramCart hook writes to the same localStorage key (app-request-template-checkout) that the web checkout provider reads, so the Mini App cart IS the web cart with no sync step; TelegramCartView adds qty controls, remove, and a "Continue to payment" link that hands off seamlessly. Remaining buyer-parity roadmap: offers view/accept on requests, delivery confirmation, payments list, points/referral, addresses CRUD, TON Connect payments (Telegram Wallet is TON-native; backend already has tonProofService).
Verification: tsc + eslint clean across all three commits. Admin verifies after deploy: (shop) فروشگاه → tap seller → in-shell shop → سفارش این قالب → web checkout; (cart) افزودن به سبد → cart badge → سبد overlay → ادامه و پرداخت → web checkout shows same items; (account) account tab → preferences rows → notifications overlay in-shell, remaining rows open web dashboard.
Linked docs updated: 04 - Flows/Telegram Mini App.md (major update — navigation model, all view files, shop/cart/checkout flow, account tab, SDK surfaces, API call table), 01 - Architecture/Frontend Architecture.md (updated — Telegram Mini App section)
2026-06-02 — backend@cf59726, frontend@a2b972b — normalize Postgres repository store modes
Commits: backend cf59726 (version 2.8.37), frontend a2b972b (version 2.8.37)
Touched:
- Backend:
src/db/repositories/factory.ts,src/services/health/healthCheckService.ts,__tests__/repository-factory-modes.test.ts,__tests__/health-check-service.test.ts,package.json,package-lock.json - Frontend:
package.jsonversion metadata only. Why: Fix migration-control drift found after enabling notification PG mode in dev. Repository factory flags now treatpostgresas an alias forpg, soNOTIFICATION_STORE=postgresactually resolves to the Drizzle notification repo. Release-hold mode is now independent from dispute mode, soDISPUTE_STORE=postgresno longer makes health or repository selection falsely report release holds as cut over. Verification: Backendnpm test -- --runTestsByPath __tests__/repository-factory-modes.test.ts __tests__/health-check-service.test.ts __tests__/notification-service-repo.test.ts --runInBand; backendnpm run typecheck; backend/frontendgit diff --check. Linked docs updated: Postgres Runtime Cutover Status
2026-06-02 — backend@882096f, deployment@8764fdf — enable notification Postgres dev cutover
Commits: backend b64995a and 882096f (version 2.8.36), frontend 28ad8e6 (version 2.8.36, already on remote), deployment 8764fdf
Touched:
- Backend:
src/services/marketplace/index.ts,__tests__/marketplace-runtime-import-surface.test.ts,package.json,package-lock.json - Deployment:
docker-compose.yml,gatus/config.yamlWhy: Continue MongoDB removal by detaching the unmounted legacy marketplace router export that still pulled in top-level Mongoose/model imports, and move notifications from PG-capable/operator-ready to PG-backed in the dev runtime. Dev Gatus now requires eight enabled Postgres stores and explicitly assertsstoreModes.notification == "postgres". Verification: Backendnpm run typecheck; backendnpm test -- --runTestsByPath __tests__/marketplace-runtime-import-surface.test.ts __tests__/blog-service-repo.test.ts __tests__/health-check-service.test.ts --runInBand; backend active-surface static scan for non-type top-levelmongoose/models/*imports returned no matches; backend/frontend/deploymentgit diff --check. Frontend push was not needed because remote frontend was already at2.8.36. Linked docs updated: Postgres Runtime Cutover Status
2026-06-02 — backend@f1ba14b, frontend@b94d8a9 — add notification Postgres backfill tooling
Commits: backend f1ba14b (version 2.8.34), frontend b94d8a9 (version 2.8.34)
Touched:
- Backend:
src/services/notification/notificationBackfill.ts,src/scripts/backfillNotificationPostgres.ts,src/db/backfill/backfill-notifications.ts,src/db/backfill/run-backfill.ts,scripts/smoke/notifications-postgres.sh,__tests__/notification-backfill.test.ts,package.json,package-lock.json - Frontend:
package.jsonversion metadata only. Why: Continue the MongoDB removal by making the already repo-backed notification domain operator-ready for Postgres cutover. Existing notification runtime paths usegetNotificationRepo(); this adds Mongo→Postgres backfill, ordered-runner inclusion, dry-run support, and a focused PG smoke for notification create/list/read/delete behavior. Verification: Backendnpm run typecheck; backendnpm test -- --runTestsByPath __tests__/notification-service-repo.test.ts __tests__/notification-backfill.test.ts __tests__/health-check-service.test.ts --runInBand; backendbash scripts/smoke/marketplace-core-postgres-backfill.sh(static checks passed; optional live dry-run skipped because migration DSNs were not set); backend active-surface static scan for non-type top-levelmongoose/models/*imports returned no matches; backend/frontendgit diff --check. The newscripts/smoke/notifications-postgres.shwas added but not run locally because noPG_URL/DATABASE_URL/POSTGRES_URLis configured in the backend env files. Linked docs updated: Postgres Runtime Cutover Status
2026-06-02 — backend@10de752, frontend@3dfbac2 — defer legacy Mongo runtime imports
Commits: backend 10de752 (version 2.8.33), frontend 3dfbac2 (version 2.8.33)
Touched:
- Backend:
src/infrastructure/database/connection.ts,src/services/health/healthCheckService.ts,src/services/admin/dataCleanupService.ts,src/services/payment/migration/reportService.ts,package.json,package-lock.json - Frontend:
package.jsonversion metadata only. Why: Continue removing MongoDB as a runtime dependency by deferring the remaining active startup/health/admin/report Mongoose/model loads. Legacy Mongo connection, health ping, admin cleanup, and SHKeeper migration report paths still work, but now load Mongoose/models only when those legacy actions actually run. Verification: Backendnpm run typecheck; backendnpm test -- --runTestsByPath __tests__/health-check-service.test.ts --runInBand; backendnpm test -- --runTestsByPath __tests__/payment-migration.service.test.ts --runInBand; backend static scan for non-type top-levelmongoose/models/*imports in active app/routes/services/infrastructure returned no matches; backend/frontendgit diff --check;BASE_URL=https://dev.amn.gg bash scripts/smoke/backend-health.shpassed against dev before push. Linked docs updated: Postgres Runtime Cutover Status
2026-06-02 — backend@134d155, frontend@18af5dd — lazy-load PG-capable store Mongo fallbacks
Commits: backend 134d155 (version 2.8.32), frontend 18af5dd (version 2.8.32)
Touched:
- Backend:
src/services/config/configStore.ts,src/services/marketplace/reviewStore.ts,src/services/marketplace/shopSettingsStore.ts,package.json,package-lock.json - Frontend:
package.jsonversion metadata only. Why: Continue removing MongoDB as a runtime dependency by making the already PG-capable config, review, and shop-settings stores avoid top-level Mongoose/model imports. Mongo fallback/backfill paths still lazy-load the legacy models when they are actually used, preserving rollback/mirror behavior. Verification: Backendnpm run typecheck; backendbash scripts/smoke/marketplace-core-postgres-backfill.sh(static Jest checks passed; optional live dry-run skipped becauseMIGRATION_MONGO_URL/MIGRATION_PG_URLwere not set); backendnpx jest __tests__/health-check-service.test.ts __tests__/telegram-service.test.ts __tests__/telegram-auth.test.ts --runInBandrerun outside the sandbox afterMongoMemoryServerhit local bind restrictions (16/16 passed); backend/frontendgit diff --check. Linked docs updated: Postgres Runtime Cutover Status
2026-06-01 — backend@2c5c3c7, frontend@775a73b — route funds ledger through payment repo seam
Commits: backend 2c5c3c7, frontend 775a73b (backend 2.8.20, frontend 2.8.20)
Touched:
- Backend:
src/services/payment/ledger/fundsLedgerService.ts,src/db/repositories/factory.ts,src/db/repositories/drizzle/DrizzlePaymentRepo.ts,src/db/repositories/mongo/MongoPaymentRepo.ts,__tests__/payment-ledger.service.test.ts,__tests__/mongo-payment-repo.test.ts,scripts/smoke/funds-ledger-repo.sh,package.json,package-lock.json - Frontend:
package.json,Dockerfileversion metadata only. Why: Start replacing the remaining PG-capable repository stores with a low-risk money-core slice. Funds ledger appends and balance reads now go throughgetPaymentRepo(), soREPO_PAYMENT=mongo|dual|pgcan control the ledger path. The repo factory now lazy-loads PG/dual implementations so importing it in Mongo mode no longer requiresPG_URL. Mongo/Drizzle payment repo stats were aligned with live behavior (buyerId, nestedamount.amount, andcompletedcounted as successful), and Drizzle ledger balance reads now match external/string refs as well as UUID refs. Verification: Backendgit pull --rebase --autostash(already up to date); backendscripts/smoke/funds-ledger-repo.sh; backendnpm test -- --runTestsByPath __tests__/payment-release-refund-orchestration.test.ts __tests__/money-safety.test.ts --runInBand(money-safetyskipped by its own env guard); backendnpm run typecheck -- --pretty false; backendnpm run build:server; frontendgit pull --rebase --autostash(already up to date); frontendnpx tsc --noEmit --project tsconfig.json; frontendnpm run build(passed with the existing non-fatal SSRgetPostsfetch refusal during static page generation); backend/frontendgit diff --check. Linked docs updated: Postgres Runtime Cutover Status, MongoDB to PostgreSQL Migration Plan (Drizzle), Payment
2026-06-01 — deployment@38cb75b — default PG-capable stores to Postgres in dev
Commits: deployment 38cb75b
Touched:
- Deployment:
docker-compose.yml,gatus/config.yamlWhy: Move the existing PG-capable runtime stores from opt-in env settings to the default dev runtime:AUTH_STORE,CONFIG_STORE,ADDRESS_STORE,CATEGORY_STORE,LEVEL_CONFIG_STORE,SHOP_SETTINGS_STORE, andREVIEW_STOREnow default topostgresin compose. Gatus now verifieschecks.postgres.enabledStoreCount >= 7and asserts each of those store modes ispostgres, so monitoring catches partial cutover drift. Verification: Deployment YAML parse viaruby -e 'require "yaml"; YAML.load_file("docker-compose.yml"); YAML.load_file("gatus/config.yaml"); puts "yaml ok"'; deploymentdocker compose config --quiet. Linked docs updated: Postgres Runtime Cutover Status, Monitoring, Gatus Monitoring - Proposed Config
2026-06-01 — backend@c5db471, frontend@f424a03 — add RequestTemplate Postgres backfill surface
Commits: backend c5db471, frontend f424a03 (backend 2.8.19, frontend 2.8.19)
Touched:
- Backend:
src/db/schema/requestTemplate.ts,src/db/backfill/backfill-requestTemplates.ts,src/db/backfill/run-backfill.ts,src/db/backfill/_idMap.ts,src/db/schema/purchaseRequest.ts,src/db/migrations/0010_request_templates.sql,src/db/migrations/meta/_journal.json,__tests__/marketplace-core-backfill.test.ts,package.json,package-lock.json - Frontend:
package.json,Dockerfileversion metadata only. Why: Start the 2–8 migration pass with the lowest-risk marketplace-core gap.RequestTemplatenow has a PG schema, id-map collection entry, ordered backfill step, and marketplace-core runner coverage. The same migration also adds the missing unique index forpurchase_request_specifications (purchase_request_id, key), matching the existing backfill upsert target. Verification: Backend./scripts/smoke/marketplace-core-postgres-backfill.sh(static checks passed; optional live dry-run skipped becauseMIGRATION_MONGO_URL/MIGRATION_PG_URLwere not set); backendnpm test -- --runTestsByPath __tests__/marketplace-core-backfill.test.ts; backendnpm run typecheck -- --pretty false; backendnpm run build:server; frontendnpx tsc --noEmit --project tsconfig.json; frontendnpm run build(passed with the existing non-fatal SSRgetPostsfetch refusal during static page generation); backend/frontendgit diff --check. Linked docs updated: RequestTemplate, Postgres Runtime Cutover Status, MongoDB to PostgreSQL Migration Plan (Drizzle), MongoDB to PostgreSQL Migration Guide
2026-06-01 — backend@1543b53, frontend@457de07 — enforce unique active categories
Commits: backend 1543b53, frontend 457de07 (backend 2.8.17, frontend 2.8.17)
Touched:
- Backend:
src/services/marketplace/categoryStore.ts,src/services/marketplace/CategoryService.ts,src/db/schema/category.ts,src/db/migrations/0009_unique_active_categories.sql,src/db/migrations/meta/_journal.json,__tests__/category-store.test.ts,scripts/smoke/categories-postgres-unique.sh,scripts/smoke/reference-stores-postgres.sh,package.json,package-lock.json - Frontend:
package.jsonversion metadata only. Why: Category seed/backfill reruns could leave multiple active rows with the same visible label, which surfaced in the category dropdown as repeated Persian names. The PG category store now deactivates duplicate active rows before adding a normalized active-name unique index, repoints existing category references to the kept row, catches duplicate inserts as idempotent creates, and dedupes cached/list responses so stale rows cannot leak into the UI. Verification: Backendnpm test -- --runTestsByPath __tests__/category-store.test.ts __tests__/postgres-client.test.ts; backendnpm run typecheck; backendnpm run build:server; backendPG_URL=postgresql://escrow:throwaway@127.0.0.1:5434/escrow_migration_test ./scripts/smoke/categories-postgres-unique.sh; frontendnpx tsc --noEmit --project tsconfig.json; frontendnpm run build(passed with the existing non-fatal SSRgetPostsfetch refusal during static page generation). Linked docs updated: Category, Postgres Runtime Cutover Status, MongoDB to PostgreSQL Migration Plan (Drizzle), MongoDB to PostgreSQL Migration Guide
2026-06-01 — backend@6df113d, frontend@0f1db64 — harden marketplace-core Postgres backfill
Commits: backend 6df113d, frontend 0f1db64 (backend 2.8.13, frontend 2.8.13)
Touched:
- Backend:
src/db/backfill/backfill-purchaseRequests.ts,src/db/backfill/run-backfill.ts,__tests__/marketplace-core-backfill.test.ts,scripts/smoke/marketplace-core-postgres-backfill.sh,package.json,package-lock.json - Frontend:
src/components/hook-form/rhf-select.tsx,tsconfig.json,yarn.lock,package.jsonWhy: The next Postgres migration slice is marketplace core. The existing PurchaseRequest/SellerOffer backfill path had real cutover blockers: thepurchase_requestsinsert omittedupdated_at, preferred sellers wrote the wrong junction column, and selected offers were remapped before seller offers existed. The runner now exposes amarketplaceCoregroup and a post-offer selected-offer remap step. Frontend typecheck was restored after the pulled request-template changes by installing the declaredrehype-sanitizelock entry, allowingdisplayEmptythroughRHFSelect, and silencing TS6'sbaseUrldeprecation gate. Verification: Backend./scripts/smoke/marketplace-core-postgres-backfill.sh(static checks passed; optional live dry-run skipped becauseMIGRATION_MONGO_URL/MIGRATION_PG_URLwere not set); backendnpm run typecheck; backendnpm run build:server; frontendnpx tsc --noEmit --project tsconfig.json; frontendnpm run build(passed with a non-fatal SSRgetPostsfetch refusal during static page generation); backend/frontendgit diff --check. Linked docs updated: Postgres Runtime Cutover Status, MongoDB to PostgreSQL Migration Plan (Drizzle), MongoDB to PostgreSQL Migration Guide
2026-06-01 — backend@ea43862, frontend@b4ea7c9 — expose Postgres store modes in health
Commits: backend ea43862, frontend b4ea7c9 (backend 2.8.11, frontend 2.8.11)
Touched:
- Backend:
src/infrastructure/postgres/client.ts,src/services/health/healthCheckService.ts,__tests__/postgres-client.test.ts,package.json,package-lock.json - Frontend:
package.json,Dockerfileversion metadata only. Why: Phase 0 of the Postgres cutover needed runtime visibility before moving another domain./api/healthnow reportschecks.postgres.storeModes,enabledStores, andenabledStoreCountwhile preserving the existingconfigured/required/status semantics. This lets Gatus and operators verify which opt-in stores are actually PG-backed in dev. Backend was rebased on Mojtaba's2be91d2authStore fix before push. Verification: Backendnpm test -- --runTestsByPath __tests__/postgres-client.test.ts; backendnpm run typecheck -- --pretty false; backendnpm run build; backend focused health smoke against local Mongo/Redis containers andescrow-pgmig-testPostgres asserted all seven enabled PG stores inchecks.postgres; frontendnpx tsc --noEmit --ignoreDeprecations 6.0; backend/frontendgit diff --check. Linked docs updated: Monitoring, Postgres Runtime Cutover Status
2026-06-01 — backend@1757f1e, frontend@600dd0d, deployment@6db02b0 — Postgres runtime cutover stores and health monitoring
Commits: backend 1757f1e, frontend 600dd0d, deployment 6db02b0 (backend 2.8.9, frontend 2.8.9)
Touched:
- Backend:
src/infrastructure/postgres/client.ts,src/infrastructure/database/connection.ts, auth/config/address/category/level/shop/review store facades, backfill scripts, smoke scripts,/api/health,package.json,package-lock.json - Frontend:
package.json,Dockerfileversion metadata only. - Deployment:
docker-compose.ymlPostgres service/store env wiring,gatus/config.yamlPostgres health assertions. Why: Continue the MongoDB-to-Postgres runtime cutover by moving auth-owned users and Telegram auth records, confirmation thresholds, user addresses, and the first reference/marketplace domains behind opt-in Postgres store flags while keeping Mongo as the default and rollback mirror. Monitoring now treats Postgres as a required health dependency when any PG-backed store is enabled. Verification: Backendnpm run typecheck -- --pretty false; backendnpm run build; backendPG_URL=postgres://escrow:throwaway@127.0.0.1:5434/escrow_migration_test MONGODB_URI=mongodb://127.0.0.1:27018/reference-smoke DB_NAME=reference-smoke scripts/smoke/reference-stores-postgres.sh; backend focused health smoke assertedchecks.postgres.ok/configured/required; local backendBASE_URL=http://127.0.0.1:5011 scripts/smoke/auth-basic.sh; local backendBASE_URL=http://127.0.0.1:5011 scripts/smoke/confirmation-thresholds.sh; local backendBASE_URL=http://127.0.0.1:5011 JWT_SECRET=test-secret scripts/smoke/addresses-basic.sh; frontendnpx tsc --noEmit --ignoreDeprecations 6.0; deploymentruby -e 'require "yaml"; YAML.load_file("gatus/config.yaml")'. Linked docs updated: Postgres Runtime Cutover Status, MongoDB to PostgreSQL Migration Plan (Drizzle), API Overview, Monitoring, Gatus Monitoring - Proposed Config
2026-05-31 — backend@8e03360, frontend@228eed2 — keep auth and health checks resilient under load
Commits: backend 8e03360, frontend 228eed2 (backend 2.6.84, frontend 2.7.24)
Touched:
- Backend:
src/app.ts,src/services/health/healthCheckService.ts,package.json,package-lock.json - Frontend:
package.json,package-lock.jsonversion bump only. Why: A dev performance run consumed the global 100/15m limiter and blocked/api/auth/login; repeated/api/healthcalls also drove the external Request Network reachability probe into429, making Gatus reportstatus: degradedeven though Mongo/Redis/app were healthy. Auth routes now bypass the global limiter and rely on the auth-specific limiter, and the RN health subcheck is cached and treats non-5xx HTTP responses as upstream reachable. Verification: Backendnpm test -- --runTestsByPath __tests__/health-check.test.ts; backendnpm run typecheck; backendgit diff --check; frontendnpx tsc --noEmit --ignoreDeprecations 6.0; frontendgit diff --check. Dev login was manually verified after resetting the backend limiter state. Linked docs updated: Monitoring, Gatus Monitoring - Proposed Config
2026-05-31 — backend@cbc32dc, frontend@08e8da9 — seller-owned template delivery and payment rails
Commits: backend cbc32dc, frontend 08e8da9 (backend 2.6.83, frontend 2.7.23)
Touched:
- Backend:
src/models/RequestTemplate.ts,src/services/marketplace/RequestTemplateService.ts,src/services/marketplace/requestTemplateRoutes.ts,src/services/marketplace/requestTemplateController.ts,__tests__/marketplace-request-budget-validation.test.ts,scripts/smoke/marketplace-request-budget.sh,package.json,package-lock.json - Frontend:
src/sections/request-template/request-template-checkout-billing-address.tsx,src/sections/request-template/request-template-checkout-payment.tsx,src/sections/request-template/request-template-new-edit-form.tsx,src/sections/request-template/request-template-details-summary.tsx,src/sections/request-template/view/seller-shop-view.tsx,src/sections/request-template/view/public-seller-shop-view.tsx,src/web3/components/multi-seller-provider-payment.tsx,src/actions/request-template.ts,src/types/request-template.ts,src/sections/request-template/context/types.ts,package.json,package-lock.jsonWhy: Template checkout let buyers choose delivery even though fulfillment is a seller decision, and payment creation could fail when a seller/template had no usable network/token allowlist. Sellers now choose physical vs online delivery on the template, new templates require at least one chain/token rail, checkout asks buyers only for the needed address/email details, and template payment intents resolve rails with the realtemplateId. Verification: Backendnpm test -- --runTestsByPath __tests__/marketplace-request-budget-validation.test.ts; backendnpm run typecheck; backendgit diff --check; backendBASE_URL=http://localhost:5001 ./scripts/smoke/marketplace-request-budget.shskipped with exit 77 becauseACCESS_TOKENandCATEGORY_IDwere not set; frontendnpx tsc --noEmit --ignoreDeprecations 6.0; frontendgit diff --check. No browser verification was possible because the Browser tool was unavailable in this session. Linked docs updated: RequestTemplate, PurchaseRequest, ShopSettings, Marketplace API, Payment API, Purchase Request Flow, Seller Guide
2026-05-31 — backend@a4d72df, frontend@07db9b0, scanner@ca62e7a — cap confirmations at per-chain acceptance floors
Commits: backend a4d72df, frontend 07db9b0, scanner ca62e7a (backend 2.6.82, frontend 2.7.22, scanner 0.1.7)
Touched:
- Backend:
src/services/payment/safety/confirmationThresholdService.ts,src/routes/amnScannerWebhookRoutes.ts,src/services/payment/requestNetwork/requestNetworkRoutes.ts,src/services/payment/adapters/amnPayAdapter.ts,src/services/admin/confirmationThresholdRoutes.ts,src/services/payment/requestNetwork/supportedChains.json,__tests__/confirmation-threshold-service.test.ts,package.json,package-lock.json - Frontend:
src/sections/payment/payment-table-row.tsx,src/sections/payment/view/payment-details-view.tsx,package.json,package-lock.json - Scanner:
supported-chains.json,webhook.go,chain.go,tron_chain.go,ton_chain.go,main.go,README.md,VERSION,webhook_test.goWhy: Confirmation depth should be a chain-specific acceptance floor, roughly a ten-minute safety window, not an endlessly increasing block counter. The backend now clamps runtime settings below the chain floor, caps stored settled confirmations at the effective threshold, sends the same threshold to AMN scanner intents, and the scanner includes the capped accepted count in webhooks. Frontend payment views show settled confirmation counts with a+suffix. Verification: Backendnpm test -- --runTestsByPath __tests__/confirmation-threshold-service.test.ts __tests__/transaction-safety-provider.test.ts; backendnpm run typecheck; backendBASE_URL=https://dev.amn.gg ./scripts/smoke/rn-webhook.sh; backendgit diff --check; scannergo test ./...; scannergit diff --check; frontendnpx tsc --noEmit --ignoreDeprecations 6.0; frontendgit diff --check. Linked docs updated: Payment, Payment API, Scanner API, Payment Flow - Scanner, ScannerIntent, Scanner Architecture, Scanner Operations, Environment Variables
2026-05-31 — backend@896f17f, frontend@fd8e797 — persist webhook confirmations for scanner payments
Commits: backend 896f17f, frontend fd8e797 (backend 2.6.81, frontend 2.7.21)
Touched:
- Backend:
src/routes/amnScannerWebhookRoutes.ts,src/services/payment/requestNetwork/requestNetworkRoutes.ts,src/services/payment/safety/transactionSafetyProvider.ts,__tests__/transaction-safety-provider.test.ts,package.json,package-lock.json - Frontend:
package.json,package-lock.jsonversion bump only. Why:dev.amn.ggshowed a confirmed AMN scanner payment withblockchain.confirmations = 0. Scanner webhooks reportstatus: "confirmed", but transaction safety only evaluated"completed"statuses, so no verifier evidence was produced. The webhook routes now persist confirmations from safety evidence, scanner/RN payloads, or the chain confirmation threshold fallback when the provider already says confirmed/completed. Verification: Backendnpm test -- --runTestsByPath __tests__/transaction-safety-provider.test.ts; backendnpm run typecheck; backendgit diff --check; frontendnpx tsc --noEmit --ignoreDeprecations 6.0; frontendgit diff --check. Could not inspect the actualdev.amn.ggpayment row because SSH to193.180.213.68rejected the available key. Linked docs updated: Payment, Payment API, Payment Flow - Scanner
2026-05-31 — backend@cab0719, frontend@ec2f765 — align request budget validation after Postgres migration
Commits: backend cab0719, frontend ec2f765 (backend 2.6.80, frontend 2.7.20)
Touched:
- Backend:
src/shared/constants/marketplace.ts,src/models/PurchaseRequest.ts,src/models/RequestTemplate.ts,src/services/marketplace/requestTemplateRoutes.ts,src/services/marketplace/PurchaseRequestService.ts,src/db/schema/purchaseRequest.ts,src/db/repositories/drizzle/DrizzleMarketplaceRepo.ts,__tests__/marketplace-request-budget-validation.test.ts,scripts/smoke/marketplace-request-budget.sh - Frontend:
package.json,package-lock.jsonversion bump only. Why: Product/template creation could return400when the UI senturgency: "urgent", and template-to-purchase conversion could later fail when a template budget usedUSD/EUR/IRRwhilePurchaseRequestonly acceptedUSDT/USDC. Runtime Mongoose validation, request-template route validation, and the PGbudget_currencyenum now shareUSD,EUR,IRR,USDT,USDC; urgency validation includesurgent. Verification: Backendnpm test -- --runTestsByPath __tests__/marketplace-request-budget-validation.test.ts; backendnpm run typecheck; backendgit diff --check; frontendnpx tsc --noEmit --ignoreDeprecations 6.0; smoke helper added atscripts/smoke/marketplace-request-budget.shbut not run against dev because noACCESS_TOKEN/CATEGORY_IDwere available in this session. Linked docs updated: PurchaseRequest, RequestTemplate, Marketplace API, MongoDB to PostgreSQL Migration Guide, MongoDB to PostgreSQL Migration Plan (Drizzle), Postgres Runtime Cutover Status, Data Model Overview, Payment
2026-05-31 — nick-doc@local — clarify Postgres runtime cutover status
Commits: docs-only sync after backend 3a50dc4 (integrate-main-into-development, backend 2.6.79)
Touched:
- Added Postgres Runtime Cutover Status.
- Updated overview, architecture, data-model, payment API, env, database-ops, migration-plan, migration-guide, and oracle checkout docs.
Why: Correct the overbroad assumption that the promoted Postgres branch means normal runtime traffic is already PG-backed. The code has Postgres infrastructure, migrations, repository classes, and conditional
payment_quotes, but live services still call Mongoose directly and Mongo remains authoritative until repository wiring/backfill/shadow-read cutover is completed. Verification: Code audit viargon backendorigin/integrate-main-into-development@3a50dc4: no runtimecreateRepositories()/get*Repo()use outsidesrc/db/repositories/factory.ts; only normal service import ofsrc/db/client.tsisservices/payment/priceOracle/quoteRepo.ts. Linked docs updated: Postgres Runtime Cutover Status, System Overview, Tech Stack, System Architecture, Backend Architecture, Database Strategy - Mongo vs Postgres Assessment, Data Model Overview, Payment, Payment API, Environment Variables, Database Operations, MongoDB to PostgreSQL Migration Guide, MongoDB to PostgreSQL Migration Plan (Drizzle), Oracle Pricing & Stablecoin Depeg Protection, Oracle Depeg Checkout — UI Implementation Guide
2026-05-31 — backend@3a50dc4 — promote Postgres integration branch with oracle/depeg + gasless backports
Commits: backend 11bfd02 74d73c5 1730c4d 148c803 8aa4473 a5e4da2 3a50dc4 (backend 2.6.76 → 2.6.79)
Touched:
- Branches: preserved old
integrate-main-into-developmentasintegrate-main-into-development-old; promotedfeat/pg-money-core-migrationtointegrate-main-into-development. - Payment routing:
requestNetworkRoutes.ts,requestNetworkPayInService.ts,amnScannerPayInService.ts,permitRelay.ts,amnPayAdapter.ts - Oracle/depeg:
priceOracle/*,paymentQuote.ts, migration0008_giant_winter_soldier.sql,Payment.ts,SellerOffer.ts - Tests/config:
oracle-depeg-protection.test.ts,request-network-payin.test.ts,.env.example,package.json,package-lock.jsonWhy: Combine the old integration branch's AMN scanner rail-switch fix and partial gasless permit work with the Postgres money-core branch and oracle/depeg quote engine. The final fix resolves the PG payment id throughpayments.legacy_object_id/id_mapbefore writingpayment_quotes, recordspg_dualwrite_gapsif PG is behind, and keeps the Mongo quote mirror coherent during dual-write. Verification:npm run typecheck -- --pretty false;npm test -- --runInBand __tests__/oracle-depeg-protection.test.ts;npm test -- --runInBand __tests__/request-network-payin.test.ts __tests__/request-network-adapter.test.ts __tests__/request-network-webhook.test.ts __tests__/sweep-service.test.ts. The PG decimal integration cases in the oracle suite skipped because no localPG_URL/MIGRATION_PG_URLwas configured. Linked docs updated: Payment, SellerOffer, Payment API, Environment Variables, Oracle Pricing & Stablecoin Depeg Protection, PRD - Gasless Buyer Payments (Roadmap)
2026-05-30 — frontend@9013b70, c77cf82, 8add494 — staged node-package upgrade + TS6 test fix + lint sweep
Commits: 8add494 c77cf82 9013b70
Touched:
- Deps (
package.json,yarn.lock): TypeScript 5→6, Jest 29→30, Tiptap 2→3 (all 11 sub-packages), i18next 25→26, react-i18next 15→17, @types/node 22→25, @types/jest 29→30, react-dropzone 14→15, react-apexcharts 1→2, mui-one-time-password-input 5→7, React 19.1→19.2, MUI 7.1→7.3 (in-range), zod 4.0→4.4. Constraints bumped to tested floors (@mui/material ^7.3.11,wagmi ^2.19.5, etc.). Version bumped 2.7.9 → 2.7.10. - Code fixes for new types:
src/theme/with-settings/update-core.ts(castcurrentSchemeviaRecord<string,unknown>after MUI 7.3 tightenedColorSystemOptions),src/components/editor/components/code-highlight-block.tsx(castNodeViewContent as='code'→'code' as 'div'for Tiptap 3 stricter prop typing). - Test infra:
jest.config.js(point ts-jest attsconfig.test.jsonexplicitly, ignore TS5101/TS5011),tsconfig.test.json(addrootDir: "."andignoreDeprecations: "6.0"). - Security hygiene:
.env.local+.env.productionremoved from tracking; added to.gitignore. Existing values still in git history — rotate any leaked credentials. - Lint sweep:
yarn lint:fixapplied across 64 files insrc/— mostlyperfectionist/sort-importsreorders and unused-imports removals. - Docs:
AGENTS.mdgained an "Enforced project conventions" section covering Prettier, ESLint, TypeScript, and the centralizedsrc/theme/structure.CLAUDE.mdis now a symlink →AGENTS.mdso Claude Code reads the same rules. - Tooling:
scripts/upgrade-packages.sh(reusable staged-upgrade runner with snapshot + auto-rollback) andscripts/UPGRADE-PLAN.md(strategy + per-stage rationale) added..upgrade-backups/added to.gitignore.
Why: Many runtime / dev dependencies were 3–7 minors behind; the audit was triggered by a request to "update all node packages without breaking the build." Did it as eight staged groups (in-range → @types → ESLint → Jest → Tiptap → i18next → misc → TypeScript), each gated by yarn build. Three stages were pulled back: ESLint 10 (eslint-plugin-react@7 incompatible with new context API), wagmi 3 (@coinbase/wallet-sdk declares window.ethereum: unknown, breaks type union with viem), MUI 7→9 (AGENTS.md pins to v7).
Verification: yarn build passes after every stage (34–44s, all 57 routes). yarn test recovered from "45 suites fail, 0 tests run" (TS6 blocker) to 530 tests pass, 18 unrelated mock failures. yarn lint went 204 → 21 problems (the remaining 5 errors are pre-existing: 2× @ts-nocheck, 3× no-bitwise). Dev server (/, /auth/jwt/sign-in, /post, /shop, /dashboard, /telegram) all return 200. Manual smoke test of the Tiptap editor + wagmi connect flow is still recommended before promoting to prod.
Linked docs updated: none yet — 07 - Development/ should grow a "Node dependency upgrade runbook" pointing at frontend/scripts/UPGRADE-PLAN.md and the staged-rollback pattern. Also worth promoting the new AGENTS.md conventions section to 07 - Development/Coding Standards.md.
2026-05-29 — backend@cdc8df1 — AMN Pay Scanner integration (retire Request Network)
Commits: backend cdc8df1, scanner 8fee27e
Touched:
- Backend:
src/services/payment/adapters/amnPayAdapter.ts,src/routes/amnScannerWebhookRoutes.ts,src/services/payment/adapters/types.ts,src/services/payment/providerConfig.ts,src/app.ts,.env.example,docker-compose.dev.yml,docker-compose.production.yml - Scanner (new repo):
scanner/*.go,Dockerfile,supported-chains.json - Frontend:
src/actions/network-registry.ts,src/sections/admin/networks/networks-list-view.tsxWhy: Implement AMN Pay Scanner perPRD - Retire Request Network — In-House Payment Scanner.md. Standalone Go microservice scansERC20FeeProxyTransferWithReferenceAndFeeevents directly, eliminating RN API dependency. Supports any destination address (derived HD wallets enabled). Parallel run: RN stays active for existing payments; new payments route to scanner whenAMN_SCANNER_URLis configured. Verification:tsc --noEmitclean. Scanner binary builds (go build). Go tests pass (3/3). Frontend networks page renders scanner lag column. Linked docs updated: 07 - Development/Environment Variables, PRD - Retire Request Network — In-House Payment Scanner
2026-05-29 — backend@7688f57 — Sweep gas strategy: PermitPull + GasTopUp signers
Commits: backend 7688f57
Touched:
- Backend:
src/services/payment/wallets/sweepService.ts,__tests__/sweep-service.test.ts,.env.exampleWhy: Implement hybrid two-signer sweep strategy perPRD - Sweep Gas Strategy - Permit Pull vs Gas Top-Up.md.PermitPullSweepSigneruses EIP-2612 permit for non-BSC chains (ETH, Arbitrum, Polygon, Base) so derived addresses never need native gas.GasTopUpSweepSignerhandles BSC by topping up BNB from a master wallet before the derived address callstransfer().getSweepSigner(chainId, tokenSymbol)auto-selects the correct signer. StaticPERMIT_CAPABLE_TOKENSmap seeded from on-chain audit 2026-05-29. Verification:tsc --noEmitclean.npx jest __tests__/sweep-service.test.ts— 31/31 pass (including 16 new tests for auto-selection and permit capability matrix). Linked docs updated: 07 - Development/Environment Variables, PRD - Sweep Gas Strategy - Permit Pull vs Gas Top-Up
2026-05-28 — deployment@4e8658d — Gatus monitoring: Docker service + config
Commits: deployment 1ac2e74 → 4e8658d
Touched: deployment/gatus/config.yaml, deployment/docker-compose.yml, deployment/.env
Why: Add Gatus monitoring service to the deployment stack. Config covers backend-dev, backend-prod, frontend-dev, frontend-prod, and external deps (RN API, Chainalysis, BSC RPC). Telegram alerting configured. Service exposed via Traefik at gatus.ch.manko.yoga.
Verification: Config file validated against Gatus schema. Awaiting docker-compose up -d gatus on server.
Linked docs updated: 08 - Operations/Gatus Monitoring - Proposed Config
2026-05-28 — backend@6c01a30 — Gatus monitoring: GET /api/health endpoint
Commits: backend 19f7eb9 → 44579d6 → 6c01a30 (2.6.48 → 2.6.49)
Touched:
- Backend:
src/services/health/healthCheckService.ts,src/services/health/index.ts,src/app.ts,__tests__/health-check.test.tsWhy: ImplementGET /api/healthfor Gatus monitoring. Exposes 5 checks (db, redis, rnChainRegistry, rnTokenRegistry, rnApi) in a single public endpoint. Status semantics:ok|degraded|down(503 when DB fails). Each check includeslatencyMs; registry checks include counts. Rate limiter and request logging skip/api/health. 5 route-level unit tests cover ok/degraded/down transitions. Verification:tsc --noEmitclean.npx jest __tests__/health-check.test.ts— 5/5 pass. Linked docs updated: 08 - Operations/Gatus Monitoring - Proposed Config
2026-05-28 — backend@19f7eb9, frontend@60ee6fb — Task #10: AML screening (Chainalysis, seller-paid, seller opt-in)
Commits: backend 441c8be → 80ba046 → 19f7eb9 (2.6.46 → 2.6.47), frontend 717d5c8 → b7540f5 → 60ee6fb (2.6.46 → 2.6.47)
Touched:
- Backend:
src/services/payment/safety/amlProvider.ts,src/services/payment/safety/chainalysisProvider.ts,src/services/payment/safety/amlScreeningService.ts,src/services/payment/safety/transactionSafetyProvider.ts,src/services/payment/paymentCoordinator.ts,src/services/admin/amlConfigRoutes.ts,src/models/SellerOffer.ts,src/app.ts,.env.example - Frontend:
src/sections/request/components/seller-steps/step-1-send-proposal.tsx,src/types/marketplace.tsWhy: Task #10 implementation. Chainalysis Public Sanctions API integration for seller-paid AML screening. Seller can opt-in per-offer viarequireAmlCheck+amlBlockOnFailuretoggles.TransactionSafetyProviderscreens buyer source address after on-chain transfer verification.paymentCoordinatordeductsAML_CHECK_COST_USD(default 0, API is free) from seller escrow on payment completion. Admin routes for AML config. Verification: Frontendtsc --noEmitclean. Backend relevant tests pass (module resolution issues in unrelated test files). Linked docs updated: 02 - Data Models/SellerOffer, 03 - API Reference/Admin API, 04 - Flows/Escrow Flow
2026-05-28 — backend@441c8be, frontend@717d5c8 — Task #9: Per-chain confirmation thresholds + admin UI
Commits: backend 4a85737 → 441c8be (2.6.47 → 2.6.48), frontend 0ebb2f1 → 717d5c8 (2.6.46 → 2.6.48)
Touched:
- Backend:
src/models/ConfigSetting.ts,src/services/payment/safety/confirmationThresholdService.ts,src/services/payment/safety/transactionSafetyProvider.ts,src/services/admin/confirmationThresholdRoutes.ts,src/services/admin/awaitingConfirmationRoutes.ts,src/app.ts - Frontend:
src/sections/admin/confirmation-thresholds/,src/sections/admin/payments-awaiting-confirmation/,src/actions/confirmation-thresholds.ts,src/routes/paths.ts,src/layouts/nav-config-dashboard.tsxWhy: PRD §3 — Task #9 implementation. Runtime per-chain confirmation thresholds viaConfigSettingMongo model with 30s in-memory cache.TransactionSafetyProvidernow readsgetConfirmationThreshold(chainId)instead of static env. Admin endpoints:GET/PATCH /api/admin/settings/confirmation-thresholds,GET /api/admin/payments/awaiting-confirmation. Frontend admin pages for threshold editing and awaiting-confirmation payment monitoring. Verification: All 56 relevant backend tests green. Frontendtsc --noEmitclean. Linked docs updated: 03 - API Reference/Payment API
2026-05-28 — backend@4a85737, frontend@0ebb2f1 — Task #8: Multichain RN proxy registry + USDC/USDT support + Base fix + USDT fork test
Commits: backend 01b9ea0 → ae17b18 → 4a85737 (2.6.45 → 2.6.47), frontend 0ebb2f1 (2.6.44 → 2.6.46)
Touched:
- Backend:
src/services/payment/requestNetwork/supportedChains.json,src/services/payment/requestNetwork/tokens.json,src/services/payment/requestNetwork/tokens.ts,src/services/payment/requestNetwork/proxyAddresses.ts,src/services/payment/requestNetwork/inHouseCheckout.ts,src/services/payment/requestNetwork/networkRegistryRoutes.ts,src/services/payment/wallets/sweepService.ts,src/app.ts,scripts/probe-rn-chains.ts - Frontend:
src/web3/config.ts,src/sections/payment/checkout/rn-in-house-checkout-view.tsx,src/sections/admin/networks/,src/app/dashboard/admin/networks/page.tsx,src/actions/network-registry.ts,src/routes/paths.ts,src/layouts/nav-config-dashboard.tsxWhy: PRD §2 — Task #8 implementation. 5-chain registry (BSC, Arbitrum, Ethereum, Polygon, Base) with canonical RN ERC20FeeProxy addresses and per-chain USDC/USDT entries including Base.tokens.tsandproxyAddresses.tsnow load from JSON files with admin reload capability.buildInHouseCheckoutBlockreturnsunsupported_chain:<id>for unknown chains. Frontend wagmi config expanded to include arbitrum + base. Per-chain explorer URLs in checkout view. USDT-mainnetapprove(0)reset quirk handled in approve flow. New admin page/dashboard/admin/networksrenders registry with reload button. New probe scriptscripts/probe-rn-chains.tsverifies proxy deployment on-chain. Verification: All 58 relevant backend tests green (rn-in-house-checkout,derived-destinations,sweep-service,request-template-orphan-cleanup). Frontendtsc --noEmitclean. Linked docs updated: 03 - API Reference/Payment API (newGET /api/admin/rn/networksandPOST /api/admin/rn/networks/reloadendpoints)
2026-05-28 — backend@34f542e — Task #7 B: unit tests for derived-destinations + sweep-service + orphan-cleanup regression
Commits: backend 34f542e (2.6.44 → 2.6.45)
Touched: __tests__/derived-destinations.test.ts (26 tests), __tests__/sweep-service.test.ts (18 tests), __tests__/request-template-orphan-cleanup.test.ts (2 tests)
Why: PRD item B — regression lock-in test suite for Task #7. Covers: getDestinationFor idempotency, E11000 race fallback, validateXpub rejection of xpriv/tprv/garbage, deriveAddressAtIndex determinism, recordSweep $inc accumulation (regression lock-in for item E), and orphan-payment cleanup provider filtering (regression lock-in for Gap 2 fix in 2.6.44).
Verification: All 46 tests green (npx jest derived-destinations.test.ts sweep-service.test.ts request-template-orphan-cleanup.test.ts).
Linked docs updated: 08 - Operations/Handoff - Request Network In-House Checkout - 2026-05-28
2026-05-28 — backend@1889169, frontend@c44ed64 — Task #7 A verification fix: multi-checkout conversion + orphan-payment guard
Commits: backend 1889169 (2.6.43 → 2.6.44), frontend c44ed64 (2.6.43 → 2.6.44)
Touched:
- Backend:
src/services/marketplace/RequestTemplateService.ts - Frontend:
src/sections/payment/checkout/rn-multi-checkout-view.tsxWhy: A verification revealed two gaps: (1)RnMultiCheckoutView.handleFinishonly navigated to payment list and never calledconvertTemplatesToRequests, so multi-seller carts never created PurchaseRequests; fixed by calling conversion with stashed cart items and navigating to the first created request. (2) Backend orphan-payment cleanup found ALL pending payments for the buyer and hard-deleted all but the first — fatal for multi-seller carts; fixed by restricting orphan query toprovider: 'shkeeper'only so request.network payments retain their independent lifecycle. Verification: Pushed tointegrate-main-into-developmenton both repos — Woodpecker builds pending. Linked docs updated: 03 - API Reference/Payment API
2026-05-28 — backend@faf2221, frontend@022ecb6 — Task #7 derived destinations: sweep autostart, recordSweep fix, multi-seller checkout UX
Commits: backend faf2221 (2.6.42 → 2.6.43), frontend 022ecb6 (2.6.42 → 2.6.43)
Touched:
- Backend:
src/app.ts,src/models/DerivedDestination.ts,src/models/Payment.ts,src/services/payment/requestNetwork/requestNetworkPayInService.ts,src/services/payment/wallets/derivedDestinations.ts,.env.example - Frontend:
src/sections/payment/checkout/rn-in-house-checkout-view.tsx,src/sections/request-template/request-template-checkout-payment.tsx,src/web3/components/multi-seller-provider-payment.tsx,src/sections/payment/checkout/rn-multi-checkout-view.tsx,src/app/checkout/request-network/multi/page.tsxWhy: PRD items D/E/F + frontend cart-aware checkout (A). Auto-start sweep cron on boot; fixrecordSweepto$inctotalSwept instead of$setOnInsert; widen Payment unique index to includesellerOfferIdfor multi-seller carts; add multi-seller checkout wrapper and wire into template + request flows. Verification: Pushed tointegrate-main-into-developmenton both repos — Woodpecker builds pending. Linked docs updated: 03 - API Reference/Payment API (derived-destination endpoints)
2026-05-28 — backend@e46be98, frontend@af77b3c — add nick-doc sync rule + version bumps
Commits: backend e46be98 (2.6.24 → 2.6.25), frontend af77b3c (2.6.25 → 2.6.26)
Touched: backend/AGENTS.md, frontend/AGENTS.md (new), both package.json +
package-lock.json
Why: Establish a mandatory rule that every code push must be followed by a
nick-doc Activity Log entry (and relevant section updates) so the vault never
falls behind the code. Frontend AGENTS.md created from scratch (was missing).
Verification: Pushed to integrate-main-into-development on both repos —
Woodpecker builds pending.
Linked docs updated: This vault's AGENTS.md updated with the same rule.
Note: Backend (2.6.25) and frontend (2.6.26) are intentionally one patch
apart — backend was a version behind before this session. Should be re-aligned
on the next paired bump.
2026-05-28 — frontend@9d4aa37 — fix 429 request storm on template SWR hooks
Commits: 9d4aa37
Touched: src/actions/request-template.ts
Why: Production browser showed repeated 429 (Too Many Requests) on
/api/marketplace/request-templates/sellers. Default SWR config was
revalidating on focus/reconnect and retrying on errors, making backend
rate-limit recover impossible without a restart.
Verification: Pushed, awaiting Woodpecker build. Visual confirmation on
dev.amn.gg after deploy.
Linked docs updated: none yet — SWR pattern should be promoted to
07 - Development/Coding Standards.md in a follow-up.
2026-05-28 — frontend@6c89444 — improve request template form debug feedback
Commits: 6c89444
Touched: src/sections/request-template/request-template-new-edit-form.tsx
Why: Users could not tell why "ایجاد قالب" failed — validation errors
silently blocked submission, API errors collapsed to generic "خطایی رخ داده
است!", and the "انتشار" Switch in renderActions was visual-only.
Verification: Type-check passes via Docker build in prior session; manual
browser test pending.
Linked docs updated: none.
2026-05-27 — frontend@8c0f14d, ad498f4, f3a3c9d, bb72a66 — unblock 2.6.19 Docker build
Commits: bb72a66 f3a3c9d ad498f4 8c0f14d
Touched: src/sections/request-template/request-template-checkout-payment.tsx,
src/web3/components/wallet-selector.tsx, tsconfig.json, src/types/payment.ts
Why: Docker build was failing on TypeScript compilation after the
wallet-support + test-payment feature merge. Four distinct errors fixed:
User type uses _id not id; wallet-selector imported non-existent
@/components/ui/dialog; @/* path alias missing from tsconfig; IPayment
metadata type didn't allow test-payment fields.
Verification: Local docker build succeeded — image
escrow-frontend:2.6.19 created.
Linked docs updated: none — should add SWR + UI library notes to
07 - Development/Coding Standards.md.
2026-06-02 — backend@4949988, frontend@integrate-main-into-development — route admin user counts through postgres-capable stores
Commits: 4949988 (backend), version bump (frontend)
Touched: src/services/user/userController.ts, src/services/auth/authStore.ts,
src/db/repositories/interfaces/IMarketplaceRepo.ts, src/db/repositories/interfaces/IPaymentRepo.ts,
src/db/repositories/mongo/MongoMarketplaceRepo.ts, src/db/repositories/drizzle/DrizzleMarketplaceRepo.ts,
src/db/repositories/dual/DualWriteMarketplaceRepo.ts,
src/db/repositories/mongo/MongoPaymentRepo.ts, src/db/repositories/drizzle/DrizzlePaymentRepo.ts,
src/db/repositories/dual/DualWritePaymentRepo.ts,
__tests__/auth-store-pg-query.test.ts, __tests__/user-dependencies-repo.test.ts,
scripts/smoke/user-admin-postgres.sh, scripts/smoke/user-dependencies.sh
Why: GET /api/user/admin/:userId/dependencies was directly importing Mongoose models
(RequestTemplate, PurchaseRequest, Payment, Chat) bypassing the repository layer and
blocking MONGO_CONNECT_MODE=never. Routed through getUserDependencyCounts / countByParticipant
on all three repo tiers (Mongo, Drizzle, DualWrite). Also hardened AuthUser PgQuery facade with
generic multi-field sorting, nested path support, and isActive/isVerified filter aliases so
admin list/stats routes work correctly in AUTH_STORE=postgres mode.
Verification: 5 test suites, 11 tests pass. typecheck clean. Smoke scripts added but not
run end-to-end (require live ADMIN_TOKEN).
Linked docs updated: none — Mongo removal remaining work tracked in MONGODB_REMOVAL_HANDOFF_2026-06-02.md.
2026-06-02 — backend@515bea3 — guard dataCleanupService against MONGO_CONNECT_MODE=never
Commits: 515bea3
Touched: src/services/admin/dataCleanupService.ts
Why: dataCleanupService dynamically imported 10 Mongoose models unconditionally; under MONGO_CONNECT_MODE=never this throws at runtime. Routed user counts through AuthUser facade (Postgres-gated). Wrapped all other model access in isMongoAvailable() guard — cleanup ops return a safe error result when MongoDB is disconnected.
Verification: 5 test suites 11 tests pass. typecheck clean. Mongo scan: all remaining hits confirmed inside Postgres-gated fallback branches.
Linked docs updated: none.
2026-06-02 — backend@14c231e, frontend@d7a2a86 — make admin user management work end-to-end (v2.8.50)
Commits: 14c231e (backend), d7a2a86 (frontend)
Touched (backend): src/services/auth/authStore.ts, src/services/user/userRoutes.ts,
__tests__/auth-store-pg-query.test.ts
Touched (frontend): src/actions/user.ts, src/types/user.ts,
src/sections/user/view/user-list-view.tsx, src/sections/user/user-table-row.tsx,
src/sections/user/user-quick-edit-form.tsx, src/sections/user/user-new-edit-form.tsx,
src/sections/request/view/admin/admin-request-list-view.tsx,
src/sections/overview/app/view/overview-admin-view.tsx, Dockerfile
Why: Admin could not delete users on dev (DELETE /api/users/admin/:id → 404). Root cause:
PG rows seeded outside the auth store have NULL legacy_object_id; the auth store fabricated a
fresh random _id on every read, so no admin action keyed on that id could ever resolve.
Audit of the admin dashboard surfaced further breakage which is also fixed in this pair of
commits:
- Backend: legacy-id self-heal on read;
findByIdaccepts PG uuids; missing/api/users/admin/:userId/toggle-statusand/dependenciesroutes added (frontend called them under the plural prefix where they did not exist); soft-deleted users excluded from admin list and all stats; list/detail return full profile address fields. - Frontend:
updateUserStatussent{status}but backend reads{isActive}— activating a user actually suspended them; user quick-edit form was a mock (no API call); "حذف کاربر" button in edit form had no handler; bulk deletes usedPromise.all(partial failures hidden); list query params (query/status) were ignored by the backend (nowsearch/isActive); profile payloads now match the backend schema (dotted paths, no whole-profile overwrite); blockedaria-hiddenconsole warnings fixed. Verification: Backend: 10 tests pass (auth-store-pg-query,user-dependencies-repo,repository-factory-modes),tsc --noEmitclean. Frontend:tsc --noEmit+ eslint clean (jest suite is broken repo-wide — pre-existing ESM transform issue, unrelated). Smoke test against dev pending post-deploy (admin will verify delete in UI). Linked docs updated:03 - API Reference/Admin API.md,03 - API Reference/User API.md(stale KNOWN BUG notes removed; route availability updated).
2026-06-03 — backend@378f8f6, frontend@6fe1328 — unblock user creation & purchase requests for native-PG users (v2.8.51)
Commits: 378f8f6 (backend), 6fe1328 (frontend)
Touched (backend): src/services/auth/authStore.ts, src/services/auth/authController.ts,
src/services/user/userRoutes.ts, src/services/user/userController.ts,
src/db/repositories/drizzle/DrizzleMarketplaceRepo.ts, DrizzleUserRepo.ts,
DrizzleTrezorAccountRepo.ts, DrizzleDerivedDestinationRepo.ts,
__tests__/auth-store-pg-query.test.ts
Touched (frontend): src/actions/user.ts, user section forms/views (error toasts)
Why: Two follow-up dev blockers after v2.8.50:
- Admin create returned 409 for emails held by soft-deleted accounts (users.email is unique;
deleted rows kept the address and are hidden from the list). Fix: delete releases the email
(
deleted_<id>_<email>); create/register lazily free emails held by previously deleted rows. - Purchase request creation threw "Buyer not found in Postgres id map" — users created
natively in PG (auth store / Telegram / Google / admin create) never get id_map rows. Fix:
resolveId in 4 Drizzle repos falls back to the entity's own legacy_object_id column and
self-heals id_map.
Verification: 47 backend tests green across 6 suites, tsc clean (both repos), eslint clean.
Deployed to dev via CI; admin verifies create-user and create-request flows in UI.
Linked docs updated:
03 - API Reference/Admin API.md,03 - API Reference/User API.md.
2026-06-03 — backend@804bb99, frontend@714dfbd — fix PG response serialization & id resolution (v2.8.52)
Commits: 804bb99 (backend), 714dfbd (frontend)
Touched (backend): src/services/marketplace/PurchaseRequestService.ts,
src/services/chat/ChatService.ts, src/db/repositories/drizzle/DrizzleChatRepo.ts,
src/db/repositories/drizzle/DrizzleMarketplaceRepo.ts
Touched (frontend): request list views (buyer/seller/admin), src/socket/hooks/use-purchase-requests.ts,
src/types/marketplace.ts
Why: After v2.8.51, request detail pages opened /purchase-requests/[object Object] and the
seller request list returned 500. Root causes (all PG-path):
mongoCompatIdreturned{toString: () => id}— JSON.stringify drops functions, so every response carried_id: {}. Now a plain string; chat compat ObjectIds gettoJSON()instead.findPurchaseRequestspassed unresolved legacy 24-hex user ids into uuid column comparisons (PG cast error → 500); the route's Mongo-style$orfilter was silently ignored (privacy: non-admin users saw all requests). Both fixed — ids resolved up front,$orhonored.- 16
resolveId(...) ?? originalIdfallbacks replaced with a nil-UUID fallback (500 → empty/404). - Frontend reads
request.id || request._ideverywhere (tolerates both API shapes). Verification: 47 backend tests green, tsc clean both repos, eslint clean. Deployed to dev via CI; admin verifies: request detail page, seller request list, chat. Linked docs updated: none beyond this log (API id semantics documented in Marketplace API as needed later).
2026-06-03 — frontend@7b949bf — Mini App live socket updates (v2.8.53)
Commits: 7b949bf (frontend only; backend stays at 2.8.52)
Touched: src/sections/telegram/hooks/use-telegram-realtime.ts (new),
telegram-request-detail-view.tsx, telegram-requests-view.tsx, telegram-mini-app-view.tsx
Why: Mini App request views were SWR-only — status changes required a manual reload.
New useTelegramRealtime hook bridges marketplace socket events to SWR refresh (plus a 30s
periodic fallback for WebView throttling). Detail view joins the request room; list view joins
the buyer/seller room.
Verification: tsc + eslint clean. Admin verifies live stepper advance in Telegram after deploy.
Linked docs updated: none.
2026-06-03 — backend@8b8c1ae, frontend@583d55a — 'guard' role + Mini App tab fix (v2.8.54)
Commits: 8b8c1ae (backend), 583d55a (frontend)
Touched (backend): User model, drizzle users schema + migration 0017_user_role_guard.sql,
postgresAuthSchema (enum + ALTER TYPE for existing DBs), shared types, IUserRepo,
authStore/authService role types, userRoutes role validation
Touched (frontend): role types/permissions/display-names, user forms, useRole hook,
_roles mock, user-table-row (central role labels), telegram-mini-app-view (tab dispatch)
Why:
- New admin-assignable role «نگهبان» (guard), registered across every role definition site — modeled on resolver. No special endpoint permissions yet; grant via authorizeRoles() later. Side fix: the admin role-change endpoint previously rejected 'resolver' (validation list only had buyer/seller/admin) — both resolver and guard now pass.
- Mini App: tapping a bottom tab while a request-detail/chat/new-request overlay was open did
nothing (overlay kept rendering over the new tab). Tab selection now dismisses overlays.
Verification: Backend tsc clean, 12 tests green. Frontend tsc + eslint clean. Admin verifies
after deploy: role dropdown shows نگهبان; Mini App tabs always respond.
Linked docs updated:
03 - API Reference/User API.md(role enum), pending.
2026-06-03 — backend@9424395, frontend@a18e870 — chat/notification fixes, role dashboards, live Mini App chat (v2.8.55)
Commits: 9424395 (backend), a18e870 (frontend)
Why (from chat + notifications + Mini App audits):
- Chat (backend): 5 endpoints were dead — routes pass
:idbut controllers destructuredreq.params.chatId(undefined): edit/delete message, archive chat, add/remove participant. - Notifications → Telegram (backend):
sendTelegramNotificationexisted but was never called. Every in-app notification is now also delivered as a Telegram bot message when the user has an active telegram_link (newsendTelegramNotificationToUser, lazy-required, fire-and-forget). - Role dashboards (frontend): resolver landed on the buyer dashboard. New
OverviewResolverView(dispute stats) andOverviewGuardView(oversight stats); dispatch updated; «حل اختلاف» nav item now visible to resolver. - Mini App chat (frontend): was SWR-only. Thread view joins its conversation socket room,
list joins the user room — messages now appear in real-time.
Touched (backend):
src/services/chat/chatController.ts,src/services/telegram/botService.ts,src/services/notification/NotificationService.tsTouched (frontend):src/sections/overview/app/view/*(2 new views + dispatch),src/layouts/nav-config-dashboard.tsx,src/sections/telegram/hooks/use-telegram-chat-thread.ts,use-telegram-conversations.ts,telegram-chat-view.tsxVerification: backend tsc clean + 28 tests green; frontend tsc clean, eslint clean (pre-existing no-img-element rule-config errors in untouched files). Admin verifies after deploy: resolver dashboard, Mini App live chat, Telegram bot messages on new offers, chat edit/delete. Known remaining (documented, not yet built): Mini App notifications tab; web chat "new conversation" button uses a placeholder id; Drizzle chat participant population.
2026-06-03 — backend@14d164c, frontend@6adb2e0 — Mini App account tab, pinned support chat, shop fix (v2.8.56)
Commits: 14d164c (backend), 6adb2e0 (frontend)
Why:
- Mini App account tab: «بهزودی» rows are now functional — notifications (new in-shell list
view + hook, socket-live, mark-all-read), support (creates/opens support chat via new
createSupportChataction → POST /chat/support), wallet (shows linked address), guard role label. - Mini App chat tab: pinned «پشتیبانی AMN» row always at top (per user request); support-type conversations filtered from the regular list.
- Shop bug «خطا در بارگذاری اطلاعات فروشنده»: PG sellers list returns uuid ids but
seller-shop-view only accepted legacy 24-hex ids → uuid sellers always errored. Both formats
accepted now (frontend validation + backend lookup comparison).
Touched (backend):
DrizzleMarketplaceRepo.findSellerWithActiveRequestTemplatesTouched (frontend): telegram account/chat/notifications views + hooks, locales (fa/en/types),src/actions/chat.ts(createSupportChat),src/lib/axios.ts,seller-shop-view.tsxVerification: tsc clean both repos, 16 backend tests green, eslint clean (pre-existing no-img-element config errors aside). Admin verifies after deploy: account tab rows, pinned support chat, opening a seller shop from فروشگاه. Known remaining: in-shell seller shop detail inside the Mini App (currently opens the web view — now working after the id fix); Mini App notifications row could get an unread badge.
2026-06-03 — frontend@a8ae1e3 — full in-shell shop inside the Mini App (v2.8.57)
Commits: a8ae1e3 (frontend only; backend stays at 2.8.56)
Why: Tapping a seller in فروشگاه opened the web dashboard inside the Telegram webview. The
seller's shop now renders in-shell: new TelegramSellerShopView (seller header + active templates
with budget/usage), useTelegramSellerShop hook, TelegramShopRow converted from <a href> to
in-shell onOpen, and an openSellerId overlay in the shell (BackButton + tab dismissal).
Template ordering hands off to the web from-template checkout (wallet stack lives there).
Cleanup: removed eslint-disable comments for the unregistered @next/next/no-img-element rule.
Verification: tsc clean, eslint clean (0 errors). Admin verifies after deploy: فروشگاه → tap
seller → in-shell shop → سفارش این قالب → web checkout.
2026-06-03 — frontend@HEAD — Mini App account tab parity with web sections (v2.8.58)
Why: The web account menu (تنظیمات عمومی، اعلانها، کیف پول، آدرسهای تحویل، مدیریت Passkey) had no counterpart in the Mini App. All five are now reachable from the Mini App account tab — notifications stay in-shell; settings/wallet/addresses/passkey deep-link to the web dashboard pages (passkey/wallet need browser-context APIs). Labeled «در داشبورد وب باز میشود». Touched: telegram-account-view.tsx, telegram locales (fa/en/types) Verification: tsc + eslint clean. Pending: in-shell shop cart/checkout (user request — payment hand-off design needed since the crypto wallet stack lives in web).
2026-06-03 — frontend@HEAD — Mini App in-shell shopping cart (v2.8.59) — buyer-parity phase 1
Why: Goal: full buyer-role parity in the Mini App (then other roles). Phase 1 = cart.
New useTelegramCart hook shares the web checkout's localStorage key
(app-request-template-checkout) so the Mini App cart IS the web cart; new TelegramCartView
(qty stepper, remove, total, checkout → web); add/remove-to-cart buttons in the in-shell seller
shop; cart badge + overlay in the shell.
Buyer-parity roadmap (remaining): offers view/accept on requests → delivery confirmation →
payments list → points/referral → addresses CRUD → TON Connect payments (Telegram Wallet is
TON-only, no EVM; backend already has tonProofService).
Verification: tsc + eslint clean. Admin verifies: فروشگاه → افزودن به سبد → سبد → ادامه و
پرداخت → web checkout shows the same items.
2026-06-03 — frontend@HEAD — Mini App floating cart FAB (v2.8.60)
Why: User wants the web shop's small edge-docked basket (count badge) in the Mini App too.
New TelegramCartFab component pinned above the tab bar, shown on shop tab + in-shell seller
shop, opens the in-shell cart. Replaced the header cart chip + bottom cart bar.
Pending next (user requests): (1) Mini App «تنظیمات» — dark/light mode for the Telegram shell
(needs a dark palette variant of telegram-shell-css + toggle; should follow webApp.colorScheme);
(2) «درخواست جدید» button font — it is Telegram's NATIVE MainButton, font cannot be customized;
option is replacing it with an in-shell button using the project font.
Verification: tsc + eslint clean.
2026-06-02 — backend@7c4dedf — complete dual-write repos, migrations pipeline, TTL scheduler, address reconciliation
Commits: 7c4dedf (backend v2.8.44), frontend v2.8.44
Touched: src/db/repositories/dual/DualWriteDisputeRepo.ts (new), DualWriteTrezorAccountRepo.ts (new), DualWriteDerivedDestinationRepo.ts (new), src/db/repositories/factory.ts, src/db/schema/dispute.ts, src/db/schema/address.ts, src/db/schema/fundsLedgerEntry.ts, src/services/address/addressStore.ts, src/services/admin/dataCleanupService.ts, src/services/admin/ttlCleanupJob.ts (new), src/app.ts, src/shared/types/address.ts, drizzle.config.ts, migrations/ (new), __tests__/dispute-dual-write.test.ts (new)
Why: Complete all remaining Phase 1 migration prerequisites: the three missing DualWrite repos (Dispute, TrezorAccount, DerivedDestination) unblock PG cutover for those domains; migrations pipeline enables drizzle-kit schema management; FundsLedgerEntry immutability trigger (DDL in migrations/) protects money records from mutation; Dispute composite indexes match Mongo query patterns; TTL scheduler replaces Mongo TTL indexes for Notification/TempVerification/TelegramSession; Address schema reconciled so Drizzle is authoritative.
Verification: typecheck clean. 5 core suites (11 tests) pass. DualWriteDisputeRepo 21 tests pass.
Linked docs updated: MIGRATION_TODO.md — all 9 tasks marked done.
2026-06-03 — frontend@HEAD — Mini App floating support bubble (v2.8.61)
Why: Parity with the web dashboard's green floating chat widget. New TelegramSupportFab
(edge-docked, green bubble) on home/shop/requests tabs + in-shell seller shop; opens/creates the
support chat. Stacks above the cart FAB in shop contexts.
Verification: tsc + eslint clean.
In progress / queued: Points & Referral audit (background agent — bugs observed: values render
as "·", Bronze level claims "highest level"); Mini App dark mode (تنظیمات); buyer-parity phase 2
(offers view/accept).
2026-06-03 — backend@c5d6490 — Points & Referral audit fixes (v2.8.62)
Why (from points audit): /dashboard/points showed "·" instead of numbers and told Bronze users
they are at "the highest level". Root causes: (1) level boundary off-by-one — seeds define
inclusive maxPoints (Bronze 0–999) but PG used > and Mongo <, so exact-boundary users resolved
to no level; (2) level_configs table in Postgres was created but NEVER seeded → zero levels →
null next-level → "highest level" message. Fixes: inclusive comparisons in both repos +
self-seeding of the 5 default levels (برنز/نقره/طلا/پلاتین/الماس) in ensurePostgresLevelConfigSchema.
Remaining from audit: frontend points page swallows API errors (shows zeros instead of an
error state); integration ideas: award points on completed escrow, show points in Mini App.
Verification: tsc clean, 8 tests green. Admin verifies after deploy: /dashboard/points shows
real numbers and Bronze shows progress toward نقره.
2026-06-03 — frontend@131700b — compact floating cart/support FABs (v2.8.63)
Why: User feedback — the two edge-docked FABs were too large. Compacted paddings, icons, badge, and stack positions. Verification: tsc clean.
2026-06-03 — frontend@d64e194 — Mini App points view + tap-to-verify email (v2.8.64)
Why: Buyer parity — امتیازات و رفرال now in-shell (TelegramPointsView: points cards, level progress, referral code copy + stats; account-tab row). Email verification from the Mini App: unverified badge is tappable → sends code → code-entry sheet → verifyProfileEmail → session refresh. Reuses existing account.ts actions. Verification: tsc + eslint clean. Test after deploy: account tab → امتیازات row; unverified user → tap red badge → enter emailed code → badge turns green.