[CL-COVTESTS2] test(api): branch-покрытие webhook/worker/buyback (batch 2) #434

Merged
andrei merged 2 commits from feature/claude-cl-branch-coverage2-20260607 into master 2026-06-07 17:30:03 +00:00
Owner

Что сделано

Batch 2 branch-coverage hunt (lane #3, продолжение PR #416). Только тесты — production-код не тронут.

Файл branches до branches после
api/src/services/premiumSubscription.webhook.service.ts 11% 94%
api/src/workers/recurring-invest.worker.ts 35% 93%
api/src/services/buyback.service.ts 69% 98%

Итого +90 branches на Stripe-webhook / recurring-worker / buyback money путях.

premiumSubscription.webhook.service.ts (нет webhook-теста был)

Все 5 Stripe event cases: checkout.session.completed (mode/product filter, missing-metadata, subscription/customer string vs object, periodEnd null), customer.subscription.updated (determinePlan price-id BASIC/PRO + unit_amount fallback + FREE, status-map hit/default, cancel_at_period_end), customer.subscription.deleted, invoice.payment_failed (parentSub string/object/null, sub-not-found), default unhandled. Env price-id константы выставлены в vi.hoisted до импорта модуля.

recurring-invest.worker.ts

guard-skips (room not found, risk not acked, sharePrice<=0, shares<=0, no record, advanced.count===0), WEEKLY vs MONTHLY schedule, non-balance rethrow (без audit), failed-handler (transient/DLQ/Sentry/alert/DLQ-throw/not-exhausted), error handler.

buyback.service.ts

sellToPlatform input guards + tx guards (locked, no-shares, room-not-found, orphaned-room, frozen, zero-price, insufficient-liquidity, happy settlement+burn), validateBuybackQuote (missing/mismatch/valid), getBuybackQuote (room/frozen/insufficient/happy). $transaction mock с SQL-routed $queryRaw (по содержимому SQL, не порядку вызова).

Зачем

Продолжение coverage-hunt из PR #416 (audit residual #3, branch 70.88%). Coverage-summary.json выявил эти файлы как настоящие низко-покрытые financial-модули. Непокрытые webhook/worker/tx-guard ветки = регрессии в idempotency/error/race не ловятся до прода.

План тестирования

  • npx vitest run9894 passed, 0 регрессий.
  • Scoped coverage подтверждает рост на каждом файле (таблица).
  • npx tsc --noEmit clean; npx eslint src --max-warnings 0 на изменённых clean.
  • Local code-reviewer: 0 CRITICAL, 2 HIGH + MED/LOW — все addressed (price-id non-fallback unit_amount, rethrow logAudit-not-called assert, MONTHLY month assert, orphaned-room test, FAR_FUTURE анти-flake).
  • pre-commit (i18n/migrations/audit-trail/mock-sync/security) + pre-push (tsc+build) passed.

Где могу ошибаться

  • Непокрытые остатки: env || '' defaults в premium (5 веток, env-misconfig only), recurring line 224 + buyback line 251 (fire-and-forget .catch callbacks). Low-value safety-края.
  • Follow-up таргеты: stripePayout.service.ts (50%), p2p-trade/execute-trade.ts (70%).
  • recurring/buyback тесты используют capture-on mock + SQL-routed $queryRaw — robust к порядку, но завязаны на текущий набор SQL-запросов в buyback (при добавлении нового FOR UPDATE с 'balance::text'/'share_ownerships' router нужно обновить).
## Что сделано Batch 2 branch-coverage hunt (lane #3, продолжение PR #416). **Только тесты — production-код не тронут.** | Файл | branches до | branches после | |---|---|---| | `api/src/services/premiumSubscription.webhook.service.ts` | 11% | **94%** | | `api/src/workers/recurring-invest.worker.ts` | 35% | **93%** | | `api/src/services/buyback.service.ts` | 69% | **98%** | Итого **+90 branches** на Stripe-webhook / recurring-worker / buyback money путях. ### premiumSubscription.webhook.service.ts (нет webhook-теста был) Все 5 Stripe event cases: `checkout.session.completed` (mode/product filter, missing-metadata, subscription/customer string vs object, periodEnd null), `customer.subscription.updated` (determinePlan price-id BASIC/PRO + unit_amount fallback + FREE, status-map hit/default, cancel_at_period_end), `customer.subscription.deleted`, `invoice.payment_failed` (parentSub string/object/null, sub-not-found), default unhandled. Env price-id константы выставлены в `vi.hoisted` до импорта модуля. ### recurring-invest.worker.ts guard-skips (room not found, risk not acked, sharePrice<=0, shares<=0, no record, advanced.count===0), WEEKLY vs MONTHLY schedule, non-balance rethrow (без audit), failed-handler (transient/DLQ/Sentry/alert/DLQ-throw/not-exhausted), error handler. ### buyback.service.ts `sellToPlatform` input guards + tx guards (locked, no-shares, room-not-found, orphaned-room, frozen, zero-price, insufficient-liquidity, happy settlement+burn), `validateBuybackQuote` (missing/mismatch/valid), `getBuybackQuote` (room/frozen/insufficient/happy). `$transaction` mock с SQL-routed `$queryRaw` (по содержимому SQL, не порядку вызова). ## Зачем Продолжение coverage-hunt из PR #416 (audit residual #3, branch 70.88%). Coverage-summary.json выявил эти файлы как настоящие низко-покрытые financial-модули. Непокрытые webhook/worker/tx-guard ветки = регрессии в idempotency/error/race не ловятся до прода. ## План тестирования - `npx vitest run` — **9894 passed**, 0 регрессий. - Scoped coverage подтверждает рост на каждом файле (таблица). - `npx tsc --noEmit` clean; `npx eslint src --max-warnings 0` на изменённых clean. - Local code-reviewer: 0 CRITICAL, 2 HIGH + MED/LOW — все addressed (price-id non-fallback unit_amount, rethrow logAudit-not-called assert, MONTHLY month assert, orphaned-room test, FAR_FUTURE анти-flake). - pre-commit (i18n/migrations/audit-trail/mock-sync/security) + pre-push (tsc+build) passed. ## Где могу ошибаться - Непокрытые остатки: env `|| ''` defaults в premium (5 веток, env-misconfig only), recurring line 224 + buyback line 251 (fire-and-forget `.catch` callbacks). Low-value safety-края. - Follow-up таргеты: stripePayout.service.ts (50%), p2p-trade/execute-trade.ts (70%). - recurring/buyback тесты используют capture-`on` mock + SQL-routed `$queryRaw` — robust к порядку, но завязаны на текущий набор SQL-запросов в buyback (при добавлении нового FOR UPDATE с 'balance::text'/'share_ownerships' router нужно обновить).
[CL-COVTESTS2] test(api): branch-покрытие webhook/worker/buyback (batch 2)
Some checks failed
CI / API (pull_request) Has been cancelled
CI / App (pull_request) Has been cancelled
CI / Contracts (pull_request) Has been cancelled
CI / Telegram Mini App (pull_request) Has been cancelled
CI / Python SDK (pull_request) Has been cancelled
CI / Secrets Scan (pull_request) Has been cancelled
CI / Prisma Migrate Gate (pull_request) Has been cancelled
React Doctor / React Doctor / App (pull_request) Has been cancelled
SEO Audit / SEO Audit / europatech (pull_request) Has been cancelled
d3fe84a2f8
Тесты-only, prod-код не тронут. +90 branches на financial путях:

- premiumSubscription.webhook.service.ts: 11% -> 94% branches.
  Все 5 Stripe event cases: checkout.session.completed (mode/product filter, missing-metadata,
  subscription/customer string vs object, periodEnd null), customer.subscription.updated
  (determinePlan price-id BASIC/PRO + unit_amount fallback + FREE, status-map + default,
  cancel_at_period_end), .deleted, invoice.payment_failed (parentSub string/object/null,
  not-found), default unhandled.

- recurring-invest.worker.ts: 35% -> 93% branches.
  guard-skips (room not found, risk not acked, sharePrice<=0, shares<=0, no record,
  advanced.count===0), WEEKLY vs MONTHLY schedule, non-balance rethrow, failed-handler
  (transient/DLQ/Sentry/alert/DLQ-throw/not-exhausted), error handler.

- buyback.service.ts: 69% -> 98% branches.
  sellToPlatform input guards + tx guards (locked, no-shares, room-not-found, frozen,
  zero-price, insufficient-liquidity, happy settlement+burn), validateBuybackQuote
  (missing/mismatch/valid), getBuybackQuote (room/frozen/insufficient/happy).
  $transaction mock с SQL-routed $queryRaw (по содержимому, не порядку).

Full suite: 9894 passed, 0 регрессий. tsc + eslint clean.
[CL-COVTESTS2] test(api): harden batch-2 tests per code review
All checks were successful
CI / Contracts (pull_request) Successful in 1m58s
CI / Telegram Mini App (pull_request) Successful in 1m18s
CI / Secrets Scan (pull_request) Successful in 21s
CI / Python SDK (pull_request) Successful in 28s
SEO Audit / SEO Audit / europatech (pull_request) Successful in 7s
CI / Prisma Migrate Gate (pull_request) Successful in 1m28s
React Doctor / React Doctor / App (pull_request) Successful in 2m45s
CI / API (pull_request) Successful in 6m54s
CI / App (pull_request) Successful in 7m3s
1b97214953
Адресованы замечания local code-reviewer (0 CRITICAL, 2 HIGH + MED/LOW):

- premium webhook (HIGH): price-id тесты теперь шлют unit_amount:1 (не fallback-значение),
  чтобы BASIC/PRO результат доказывал срабатывание price-id ветки, а не маскировался
  unit_amount fallback.
- recurring rethrow (HIGH): добавлен assert logAudit НЕ вызван в rethrow-пути.
- recurring MONTHLY: assert getUTCMonth === next month (ловит "1st of this month" баг).
- recurring error handler: assert logger.error вызван (не вакуумный тест).
- buyback (MED): добавлен тест orphaned room (!room.object) → 404.
- buyback (LOW): фиксированная FAR_FUTURE дата вместо Date.now()+offset (анти-flake).

52 tests pass, tsc + eslint clean.
Author
Owner

admin-merge reason: solo-dev (Rule 103.1)
local-review: Agent(code-reviewer) — 0 CRITICAL, 2 HIGH + 3 MED + 3 LOW, ключевые findings addressed в 1b9721495 (price-id non-fallback unit_amount, rethrow logAudit-not-called assert, MONTHLY month assert, orphaned-room test, FAR_FUTURE анти-flake)
copilot-review: бот отсутствует на Forgejo → fallback на local code-reviewer (Rule 103.1)
scope: test-only, production-код не тронут
evidence: GitNexus context sellToPlatform (buyback.service.ts:70-272) + full suite 9894 passed

admin-merge reason: solo-dev (Rule 103.1) local-review: Agent(code-reviewer) — 0 CRITICAL, 2 HIGH + 3 MED + 3 LOW, ключевые findings addressed в 1b9721495 (price-id non-fallback unit_amount, rethrow logAudit-not-called assert, MONTHLY month assert, orphaned-room test, FAR_FUTURE анти-flake) copilot-review: бот отсутствует на Forgejo → fallback на local code-reviewer (Rule 103.1) scope: test-only, production-код не тронут evidence: GitNexus context sellToPlatform (buyback.service.ts:70-272) + full suite 9894 passed
andrei merged commit 63f22053ae into master 2026-06-07 17:30:03 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
europa-tech-srl/europatech!434
No description provided.