Invitations & activation
Requirements IVT-01 to IVT-04: invitation code, link and QR code, sharing, the activation funnel and attribution of the sign-up to the inviting delegate.
This area covers how a delegate invites a point of sale to install the reseller app, how the activation is followed step by step, and how the resulting account is attributed to the right delegate (cahier §6.6, §12 scenario Invitation). Apps: delegate app (create, share, follow), reseller app (install referrer, code at sign-up), reseller web (landing page /i/{code} and web sign-up — part of V1, deployed before the pilot), back-office (funnel). Server module: invitations (with identity for sign-up and crm for the point of sale's status).
| ID | Requirement | Release | Priority | Source | Apps |
|---|---|---|---|---|---|
IVT-01 | Unique, secure invitation link and QR code per reseller and delegate | V1 | MUST | §6.6 | API · DA |
IVT-02 | Share by WhatsApp, SMS or link; copyable referral code | V1 | MUST | §6.6 | DA |
IVT-03 | Activation steps updated automatically: app installed, account created, phone verified, catalog viewed, first order | V1 | MUST | §6.6 | API · DA · BO |
IVT-04 | The link opens the right app or store and attributes the sign-up to the inviting delegate | V1 | MUST | §6.6, §12 | API · RA · RW |
IVT-01 — Unique, secure link and QR code
Statement — The system shall issue, per point of sale and inviting delegate, one unique and unguessable invitation made of a code, a link and a QR code.
Rules
- Code: 8 characters drawn with a cryptographic random generator from
ABCDEFGHJKMNPQRSTUVWXYZ0123456789(letters I, L and O excluded, so 0 and 1 are unambiguous) — about 1.4 × 10¹² combinations; uniqueness enforced by a unique index (regenerate on collision). DisplayedAB12-CD34; typed input is upper-cased, spaces and hyphens removed, andO→0,I/L→1. - Link:
https://app.hoco.dz/i/AB12CD34(domain to confirm, D-12). QR payload: the same URL, so any camera opens it. - An invitation belongs to one point of sale (a
Resellerin the delegate's scope,403 OUT_OF_SCOPEotherwise) and one delegate.delegate.invitations.createreturns the active invitation if one exists for that pair (no second code), otherwise creates one. - Preconditions: the point of sale has a main phone (
422 RESELLER_PHONE_MISSING) and no reseller account yet (409 RESELLER_ALREADY_HAS_ACCOUNT). - Validity:
invitations.validityDays(30) from creation; sharing again does not extend it; after expiry the delegate taps « Renouveler » for a new code. Reassigning the point of sale to another delegate revokes the previous delegate's active invitations. - An invitation is consumed by the first account created with it.
- The public resolution (
invitations.resolve) returns only the store name, the delegate's first name and the validity — no phone or address — and is rate-limited per IP (30 per minute). - Creation needs network; once created, the code, link and QR are cached and shown offline.
Acceptance criteria
- Creating an invitation twice for the same point of sale returns the same code.
- Resolving an unknown code →
404 INVITATION_NOT_FOUND; an expired one →410 INVITATION_EXPIRED; a revoked one →410 INVITATION_REVOKED; a consumed one →409 INVITATION_ALREADY_USED. - Inviting a point of sale that already has an account →
409 RESELLER_ALREADY_HAS_ACCOUNT. - Typing
ab12 cd34at sign-up resolvesAB12CD34.
Data — Invitation, InvitationEvent, Reseller, Setting.
Interfaces
- Screens: DA-16 Invite a reseller
- Endpoints:
delegate.invitations.create
IVT-02 — Share by WhatsApp, SMS or link; copyable code
Statement — The delegate app shall let the delegate show the QR code, share the invitation by WhatsApp, SMS or copied link, and copy the code.
Rules
- « Partager par WhatsApp » opens
https://wa.me/<WhatsApp or main phone>?text=…with the share text; « Envoyer par SMS » opens the phone's SMS app (sms:) with the text — sent from the delegate's phone, at no gateway cost; « Copier le lien » and the code copy button put the link orAB12-CD34in the clipboard; the QR is shown full screen. - Share texts come from localised templates (
DQA-10) with{storeName},{delegateFirstName},{link},{code}; the SMS text fits one GSM-7 segment (160 characters) in French, e.g. « HOCO : installez l'app revendeur pour commander au meilleur prix : https://app.hoco.dz/i/AB12CD34 Code AB12-CD34 ». - Each share calls
delegate.invitations.markSharedwith theShareChannel(QRwhen the QR is opened full screen,WHATSAPP,SMS,LINK) andoccurredAt; offline it is queued. The first share records theSENTstep. - Assumption — sending the invitation SMS through the server's gateway is not in V1; it can be added when HOCO validates the cost (D-13).
Acceptance criteria
- Tapping WhatsApp opens WhatsApp with the store's number and the text containing the link and code; the funnel shows Invitation envoyée.
- Sharing offline records the share after reconnection with the original time.
Data — Invitation, InvitationEvent.
Interfaces
- Screens: DA-16 Invite a reseller
- Endpoints:
delegate.invitations.create·delegate.invitations.markShared
Notes / open points — A generic per-delegate code for printed flyers (DQA-07) is not modelled: invitations are per point of sale; the flyer carries a blank for the code.
IVT-03 — Activation steps updated automatically
Statement — The system shall record each activation step of an invitation automatically and show the funnel to the delegate and the back-office.
Rules
-
Steps (
InvitationStep) and triggers:Step Recorded when SENTfirst markSharedAPP_INSTALLEDfirst invitations.attributecall with this code (Play install referrer or app link); inferred at account creation from the reseller app when missingPHONE_VERIFIEDthe OTP of the sign-up that carries this code is verified ACCOUNT_CREATEDauth.signup.resellersucceeds with this invitation attributedCATALOG_VIEWEDfirst catalog read ( catalog.home,catalog.products.*) by the new account — detected server-sideFIRST_ORDERthe order flagged first order (ORD-09) is submitted -
Each step is an
InvitationEventwith its own time, source (APP_LINK,PLAY_REFERRER,TYPED_CODE,PHONE_MATCH,SERVER) and an inferred flag; steps are displayed in the enum order even thoughPHONE_VERIFIEDusually happens moments beforeACCOUNT_CREATED. A step is recorded once. -
Steps drive the automatic CRM transitions Application installée, Compte créé, Première commande (CRM-04) and count in objectives (FLD-02).
-
Every step notifies the inviting delegate (
FIELD): « Magasin El Wafa a créé son compte »; DA-16 refreshes when open. -
Anti-fraud: an install reported from a device registered to a staff or delegate account is recorded but flagged and not counted in
APP_INSTALLS. -
The back-office funnel (
admin.invitations.list) shows per delegate and period: sent → installed → account → verified → catalog → first order, with conversion between steps.
Acceptance criteria
- After the invited reseller installs from the link and signs up, DA-16 shows Application téléchargée, Compte créé, Téléphone vérifié completed and Catalogue consulté pending, then completed after the first catalog view (reference screen Téléchargement de l'application).
- An install attributed from the delegate's own phone is flagged and does not count.
Data — Invitation, InvitationEvent, Reseller, Order, Device.
Interfaces
- Screens: DA-16 Invite a reseller
- Endpoints:
invitations.attribute·delegate.invitations.get·admin.invitations.list
Notes / open points — The attribution source values are not yet an enum in enums.json.
IVT-04 — Link opens the right app or store and attributes the sign-up
Statement — Opening the invitation link shall lead to the right app, store or web sign-up, and the resulting account shall be attributed to the inviting delegate.
Rules
- Opening
https://app.hoco.dz/i/AB12CD34:- Android with the app: verified App Link (
/.well-known/assetlinks.jsonfordz.hoco.reseller) opens sign-up with the code pre-filled; the app callsinvitations.attribute(sourceAPP_LINK). - Android without the app: the landing page (reseller web) resolves the code, shows « Invitation de Yacine pour Magasin El Wafa » and redirects to
https://play.google.com/store/apps/details?id=dz.hoco.reseller&referrer=utm_source%3Dhoco%26utm_medium%3Dinvitation%26invite_code%3DAB12CD34. At first launch the app reads the Play Install Referrer, extractsinvite_code, callsinvitations.attribute(sourcePLAY_REFERRER, withX-Device-Id) and pre-fills the code on RA-03 as a removable chip. - iOS (only if D-10 decides it): no referrer; the landing shows the App Store button and the code « saisissez-le lors de l'inscription »; the code is typed at sign-up (source
TYPED_CODE). Universal Links open an installed app. - Desktop or other: the landing offers the web sign-up with the code (
/inscription?code=AB12CD34) and the store buttons.
- Android with the app: verified App Link (
- The landing route and the
.well-knownfiles go live with the V1 production deployment, before the pilot (the reseller web is part of V1). - Attribution at account creation, in this order:
- a valid code presented in the sign-up (pre-filled or typed) wins — the link or QR actually used decides (§12 « Le QR code et le lien attribuent l'installation au bon délégué »);
- otherwise the device's attribution recorded by
invitations.attributein the last 30 days; - otherwise phone match: among valid invitations of the point of sale whose main phone equals the verified phone, the first shared (earliest
SENT) wins.
- Exactly one invitation is attributed per account; other active invitations of the same point of sale are closed and their delegates notified. Attribution is fixed at account creation; only a
field.validateholder can change it, with a reason (auditedOVERRIDE). - An invalid code never blocks sign-up: RA-03 checks it with
invitations.resolveand shows an inline error that can be cleared; atauth.signup.reselleran invalid code is ignored and the response reports the attribution status. - A code presented with a phone different from the point of sale's phone attributes the delegate but does not claim the existing record (AUTH-05); the new account goes to the validation queue with a duplicate hint.
invitations.attributeis public, idempotent, device-scoped and rate-limited (10 per minute per IP, 3 per device per day).
Acceptance criteria
- Scanning the QR on an Android phone without the app leads to the Play Store; after install and sign-up the account is attributed to the inviting delegate (§12 scenario Invitation).
- Delegates A and B both hold valid invitations for the same point of sale; the reseller signs up with B's code → attributed to B, A notified. Without any code, the phone match attributes A if A shared first.
- An expired code typed at sign-up shows « Code expiré »; sign-up continues without attribution unless rule 3.3 applies.
- On a desktop browser, the link opens the landing with the web sign-up and the code pre-filled.
Data — Invitation, InvitationEvent, User, Reseller, Device, AuditLog.
Interfaces
- Screens: RA-02 Welcome · RA-03 Sign-up — phone & invitation code
- Endpoints:
auth.signup.reseller·invitations.resolve·invitations.attribute·invitations.landing
Notes / open points — The attribution order (presented code first, then device, then earliest shared invitation) is a proposal for the decision register; open versus invitation-only sign-up is D-28.
Field operations (delegates, tours, visits)
Requirements FLD-01 to FLD-19: delegates, objectives, tour planning and lifecycle, GPS check-in, visits, reports, field sign-up, tour closing and the location policy.
Support & claims
Requirements SUP-01 to SUP-05: reseller tickets, back-office handling, support contacts and FAQ, after-sales claims (SAV) with resolutions, and the regional WhatsApp button.