Deployment and operations
Environments, the delivery pipeline, infrastructure sizing, domains, secrets, backups and restore, monitoring and alerts, the initial data import, training, the go-live checklist, the pilot, the maintenance and support model, and the runbook index.
Cahier §13 asks for three environments (développement, préproduction / recette client, production, §13.1), a deployment that covers « serveur, base de données, stockage et sauvegardes », « domaines, certificats et services externes » and the « import initial des produits, revendeurs et comptes utilisateurs » (§13.2), training (§13.3) and a maintenance model with « délais de prise en charge et niveaux de priorité » (§13.4). The requirements are OPS-01 to OPS-06; the work is planned in OPS-01, OPS-02, SRV-28, MOB-14 and the launch tasks LCH-01 to LCH-05. Dates are on the timeline.
Timing within the three-month frame. V1 — design, development and deployment, the reseller web included — fits in three months from the cadrage. Production goes live at the start of January (milestone Production go-live), the two-week pilot starts right after (Pilot starts), and generalisation and V2 come after the three months. The consequences for operations:
3-month frame: design → development → deployment — deadline 17 Jan 2027.
| Date | Milestone | Target | Reached when these tasks end |
|---|---|---|---|
| 18 Oct 2026 | Cadrage validated — validation sheet signed | — | PRJ-03 |
| 18 Oct 2026 | API contract v1 published (OpenAPI + mock server) | — | SRV-03 |
| 19 Oct 2026 | Server V1 feature-complete | — | SRV-26, SRV-40 |
| 21 Oct 2026 | Design system v1 ready (tokens + components) | — | DES-04 |
| 22 Oct 2026 | Screen inventory frozen | — | DES-05 |
| 29 Oct 2026 | Reseller app designs ready for client review | — | DES-10 |
| 05 Nov 2026 | Delegate app designs ready for client review | — | DES-14 |
| 08 Nov 2026 | Mobile foundations ready | — | MOB-11 |
| 12 Nov 2026 | Back-office designs ready for client review | — | DES-19 |
| 16 Nov 2026 | Design handoff complete | — | DES-21 |
| 03 Dec 2026 | Back-office and reseller web V1 feature-complete | — | DSH-12, WEB-05, WEB-06 |
| 15 Dec 2026 | Mobile apps V1 feature-complete | — | MDA-12 |
| 22 Dec 2026 | Staging integration complete | — | MOB-14, SRV-28 |
| 28 Dec 2026 | Acceptance report (PV de recette) signed | — | QA-02 |
| 29 Dec 2026 | Production go-live | on time — 17 Jan 2027 | LCH-01 |
| 30 Dec 2026 | Pilot starts | on time — 17 Jan 2027 | LCH-02 |
| 14 Jan 2027 | Pilot go / no-go | — | LCH-03, LCH-03B |
| 21 Jan 2027 | Generalisation complete | — | LCH-05 |
| 22 Feb 2027 | V2 delivered | — | SRV-38, DSH-21, MDA-20, WEB-20, DQA-12 |
- Acceptance falls around the year end. The functional campaign (QA-03), the end-to-end tests (QA-01) and the client acceptance (QA-02) run back to back over the last working days of December and the first of January. HOCO's testers, the PV signatory and the import data owners are booked at the cadrage, with named back-ups, so that year-end absences do not stop the recette.
- Production is prepared before the recette, not after it. The acceptance report is signed one working day before go-live, so everything that does not depend on the accepted build — infrastructure, domains, backups, monitoring, the SMS sender ID, the Play Console listing, the privacy policy, the import rehearsal — is done during the build phase (go-live checklist).
- No slack on the critical lane. Anis's lane fills the three months; an operational task that slips (sender-ID approval, store review, data delivery) is escalated the same week and handled with the levers of the timeline and D-38.
Environments
hoco.dz is a placeholder until D-12; the admin, app and cdn names are proposals.
| Local | Staging | Pre-production (recette) | Production | |
|---|---|---|---|---|
| Purpose | Development | Integration of dev; the team's daily testing; the functional campaign (QA-03) | Client acceptance of a release candidate (QA-02); import rehearsal; training | Real use (pilot, then everyone) |
| API | http://localhost:3100/v1 | https://api-staging.hoco.dz/v1 | https://api-preprod.hoco.dz/v1 | https://api.hoco.dz/v1 |
| Back-office | http://localhost:3101 | https://admin-staging.hoco.dz | https://admin-preprod.hoco.dz | https://admin.hoco.dz |
| Reseller web and invitation links | http://localhost:3102 | https://app-staging.hoco.dz | https://app-preprod.hoco.dz | https://app.hoco.dz |
| Public files | MinIO :9100 | https://cdn-staging.hoco.dz | https://cdn-preprod.hoco.dz | https://cdn.hoco.dz |
| Deployed from | Working copy | Every merge to dev, automatically | A release-candidate tag vX.Y.Z-rc.N from release/X.Y.Z, on Anis's approval | A tag vX.Y.Z on master, on Anis's approval |
| Mobile builds | dev flavor on emulators | staging flavor, Firebase App Distribution to the team | staging flavor built with the pre-production API URL, Firebase App Distribution to HOCO's testers | prod flavor, Play internal → closed → production tracks |
| Who has access | The team | The team; HOCO on request | HOCO's key users and the team | Everyone, per role |
Assumption — the pre-production apps are the staging flavor with API_BASE_URL set at build time (--dart-define), so no fourth flavor is needed; Imad confirms in the mobile guide.
Data policy per environment
| Local | Staging | Pre-production | Production | |
|---|---|---|---|---|
| Personal data | Synthetic seed only | Synthetic seed and the recette seed | Recette seed; HOCO's real catalog (not personal); real reseller data only with HOCO's written agreement and production-grade access control | Real |
| SMS | Simulator (printed in the server log viewer) | Simulator; real SMS only to the team's allow-listed numbers | Real gateway, allow-listed tester numbers only | Real |
| Push | Firebase hoco-dev | Firebase hoco-staging | Firebase hoco-staging | Firebase hoco-prod |
Mailpit (:8125) | Sandbox or allow-listed domain | Real provider, allow-listed recipients | Real | |
| Maps and other keys | Development keys | Staging keys | Staging keys | Production keys, restricted |
| Backups | None | Nightly, 7 days | Nightly, 14 days | Full policy (backups) |
| Session cookies | hoco-dev prefix | hoco-stg prefix | hoco-pp prefix | hoco prefix — distinct names so sessions never cross environments under the shared .hoco.dz cookie domain |
Delivery pipeline
Server, back-office and reseller web
| Stage | Trigger | What runs | Result |
|---|---|---|---|
| Pull request | Every PR to dev | Biome, type-check, unit and integration tests (PostgreSQL and Redis services), OpenAPI diff, migration drift check, gitleaks, dependency audit, docs check-mdx, Docker builds without push (quality gates) | Mergeable when green and reviewed |
| Integration | Merge to dev | Build and push images ghcr.io/anisbetehi/hoco-server, -dashboard, -web tagged with the commit SHA; call the Dokploy deploy hooks of staging; run prisma migrate deploy as a one-off job before the new api and worker start; smoke test (health, sign-in, catalog read) | Staging updated within about 10 minutes |
| Release candidate | Tag vX.Y.Z-rc.N on release/X.Y.Z | Same build, images tagged X.Y.Z-rc.N; GitHub environment preprod requires Anis's approval; deploy to pre-production; smoke test | Recette build |
| Production | Tag vX.Y.Z on master | No rebuild: the release-candidate images are re-tagged X.Y.Z (same digest); pre-deploy database dump; migrations; deploy with approval (environment production); smoke test; Sentry release created | Production updated |
| Documentation | Merge to master (or dev) touching apps/docs | next build, deployed with the other apps (later) | Docs on the VPS, restricted access |
Rules:
- One image, two processes.
api(HTTP) andworker(BullMQ workers and the scheduler) run from the same image with different commands;apiruns two replicas in production,workerone. - Migrations are expand-then-contract. A release only adds columns, tables and indexes, or relaxes constraints; removals ship one release later, so the previous image can always run against the new schema — that is what makes a rollback safe.
- Rollback = redeploy the previous image tag in Dokploy (runbook); a database rollback is a restore, never a down-migration.
- Feature flags (settings) hide unfinished V1 features rather than long-lived branches.
Mobile apps
Imad's repository hoco-mobile, GitHub Actions (MOB-01, MOB-14):
| Stage | Trigger | What runs | Result |
|---|---|---|---|
| Pull request | Every PR | dart format check, flutter analyze, unit, widget and golden tests, APK build | Mergeable when green |
| Integration | Merge to dev | dev and staging APKs of both apps, Dart symbols uploaded to Sentry | Firebase App Distribution: group Team (dev, staging) and HOCO testers (staging) |
| Release | Tag reseller-vX.Y.Z or delegate-vX.Y.Z | prod AAB signed with the upload key; release notes from the changelog | Play internal track (team smoke test) → closed track (pilot users) → production with staged rollout 10 % → 50 % → 100 % |
versionName follows semantic versioning; versionCode is the CI build number. The minimum and latest versions per app and platform are set on BO-66 (AppVersionPolicy); raising the minimum forces an update (426 UPGRADE_REQUIRED). A new server release that mobile depends on is deployed before the app release that uses it.
Infrastructure sizing
Proposal for the volumes of the sizing table (Assumption; provider and data location are D-15).
| Component | Production | Staging + pre-production |
|---|---|---|
| Server | One VPS: 8 vCPU, 16 GB RAM, 240 GB NVMe, Ubuntu 24.04 LTS, Dokploy (Docker + Traefik) | One VPS: 4 vCPU, 8 GB RAM, 160 GB NVMe; two Dokploy projects, separate databases, Redis databases and buckets |
| API | 2 replicas, about 1 GB RAM each | 1 replica per environment |
| Worker | 1 replica, about 1 GB | 1 per environment |
| Back-office · reseller web | 1 replica each, about 512 MB each | 1 each per environment |
| PostgreSQL 17 | Self-hosted on the VPS (4 GB shared_buffers), WAL archiving for point-in-time recovery — or a managed PostgreSQL 17 with point-in-time recovery if the provider offers it | Self-hosted, nightly dumps |
| Redis 7 | AOF persistence (everysec), 1 GB maxmemory, maxmemory-policy noeviction (required by BullMQ queues) | Same, smaller |
| Object storage | S3-compatible, three buckets (storage) | Same layout, per environment |
| Backup target | Another provider or account, encrypted copies | Same target, separate prefix |
| Uptime monitoring | Outside the production VPS (a small separate host or a hosted monitor) | Same monitor |
Headroom: the production VPS runs the generalisation volume at about a third of its capacity; the next steps are a larger VPS, then a separate database server, then more API replicas (NFR-03).
Domains and TLS
| Record | Points to | Notes |
|---|---|---|
api, admin, app (and -staging, -preprod) | The VPS of the environment | A/AAAA; TLS by Traefik with Let's Encrypt, renewed automatically |
cdn (and variants) | The public bucket or its CDN | Custom domain on the storage provider |
mail (sending subdomain) | Email provider | SPF, DKIM, DMARC and bounce records (email) |
| CAA on the apex | 0 issue "letsencrypt.org" | Only the chosen certificate authority may issue |
app.hoco.dz/.well-known/assetlinks.json | Served by the reseller web app | Android App Links for invitation links: the package names and the SHA-256 fingerprints of the Play app-signing and upload certificates; apple-app-site-association too if iOS |
Invitation links work from the first production day. The reseller web is part of V1 (WEB-01 to WEB-05) and goes live with production (LCH-01); it serves the /i/{code} landing (open the app, else the Play Store with the referrer, else the web sign-up) and /.well-known/assetlinks.json, so the invitations delegates share during the pilot resolve correctly. The fingerprints in assetlinks.json are those of the production Play app-signing key, known once the app exists in the Play Console (MOB-14).
HSTS is enabled per host first, then with includeSubDomains once every subdomain serves HTTPS (SEC-03).
Secrets
| Secret | Used by | Stored in | Rotation |
|---|---|---|---|
DATABASE_URL (application role), migration role URL | api, worker · migration job | Dokploy environment of each app | On leak; on team departure |
REDIS_URL | api, worker | Dokploy | On leak |
BETTER_AUTH_SECRET | api | Dokploy | Yearly or on leak (rotating it ends cookie signatures: plan a re-sign-in) |
S3_* and BACKUP_S3_* | api, worker · backup job | Dokploy (separate credentials) | Yearly or on leak |
FCM_SERVICE_ACCOUNT_JSON | worker | Dokploy | Yearly or on leak (new key in Google Cloud, old one deleted) |
SMS_API_KEY, SMTP_PASSWORD, GOOGLE_MAPS_SERVER_KEY | worker, api | Dokploy | On leak; provider policy |
SENTRY_DSN | all apps | Environment (not secret, but per environment) | — |
| Backup encryption private key | Restores only | Offline, held by Anis and a person designated by HOCO | Yearly |
| GitHub Actions secrets: registry token, Dokploy deploy hooks | CI | Repository environments with approval rules | Yearly or on leak |
Mobile: upload keystore and passwords, Play service account, google-services.json | hoco-mobile CI | Repository secrets of hoco-mobile; the upload key escrowed with HOCO | Upload key reset through Play support if lost |
The env package validates every variable at boot; a missing or malformed secret stops the process with a clear message. Secrets never appear in the repositories (gitleaks) or in logs (SEC-0.7).
Backups
| What | How | When | Kept |
|---|---|---|---|
| PostgreSQL | Continuous WAL archiving and a weekly base backup (point-in-time recovery), plus a nightly logical dump (pg_dump -Fc), both encrypted before upload | WAL continuous · base backup Sunday 01:30 · dump daily 02:00 Africa/Algiers | 7 daily, 4 weekly, 12 monthly |
| Private bucket | Versioning, plus a nightly copy to the backup target | 03:00 | Non-current versions 30 days; copies per the same rule |
| Public bucket | Re-creatable from the private originals and imports; nightly copy | 03:00 | 7 days |
| Redis | Not backed up (queues are transient; undispatched outbox rows are re-dispatched after a restore) | — | — |
| Dokploy configuration and environment | Export to the password vault after every change | On change | Current and previous |
| Repositories | GitHub, plus a mirror for HOCO at the end of the warranty (D-25) | — | — |
A verification job at 04:00 checks that last night's dump exists, is larger than 50 % of the previous one and can be listed by pg_restore; otherwise it alerts. A full restore is tested every month (and in SRV-28 before go-live).
Restore runbook
- Declare the incident (P1), name the person in charge, inform HOCO's referent.
- Stop writes: switch maintenance mode on (BO-66 or the settings switch; the API answers
503 MAINTENANCE); stop theworker. The delegate app keeps working offline and queues its actions. - Choose the recovery point: the latest consistent point (point-in-time recovery) or the last good dump; write it down.
- Provision a fresh database (new instance or container); never restore over the damaged one, keep it for analysis.
- Fetch and decrypt the base backup and WAL (or the dump) from the backup target with the offline key.
- Restore: point-in-time recovery to the chosen time, or
pg_restore --no-owner --clean --if-existsinto the fresh database. - Check integrity:
prisma migrate statusclean; row counts of key tables against the last metrics; the lastCMD-,FAC-,PAY-andRET-numbers againstNumberSequence; outbox rows not yet dispatched listed. - Switch
DATABASE_URLofapiandworkerto the restored database; start theworker(it re-dispatches pending outbox events). - Smoke test: sign-in, catalog, the orders-to-confirm queue, a test order on a test reseller, a delegate sync.
- Reopen: maintenance off; delegates' queued actions replay; announce the end of the incident.
- Report within two working days: cause, data lost (between the recovery point and the incident), duration against the 4-hour objective, actions.
Restore drill
The drill proves step 4 to 9 of the runbook on a fresh database without touching the live one. The smoke check is docker/restore-smoke.sql (row counts of the key tables, pending outbox rows, stock totals and the NumberSequence values): run it on the source and on the restored database and compare.
# 1. dump (inside the PostgreSQL container; on the VPS: fetch and decrypt last night's dump instead)
docker exec postgres pg_dump -U postgres -Fc -f /tmp/hoco-drill.dump hoco
# 2. restore into a fresh database
docker exec postgres createdb -U postgres hoco_restore
docker exec postgres pg_restore -U postgres -d hoco_restore --no-owner --exit-on-error /tmp/hoco-drill.dump
# 3. smoke: identical counts and sequences, then the API against it
docker cp docker/restore-smoke.sql postgres:/tmp/restore-smoke.sql
docker exec postgres psql -U postgres -d hoco -At -f /tmp/restore-smoke.sql > source.txt
docker exec postgres psql -U postgres -d hoco_restore -At -f /tmp/restore-smoke.sql > restored.txt
diff source.txt restored.txt
DATABASE_URL=…/hoco_restore # an api process on it: GET /ready, sign-in, catalog, admin.orders.list
# 4. clean up
docker exec postgres dropdb -U postgres hoco_restore| Drill | Date | Database | Dump | Restore | Smoke | Result |
|---|---|---|---|---|---|---|
| Local (SRV-28, development machine, demo seed) | 19 Oct 2026 | 31 MB, dump file 1.3 MB | 0.8 s | 1.7 s | counts and sequences identical; /ready 200, sign-in, catalog and admin.orders.list 200 | Passed — the procedure works; times are not representative of production |
| VPS (staging, production-sized copy) | at deployment (OPS-02) | — | — | — | — | To do: restore last night's encrypted dump (and a point-in-time recovery), time steps 4 to 9 against the 4-hour objective, record RPO (age of the recovery point) and RTO here |
Monitoring
| Signal | Tool | Notes |
|---|---|---|
| Uptime | External monitor, 1-minute checks of /health on api, admin and app hosts; a synthetic sign-in and catalog read every 5 minutes | Hosted outside the production VPS |
| Errors | Sentry for server, back-office, reseller web and both Flutter apps; releases, source maps, Dart symbols | Personal data scrubbed (NFR-8.2) |
| Logs | Container logs (JSON) collected per app; searchable 30 days | Redaction enforced in the server |
| Metrics | Request rate, latency and errors per operation; BullMQ queue depth, oldest job, failed jobs; PostgreSQL connections and slow queries; disk, memory, CPU; SSE connections; SMS delivery rate; push failure rate | Dashboard per environment |
| Business health | Orders waiting for confirmation and their age, sync errors per delegate, pending payment declarations, open after-sales claims | Back-office dashboards and the daily digest |
Alert thresholds
Proposed thresholds; alerts go by email and to the team's chat channel; during the pilot P1 alerts also call the on-call phone.
| Alert | Condition | Priority |
|---|---|---|
| API down | 2 consecutive failed uptime checks (2 minutes) | P1 |
| Error rate | HTTP 5xx above 2 % of requests over 5 minutes | P1 |
| Latency | p95 above 1 s over 10 minutes on catalog or checkout operations | P2 |
| Queue backlog | notify.* or outbox queue with more than 500 waiting jobs or an oldest job older than 10 minutes | P2 |
| Failed jobs | More than 20 failed jobs in an hour on any queue | P2 |
| Backup | No successful dump by 04:00, or WAL archiving lagging more than 15 minutes | P2 |
| Disk | Above 80 % on any volume | P2 (P1 above 90 %) |
| Certificates | Expiry in under 14 days | P3 |
| SMS | Delivery rate below 90 % over an hour, or 5 consecutive send failures | P1 (OTP path) |
| Push | FCM failure rate above 10 % over an hour (invalid tokens excluded) | P3 |
| SSE | Redis unavailable, or active SSE connections dropping by more than 50 % in 5 minutes | P2 |
| Orders waiting | An order unconfirmed for more than 8 working hours | P3 (business alert to the commercial admins) |
| Crash rate | Crash-free sessions below 99 % for a mobile release over 24 hours | P2 |
Initial data import
Cahier §13.2 « Import initial des produits, revendeurs et comptes utilisateurs »; ADM-06, CAT-06; built in SRV-27 (import jobs with dry-run report, idempotent apply and error rows), run in LCH-01; sources and format are D-31.
| Data set | Template (XLSX) — key columns | Owner at HOCO | Order |
|---|---|---|---|
| Brands, categories and sub-categories | brand, category path (Chargeurs > Chargeurs muraux) | Stock manager | 1 |
| Attribute definitions per category | category, attribute key, label, type, unit, allowed values (CAT-13) | Stock manager with Akram | 2 |
| Products and variants | brand, reference (SKU), name, category path, description, barcode (EAN-13), warranty months, VAT rate, purchase price HT, price super-gros, demi-gros and détail (HT or TTC as agreed in D-01), recommended price, min, step and max quantity, attribute values, image file names | Stock manager, commercial direction for prices | 3 |
| Product images | ZIP of images named by SKU (N32-1.jpg) or URLs | Marketing | 3 |
| Warehouses and stock levels | warehouse, SKU, physical quantity, alert threshold | Stock manager | 4 (at the freeze) |
| Users (staff and delegates) | first and last name, phone, email (staff), roles, zones (delegates) | Super admin | 5 |
| Zones | zone name, wilayas, communes, delegate | Commercial direction | 5 |
| Support regions | region, wilayas, WhatsApp number, hours, default region (D-36) | Commercial direction | 5 |
| Resellers | store name, owner name, main phone, WhatsApp, email, wilaya code, commune, address, latitude, longitude, business type, potential, customer type, assigned delegate (phone), credit limit, status | Commercial direction, finance for limits | 6 |
| Opening balances (optional) | reseller number or phone, open invoice references and balances | Finance | 7 (at the freeze) |
Cleansing rules applied by the dry-run and reported row by row: phones normalised to E.164, duplicates by normalised phone listed for HOCO to merge before import (CRM-03); communes matched to the official reference with suggestions for near spellings (Bir el Djir → Bir El Djir); brands limited to HOCO, ACEFAST and BOROFONE; EAN-13 checksums verified; prices positive and in the order super-gros ≤ demi-gros ≤ détail (warning otherwise); VAT 19 % when empty; missing GPS accepted (captured at the first visit); a reseller without a customer type is rejected.
Steps
- Templates and samples — HOCO receives the templates and returns 20 sample rows per data set as early as possible, so the templates are tuned before SRV-27 ends.
- Full extract — HOCO's data owners fill the templates; Anis runs the first dry-run on pre-production and shares the report.
- Cleansing rounds — HOCO corrects; dry-run again until zero errors (warnings reviewed).
- Rehearsal — full import on pre-production; HOCO checks 20 random products (prices of the three types, attributes, images) and 20 random resellers (customer type, delegate, wilaya) and signs the check.
- Freeze — from the agreed freeze moment, changes are made by hand in the new back-office; stock and opening balances are taken at the freeze.
- Production import during the go-live window in the order of the table; each apply is idempotent and can be re-run.
- Reconciliation — counts per data set, total stock per warehouse and total credit limits compared with HOCO's figures; signed by HOCO.
Cut-over. During the pilot, non-pilot resellers keep ordering by phone and WhatsApp as today; orders of pilot resellers received by phone are entered by staff on BO-40 so every pilot order is in the platform and goes through the « Commandes à confirmer » queue. From go-live the platform is the stock reference for every order it handles (D-34).
Training
Cahier §13.3: administrators and managers, delegates on a full tour scenario, a quick guide for resellers, administration documentation and support procedures (OPS-03). Materials by Akram with Anis (DQA-06); sessions in LCH-02 on pre-production with the recette data, repeated for each generalisation wave (LCH-05).
| Audience | Duration | Content (scenarios) | Material | Trainer |
|---|---|---|---|---|
| Super admins | 2 h | Users and roles, permissions matrix, settings, reference lists, support regions, app versions and maintenance mode, imports, activity log, session revocation | Admin reference, runbook extracts | Anis |
| Commercial admins | 3 h | The orders-to-confirm queue as a daily routine (controls, confirm, refuse, modify, on hold), assisted orders, account validation and customer types, CRM and follow-ups, tour planning and the live map, promotions and banners, announcements, reports | Quick reference card per role | Anis |
| Stock manager | 1.5 h | Products, three prices and attributes, stock levels, receipts and adjustments, inventories, alerts, return reception with automatic restock | Quick reference card | Anis |
| Finance manager | 1.5 h | Invoices, payment declarations and verification, credit limits and overrides, credit notes, exports | Quick reference card | Anis |
| Delivery manager | 1 h | Delivery board, picking list, carriers and tracking, proof of delivery, delivery failures | Quick reference card | Anis |
| Support agents | 1 h | Tickets, after-sales claims from diagnosis to resolution (replacement, return, credit note, repair, rejection), regional WhatsApp numbers | Quick reference card | Anis |
| Direction | 45 min | Dashboards, reports, exports | Quick reference card | Anis |
| Pilot delegates | Half a day (3.5 h) | A full tour scenario on test phones: consent, sign-in, start the tour, navigate, check in, visit (checklist, photos, report), not-done reason, new prospect, invitation by QR and WhatsApp, first-order assistance, offline visit and the sync centre, closing; then one real tour accompanied by Akram during the pilot (DQA-08) | Delegate field guide, QR flyer (DQA-07) | Anis, Akram, Imad |
| Resellers | Self-service | Illustrated quick guide (PDF and a one-page leaflet given by delegates): browse as a guest, sign up with the customer type, wait for validation, order, follow the live status, claim after-sales, request a return, WhatsApp support | Reseller quick guide | Delegates |
Train-the-trainer: HOCO names one champion per function who trains later arrivals with the same materials. The administration documentation and support procedures (L1 playbook) are handed over at generalisation.
Go-live checklist
Keyed to the milestones of the plan, because acceptance ends one working day before go-live. Owner in brackets.
During the build — before Staging integration complete
- Production infrastructure provisioned and hardened (SEC-0.10), DNS and TLS live, HSTS per host — done with OPS-02 (Anis).
- Backups running and one full restore tested in SRV-28 (Anis).
- Monitoring and alerts live; a test alert fired and received (Anis).
- SMS sender ID approved; a real OTP received on a Mobilis, a Djezzy and an Ooredoo number — the registration is started at the cadrage because approval takes time (HOCO, Anis).
- Firebase
hoco-prod, production Maps keys restricted, email SPF/DKIM/DMARC passing (Anis, Imad). - Play Console: apps created, closed track with the pilot users' emails, data safety form, foreground-service declaration, privacy policy URL, reviewer demo accounts — MOB-14, leaving the store review time before go-live (Imad).
- Privacy policy and account-deletion page published (HOCO, Anis).
- HOCO's testers, PV signatory and data owners booked for the year-end recette, with back-ups (HOCO, Anis).
During the recette — before Acceptance report (PV de recette) signed
- Business settings validated by HOCO on pre-production: minimum order, payment methods, credit policy, reservation status, GPS tolerance, assisted-order delay, return window, quiet hours (HOCO, Anis).
- Full import rehearsed on pre-production with zero errors; reference lists, attribute definitions and support regions with their WhatsApp numbers ready (HOCO, Anis).
- Staff accounts listed; training sessions and the pilot delegates' half-day scheduled; champions named (Anis, Akram).
- Pilot delegates' phones checked (Google Play services, battery optimisation exclusion); tours of the first pilot week drafted (Akram, HOCO).
- Go/no-go meeting at the end of the recette: open defects against the exit criteria, risks, rollback plan (all).
Go-live day — Production go-live
- Freeze; production import in order; reconciliation signed (Anis, HOCO).
- Production release deployed (API, back-office, reseller web with the invitation landing and
assetlinks.json); smoke test on production with test accounts (Anis). - Apps promoted to the closed track; pilot users invited (Imad).
- Support channels staffed (regional WhatsApp numbers, phone), escalation contacts shared (HOCO).
Next working day — Pilot starts
- Training of administrators, managers and pilot delegates (LCH-02) (Anis, Akram).
- Morning check: errors, queues, orders to confirm, sync errors, SMS delivery (Anis, Imad); first daily pilot triage (LCH-03, LCH-03B).
Pilot and generalisation
The pilot runs two weeks right after go-live, with a limited group of delegates and resellers using the two apps and the reseller web (OPS-06; group and length in D-32). It ends before Ramadan, so field activity is representative. Daily triage at the end of the field day; hotfixes on the closed track. Proposed go/no-go criteria for the Pilot go / no-go milestone:
| Criterion | Threshold |
|---|---|
| Open P1 or P2 incidents | 0 |
| Pilot orders placed through the apps (rather than by phone) | ≥ 70 % |
| Orders confirmed by the back-office | Median under 4 working hours |
| Offline sync | ≥ 99 % of queued actions applied without manual help |
| Crash-free sessions | ≥ 99.5 % on both apps |
| Check-ins accepted within tolerance | ≥ 90 % of attempts (otherwise review D-06) |
| Delegates and HOCO managers | Positive feedback in the retrospective; improvement list prioritised (LCH-04, MOB-18) |
Generalisation comes after the three months and opens zone by zone (LCH-05): train the zone's delegates, import or validate its resellers, promote the apps to the public Play track and announce the reseller web to the zone; one wave per week as long as the support load stays within the targets below. The iOS build, if HOCO decides it (D-10), ships in this phase (MOB-16).
Maintenance and support
Cahier §13.4: « Période de garantie corrective à préciser », « Maintenance corrective, préventive et évolutive selon contrat », « Support, délais de prise en charge et niveaux de priorité », « Suivi des performances, sauvegardes et mises à jour de sécurité » (OPS-04). Everything below is proposed and becomes binding through the contract.
Warranty. Two months of corrective warranty from production go-live (covering the pilot and generalisation): defects in the delivered and accepted scope are fixed at no cost.
| Type | Scope | How |
|---|---|---|
| Corrective | Defects against the specification and the accepted scenarios | Tickets prioritised P1–P4; fixes in hotfix or scheduled releases |
| Preventive | Monthly: dependency and security updates, PostgreSQL and Redis minor upgrades, certificate and backup checks, restore test; quarterly: capacity review, permission and access review | Monthly maintenance report |
| Evolutive | New features and changes (V2 included) | Change request → estimate → planning (change requests) |
Support levels and channels
| Level | Who | Handles | Channel |
|---|---|---|---|
| L1 | HOCO's support agents and champions | How-to questions, account and password help, order and claim follow-up, reseller calls and regional WhatsApp | Reseller tickets, WhatsApp, phone |
| L2 | Anis (server, back-office, web), Imad (mobile) | Defects, data corrections, configuration, incidents | Support email and a shared tracker; phone for P1 |
| L3 | Providers (hosting, SMS gateway, Firebase, email) | Provider incidents | Provider support, opened by L2 |
Priorities and targets (business hours Sunday–Thursday 08:30–17:30 Africa/Algiers; during the pilot, P1 is covered every day 08:00–20:00)
| Priority | Definition | Example | First response | Workaround or restore | Fix |
|---|---|---|---|---|---|
| P1 — Critical | Production down, or a core flow blocked for all users, or a security or data-integrity breach | API down; no order can be submitted or confirmed; delegates cannot sync; OTP not delivered; another reseller's data visible | 1 hour | 4 hours | 1 working day |
| P2 — High | A major function degraded for many users, no workaround | Live status not updating; notifications not sent; payment verification failing; returns cannot be received | 4 business hours | 1 working day | 3 working days |
| P3 — Medium | A function impaired with a workaround, or few users affected | Export failing for one report; a filter count wrong; one device model misbehaving | 1 working day | — | Next scheduled release (≤ 10 working days) |
| P4 — Low | Cosmetic issue, question, small improvement | Label, alignment, wording | 2 working days | — | Planned in the backlog |
Recette severities map to these priorities: Blocker ≈ P1, Critical ≈ P2, Major ≈ P3, Minor ≈ P4 (acceptance procedure).
Releases after go-live: hotfixes any day for P1 and P2; a minor release every two weeks during pilot and generalisation, then monthly. Reporting: a monthly report to HOCO with tickets by priority and targets met, availability, incidents, backups and restore tests, security updates and the next month's plan.
Runbooks
Each runbook lives in the operations repository folder and is rehearsed on pre-production before go-live.
| Runbook | When | Owner | Time |
|---|---|---|---|
| Deploy | Every release | Anis (web), Imad (mobile) | 15 min |
| Roll back | Release causing a P1 or P2 | Anis | 10 min |
| Restore the database | Data loss or corruption | Anis | ≤ 4 h (restore runbook) |
| Rotate secrets | Leak, departure, yearly | Anis | 30–60 min |
| Revoke sessions | Compromised account or device, departure | Super admin, Anis | 5 min |
| Disable an app version | Vulnerable or broken app release | Anis, Imad | 5 min |
| Maintenance mode | Planned maintenance, restore | Anis | 2 min |
| SMS outage | Delivery alert, user reports | Anis | 30 min |
| Push outage | FCM failures | Imad, Anis | 30 min |
| Real-time outage | SSE or Redis alert | Anis | 30 min |
Integrations
Every external service and platform the ecosystem depends on — maps, device location, push, real-time streams, SMS, email, WhatsApp, file storage, carriers, ERP and accounting, the stock system and the app stores — with purpose, release, data exchanged, configuration, failure modes, costs to validate and the decision each depends on.
Hardening report
SRV-28 findings — permission, scope and exposure sweeps, security headers, rate limits, dependency and secret scan, upload checks, slow-query pass, restore drill and load-test kit — each with severity, status and evidence.