HOCO B2B
SRSRequirements

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).

IDRequirementReleasePrioritySourceApps
IVT-01Unique, secure invitation link and QR code per reseller and delegateV1MUST§6.6API · DA
IVT-02Share by WhatsApp, SMS or link; copyable referral codeV1MUST§6.6DA
IVT-03Activation steps updated automatically: app installed, account created, phone verified, catalog viewed, first orderV1MUST§6.6API · DA · BO
IVT-04The link opens the right app or store and attributes the sign-up to the inviting delegateV1MUST§6.6, §12API · RA · RW

IVT-01 — Unique, secure link and QR code

ReleasePrioritySourceAppsOwner tasks
V1MUSTcahier §6.6API · DASRV-22, MDA-08, DES-14

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

  1. 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). Displayed AB12-CD34; typed input is upper-cased, spaces and hyphens removed, and O → 0, I/L → 1.
  2. Link: https://app.hoco.dz/i/AB12CD34 (domain to confirm, D-12). QR payload: the same URL, so any camera opens it.
  3. An invitation belongs to one point of sale (a Reseller in the delegate's scope, 403 OUT_OF_SCOPE otherwise) and one delegate. delegate.invitations.create returns the active invitation if one exists for that pair (no second code), otherwise creates one.
  4. Preconditions: the point of sale has a main phone (422 RESELLER_PHONE_MISSING) and no reseller account yet (409 RESELLER_ALREADY_HAS_ACCOUNT).
  5. 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.
  6. An invitation is consumed by the first account created with it.
  7. 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).
  8. 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 cd34 at sign-up resolves AB12CD34.

Data — Invitation, InvitationEvent, Reseller, Setting.

Interfaces

IVT-02 — Share by WhatsApp, SMS or link; copyable code

ReleasePrioritySourceAppsOwner tasks
V1MUSTcahier §6.6DASRV-22, MDA-08, DQA-07, DQA-10

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

  1. « 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 or AB12-CD34 in the clipboard; the QR is shown full screen.
  2. 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 ».
  3. Each share calls delegate.invitations.markShared with the ShareChannel (QR when the QR is opened full screen, WHATSAPP, SMS, LINK) and occurredAt; offline it is queued. The first share records the SENT step.
  4. 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

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

ReleasePrioritySourceAppsOwner tasks
V1MUSTcahier §6.6API · DA · BOSRV-22, MRA-09, MDA-08

Statement — The system shall record each activation step of an invitation automatically and show the funnel to the delegate and the back-office.

Rules

  1. Steps (InvitationStep) and triggers:

    StepRecorded when
    SENTfirst markShared
    APP_INSTALLEDfirst invitations.attribute call with this code (Play install referrer or app link); inferred at account creation from the reseller app when missing
    PHONE_VERIFIEDthe OTP of the sign-up that carries this code is verified
    ACCOUNT_CREATEDauth.signup.reseller succeeds with this invitation attributed
    CATALOG_VIEWEDfirst catalog read (catalog.home, catalog.products.*) by the new account — detected server-side
    FIRST_ORDERthe order flagged first order (ORD-09) is submitted
  2. Each step is an InvitationEvent with 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 though PHONE_VERIFIED usually happens moments before ACCOUNT_CREATED. A step is recorded once.

  3. Steps drive the automatic CRM transitions Application installée, Compte créé, Première commande (CRM-04) and count in objectives (FLD-02).

  4. Every step notifies the inviting delegate (FIELD): « Magasin El Wafa a créé son compte »; DA-16 refreshes when open.

  5. 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.

  6. 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

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

ReleasePrioritySourceAppsOwner tasks
V1MUSTcahier §6.6, §12API · RA · RWSRV-22, WEB-01, MRA-09

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

  1. Opening https://app.hoco.dz/i/AB12CD34:
    • Android with the app: verified App Link (/.well-known/assetlinks.json for dz.hoco.reseller) opens sign-up with the code pre-filled; the app calls invitations.attribute (source APP_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, extracts invite_code, calls invitations.attribute (source PLAY_REFERRER, with X-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.
  2. The landing route and the .well-known files go live with the V1 production deployment, before the pilot (the reseller web is part of V1).
  3. Attribution at account creation, in this order:
    1. 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é »);
    2. otherwise the device's attribution recorded by invitations.attribute in the last 30 days;
    3. otherwise phone match: among valid invitations of the point of sale whose main phone equals the verified phone, the first shared (earliest SENT) wins.
  4. 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.validate holder can change it, with a reason (audited OVERRIDE).
  5. An invalid code never blocks sign-up: RA-03 checks it with invitations.resolve and shows an inline error that can be cleared; at auth.signup.reseller an invalid code is ignored and the response reports the attribution status.
  6. 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.
  7. invitations.attribute is 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

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.

On this page