SRV-14 — CRM module — resellers, prospects, lifecycle, tasks
Reseller records, unique normalised phone, lifecycle automation from events, assignment, segments, interaction timeline, follow-up tasks, documents/photos, validation queue.
| Field | Details |
|---|---|
| Task code | SRV-14 |
| 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 | 1.5 person-day(s) planned · 8 from scratch · size S |
| Area · app | Server · server |
| Depends on | SRV-10 |
| Unblocks | SRV-21, SRV-22, DSH-03, SRV-27 |
| Milestones | — |
Summary
Reseller records, unique normalised phone, lifecycle automation from events, assignment, segments, interaction timeline, follow-up tasks, documents/photos, validation queue.
Description
HOCO's commercial follow-up runs today on calls and spreadsheets; the CRM module makes the reseller the shared record for the back-office, delegates and the reseller apps (cahier §4.2, §6.5; CRM-01…CRM-12). This task implements the reseller/prospect record with the minimum data set, creation from every source (ResellerSource) with the unique normalised phone and duplicate checks (admin.resellers.checkPhone, delegate.resellers.checkPhone), the 10-status lifecycle with manual transitions and automatic ones driven by events (invitation steps, sign-up, first order, visit reports), assignment to a delegate and zone with history, segments, the unified interaction timeline, follow-up tasks with due dates and notifications, protected documents and photos, the validation queue (approve/reject with reason, review of the declared customer type, AUTH-11), list/map/export, and the reseller's own profile and addresses. Out of scope: field visits (SRV-21), invitations (SRV-22) and the CRM pages (DSH-03).
Subtasks
| # | Subtask | Owner |
|---|---|---|
| 1 | Reseller record CRUD (admin.resellers.create/get/update) with source, owner, store, contact, wilaya/commune, address, GPS, business type, potential | Anis |
| 2 | Duplicate prevention on every path: E.164 normalisation, unique constraint, checkPhone endpoints returning the existing record summary (CRM-03) | Anis |
| 3 | Lifecycle service: manual transitions (admin.resellers.setStatus) and event consumers (invitation.app_installed, account.created, order.first, visit.reported) writing ResellerStatusChange | Anis |
| 4 | Assignment to delegate and zone with ResellerAssignment history and notification to the new delegate (admin.resellers.assign, bulk) | Anis |
| 5 | Validation queue: admin.resellers.validation.list/validate, approve or reject with reason, review and optional change of customerType (audited), account status update | Anis |
| 6 | Segments (rule-based on potential, business type, brands sold, activity; ResellerSegment refreshed by a job) and admin.segments.crud | Anis |
| 7 | Interaction timeline (admin.resellers.timeline) fed by visits, notes, orders, payments, claims and status changes | Anis |
| 8 | CrmTask follow-ups: admin.tasks., delegate.tasks., due-date reminders through notifications (CRM-08) | Anis |
| 9 | Documents and photos (ResellerDocument, ResellerPhoto) on private files; list/map queries with filters and async export | Anis |
| 10 | Reseller self-service: profile.get/update (customerType read-only), documents, addresses CRUD and setDefault | Anis |
Deliverables
- apps/server/src/modules/crm/{resellers,lifecycle,assignment,validation,segments,timeline,tasks,documents,profile}.{service,router}.ts
- packages/contracts/src/{profile.ts,admin/crm.ts}
- Event consumers apps/server/src/modules/crm/consumers.ts
Acceptance criteria
- Creating a reseller with an existing normalised phone from any source returns 409 RESELLER_PHONE_EXISTS with the existing reseller id (CRM-03)
- A first order moves the reseller to FIRST_ORDER automatically with a ResellerStatusChange entry (CRM-04)
- Approving an account sets AccountStatus ACTIVE and notifies the reseller; rejecting requires a reason (CRM-09)
- A reseller calling profile.update with customerType gets 403 FIELD_NOT_EDITABLE; a back-office change is audited with old and new values (AUTH-11)
- The timeline lists visits, notes, orders, payments and claims in chronological order (CRM-07)
- A delegate sees only resellers in their zones or assigned to them (ACL-03)
Requirements covered
| Requirement | Title | Release |
|---|---|---|
| CRM-01 | Reseller/prospect record with the minimum data set (store, owner, phone, WhatsApp, email, wilaya, commune, address, GPS, type, potential, delegate, photos, documents, status) | V1 |
| CRM-02 | Creation from the back-office, the delegate app, reseller self sign-up or import, with the source recorded | V1 |
| CRM-03 | Duplicate prevention: the main phone number is unique (normalised); duplicate check on every creation path | V1 |
| CRM-04 | Reseller lifecycle (10 statuses) with automatic and manual transitions and full history | V1 |
| CRM-05 | Assignment to a delegate and a zone; link to the creating delegate; reassignment history | V1 |
| CRM-06 | Segmentation by potential, business type, brands sold, level and activity | V1 |
| CRM-07 | Unified interaction history: calls, visits, notes, orders, payments, claims | V1 |
| CRM-08 | Follow-ups (relances), tasks and next actions with due dates and notifications | V1 |
| CRM-09 | Account validation by an authorised user (approve / reject with reason) | V1 |
| CRM-10 | Store photos and documents (façade, interior, RC, NIF, ID) with protected access | V1 |
| CRM-11 | CRM list and map views with filters (status, zone, wilaya, commune, delegate, segment, potential, activity) and export | V1 |
| CRM-12 | Reseller 360° page: orders, invoices, payments, visits, reports, tasks, interactions | V1 |
Screens
| Screen | Name | App |
|---|---|---|
| BO-09 | Resellers & prospects list | BO |
| BO-10 | Resellers map | BO |
| BO-11 | Reseller 360° | BO |
| BO-12 | Reseller create / edit | BO |
| BO-13 | Account validation queue | BO |
| BO-14 | Follow-ups & tasks | BO |
| BO-15 | Segments | BO |
API surface
| Endpoint group | Operations |
|---|---|
| Reseller profile, addresses & documents | 9 |
| CRM | 21 |
Test measures
- DB tests for duplicate prevention across back-office, delegate and self-sign-up paths
- Event-driven lifecycle tests (emit events, assert transitions and history)
- Contract tests for list filters and pagination
Risks
- Automatic lifecycle transitions conflict with manual ones — manual statuses NOT_INTERESTED and SUSPENDED are never overridden by automation
KPI
- Delivered by Mon 19 Oct 2026 within 1.5 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-10 — Geography & zones module
Wilaya/commune reference endpoints with ETag caching, zones and their membership, distance helpers.
SRV-15 — Cart & checkout rules
Server-side cart, re-validation of price/stock/promotions, minimum amount and quantities, max per order, credit check, checkout options and idempotent checkout.