HOCO B2B
Team tasksAnis

SRV-05 — Authentication & sessions (Better Auth)

Phone/email + password sign-in, OTP, reseller sign-up with declared customer type and account claim, guest (anonymous) access rules, password reset/change, bearer sessions for mobile and cookies for web, lockout, status gating, device registration.

FieldDetails
Task codeSRV-05
PhaseP0 — Foundations (cadrage, UX/UI, architecture & contract)
Product scopeV1
StatusDone (Sun 18 Oct 2026)
StartSun 18 Oct 2026
DueSun 18 Oct 2026
ResponsibleAnis — Full-stack developer
Co-responsible—
Effort1.5 person-day(s) planned · 6 from scratch · size S
Area · appServer · server
Depends onSRV-04
UnblocksSRV-06
Milestones—

Summary

Phone/email + password sign-in, OTP, reseller sign-up with declared customer type and account claim, guest (anonymous) access rules, password reset/change, bearer sessions for mobile and cookies for web, lockout, status gating, device registration.

Description

Authentication serves four audiences with different rules (cahier §3, §5, §6, §10; AUTH-01…AUTH-11, SEC-01, SEC-02): staff sign in by email or phone, delegates and resellers by phone + password, resellers sign up themselves with an OTP-verified phone, and guests browse without any account. This task configures Better Auth with the Prisma adapter — bearer sessions for mobile (30 days sliding), httpOnly cookies on .hoco.dz for the web apps (back-office 7 days) — and adds the HOCO-specific flows: OTP send/verify with the limits of AUTHORING §3, auth.signup.reseller with store details and the declared customer type (SUPER_GROS, DEMI_GROS, DETAIL, AUTH-11) and an optional invitation code, account claim of a field prospect with the same normalised phone (AUTH-05), lockout, status gating (ACCOUNT_PENDING_VALIDATION blocks ordering, prices visible right away by default), and device registration. Guest access is the absence of a session: an optional-auth resolver lets catalog procedures run anonymously and withhold prices (AUTH-10). Out of scope: permissions (SRV-06) and the CRM validation queue (SRV-14).

Subtasks

#SubtaskOwner
1Better Auth setup (Prisma adapter, phone + password and email + password for staff, bearer plugin for mobile, cross-subdomain cookie for web)Anis
2OTP service: 6 digits, 5 min validity, 5 attempts, 1 send per 60 s and 5 per hour per phone, purposes SIGNUP / PASSWORD_RESET / PHONE_CHANGE, SMS adapterAnis
3auth.signup.reseller: verified-phone token, store details, wilaya/commune, required customerType, password, optional invitation code; creates User + Reseller (PENDING_VALIDATION, source SELF_SIGNUP) in one transactionAnis
4Account claim: phone matches a field prospect → attach the user to the existing Reseller, keep the creating delegate and attribution, no duplicate (AUTH-05, CRM-03)Anis
5Lockout after 5 failures for 15 min (429 AUTH_LOCKED), password policy and hashing, password reset by OTP and change with session revocationAnis
6Status gating middleware: PENDING_VALIDATION (browse with prices per catalog.visibleBeforeValidation, no ordering → 403 ACCOUNT_PENDING_VALIDATION), SUSPENDED, DISABLEDAnis
7Optional-auth resolver for auth: optional procedures (guest context, no cart, no favorites)Anis
8Sessions list/revoke and sign-out; device registration me.devices.register with FCM token and X-Device-Id; me.get/me.updateAnis
9AuditLog entries LOGIN, LOGIN_FAILED, LOGOUT with IP, client app and deviceAnis
10Flow review for sign-up, claim and guest-to-account transition on mobileImad

Deliverables

  • apps/server/src/modules/identity/{auth.ts,otp.service.ts,signup.service.ts,claim.service.ts,sessions.router.ts,me.router.ts}
  • apps/server/src/middleware/{optional-auth,status-gate}.ts
  • packages/contracts/src/{auth,me}.ts implemented end to end

Acceptance criteria

  • Sign-up without customerType fails with 422 VALIDATION_FAILED; a successful sign-up stores the declared type on Reseller.customerType (AUTH-03, AUTH-11)
  • Signing up with the phone of an existing field prospect claims that reseller record instead of creating a second one (AUTH-05)
  • The 6th wrong password within the window returns 429 AUTH_LOCKED for 15 minutes; OTP limits return 429 OTP_RATE_LIMITED
  • A PENDING_VALIDATION reseller can sign in and browse but cart.checkout returns 403 ACCOUNT_PENDING_VALIDATION (AUTH-08)
  • A request without a session to catalog.products.list succeeds; the same request to cart.get returns 401 UNAUTHENTICATED (AUTH-10)
  • Revoking a session invalidates its bearer token on the next request (AUTH-06)

Requirements covered

RequirementTitleRelease
AUTH-01Back-office staff sign-in (email or phone + password)V1
AUTH-02Delegate sign-in with phone + password; suspended accounts blocked with an explicit messageV1
AUTH-03Reseller self sign-up: phone verified by OTP, store details, declared customer type (super-gros, demi-gros, détail), password, optional invitation codeV1
AUTH-04Reseller sign-in (phone + password) and password reset by OTPV1
AUTH-05Account claim: a prospect created in the field is activated by the reseller without creating a duplicateV1
AUTH-06Sessions: expiry, multi-device, listing and revocation, sign-outV1
AUTH-07Password policy, hashing, OTP expiry/resend cooldown and attempt limitingV1
AUTH-08Account statuses (pending validation, active, suspended, disabled) gate what each user can doV1
AUTH-09Device registration for push and minimum-app-version enforcementV1
SEC-01Secure authentication with hashed passwordsV1
SEC-02Session expiry, revocation and attempt limitingV1
AUTH-10Guest mode: the reseller app and web can be browsed without an account; prices stay hidden until the visitor signs up and declares a customer typeV1
AUTH-11Customer type declared at sign-up, reviewed at account validation; any later change is made by the back-office and auditedV1

API surface

Test measures

  • Integration tests against Postgres and Redis for sign-up, claim, lockout and OTP limits
  • Unit tests for phone normalisation to E.164 (+213 forms with and without leading zero)
  • E2E: sign up on staging with the SMS simulator, sign in from the web cookie and from a bearer client

Risks

  • Better Auth phone flows do not fit the claim/sign-up contract exactly — keep Better Auth for credentials and sessions and implement sign-up/claim as HOCO procedures that call its internal API
  • SMS delivery delays in Algeria during OTP — resend cooldown visible in the response and provider fallback planned in SRV-08

KPI

  • Delivered by Sun 18 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.

On this page