fix(marketplace): credits-client camelCase + grant() + referenceId
Some checks are pending
CI / validate (push) Waiting to run
Some checks are pending
CI / validate (push) Waiting to run
Validierung gegen mana-credits internalReserveSchema / internalGrantSchema: - snake_case → camelCase (userId, appId, reservationId, referenceId) Vorher hätte jeder reserve-Call 400 geworfen — fiel nicht auf, weil Paid-Decks dormant sind. - grant()-Methode neu: für Author-Payouts beim Paid-Deck-Live-Schalten. Braucht referenceId (Pflicht, max 128 chars) + reason (max 64). - appId 'wordeck' statt 'cards' (Brand-Konsistenz mit ev.mana.wordeck- Rebrand 2026-05-17). - commit() akzeptiert optionalen description-Parameter. - Response-Type: reservationId/grantId statt snake_case. Bereitet den Live-Bezahl-Flow vor (immer noch dormant). Synchron mit Comicello-Fix vom 2026-05-19. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
070cb44de8
commit
b13c9dd914
1 changed files with 39 additions and 6 deletions
|
|
@ -39,27 +39,32 @@ export class CreditsClient {
|
|||
/**
|
||||
* Reserviert Credits — `commit` oder `refund-reservation` muss
|
||||
* folgen. Pattern für teure asynchrone Operationen.
|
||||
*
|
||||
* Verifiziert gegen mana-credits internalReserveSchema (2026-05-19):
|
||||
* camelCase-Felder, appId Pflicht seit Verein-Konsolidierung
|
||||
* 2026-05-05. Korrektur vom 2026-05-19 (vorher snake_case — wäre
|
||||
* 400 geworden, fiel nur nicht auf weil Paid-Decks dormant sind).
|
||||
*/
|
||||
async reserve(input: { userId: string; amount: number; reason: string }) {
|
||||
const r = await fetch(`${CREDITS_URL}/api/v1/internal/credits/reserve`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', ...authHeader() },
|
||||
body: JSON.stringify({
|
||||
user_id: input.userId,
|
||||
userId: input.userId,
|
||||
amount: input.amount,
|
||||
reason: input.reason,
|
||||
app_id: 'cards',
|
||||
appId: 'wordeck',
|
||||
}),
|
||||
});
|
||||
if (!r.ok) throw new Error(`mana-credits reserve ${r.status}`);
|
||||
return r.json() as Promise<{ reservation_id: string }>;
|
||||
return r.json() as Promise<{ reservationId: string; balance: number }>;
|
||||
}
|
||||
|
||||
async commit(reservationId: string) {
|
||||
async commit(reservationId: string, description?: string) {
|
||||
const r = await fetch(`${CREDITS_URL}/api/v1/internal/credits/commit`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', ...authHeader() },
|
||||
body: JSON.stringify({ reservation_id: reservationId }),
|
||||
body: JSON.stringify({ reservationId, description }),
|
||||
});
|
||||
if (!r.ok) throw new Error(`mana-credits commit ${r.status}`);
|
||||
return r.json();
|
||||
|
|
@ -69,11 +74,39 @@ export class CreditsClient {
|
|||
const r = await fetch(`${CREDITS_URL}/api/v1/internal/credits/refund-reservation`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', ...authHeader() },
|
||||
body: JSON.stringify({ reservation_id: reservationId }),
|
||||
body: JSON.stringify({ reservationId }),
|
||||
});
|
||||
if (!r.ok) throw new Error(`mana-credits refund ${r.status}`);
|
||||
return r.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gewährt Credits an einen User (Author-Payout). `referenceId` ist
|
||||
* Pflicht (Reconcile-Anker), `reason` max 64 chars.
|
||||
*
|
||||
* Reason-Konvention: `wordeck.payout.<purchase_id>`.
|
||||
*/
|
||||
async grant(input: {
|
||||
userId: string;
|
||||
amount: number;
|
||||
reason: string;
|
||||
referenceId: string;
|
||||
description?: string;
|
||||
}) {
|
||||
const r = await fetch(`${CREDITS_URL}/api/v1/internal/credits/grant`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', ...authHeader() },
|
||||
body: JSON.stringify({
|
||||
userId: input.userId,
|
||||
amount: input.amount,
|
||||
reason: input.reason,
|
||||
referenceId: input.referenceId,
|
||||
description: input.description,
|
||||
}),
|
||||
});
|
||||
if (!r.ok) throw new Error(`mana-credits grant ${r.status}`);
|
||||
return r.json() as Promise<{ grantId: string }>;
|
||||
}
|
||||
}
|
||||
|
||||
let cached: CreditsClient | null = null;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue