HOCO B2B
SRS

Smart notifications

HOCO's document 03 (Smart Notifications) treated as a change request: the 24 notification types, the Notification Centre, the action button, the Top 3 and the promotion tabs, each with its trigger, audience, channel, group, action and release, plus anti-fatigue rules, data and API impact and the French and Arabic copy.

Source and status

ItemValue
DocumentDOCUMENT 03 : SMART NOTIFICATIONS, written by HOCO in Algerian Arabic and French
Received18 October 2026
StatusChange request against the cahier (cahier §8 Notifications, §14 phases). It is accepted into the specification with the release placement below. V1 items fit the existing modules. V2 items wait for the loyalty engine. Later items are new modules and need a separate estimate (validation sheet, Clause de périmètre)
RequirementsV1: NOT-09 to NOT-17 and PRM-07. V2: NOT-18, PRM-08, LOY-06, LOY-07
DecisionsD-39 to D-44, all Defaulted (18 Oct 2026)
PlanDES-23, SRV-39, SRV-40, DSH-14, WEB-06, MRA-11
RelatedNotifications matrix (event rows, copy, quiet hours, caps) · scope · jobs

The client's principle

The document opens with four goals: keep the app present in the reseller's mind (« يخلي التطبيق ديما حاضر في بالو »), increase the number of orders, make sure no offer is missed, and help the reseller run their shop better. It states the rule « كل Notification لازم يكون عندها هدف تجاري »: every notification must have a commercial goal. It ends with a second rule the client is "100 % convinced" of: « كل Notification لازم يكون فيها زر Action », every notification carries an action button.

The specification turns this into three rules:

  1. Every reseller notification has a group (NotificationGroup, the section of the Notification Centre) and an action (action { label, deepLink }). The transactional notifications already in the matrix get one too (NOT-10).
  2. Smart notifications are rule-based and computed by the server from data the platform already holds: catalog, availability, prices, carts, orders, favorites, promotions. They are never sent by hand, except the commercial push, where HOCO picks the product and the audience.
  3. Smart notifications are commercial (PROMOTIONAL category). They obey the anti-fatigue rules so that the Notification Centre stays useful and the reseller does not mute the app. Two decisions of 17 October still apply: resellers never see a stock quantity (STK-07), and guests receive no notification.

Release placement

ReleaseItemsWhy
V1SN-01 Nouvel arrivage · SN-02 Retour en stock · SN-03 Stock faible · SN-04 Promotion · SN-12 Smart reminder (rule-based) · SN-14 Produit complémentaire (configured pairs) · SN-17 Produit tendance (weekly top seller) · SN-18 Flash sale (countdown, 2 h to 48 h) · SN-19 Nouveau catalogue · SN-20 Panier abandonné · SN-21 Alerte prix · SN-23 Notification commerciale · SN-25 Notification Centre (6 groups) · SN-26 Action button · SN-28 tabs Promotions and Flash SalesEvery trigger reads data that V1 modules already hold: catalog (SRV-11), inventory availability (SRV-13), cart (SRV-15), orders (SRV-16), promotions (SRV-19), price history, favorites and announcements. The only new mechanisms are scheduled scans and per-reseller rules on the existing notification pipeline (SRV-08). The work costs about 6.5 working days across the lanes. The plan shows the effect on the schedule
V2SN-05 Double points · SN-06 Nouveau niveau · SN-07 Missions (commercial, interaction, challenge, surprise) · SN-08 Mission terminée · SN-09 Cadeau disponible · SN-15 Anniversaire d'inscription · SN-16 Objectif presque atteint (next level) · SN-22 Missions personnalisées · SN-24 Challenge du mois · SN-27 Top 3 revendeurs du mois · SN-28 tab Offres exclusives (by level)All of them need points, levels or rewards. The loyalty programme is V2 (LOY-01 to LOY-05, D-16), built in SRV-30. They plug into the V1 groups, actions and caps without changing them
Later / to decideSN-10 HOCO Academy (videos) · SN-11 Quiz · SN-13 Suggestions IA (bought together) · the Academy missions (watch videos, pass a quiz) · the Daily / Weekly / Monthly Mission cadence · the product-review missionNew modules that the cahier does not have: video hosting and a learning module (D-40), product reviews, and a recommendation model fed by V2 advanced analytics (ANA-06, D-41). The cadence of missions is a loyalty-policy choice made with the V2 engine

The ACADEMY group exists in the enum from V1, so the Notification Centre keeps its six sections. Until the module exists the section is hidden (NOT-09).

Catalogue

Conventions used in the table:

  • Channels: IN_APP is the inbox row, shown in the Notification Centre. PUSH goes to the reseller app; the reseller web has no web push in V1 and relies on the inbox and the live stream. No smart notification uses SMS: none meets the critical SMS rule, and marketing by SMS needs a prior opt-in (Law 18-07). The WhatsApp Business templates of V2 (NOT-08) are the channel to consider for SN-18 and SN-20 later.
  • Category is the preference category (NotificationCategory). Group is the section of the Notification Centre (NotificationGroup).
  • Recipients are always active, validated resellers whose account can order (store.canOrder) and who can see the product under its visibility rules (CAT-05). Guests, pending and suspended accounts receive nothing.
  • Deep links are proposals, like the rest of the route table. The reseller app and the reseller web use the same paths.
  • Settings in code are proposals for the settings catalogue. The defaults come from D-39 to D-44.

V1 types

IdName (client)Trigger (rule)RecipientsChannelsCategory · groupAction (label → deep link)Release · dependencies
SN-01Nouvel ArrivageA product is published for the first time (Product.publishedAt set; status ACTIVE with at least one variant IN_STOCK), with the BO-28 box « Annoncer comme nouveauté » ticked (on by default). Job smart.newArrivalsDigest at 10:00 and 16:00 groups the products published since the last runEvery eligible reseller who can see the productIN_APP · PUSHPROMOTIONAL · NEW_PRODUCTS« Commander maintenant » → RA-14 / RW-04 /products/{productId}; grouped (2 or more products) → RA-12 /catalog?tab=newV1 · SRV-11, SRV-40
SN-02Retour en StockThe availability of a variant changes OUT_OF_STOCK → IN_STOCK (available quantity goes from 0 to above 0 in the inventory module). The variant must have stayed OUT_OF_STOCK for at least smart.restockMinOutHours (default 24 h), so that a correction does not trigger itOnly targeted resellers (the client's « ماشي كامل التجار »): those who ordered the variant in the last smart.restockLookbackDays (default 90, D-43) on an order that was not refused or cancelled, those who have the product in their favorites, and those whose cart holds the variant with the OUT_OF_STOCK issueIN_APP · PUSHPROMOTIONAL · NEW_PRODUCTS« Commander maintenant » → /products/{productId}?variantId={variantId}V1 · SRV-13, SRV-16, SRV-11 (favorites), SRV-15
SN-03Stock FaibleThe available stock of an IN_STOCK variant falls to or below its alert threshold, the same threshold as the staff stock.low alert (default 20, D-02). It fires once, then rearms only when the stock goes back above the threshold. No quantity is ever shown: the message says the quantity is limited, and the product page keeps « En stock » (STK-07)Resellers who have the product in favorites or the variant in their cart, and resellers who ordered the variant at least twice in the last 90 daysIN_APP · PUSHPROMOTIONAL · NEW_PRODUCTS« Commander maintenant » → /products/{productId}?variantId={variantId}V1 · SRV-13, SRV-16
SN-04Promotion (offre normale)Existing event promotion.started: a promotion becomes ACTIVE with « Notifier les revendeurs » ticked in BO-50. It covers clearance (déstockage), seasonal offers, back to school, Ramadan and year-end. The offer lasts until its end date or until its stock cap is consumed (PRM-04)audience: resellers targeted by the promotion (PRM-02)IN_APP · PUSHPROMOTIONAL · PROMOTIONS« Voir l'offre » → RA-25 / RW-10 /promotions/{promotionId}V1 · SRV-19 (exists)
SN-12Smart ReminderRule-based on purchase cadence, not AI. For each reseller and leaf sub-category with at least 3 orders in the last 180 days, the median interval between those orders is the cadence. The reminder fires when the days since the last order containing that sub-category reach the cadence + smart.reorderGraceDays (default 1). Example: a weekly buyer of cables gets it on day 8. One reminder per sub-category and cycle; none when the cart already holds that sub-category. Job smart.reorderReminders runs daily at 09:30The reseller concernedIN_APP · PUSHPROMOTIONAL · SUGGESTIONS« Commander à nouveau » → RA-22 / RW-09 /orders/{lastOrderId}?reorder=1, which opens the existing reorder sheet filtered on the sub-categoryV1 · SRV-16, SRV-40
SN-14Produit ComplémentaireConfigured pairs. Each product may list up to 5 complementary products in BO-28 (« Produits complémentaires », ProductComplement). Example: a phone case gets tempered glass. The day after an order containing the product is confirmed (VALIDATED), job smart.complementSuggestions at 10:30 picks the first complement by position. That complement must be IN_STOCK, visible to the reseller, and not ordered by the reseller in the last 60 days. At most one per orderThe reseller who placed the orderIN_APP · PUSHPROMOTIONAL · SUGGESTIONS« Voir le produit » → /products/{complementProductId}V1 · SRV-11, SRV-16, SRV-39
SN-17Produit TendanceJob smart.trendingWeekly, Sunday at 09:00. It finds the product with the most units on confirmed orders over the previous 7 days, nationally, IN_STOCK, with at least 5 distinct buyers. Ties go to the larger number of buyersEligible resellers who did not order that product in the last 30 daysIN_APP · PUSHPROMOTIONAL · NEW_PRODUCTS« Voir le produit » → /products/{productId}V1 · SRV-16, SRV-40
SN-18Flash Sale (vente flash)A promotion flagged isFlashSale becomes ACTIVE (job promotions.applySchedule). A flash sale lasts from 2 h to 48 h between startsAt and endsAt (validated in BO-50). The apps show a countdown computed from the server time (PRM-07). Typical uses: move stock fast, more orders in a short window, clear a limited quantity, special occasionsaudience of the promotionIN_APP · PUSH (high priority, TTL = the time left)PROMOTIONAL · PROMOTIONS« Commander maintenant » → RA-24 / RW-10 /promotions/{promotionId}V1 · SRV-19, SRV-39
SN-19Nouveau CatalogueHOCO publishes a new edition of its catalogue in BO-57 (announcement of kind NEW_CATALOGUE). It carries a PDF file (CATALOG_PDF), optionally a category or a brand to open, and a cover imageaudience of the announcement (default: every reseller)IN_APP · PUSHPROMOTIONAL · NEW_PRODUCTS« Voir le catalogue » → RA-26 announcement sheet /messages/{announcementId} with the PDF link, or RA-12 /catalog?categoryId= when a category is setV1 · SRV-24, SRV-39
SN-20Panier AbandonnéThe reseller's cart holds at least one line, its last change (Cart.updatedAt) is more than smart.abandonedCartDelayHours old (default 2, D-44), and no checkout happened since. It is sent once per cart version: any change to the cart resets it, and a checkout cancels a pending reminder. At most one per reseller per 24 h. Job smart.abandonedCarts runs every 15 minutesThe resellerIN_APP · PUSHPROMOTIONAL · SUGGESTIONS« Finaliser ma commande » → RA-17 / RW-06 /cartV1 · SRV-15, SRV-40
SN-21Alerte PrixA PriceChange lowers the price of a variant for a customer type by at least smart.priceDropMinPercent (default 5 %). Promotions are excluded because they have their own notification. Price increases are never notifiedResellers of that customer type who have the product in favorites, hold the variant in their cart, or ordered it in the last 90 daysIN_APP · PUSHPROMOTIONAL · PROMOTIONS« Voir le produit » → /products/{productId}?variantId={variantId}V1 · SRV-12, SRV-40
SN-23Notification Commerciale (HOCO's own idea)The back-office picks a product (or a promotion, category or brand), an audience, a message and a send time in BO-57 (announcement of kind COMMERCIAL_PUSH, permission communication.validate). The editor shows how many resellers get the push and how many get the inbox entry only because of the capsaudience: wilayas, segments, customer types, named resellers, or buyers of a category in the last N daysIN_APP · PUSHPROMOTIONAL · PROMOTIONSEditable, default « Commander maintenant » → /products/{productId} (or /promotions/{id}, /catalog?categoryId=, /catalog?brandId=)V1 · SRV-24, SRV-39, DSH-14
SN-25Centre de NotificationsNot an event. It is a section of the home page (RA-09, RW-02) and the grouped inbox (RA-26, RW-11) with six groups, in the client's colours: Urgent (red), Promotions (orange), Nouveautés (green), Points et niveaux (blue), Academy (purple), Suggestions (star). Each group shows its unread count and its latest items. It replaces pop-ups (the client: the reseller finds everything in order and does not feel harassed)Every signed-in reseller—URGENT holds the TRANSACTIONAL and SECURITY notifications and urgent announcementsTapping a group opens RA-26 / RW-11 /notifications?group={group}V1 · NOT-09; SRV-39, MRA-11, WEB-06, DES-23
SN-26Bouton ActionEvery reseller notification has an action with a French label and a deep link. The inbox and the Notification Centre render it as a button. On Android the push carries it as a notification action, and a tap on the body opens the same link———Defaults for the existing events: belowV1 · NOT-10
SN-28Promotion tabsRA-24 and RW-10 are split into tabs. Promotions holds the normal offers that last several days or until the stock runs out, daily offers included. Flash Sales holds isFlashSale offers with their countdown. The third tab, Offres exclusives, is V2 (row below)———Tab routes /promotions?tab=promotions, /promotions?tab=flashV1 · PRM-07

The client gives each group a colour (red, orange, green, blue, purple, a star for suggestions). In the apps the colours become the tones of NotificationGroup, and Akram chooses the icons in DES-23.

V2 types (loyalty engine)

IdName (client)Trigger (rule, V2)RecipientsChannelsCategory · groupAction (label → deep link)Dependencies
SN-05Double PointsA loyalty campaign with a ×2 multiplier starts (LOY-01 bonus campaigns, BO-53), for one day or a periodAudience of the campaignIN_APP · PUSHPROMOTIONAL · LOYALTY« Commander maintenant » → /catalogSRV-30
SN-06Nouveau Niveauloyalty.recomputeLevels moves the reseller up a level (Bronze → Silver → Gold → VIP, LOY-03)The resellerIN_APP · PUSHTRANSACTIONAL · LOYALTY« Découvrir mes avantages » → RA-38 /loyaltySRV-30
SN-07Mission DisponibleA mission is assigned. Kinds from the document: commercial (first order of the month +200 points, 5 orders +500, more than 5 000 000 DA of purchases +700, a first-time product, 3 different categories), interaction (rate the last order +50, enable notifications), challenge (Challenge de la semaine: 3 orders in 7 days; Flash Challenge: buy the chosen product today) and surprise (one random mission a week, e.g. order 10 cables) — LOY-06The resellerIN_APP · PUSHPROMOTIONAL · LOYALTY« Voir la mission » → /missions/{missionId} (V2 screen to design)SRV-30, DES-30
SN-08Mission TerminéeThe mission's condition is met and its points are creditedThe resellerIN_APP · PUSHTRANSACTIONAL · LOYALTY« Voir mon solde » → RA-38 /loyaltySRV-30
SN-09Cadeau DisponibleA reward becomes claimable (level reward, mission prize, Top 3 voucher, LOY-04)The resellerIN_APP · PUSHTRANSACTIONAL · LOYALTY« Récupérer mon cadeau » → RA-39 /loyalty/rewardsSRV-30
SN-15Anniversaire d'inscriptionDaily job: today is the anniversary of the account's validation date; a bonus of 300 points (setting) is creditedThe resellerIN_APP · PUSHPROMOTIONAL · LOYALTY« Voir mon cadeau » → RA-38 /loyaltySRV-30
SN-16Objectif Presque AtteintPurchases over the level period are within loyalty.almostThresholdAmount (example: 1 000 000 DA) of the next level, sent once per period and levelThe resellerIN_APP · PUSHPROMOTIONAL · LOYALTY« Commencer une commande » → /catalogSRV-30
SN-22Notification Personnalisée (missions personnalisées)A mission generated from the reseller's own history: « 20 chargeurs de plus cette semaine = 500 points » for a heavy charger buyer, « votre première montre connectée = 300 points » for a reseller who never bought one. Rule-based on category history in V2The resellerIN_APP · PUSHPROMOTIONAL · LOYALTY« Relever le défi » → /missions/{missionId}SRV-30, LOY-06
SN-24Challenge du MoisThe monthly challenge opens, for example 5 000 000 DA of purchases this month for 1 000 extra points; progress reminders follow the capsAudience of the challengeIN_APP · PUSHPROMOTIONAL · LOYALTY« Voir le challenge » → /missions/{missionId}SRV-30
SN-27Top 3 Revendeurs du MoisOn the 1st of the month, the previous month's ranking is published. A weighted score combines purchase volume, number of orders and activity in the app (D-42). Prizes: 1st, a 20 000 DA voucher, the badge « Meilleur Revendeur » and a month on the home page; 2nd, 10 000 DA and « Top Revendeur »; 3rd, 5 000 DA and « Top 3 Revendeur » (LOY-07)Winners; a home-page highlight for everyoneIN_APP · PUSH (winners)TRANSACTIONAL · LOYALTY« Voir le classement » → /loyalty/leaderboardSRV-30, DES-30
SN-28 (V2)Offres Exclusives tabPromotions whose audience is restricted to loyalty levels (Gold, VIP, …), the V2 criterion of PRM-02Resellers of those levels—PROMOTIONAL · PROMOTIONSTab /promotions?tab=exclusivePRM-08, SRV-30

Later / to decide

IdName (client)What it needsDecision
SN-10HOCO Academy (new video)A learning module: video hosting or embedding, lessons, progress, an Academy section in both reseller apps, and back-office authoringD-40
SN-11QuizQuizzes with questions, scoring and points (needs Academy and loyalty)D-40
SN-13Suggestions IA (« les revendeurs qui ont acheté un Power Bank ont aussi acheté un Chargeur 65W »)Co-purchase statistics over enough orders, in V2 advanced analytics (ANA-06); until then SN-14 covers the need with configured pairsD-41
SN-07 optionsDaily / Weekly / Monthly missions (« Si nn » in the document): watch a video, browse the catalogue, add a favorite, 3 orders a week, enter the Top 10 of the wilaya, buy from 5 categoriesA mission cadence engine; part of the V2 loyalty policy (D-05). Video missions wait for Academy; the product-review mission needs reviews, which are not in the cahierD-40, D-42

Actions of the existing notifications

The client's examples set the tone: new product → « Commander maintenant », points earned → « Voir mon solde », new level → « Découvrir mes avantages », new video → « Regarder maintenant », one million left before Silver → « Commencer une commande ». The V1 events of the matrix get these default labels. Each template can override its label in BO-58.

EventsAction labelDeep link
order.*, delivery.failed, assisted_order.confirmed.by_admin, assisted_order.expired« Voir la commande »RA-22 / RW-09 /orders/{orderId}
assisted_order.awaiting_confirmation, assisted_order.reminder« Confirmer la commande »RA-23 /orders/{orderId}/confirm
return.*« Voir le retour »RA-40 /returns/{returnId}
ticket.replied, ticket.status_changed.waiting_reseller« Répondre »RA-34 /support/tickets/{ticketId}
ticket.resolved.*, ticket.rejected, other ticket.*« Voir la demande »RA-34
payment.confirmed, payment.rejected« Voir mes paiements »RA-31 /finance/payments
invoice.issued« Voir la facture »RA-30 /finance/invoices/{invoiceId}
account.approved, account.customer_type_changed« Voir le catalogue »RA-12 /catalog
account.rejected« Compléter mon dossier »RA-06
promotion.started, daily_offer.published« Voir l'offre »RA-25 / RA-24
announcement.publishedSet by the author; default « Lire le message »/messages/{announcementId}
security.*« Vérifier mon compte »RA-35

Notification Centre and groups

ValueUI label (fr)Meaning
URGENTUrgentTransactional and security notifications, urgent announcements.
PROMOTIONSPromotionsPromotions, flash sales, price drops, commercial pushes, daily offers.
NEW_PRODUCTSNouveautésNew arrivals, back in stock, limited quantity, trending product, new catalogue.
LOYALTYPoints et niveauxV2: points, levels, missions, gifts, challenges, Top 3.
ACADEMYAcademyLater: HOCO Academy videos and quizzes; hidden while empty.
SUGGESTIONSSuggestionsReorder reminders, complementary products, abandoned cart.
GroupHolds (V1)Push opt-out (RA-35, RW-12)
URGENT UrgentEvery TRANSACTIONAL and SECURITY reseller notification (orders, assisted orders, returns, claims, payments, invoices, account), plus announcements ticked « Urgent »Locked on (« Indispensable au suivi de vos commandes »)
PROMOTIONS PromotionsSN-04, SN-18, SN-21, SN-23, daily_offer.published, non-urgent announcementsYes
NEW_PRODUCTS NouveautésSN-01, SN-02, SN-03, SN-17, SN-19Yes
LOYALTY Points et niveauxV2: SN-05 to SN-09, SN-15, SN-16, SN-22, SN-24, SN-27Yes (V2)
ACADEMY AcademyLater: SN-10, SN-11; the section is hidden while emptyYes (later)
SUGGESTIONS SuggestionsSN-12, SN-14, SN-20; later SN-13Yes

Rules:

  1. Home section (RA-09, RW-02): a card « Centre de notifications » under the attention slot. It shows one chip per visible group with its unread count, ordered Urgent, Promotions, Nouveautés, Suggestions (V2 adds Points et niveaux; Academy comes later), and the 3 latest unread items with their action buttons. With nothing unread it shows « Vous êtes à jour » and the 3 latest items. A chip opens the inbox filtered on that group.
  2. Inbox (RA-26, RW-11): the filter chips become the group tabs: « Toutes », then the groups. The « Non lues » toggle stays.
  3. Pop-ups: smart notifications never open a modal. In the foreground, a push appears as the usual in-app banner (realtime), and only for the URGENT group. Other groups only update the badge and the home section.
  4. Groups apply to resellers only. Delegate and staff notifications have no group.
  5. A notification's group is fixed by its template, never by the client app. A template that has no group defaults to URGENT for TRANSACTIONAL and SECURITY and to PROMOTIONS otherwise.

Anti-fatigue rules

Proposal to validate with HOCO (D-39, defaulted). Without limits, the 24 types could send a reseller several pushes a day. The client's own concern (« ما يحسش التطبيق يزعجو », the app must not feel like it harasses him) is the reason for these rules (NOT-17).

  1. Caps on promotional pushes. At most 1 push per reseller per day and 3 per rolling 7 days for the PROMOTIONAL category. The settings are notifications.promotionalDailyCap (exists, 1) and notifications.promotionalWeeklyCap (new, 3). TRANSACTIONAL and SECURITY are never capped and do not count.
  2. Capped means inbox only. A notification over the cap still writes its inbox row; it shows in the Notification Centre and in the badge. Only the push is dropped. Nothing is lost.
  3. Priority for the day's push. When several promotional notifications compete for a reseller's slot within the same dispatch window, the push goes to the highest of: SN-18 flash sale → SN-02 back in stock → SN-20 abandoned cart → SN-23 commercial push → SN-21 price drop → SN-03 low stock → SN-04 promotion → SN-12 reorder → SN-14 complement → SN-01 new arrival → SN-17 trending → SN-19 catalogue. The others go to the inbox only. A commercial push counts like any other: the back-office cannot exceed the caps, but BO-57 shows the split before sending.
  4. Quiet hours as already documented: PROMOTIONAL pushes only between 09:00 and 20:00, never on Friday before 14:00, and the Ramadan profile (quiet hours). A deferred push that would arrive after its TTL is dropped, for example a flash sale that has ended.
  5. Merge of similar events. Events of the same type for the same reseller within 24 h become one notification with a count: « 3 nouveaux produits chez HOCO », « 2 produits de retour en stock ». The digest jobs batch arrivals and complements. The same product does not notify the same reseller twice in 7 days, whatever the type (back in stock, low stock, price drop, trending, complement).
  6. Opt-out per group for the non-transactional groups (Promotions, Nouveautés, Suggestions; later Points et niveaux and Academy). The reseller sets it on RA-35 and RW-12, and it applies to push only, like every preference (NOT-06). The URGENT group is locked on. Turning off the category Offres et promotions turns off every promotional group at once.
  7. Back-off (proposal): after 5 promotional pushes in a row that were not opened, the reseller's weekly cap drops to 1 for 30 days. The first opened push restores it.

Data and API impact

Additive changes only: no V1 operation is renamed and no field is removed. They are made in SRV-39 (contract and schema) and used by SRV-40.

WhereChange
Enum NotificationGroup (new)URGENT, PROMOTIONS, NEW_PRODUCTS, LOYALTY, ACADEMY, SUGGESTIONS, with French labels and tones in enums.json
Enum AnnouncementKind (new)MESSAGE (the existing announcements), COMMERCIAL_PUSH (SN-23), NEW_CATALOGUE (SN-19)
Notificationgroup NotificationGroup? (null for delegates and staff), actionLabel String?, actionRoute String? (the route already in data.route moves here; data.route is kept for compatibility) · index (userId, group, createdAt)
NotificationTemplategroup NotificationGroup?, actionLabel per locale (fr required, ar and en fall back)
NotificationRulepriority Int (rank of rule 3 above), mergeWindowHours (rule 5)
NotificationPreferenceOptional group NotificationGroup?: a row with a group mutes push for that group, and a row without a group keeps the current category × channel meaning. URGENT rows are refused with 422 PREFERENCE_NOT_EDITABLE
PromotionisFlashSale Boolean @default(false). Validation: when true, endsAt − startsAt is between 2 h and 48 h (400 VALIDATION_FAILED, field code FLASH_SALE_DURATION); a flash sale cannot also be a daily offer
ProductComplement (new model, catalog)productId, complementProductId, position, createdById, unique (productId, complementProductId), at most 5 per product, no self-reference
ProductannounceAsNew Boolean @default(true) (BO-28 box), publishedAt DateTime? (first publication; set once, never reset)
Announcementkind AnnouncementKind @default(MESSAGE), group NotificationGroup?, productId?, promotionId?, categoryId?, brandId?, fileId? (catalogue PDF), actionLabel?
notifications.listItems gain group and action: { label, deepLink } | null; new query ?group=
notifications.unreadCountAdds byGroup (count per NotificationGroup) for the home section
promotions.listItems gain isFlashSale; new query ?tab=promotions|flash (V2 exclusive). catalog.home adds flashSales[] (at most 3, with endsAt) next to dailyOffer
notifications.preferences.get / .updateAccept and return per-group push toggles
Adminadmin.promotions.crud accepts isFlashSale; the admin product write payload accepts complementProductIds[] and announceAsNew; admin.announcements.crud / .send accept kind, the target and actionLabel and return the push / inbox-only split
Push payloaddata.actionLabel and data.group are added next to route; the Android channel_id follows the category as today
EventsThe new event keys of the matrix; no SSE event is added: notification.created carries group so the open home updates its counts

No operation id is added to endpoints.json: every change extends an existing operation.

French UI copy

The apps are French-first. The table gives the French copy (fr, seed of NotificationTemplate) and keeps the client's own Arabic wording as the ar variant. The client's samples start with an emoji (a parcel, a flame, an hourglass, a party popper…); whether pushes keep a leading emoji is decided in DQA-10. The copy below leaves them out. The copy rules apply: title ≤ 40 characters, body ≤ 120, vous, no stock quantity.

Id · templateTitle (fr)Body (fr)Action (fr)ar (client wording)
SN-01 product.arrivedNouveauté chez HOCO{{productName}} vient d'arriver. Découvrez-le avant qu'il ne parte.Commander maintenantوصل منتج جديد عند HOCO. اكتشفه الآن قبل نفاد الكمية.
SN-01 product.arrived.grouped{{count}} nouveautés chez HOCODont {{productName}}. Découvrez-les avant qu'elles ne partent.Voir les nouveautésوصلت منتجات جديدة عند HOCO. اكتشفها الآن قبل نفاد الكمية.
SN-02 variant.restockedDe retour en stock{{productName}}, que vous attendiez, est de nouveau disponible.Commander maintenantالمنتج اللي كنت تستناه رجع للمخزن.
SN-03 variant.low_stock_reachedQuantité limitée{{productName}} : la quantité disponible est limitée. Commandez avant la rupture.Commander maintenantالكمية المتوفرة قليلة، اطلب الآن قبل نفاد المخزون.
SN-04 promotion.startedNouvelle offreProfitez d'une remise spéciale sur {{promotionLabel}}, jusqu'à la fin de l'offre ou épuisement.Voir l'offreعرض جديد. استفد من تخفيض خاص على {{promotionLabel}}. العرض ساري حتى نهاية الحملة أو نفاد الكمية.
SN-05 loyalty.double_points_started (V2)Points doublés aujourd'huiAujourd'hui seulement, tous vos achats rapportent deux fois plus de points.Commander maintenantاليوم فقط. كل مشترياتك تمنحك ضعف النقاط.
SN-06 loyalty.level_reached (V2)Félicitations !Vous êtes maintenant {{levelLabel}}. Découvrez vos nouveaux avantages.Découvrir mes avantagesمبروك. أصبحت {{levelLabel}}. اكتشف امتيازاتك الجديدة.
SN-07 mission.assigned (V2)Nouvelle mission{{missionLabel}} : terminez-la et gagnez {{points}} points bonus.Voir la missionعندك مهمة جديدة. أكملها واربح Bonus Points.
SN-08 mission.completed (V2)Bravo !Mission accomplie : vous gagnez {{points}} points.Voir mon soldeأحسنت. ربحت {{points}} نقطة.
SN-09 reward.unlocked (V2)Un cadeau vous attendVous avez un nouveau cadeau, à récupérer dès maintenant.Récupérer mon cadeauعندك هدية جديدة. يمكنك استلامها الآن.
SN-10 academy.video_published (later)Nouvelle leçon HOCO Academy{{lessonTitle}} est disponible.Regarder maintenantدرس جديد متوفر.
SN-11 academy.quiz_published (later)Quiz disponibleRépondez au quiz et gagnez des points supplémentaires.Répondre au quizجاوب على الاختبار واربح نقاط إضافية.
SN-12 reorder.reminder_dueBesoin de réassort ?Vous commandez souvent des {{categoryName}}. Voulez-vous recommander ?Commander à nouveauلاحظنا أنك عادة تطلب {{categoryName}}. هل تريد إعادة الطلب؟
SN-13 suggestion.bought_together (later)Souvent achetés ensembleLes revendeurs qui ont acheté {{productName}} ont aussi acheté {{otherProductName}}.Voir le produitالتجار اللي شراو {{productName}} شراو أيضًا {{otherProductName}}.
SN-14 complement.suggestedPensez au complémentAvec {{productName}}, avez-vous aussi besoin de {{complementName}} ?Voir le produitهل تحتاج أيضًا إلى {{complementName}}؟
SN-15 loyalty.anniversary_reached (V2)Joyeux anniversaire HOCO !{{years}} an(s) avec nous : {{points}} points offerts.Voir mon cadeauعيد سعيد. هدية {{points}} نقطة.
SN-16 loyalty.level_almost_reached (V2)Plus que {{remainingAmount}}Il ne vous reste que {{remainingAmount}} d'achats pour passer {{nextLevelLabel}}.Commencer une commandeبقي لك {{remainingAmount}} فقط للوصول إلى {{nextLevelLabel}}.
SN-17 trending.computedLe plus vendu de la semaine{{productName}} est le produit le plus commandé cette semaine.Voir le produitأكثر منتج مبيعًا هذا الأسبوع.
SN-18 flash_sale.startedVente flashRemise exceptionnelle sur {{productName}}. Plus que {{remaining}} : commandez avant la fin.Commander maintenantFlash Sale. خصم استثنائي على {{productName}}. باقي {{remaining}} فقط. اطلب الآن قبل انتهاء العرض.
SN-19 catalogue.publishedNouveau catalogue HOCOLe catalogue {{catalogueTitle}} est disponible.Voir le catalogueنزلت نسخة جديدة من الكاتالوغ.
SN-20 cart.abandonedVotre panier vous attendVous avez oublié {{itemCount}} articles dans votre panier.Finaliser ma commandeنسيت منتجات في السلة.
SN-21 price.droppedBaisse de prixLe prix de {{productName}}, qui vous intéresse, a baissé.Voir le produitالمنتج اللي مهتم بيه نقص سعره.
SN-22 mission.personalised (V2)Un défi pour vousCette semaine, {{missionLabel}} et gagnez {{points}} points.Relever le défiهذا الأسبوع، إذا طلبت 20 Chargeur إضافي تربح 500 نقطة.
SN-23 commercial_push.sentWritten by the author (default: {{productName}})Written by the author, ≤ 120 charactersCommander maintenant (editable)Written by the author
SN-24 challenge.started (V2)Challenge du moisAtteignez {{targetAmount}} d'achats ce mois-ci et gagnez {{points}} points en plus.Voir le challengeإذا وصلت إلى {{targetAmount}} هذا الشهر، تربح {{points}} نقطة إضافية.
SN-27 leaderboard.published (V2)Vous êtes dans le Top 3 !Vous êtes {{rankLabel}} revendeur du mois : bon d'achat de {{voucherAmount}} et badge {{badgeLabel}}.Voir le classementالمركز {{rank}}. Bon d'achat {{voucherAmount}}.

Typical values for the length check: productName BOROFONE BX51 câble USB-C 1 m · promotionLabel Power Bank HOCO J101 · remaining 18 h · categoryName câbles · itemCount 4 · remainingAmount 1 000 000,00 DA. SN-04's client example (Power Bank at 2 100 DA instead of 2 500 DA) shows the promotional price next to the normal one on RA-25, not in the push. The push never carries a price, because prices depend on the customer type.

Plan

The V1 work is six tasks: DES-23 (Akram: Notification Centre, action buttons, promotion tabs, flash-sale countdown), SRV-39 (contract and schema), SRV-40 (triggers and jobs), DSH-14 (back-office: commercial push, new catalogue, flash-sale fields, complementary products, settings), WEB-06 (reseller web) and MRA-11 (reseller app). Their dates are on the timeline. The extra 4 days on Anis's lane move Production go-live and Pilot starts by about four working days. Both still meet their targets in the milestones table. The pilot go / no-go moves by the same amount. If that matters more than scope, NOT-15 and then NOT-11 move after go-live first (D-38).

Ambiguities in the client text

PointReading appliedConfirm with HOCO
Content of the Urgent groupThe client does not list it. The transactional and security notifications go there, plus urgent announcementsYes, at the next Thursday review
« نسخة جديدة » for SN-19 (a new edition of what?)A new edition of HOCO's catalogue (PDF or collection) published in BO-57; new products alone are SN-01Yes
SN-03 low stock without quantitiesThe notification says « Quantité limitée », the product page stays « En stock », and no number appears anywhere (STK-07)Already covered by STK-07
SN-12 « الذكاء الاصطناعي أو تاريخ الطلبات » (AI or order history)Order history only in V1 (cadence rule); AI is SN-13, laterD-41
SN-07 « Si nn : Daily / Weekly / Monthly »Read as an alternative way of organising the missions, not as extra missions; decided with the V2 loyalty policyD-42, D-05
SN-07 « ادخل Top 10 في ولايتك » (enter the top 10 of your wilaya)A ranking per wilaya, next to the national Top 3 of SN-27 (V2)With D-42
SN-22 « واربح 300 نقط » written twiceA typo; one reward of 300 points—
Top 3 « النشاط داخل التطبيق » (activity in the app)Measured from sessions and orders placed in the app; the weights are to decideD-42
Abandoned cart « بعد ساعتين »2 h after the last cart change, deferred by quiet hoursD-44
Back-in-stock « إذا كان التاجر سبق وشراه » (if the reseller bought it before)Ordered in the last 90 days, plus favorites and cartsD-43
Flash Challenge (« اشترِ المنتج المحدد اليوم فقط », buy the chosen product today only) versus Flash SaleThe challenge is a V2 mission with points; the flash sale is a V1 promotion with a price—

On this page