Cartes cadeaux (gift cards)¶
Extrait du domain map API, qui était chargé dans chaque session agent. La rule garde l'index module → contexte ; le détail vit ici, à côté du code.
Le parrainage a sa propre doc : investor-referral/docs/.
- La
gift_cardest emise a l'achat (createGiftCard, appele parcreateGiftCardPurchaseWt) : ligne enpending, tandis que la WTgift_card_purchaserestewaiting. L'email destinataire (notifyGiftCardRecipient) part apres le commit SQL de l'achat : un echec ne rollback pas la carte, il declenche une alerte Slack pour renvoi manuel. Sous une transaction parente (topup carte), l'appelant l'envoie apres son propre commit. Le workerplayed-lemonway-p2pne fait plus que la confirmer quand le P2P donneur -> compte d'attente aboutit. Les WT creees avant ce changement n'ont pas degiftcardIden contexte :confirmGiftCardCreationles emet encore, email compris dans la transaction du worker, fallback a supprimer quand la file est vide - Consequence : entre l'emission et la reussite du P2P, la carte existe et est claimable alors que la WT est
waiting.refundGiftCard, pour tout P2Ppending(achat, et credit du claimer avant de le passerdeclined), interroge Lemonway (GET /p2p?reference=<wtId>) dans la transaction du refund, WT verrouilleeFOR UPDATE. Trouve chez Lemonway : refusgift-card.refund-p2p-in-flight, rien ne bouge ; l'admin reessaie une fois que le workerpending-p2p-to-playa passe le P2P ensucceeded(il se retrouve seul par la reference). Absent : pas d'argent deplace, refundconfirmedsans P2P inverse. Echec du GET :lemonway-p2p.lw-check-failed. Pas de decalage cote Bricks entre le check et le refund : le worker verrouille la meme WT (SKIP LOCKED) avant le POST et ne selectionne que les WTwaiting. Risque residuel accepte : une requete deja recue par Lemonway mais pas encore executee a l'instant du GET (crash du worker en plein POST). Si le P2P finitfailed,declineGiftCardPurchasedecline la WT en laissant la carte claimable - Le refund d'une gift card claimee doit d'abord debiter le
giftBalancedu claimer (P2P claimer -> compte d'attente), puis refund le donneur enwithdrawableBalance - Le claim applique le code parrain du donneur au claimer (si eligible : pas de referrer existant, dans la fenetre de durabilite)
- L'email est schedule en heure francaise (
emailTriggerFrenchHouren Europe/Paris), converti en UTC - L'expiration est calculee depuis
triggerDate(pas depuis l'envoi de l'email) - Le gift balance est separe du withdrawable balance (credit gift, pas withdrawable)
- La ligne
gift_carda deux ecrivains concurrents : le claim (status/claimer*) et le worker PDF (documentState). Les deux ecrivent le document entier, ce qui n'est sur que parce que chacun lit sousFOR UPDATEet ecrit dans la meme transaction — le worker PDF la tient pendant la generation + S3 + email, donc plusieurs secondes. Le claim lit enfor update skip lockedet n'attend donc jamais derriere lui : 0 ligne = code inconnu ou ligne prise, desambigue par une relecture sans verrou (gift-card-temporarily-lockedvsgift-card-not-found). Codes d'erreur du claim en kebab sans point : le front les utilise directement comme cle i18n et.y est un separateur de niveaux. Sortir l'I/O de la transaction imposera de relire la ligne sous verrou avant d'ecrire - Un P2P d'achat qui echoue sur
debit_account_blocked(codes Lemonway 111/167) gele le donneur mais ne decline pas l'achat : le P2P repart enpendingsans nouveau délai (attemptAfterconserve) et la WT restewaiting, donc les fonds restent reserves. Le ranking unifie (debitsRankedToPlayCTE) exclut P2P et retraits d'un donneur gele : un withdrawwaitingne peut pas passer devant pendant le gel. Au degel, les deux reviennent dans le FIFO, ordonnes parindex(pas de priorite gift-card). Toute autre erreur business decline l'achat (declineGiftCardPurchase+ email d'erreur au donneur) confirmGiftCardCreditrenvoieErr('gift-card.not-found-for-credit-wt')si la carte ne pointe plus vers la WT de credit. La WT restewaitinget bloque la file du customer (1 WT par customer dansplayed-lemonway-p2p) : code d'erreur loggue a chaque iteration, detection par monitor Datadog, resolution manuelle