SRV-40 — Smart notification triggers & jobs (V1 types, caps, priority, merge)
Rule-based triggers for the V1 smart notifications of document 03 — new arrival, back in stock, limited quantity, flash sale, price drop, commercial push, new catalogue, trending, abandoned cart, reorder reminder, complementary product — plus the anti-fatigue layer (weekly cap, priority, merge, per-product cool-down, group opt-out) and action labels.
| Field | Details |
|---|---|
| Task code | SRV-40 |
| Phase | P1 — V1 build & integration |
| Product scope | V1 |
| Status | Done (Mon 19 Oct 2026) |
| Start | Mon 19 Oct 2026 |
| Due | Mon 19 Oct 2026 |
| Responsible | Anis — Full-stack developer |
| Co-responsible | — |
| Effort | 2 person-day(s) planned · 6 from scratch · size M |
| Area · app | Server · server |
| Depends on | SRV-08, SRV-11, SRV-13, SRV-15, SRV-16, SRV-19, SRV-24, SRV-39 |
| Unblocks | DSH-14, WEB-06 |
| Milestones | Server V1 feature-complete |
Summary
Rule-based triggers for the V1 smart notifications of document 03 — new arrival, back in stock, limited quantity, flash sale, price drop, commercial push, new catalogue, trending, abandoned cart, reorder reminder, complementary product — plus the anti-fatigue layer (weekly cap, priority, merge, per-product cool-down, group opt-out) and action labels.
Description
Turns the catalogue of /docs/srs/smart-notifications into outbox events on the existing notification pipeline (SRV-08). Event-driven triggers: variant.restocked and variant.low_stock_reached from inventory movements (SRV-13, availability only — no quantity in any payload, STK-07), price.dropped from PriceChange (SRV-12), flash_sale.started from promotions.applySchedule (SRV-19), commercial_push.sent and catalogue.published from announcements (SRV-24). Scheduled jobs on the cron queue: smart.abandonedCarts (15 min), smart.newArrivalsDigest (10:00, 16:00), smart.reorderReminders (09:30), smart.complementSuggestions (10:30), smart.trendingWeekly (Sunday 09:00). Audience resolution uses orders (SRV-16), favorites (SRV-11) and carts (SRV-15). The anti-fatigue layer sits in the notification service: daily and weekly caps for PROMOTIONAL push (inbox always written), priority ranking for the day's slot, 24 h merge, 7-day per-product cool-down, group opt-out, quiet hours and TTL. Defaults come from D-39, D-43 and D-44. Out of scope: V2 loyalty notifications (SRV-30) and AI suggestions (D-41).
Subtasks
| # | Subtask | Owner |
|---|---|---|
| 1 | Audience resolvers: pastBuyers(variant, days), favoritedBy(product), cartHolders(variant), customerType filter, visibility rules and canOrder; unit tests per resolver | Anis |
| 2 | Event triggers: variant.restocked (min 24 h out of stock), variant.low_stock_reached (hysteresis), price.dropped (≥ 5 %, increases ignored), flash_sale.started (TTL = time left), commercial_push.sent / catalogue.published with the recipient split | Anis |
| 3 | Jobs: smart.abandonedCarts (cart version, 24 h guard, cancelled by checkout), smart.newArrivalsDigest (grouping), smart.reorderReminders (median cadence per leaf sub-category, grace 1 day), smart.complementSuggestions, smart.trendingWeekly — deterministic outbox keys, state-based selection, Redis locks | Anis |
| 4 | Anti-fatigue in the dispatcher: promotionalDailyCap and promotionalWeeklyCap, priority ranking, inbox-only when capped, 24 h merge with .grouped templates, 7-day per-product cool-down, per-group push opt-out, back-off after 5 unopened | Anis |
| 5 | Templates fr seed with action labels and groups for every smart event (copy from DQA-10), ar keys with the client's wording | Anis |
| 6 | BO-58 settings read by the jobs (smart.* keys) and admin.notifications.rules with priority; metrics smart_candidates_total{type}, smart_capped_total | Anis |
Deliverables
- apps/server/src/modules/notifications/smart/{audiences,triggers,caps,priority}.ts
- apps/server/src/modules/notifications/smart/jobs/{abandoned-carts,new-arrivals,reorder,complements,trending}.job.ts
- Seed of NotificationRule and NotificationTemplate rows for the smart events
Acceptance criteria
- A variant back in stock after 3 days notifies only its buyers of the last 90 days, favorites and carts (NOT-12)
- No reseller-facing payload of variant.low_stock_reached contains a quantity (STK-07)
- A reseller eligible for a flash sale, a back in stock and a new arrival the same day gets one push (the flash sale) and three inbox rows (NOT-17)
- An abandoned cart produces one reminder 2 h after its last change, none after checkout (NOT-14)
- Re-running any smart job the same day sends nothing twice
- A promotional push deferred by quiet hours past its TTL is dropped
Requirements covered
| Requirement | Title | Release |
|---|---|---|
| NOT-10 | An action button (label and deep link) on every reseller notification | V1 |
| NOT-11 | Catalogue notifications: new arrival, new catalogue, trending product of the week | V1 |
| NOT-12 | Targeted stock notifications: back in stock to past buyers and favorites, limited quantity without any number | V1 |
| NOT-13 | Offer notifications: promotion, flash sale, price drop alert | V1 |
| NOT-14 | Behaviour reminders: abandoned cart after 2 h, reorder reminder from purchase cadence | V1 |
| NOT-15 | Complementary product suggestions from pairs configured on the product | V1 |
| NOT-16 | Commercial push: HOCO picks a product and an audience | V1 |
| NOT-17 | Anti-fatigue rules: promotional push caps, priority, merge, quiet hours, opt-out per group | V1 |
| PRM-07 | Flash sales (2 h to 48 h) with countdown and the promotion tabs Promotions / Flash Sales | V1 |
Screens
API surface
| Endpoint group | Operations |
|---|---|
| Notifications & announcements | 10 |
| Support & communication | 10 |
Test measures
- Table-driven unit tests for the cadence rule, priority and caps (fake clock)
- Integration tests through the dev push simulator: one inbox row and at most one push per reseller per rule
- Load check: back-in-stock fan-out to 2 000 resellers dispatched under 2 minutes
Risks
- Too many candidates on the first day of production (every product looks new after the import) — the import sets publishedAt without announcing; first digest only for products published after go-live
- Cadence rule noisy with little history — require 3 orders in 180 days; the pilot shows the real volume
KPI
- Delivered by Mon 19 Oct 2026 within 2 person-day(s).
- Every acceptance criterion above demonstrated before hand-off; linked requirements' acceptance criteria pass.
- Zero open critical defects, permission gaps or data-integrity regressions at sign-off.
Generated from content/plan/tasks.json by scripts/generate-team-tasks.mjs. Dates are computed by the scheduler (Sunday–Thursday weeks, holidays excluded) — change the plan, not this page.
SRV-26 — Real-time events — back-office stream and reseller live order status (SSE)
Two permission-filtered SSE streams fed by the outbox: the back-office stream (orders, check-ins, tours, positions, stock alerts, pending accounts, returns, claims) and each user's own stream for the reseller app and web (order status changes, assisted orders, ticket replies, returns).
SRV-25 — Analytics, reports & exports
KPI and chart queries with permission-aware filters, daily aggregates, the essential report catalogue and async PDF/XLSX/CSV exports.