@mostajs/subscriptions-plan 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +17 -0
- package/dist/lib/credits.d.ts +59 -0
- package/dist/lib/credits.d.ts.map +1 -0
- package/dist/lib/credits.js +211 -0
- package/dist/lib/credits.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
## 0.8.0 — 2026-10-10
|
|
8
|
+
|
|
9
|
+
- **Crédits prépayés par lots** : `createCredits({ dialect, clock? })`, schémas `creditSchemas()` (`CreditLot`,
|
|
10
|
+
`CreditUse`). Un lot = un achat (quantité, reste, expiration, source à index unique : un webhook rejoué n'accorde
|
|
11
|
+
qu'une fois) ; un envoi = une réservation à clé unique (`reserve` → `consume` | `release`), idempotente. Lots les
|
|
12
|
+
plus proches de l'expiration d'abord ; un lot expiré ne compte plus ; tout ou rien ; solde jamais négatif, même
|
|
13
|
+
entre processus. Les refus portent un code, pas une phrase (i18n côté application).
|
|
14
|
+
- Premier usage : les forfaits annuels de signatures qualifiées de qatrax (lot D2).
|
|
15
|
+
|
|
16
|
+
**Essais** : T-CR-1..12 (base sqlite réelle), trois sabotages relevés (ordre d'expiration, rejeu, restitution).
|
|
17
|
+
|
|
7
18
|
## 0.7.1 — 2026-10-09
|
|
8
19
|
|
|
9
20
|
**Corrigé** (audit du code de travel, 09/10/2026)
|
package/README.md
CHANGED
|
@@ -76,6 +76,23 @@ Bank keys come from the `.env` (`CHARGILY_SECRET_KEY`, `PAYPAL_CLIENT_ID`/`PAYPA
|
|
|
76
76
|
`@mostajs/payment` rebuilds the bank dialect from the environment to verify a webhook. `billing.activePlan` now
|
|
77
77
|
expires a prepaid period that has ended (status `expired`, back to the free tier).
|
|
78
78
|
|
|
79
|
+
## Prepaid credits *(v0.8.0)* — annual packs (e.g. qualified signatures)
|
|
80
|
+
|
|
81
|
+
A pack bought once, valid for a time, cumulative, never reset: a **lot**. Spending is a **reservation** keyed by
|
|
82
|
+
the item it is for, then **consumed** (final) or **released** (back to the balance). Lots closest to expiry go first;
|
|
83
|
+
an expired lot no longer counts; the balance never goes below zero, even across processes. Refusals carry a **code**
|
|
84
|
+
(`INSUFFICIENT_CREDITS`, `CREDIT_USE_STATE`…), never a sentence: the application speaks its client's language.
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
const credits = createCredits({ dialect }) // schemas: creditSchemas() → CreditLot, CreditUse
|
|
88
|
+
await credits.grant({ account, resource: 'signature', quantity: 1000, validDays: 365, source: checkoutSessionId }) // idempotent by source
|
|
89
|
+
await credits.balance(account, 'signature') // → { remaining, nextExpiry, lots }
|
|
90
|
+
await credits.reserve({ account, resource: 'signature', key: 'LIV-42' }) // → { ok, replay?, code?, remaining } — idempotent by key
|
|
91
|
+
await credits.consume({ account, resource: 'signature', key: 'LIV-42' }) // the provider signed: final
|
|
92
|
+
await credits.release({ account, resource: 'signature', key: 'LIV-42' }) // the provider failed: back to the balance
|
|
93
|
+
await credits.journal(account, 'signature')
|
|
94
|
+
```
|
|
95
|
+
|
|
79
96
|
## Install
|
|
80
97
|
|
|
81
98
|
```bash
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { EntitySchema } from '@mostajs/data-plug';
|
|
2
|
+
type Dialect = any;
|
|
3
|
+
export declare const CreditLotSchema: EntitySchema;
|
|
4
|
+
export declare const CreditUseSchema: EntitySchema;
|
|
5
|
+
export declare function creditSchemas(): EntitySchema[];
|
|
6
|
+
export interface GrantParams {
|
|
7
|
+
account: string;
|
|
8
|
+
resource: string;
|
|
9
|
+
quantity: number;
|
|
10
|
+
/** L'identifiant du paiement (session Stripe…) : un même paiement n'accorde qu'un lot. */
|
|
11
|
+
source: string;
|
|
12
|
+
/** Durée de validité en jours, ou `expiresAt`. */
|
|
13
|
+
validDays?: number;
|
|
14
|
+
expiresAt?: Date;
|
|
15
|
+
label?: string;
|
|
16
|
+
amount?: number;
|
|
17
|
+
currency?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface UseParams {
|
|
20
|
+
account: string;
|
|
21
|
+
resource: string;
|
|
22
|
+
key: string;
|
|
23
|
+
quantity?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface ReserveResult {
|
|
26
|
+
ok: boolean;
|
|
27
|
+
/** La clé était déjà réservée ou consommée : rien n'a été décompté de nouveau. */
|
|
28
|
+
replay?: boolean;
|
|
29
|
+
status?: 'reserved' | 'consumed';
|
|
30
|
+
/** `INSUFFICIENT_CREDITS` quand le refus vient du solde. */
|
|
31
|
+
code?: string;
|
|
32
|
+
remaining: number;
|
|
33
|
+
}
|
|
34
|
+
export interface CreditsOptions {
|
|
35
|
+
dialect: Dialect;
|
|
36
|
+
clock?: () => Date;
|
|
37
|
+
}
|
|
38
|
+
export declare function createCredits(opts: CreditsOptions): {
|
|
39
|
+
grant: (p: GrantParams) => Promise<{
|
|
40
|
+
created: boolean;
|
|
41
|
+
lot: any;
|
|
42
|
+
}>;
|
|
43
|
+
balance: (account: string, resource: string) => Promise<{
|
|
44
|
+
remaining: any;
|
|
45
|
+
nextExpiry: any;
|
|
46
|
+
lots: any;
|
|
47
|
+
}>;
|
|
48
|
+
reserve: (p: UseParams) => Promise<ReserveResult>;
|
|
49
|
+
consume: (p: UseParams) => Promise<{
|
|
50
|
+
status: "consumed";
|
|
51
|
+
}>;
|
|
52
|
+
release: (p: UseParams) => Promise<{
|
|
53
|
+
status: "released";
|
|
54
|
+
}>;
|
|
55
|
+
journal: (account: string, resource?: string) => Promise<any>;
|
|
56
|
+
};
|
|
57
|
+
export type Credits = ReturnType<typeof createCredits>;
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=credits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credits.d.ts","sourceRoot":"","sources":["../../src/lib/credits.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGtD,KAAK,OAAO,GAAG,GAAG,CAAA;AAElB,eAAO,MAAM,eAAe,EAAE,YAiBb,CAAA;AAEjB,eAAO,MAAM,eAAe,EAAE,YAeb,CAAA;AAEjB,wBAAgB,aAAa,IAAI,YAAY,EAAE,CAE9C;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAA;IACd,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,IAAI,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,SAAS;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;AAEhG,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAA;IACX,kFAAkF;IAClF,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;IAChC,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;CAClB;AAMD,MAAM,WAAW,cAAc;IAAG,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE;AAExE,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc;eAgCxB,WAAW,KAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,GAAG,CAAA;KAAE,CAAC;uBAT7C,MAAM,YAAY,MAAM;;;;;iBA4CpC,SAAS,KAAG,OAAO,CAAC,aAAa,CAAC;iBAsClC,SAAS,KAAG,OAAO,CAAC;QAAE,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC;iBAY3C,SAAS,KAAG,OAAO,CAAC;QAAE,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC;uBAa/B,MAAM,aAAa,MAAM;EAO1D;AAED,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// @mostajs/subscriptions-plan 0.8 — LES CRÉDITS PRÉPAYÉS PAR LOTS.
|
|
2
|
+
// @author Dr Hamid MADANI <drmdh@msn.com>
|
|
3
|
+
//
|
|
4
|
+
// Le compteur de `billing.ts` borne une consommation par jour ou par mois, et se remet à zéro. Un FORFAIT est autre
|
|
5
|
+
// chose : une quantité achetée une fois, valable un temps (12 mois pour les signatures qualifiées de qatrax, décision
|
|
6
|
+
// du fondateur du 10/10/2026), qui se cumule avec les autres et ne se remet jamais à zéro. D'où deux tables :
|
|
7
|
+
//
|
|
8
|
+
// CreditLot un achat : quantité, reste, expiration, SOURCE (le paiement) à index unique — un webhook rejoué
|
|
9
|
+
// n'accorde jamais deux fois ;
|
|
10
|
+
// CreditUse un envoi : sa CLÉ (le livrable) à index unique — un double clic ou une nouvelle tentative ne
|
|
11
|
+
// décompte jamais deux fois. Statuts : reserved → consumed (définitif) | released (rendu au solde).
|
|
12
|
+
//
|
|
13
|
+
// Les lots les plus proches de l'expiration partent d'abord. Le reste d'un lot se décrémente atomiquement et revient
|
|
14
|
+
// en arrière s'il passe sous zéro : le solde n'est jamais négatif, même entre processus. Les refus portent un CODE
|
|
15
|
+
// (`INSUFFICIENT_CREDITS`…), jamais une phrase : c'est l'application qui parle la langue de son client.
|
|
16
|
+
import { BillingError } from './billing.js';
|
|
17
|
+
export const CreditLotSchema = {
|
|
18
|
+
name: 'CreditLot',
|
|
19
|
+
collection: 'credit_lots',
|
|
20
|
+
timestamps: true,
|
|
21
|
+
fields: {
|
|
22
|
+
account: { type: 'string', required: true },
|
|
23
|
+
resource: { type: 'string', required: true },
|
|
24
|
+
quantity: { type: 'number', required: true },
|
|
25
|
+
remaining: { type: 'number', required: true },
|
|
26
|
+
expiresAt: { type: 'date', required: true },
|
|
27
|
+
source: { type: 'string', required: true },
|
|
28
|
+
label: { type: 'string' },
|
|
29
|
+
amount: { type: 'number' },
|
|
30
|
+
currency: { type: 'string' },
|
|
31
|
+
},
|
|
32
|
+
relations: {},
|
|
33
|
+
indexes: [{ fields: { source: 'asc' }, unique: true }, { fields: { account: 'asc', resource: 'asc' } }],
|
|
34
|
+
};
|
|
35
|
+
export const CreditUseSchema = {
|
|
36
|
+
name: 'CreditUse',
|
|
37
|
+
collection: 'credit_uses',
|
|
38
|
+
timestamps: true,
|
|
39
|
+
fields: {
|
|
40
|
+
account: { type: 'string', required: true },
|
|
41
|
+
resource: { type: 'string', required: true },
|
|
42
|
+
key: { type: 'string', required: true },
|
|
43
|
+
quantity: { type: 'number', required: true },
|
|
44
|
+
status: { type: 'string', required: true }, // reserved | consumed | released
|
|
45
|
+
allocations: { type: 'json' }, // [{ lot, n }]
|
|
46
|
+
settledAt: { type: 'date' },
|
|
47
|
+
},
|
|
48
|
+
relations: {},
|
|
49
|
+
indexes: [{ fields: { account: 'asc', resource: 'asc', key: 'asc' }, unique: true }],
|
|
50
|
+
};
|
|
51
|
+
export function creditSchemas() {
|
|
52
|
+
return [CreditLotSchema, CreditUseSchema];
|
|
53
|
+
}
|
|
54
|
+
const t = (x) => new Date(x).getTime();
|
|
55
|
+
const allocs = (u) => (typeof u?.allocations === 'string' ? JSON.parse(u.allocations) : (u?.allocations ?? []));
|
|
56
|
+
const entierPositif = (x) => Number.isInteger(x) && x > 0;
|
|
57
|
+
export function createCredits(opts) {
|
|
58
|
+
const d = opts.dialect;
|
|
59
|
+
const clock = opts.clock ?? (() => new Date());
|
|
60
|
+
// Sérialisation par compte × ressource dans le processus (même principe que billing.ts) ; entre processus,
|
|
61
|
+
// l'incrément atomique et son retour arrière gardent le solde ≥ 0.
|
|
62
|
+
const files = new Map();
|
|
63
|
+
function enFile(cle, f) {
|
|
64
|
+
const p = (files.get(cle) ?? Promise.resolve()).then(f, f);
|
|
65
|
+
const fin = p.catch(() => { });
|
|
66
|
+
files.set(cle, fin);
|
|
67
|
+
fin.then(() => { if (files.get(cle) === fin)
|
|
68
|
+
files.delete(cle); });
|
|
69
|
+
return p;
|
|
70
|
+
}
|
|
71
|
+
/** Les lots vivants (non expirés, reste > 0), le plus proche de l'expiration d'abord. */
|
|
72
|
+
async function lotsVivants(account, resource) {
|
|
73
|
+
const now = clock().getTime();
|
|
74
|
+
const tous = await d.find(CreditLotSchema, { account, resource });
|
|
75
|
+
return tous.filter((l) => t(l.expiresAt) > now && Number(l.remaining) > 0)
|
|
76
|
+
.sort((a, b) => t(a.expiresAt) - t(b.expiresAt) || t(a.createdAt) - t(b.createdAt));
|
|
77
|
+
}
|
|
78
|
+
async function balance(account, resource) {
|
|
79
|
+
const lots = await lotsVivants(account, resource);
|
|
80
|
+
return {
|
|
81
|
+
remaining: lots.reduce((s, l) => s + Number(l.remaining), 0),
|
|
82
|
+
nextExpiry: lots[0]?.expiresAt ?? null,
|
|
83
|
+
lots: lots.map((l) => ({ id: String(l.id), source: l.source, label: l.label ?? null, quantity: Number(l.quantity), remaining: Number(l.remaining), expiresAt: l.expiresAt })),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
async function grant(p) {
|
|
87
|
+
if (!p.account || !p.resource)
|
|
88
|
+
throw new BillingError('CREDIT_INVALID', 'account et resource requis');
|
|
89
|
+
if (!entierPositif(p.quantity))
|
|
90
|
+
throw new BillingError('CREDIT_INVALID', `quantité entière positive attendue : ${p.quantity}`);
|
|
91
|
+
if (!p.source)
|
|
92
|
+
throw new BillingError('CREDIT_INVALID', 'source (identifiant du paiement) requise');
|
|
93
|
+
let expiresAt = p.expiresAt;
|
|
94
|
+
if (!expiresAt) {
|
|
95
|
+
if (!entierPositif(p.validDays))
|
|
96
|
+
throw new BillingError('CREDIT_INVALID', `validDays entier positif attendu : ${p.validDays}`);
|
|
97
|
+
expiresAt = new Date(clock().getTime() + Number(p.validDays) * 86400000);
|
|
98
|
+
}
|
|
99
|
+
const deja = await d.findOne(CreditLotSchema, { source: p.source });
|
|
100
|
+
if (deja)
|
|
101
|
+
return { created: false, lot: deja };
|
|
102
|
+
try {
|
|
103
|
+
const lot = await d.create(CreditLotSchema, {
|
|
104
|
+
account: p.account, resource: p.resource, quantity: p.quantity, remaining: p.quantity, expiresAt, source: p.source,
|
|
105
|
+
...(p.label ? { label: p.label } : {}), ...(p.amount !== undefined ? { amount: p.amount } : {}), ...(p.currency ? { currency: p.currency } : {}),
|
|
106
|
+
});
|
|
107
|
+
return { created: true, lot };
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Créé en parallèle par une double livraison : l'index unique a tranché.
|
|
111
|
+
const l = await d.findOne(CreditLotSchema, { source: p.source });
|
|
112
|
+
if (l)
|
|
113
|
+
return { created: false, lot: l };
|
|
114
|
+
throw new BillingError('CREDIT_GRANT_FAILED', `lot non créé : ${p.source}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async function usage(p) {
|
|
118
|
+
if (!p.account || !p.resource || !p.key)
|
|
119
|
+
throw new BillingError('CREDIT_INVALID', 'account, resource et key requis');
|
|
120
|
+
return d.findOne(CreditUseSchema, { account: p.account, resource: p.resource, key: p.key });
|
|
121
|
+
}
|
|
122
|
+
/** Rend au solde ce qu'une réservation avait pris (lot par lot). */
|
|
123
|
+
async function rendre(u) {
|
|
124
|
+
for (const a of allocs(u))
|
|
125
|
+
await d.increment(CreditLotSchema, a.lot, 'remaining', a.n);
|
|
126
|
+
}
|
|
127
|
+
function reserve(p) {
|
|
128
|
+
const n = p.quantity ?? 1;
|
|
129
|
+
if (!entierPositif(n))
|
|
130
|
+
return Promise.reject(new BillingError('CREDIT_INVALID', `quantité entière positive attendue : ${n}`));
|
|
131
|
+
if (!p.key)
|
|
132
|
+
return Promise.reject(new BillingError('CREDIT_INVALID', 'key requise'));
|
|
133
|
+
return enFile(`c:${p.account}|${p.resource}`, async () => {
|
|
134
|
+
const u = await usage(p);
|
|
135
|
+
if (u && u.status !== 'released')
|
|
136
|
+
return { ok: true, replay: true, status: u.status, remaining: (await balance(p.account, p.resource)).remaining };
|
|
137
|
+
// Prendre lot par lot, le plus proche de l'expiration d'abord ; tout ou rien.
|
|
138
|
+
const pris = [];
|
|
139
|
+
let reste = n;
|
|
140
|
+
for (const lot of await lotsVivants(p.account, p.resource)) {
|
|
141
|
+
if (!reste)
|
|
142
|
+
break;
|
|
143
|
+
const k = Math.min(reste, Number(lot.remaining));
|
|
144
|
+
const apres = Number((await d.increment(CreditLotSchema, String(lot.id), 'remaining', -k))?.remaining ?? 0);
|
|
145
|
+
if (apres < 0) {
|
|
146
|
+
await d.increment(CreditLotSchema, String(lot.id), 'remaining', k);
|
|
147
|
+
continue;
|
|
148
|
+
} // pris entre-temps ailleurs
|
|
149
|
+
pris.push({ lot: String(lot.id), n: k });
|
|
150
|
+
reste -= k;
|
|
151
|
+
}
|
|
152
|
+
if (reste) {
|
|
153
|
+
await rendre({ allocations: pris });
|
|
154
|
+
return { ok: false, code: 'INSUFFICIENT_CREDITS', remaining: (await balance(p.account, p.resource)).remaining };
|
|
155
|
+
}
|
|
156
|
+
const champs = { quantity: n, status: 'reserved', allocations: pris, settledAt: null };
|
|
157
|
+
try {
|
|
158
|
+
if (u)
|
|
159
|
+
await d.update(CreditUseSchema, String(u.id), champs);
|
|
160
|
+
else
|
|
161
|
+
await d.create(CreditUseSchema, { account: p.account, resource: p.resource, key: p.key, ...champs });
|
|
162
|
+
}
|
|
163
|
+
catch (e) {
|
|
164
|
+
// Un autre processus a réservé la même clé : on rend ce qu'on a pris, la sienne fait foi.
|
|
165
|
+
await rendre({ allocations: pris });
|
|
166
|
+
const autre = await usage(p);
|
|
167
|
+
if (autre && autre.status !== 'released')
|
|
168
|
+
return { ok: true, replay: true, status: autre.status, remaining: (await balance(p.account, p.resource)).remaining };
|
|
169
|
+
throw e;
|
|
170
|
+
}
|
|
171
|
+
return { ok: true, replay: false, status: 'reserved', remaining: (await balance(p.account, p.resource)).remaining };
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/** Le prestataire a signé : la réservation devient définitive. Idempotent. */
|
|
175
|
+
function consume(p) {
|
|
176
|
+
return enFile(`c:${p.account}|${p.resource}`, async () => {
|
|
177
|
+
const u = await usage(p);
|
|
178
|
+
if (!u)
|
|
179
|
+
throw new BillingError('CREDIT_USE_UNKNOWN', `aucune réservation pour ${p.key}`);
|
|
180
|
+
if (u.status === 'consumed')
|
|
181
|
+
return { status: 'consumed' };
|
|
182
|
+
if (u.status !== 'reserved')
|
|
183
|
+
throw new BillingError('CREDIT_USE_STATE', `${p.key} est ${u.status}, pas réservée`);
|
|
184
|
+
await d.update(CreditUseSchema, String(u.id), { status: 'consumed', settledAt: clock() });
|
|
185
|
+
return { status: 'consumed' };
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/** Le prestataire a échoué : la réservation revient au solde. Idempotent ; une signature consommée ne se rend pas. */
|
|
189
|
+
function release(p) {
|
|
190
|
+
return enFile(`c:${p.account}|${p.resource}`, async () => {
|
|
191
|
+
const u = await usage(p);
|
|
192
|
+
if (!u)
|
|
193
|
+
throw new BillingError('CREDIT_USE_UNKNOWN', `aucune réservation pour ${p.key}`);
|
|
194
|
+
if (u.status === 'released')
|
|
195
|
+
return { status: 'released' };
|
|
196
|
+
if (u.status === 'consumed')
|
|
197
|
+
throw new BillingError('CREDIT_USE_STATE', `${p.key} est consommée : définitive`);
|
|
198
|
+
// Le statut d'abord : un second appel concurrent (autre processus) verrait « released » et ne rendrait rien.
|
|
199
|
+
await d.update(CreditUseSchema, String(u.id), { status: 'released', settledAt: clock() });
|
|
200
|
+
await rendre(u);
|
|
201
|
+
return { status: 'released' };
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
async function journal(account, resource) {
|
|
205
|
+
const us = await d.find(CreditUseSchema, { account, ...(resource ? { resource } : {}) });
|
|
206
|
+
return us.sort((a, b) => t(b.createdAt) - t(a.createdAt))
|
|
207
|
+
.map((u) => ({ key: u.key, resource: u.resource, quantity: Number(u.quantity), status: u.status, allocations: allocs(u), createdAt: u.createdAt, settledAt: u.settledAt ?? null }));
|
|
208
|
+
}
|
|
209
|
+
return { grant, balance, reserve, consume, release, journal };
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=credits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credits.js","sourceRoot":"","sources":["../../src/lib/credits.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -12,4 +12,6 @@ export { createBilling, createStripeSale, checkLimits, assertMonotonicPlans, sec
|
|
|
12
12
|
export type { Billing, BillingOptions, ResourceDef, Verdict, Period, CustomerPort, StripeSaleOptions } from './lib/billing.js';
|
|
13
13
|
export { createPrepaidSale, addPeriod } from './lib/prepaid-sale.js';
|
|
14
14
|
export type { PrepaidSale, PrepaidSaleOptions, PrepaidPeriod, PaymentPort } from './lib/prepaid-sale.js';
|
|
15
|
+
export { createCredits, creditSchemas, CreditLotSchema, CreditUseSchema } from './lib/credits.js';
|
|
16
|
+
export type { Credits, CreditsOptions, GrantParams, UseParams, ReserveResult } from './lib/credits.js';
|
|
15
17
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,UAAU,GACX,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,aAAa,GACd,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AACvG,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAG1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAG1D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAG7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAA;AAG5D,OAAO,EACL,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,oBAAoB,EAAE,iBAAiB,EACrF,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,SAAS,GAChF,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAG9H,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACpE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,UAAU,GACX,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,aAAa,GACd,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AACvG,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAG1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAG1D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAG7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAA;AAG5D,OAAO,EACL,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,oBAAoB,EAAE,iBAAiB,EACrF,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,SAAS,GAChF,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAG9H,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACpE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGxG,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACjG,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/server.js
CHANGED
|
@@ -20,4 +20,6 @@ export { subscriptionPlanRegistration } from './register.js';
|
|
|
20
20
|
export { createBilling, createStripeSale, checkLimits, assertMonotonicPlans, secondsUntilReset, billingSchemas, UsageCounterSchema, BillingEventSchema, BillingError, UNLIMITED, } from './lib/billing.js';
|
|
21
21
|
// 0.7 — vente prépayée multi-banques (Chargily, PayPal, SATIM…) par @mostajs/payment
|
|
22
22
|
export { createPrepaidSale, addPeriod } from './lib/prepaid-sale.js';
|
|
23
|
+
// 0.8 — crédits prépayés par lots (forfaits annuels) : lot à source unique, envoi à clé unique, réserver → consommer | rendre
|
|
24
|
+
export { createCredits, creditSchemas, CreditLotSchema, CreditUseSchema } from './lib/credits.js';
|
|
23
25
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,wCAAwC;AAExC,eAAe;AACf,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,UAAU,GACX,MAAM,uBAAuB,CAAA;AAE9B,oBAAoB;AACpB,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,aAAa,GACd,MAAM,sBAAsB,CAAA;AAE7B,iBAAiB;AACjB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,yBAAyB,CAAA;AAEhC,kDAAkD;AAClD,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAGvG,eAAe;AACf,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAE1D,wBAAwB;AACxB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAE7D,eAAe;AACf,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAA;AAE5D,0FAA0F;AAC1F,OAAO,EACL,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,oBAAoB,EAAE,iBAAiB,EACrF,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,SAAS,GAChF,MAAM,kBAAkB,CAAA;AAGzB,qFAAqF;AACrF,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,wCAAwC;AAExC,eAAe;AACf,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,UAAU,GACX,MAAM,uBAAuB,CAAA;AAE9B,oBAAoB;AACpB,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,aAAa,GACd,MAAM,sBAAsB,CAAA;AAE7B,iBAAiB;AACjB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,yBAAyB,CAAA;AAEhC,kDAAkD;AAClD,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAGvG,eAAe;AACf,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAE1D,wBAAwB;AACxB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAE7D,eAAe;AACf,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAA;AAE5D,0FAA0F;AAC1F,OAAO,EACL,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,oBAAoB,EAAE,iBAAiB,EACrF,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,SAAS,GAChF,MAAM,kBAAkB,CAAA;AAGzB,qFAAqF;AACrF,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAGpE,8HAA8H;AAC9H,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA"}
|