@mostajs/ticketing 1.0.0 → 1.0.1
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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/ticket-number.d.ts +38 -0
- package/dist/lib/ticket-number.d.ts.map +1 -0
- package/dist/lib/ticket-number.js +76 -0
- package/dist/lib/ticket-number.js.map +1 -0
- package/dist/repositories/ticket.repository.d.ts +12 -2
- package/dist/repositories/ticket.repository.d.ts.map +1 -1
- package/dist/repositories/ticket.repository.js +29 -7
- package/dist/repositories/ticket.repository.js.map +1 -1
- package/dist/schemas/counter.schema.d.ts.map +1 -1
- package/dist/schemas/counter.schema.js +3 -2
- package/dist/schemas/counter.schema.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { processScan } from './lib/scan-processor';
|
|
|
5
5
|
export type { ScanDeps } from './lib/scan-processor';
|
|
6
6
|
export { computeValidUntil, isExpired, isToday } from './lib/validity-checker';
|
|
7
7
|
export { decrementQuota, isQuotaDepleted, wouldExceedQuota } from './lib/quota-manager';
|
|
8
|
+
export { DAY_MULTIPLIER, DAY_MODULO, YEAR_MODULO, MAX_SEQUENCE, MAX_TICKET_VALUE, getDayOfYear, computeCombinedDay, extractCombinedDayFromTicket, extractDayFromTicket, extractYearFromTicket, extractSequenceFromTicket, isTicketFromToday, isValidTicketFormat, } from './lib/ticket-number';
|
|
8
9
|
export { createScanHandler } from './api/scan.route';
|
|
9
10
|
export { createTicketsHandler } from './api/tickets.route';
|
|
10
11
|
export type { CodeFormat, ValidityMode, TicketStatus, ScanResult, ScanMethod, AccessType, AccessStatus, ActivityStatus, PlanType, DenyReason, ScanInput, ScanOutput, ScanGrantedResult, ScanDeniedResult, TicketInfo, ClientInfo, AccessInfo, CreateTicketInput, ScanHandlerConfig, TicketsHandlerConfig, } from './types/index';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,SAAS,EACT,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,YAAY,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,UAAU,EACV,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,SAAS,EACT,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGxF,OAAO,EACL,cAAc,EACd,UAAU,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,4BAA4B,EAC5B,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,YAAY,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,UAAU,EACV,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,8 @@ export { TicketRepository, ClientAccessRepository, ScanLogRepository, Subscripti
|
|
|
8
8
|
export { processScan } from './lib/scan-processor';
|
|
9
9
|
export { computeValidUntil, isExpired, isToday } from './lib/validity-checker';
|
|
10
10
|
export { decrementQuota, isQuotaDepleted, wouldExceedQuota } from './lib/quota-manager';
|
|
11
|
+
// ── Ticket number (Wiegand 24-bit) ───────────────────────────────
|
|
12
|
+
export { DAY_MULTIPLIER, DAY_MODULO, YEAR_MODULO, MAX_SEQUENCE, MAX_TICKET_VALUE, getDayOfYear, computeCombinedDay, extractCombinedDayFromTicket, extractDayFromTicket, extractYearFromTicket, extractSequenceFromTicket, isTicketFromToday, isValidTicketFormat, } from './lib/ticket-number';
|
|
11
13
|
// ── API route factories ────────────────────────────────────────────
|
|
12
14
|
export { createScanHandler } from './api/scan.route';
|
|
13
15
|
export { createTicketsHandler } from './api/tickets.route';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,wCAAwC;AAExC,sEAAsE;AACtE,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,sEAAsE;AACtE,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAY9B,sEAAsE;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAExF,sEAAsE;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,wCAAwC;AAExC,sEAAsE;AACtE,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,sEAAsE;AACtE,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAY9B,sEAAsE;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAExF,oEAAoE;AACpE,OAAO,EACL,cAAc,EACd,UAAU,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,4BAA4B,EAC5B,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAE7B,sEAAsE;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const DAY_MULTIPLIER = 131072;
|
|
2
|
+
export declare const DAY_MODULO = 32;
|
|
3
|
+
export declare const YEAR_MODULO = 4;
|
|
4
|
+
export declare const MAX_SEQUENCE = 131071;
|
|
5
|
+
export declare const MAX_TICKET_VALUE = 16777215;
|
|
6
|
+
/**
|
|
7
|
+
* Calcule le jour de l'annee (1-366)
|
|
8
|
+
*/
|
|
9
|
+
export declare function getDayOfYear(date: Date): number;
|
|
10
|
+
/**
|
|
11
|
+
* Calcule le combinedDay pour une date donnee
|
|
12
|
+
*/
|
|
13
|
+
export declare function computeCombinedDay(date: Date): number;
|
|
14
|
+
/**
|
|
15
|
+
* Extrait le combinedDay (annee + jour encodes, 0-127) d'un numero de ticket
|
|
16
|
+
*/
|
|
17
|
+
export declare function extractCombinedDayFromTicket(ticketNumber: string | number): number;
|
|
18
|
+
/**
|
|
19
|
+
* Extrait le jour encode (0-31) d'un numero de ticket
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractDayFromTicket(ticketNumber: string | number): number;
|
|
22
|
+
/**
|
|
23
|
+
* Extrait l'annee encodee (0-3) d'un numero de ticket
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractYearFromTicket(ticketNumber: string | number): number;
|
|
26
|
+
/**
|
|
27
|
+
* Extrait la sequence d'un numero de ticket
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractSequenceFromTicket(ticketNumber: string | number): number;
|
|
30
|
+
/**
|
|
31
|
+
* Verifie si un ticket correspond au jour et annee actuels (anti-replay)
|
|
32
|
+
*/
|
|
33
|
+
export declare function isTicketFromToday(ticketNumber: string | number): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Verifie si un numero de ticket est valide (dans les limites 24-bit)
|
|
36
|
+
*/
|
|
37
|
+
export declare function isValidTicketFormat(ticketNumber: string | number): boolean;
|
|
38
|
+
//# sourceMappingURL=ticket-number.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ticket-number.d.ts","sourceRoot":"","sources":["../../lib/ticket-number.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,YAAY,SAAS,CAAC;AACnC,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAK/C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAIrD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAGlF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAG1E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAG3E;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAG/E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAIxE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAG1E"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// @mostajs/ticketing — Ticket number generation (Wiegand 24-bit format)
|
|
2
|
+
// Adapted from MostaGare ticketService.ts
|
|
3
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
4
|
+
//
|
|
5
|
+
// Format: Ticket = ((Annee % 4) x 32 + (JourAnnee % 32)) x 131072 + Sequence
|
|
6
|
+
// - Annee encodee sur 2 bits (0-3) -> Cycle tous les 4 ans
|
|
7
|
+
// - Jour encode sur 5 bits (0-31) -> Cycle tous les 32 jours
|
|
8
|
+
// - Combinaison sur 7 bits (0-127) -> 128 combinaisons uniques
|
|
9
|
+
// - Sequence sur 17 bits (0-131071) -> 131k tickets/jour
|
|
10
|
+
// - Max: 16 777 215 (24-bit compatible)
|
|
11
|
+
export const DAY_MULTIPLIER = 131072; // 2^17
|
|
12
|
+
export const DAY_MODULO = 32; // 2^5
|
|
13
|
+
export const YEAR_MODULO = 4; // Cycle de 4 ans
|
|
14
|
+
export const MAX_SEQUENCE = 131071; // 2^17 - 1
|
|
15
|
+
export const MAX_TICKET_VALUE = 16777215; // 2^24 - 1
|
|
16
|
+
/**
|
|
17
|
+
* Calcule le jour de l'annee (1-366)
|
|
18
|
+
*/
|
|
19
|
+
export function getDayOfYear(date) {
|
|
20
|
+
const start = new Date(date.getFullYear(), 0, 0);
|
|
21
|
+
const diff = date.getTime() - start.getTime();
|
|
22
|
+
const oneDay = 1000 * 60 * 60 * 24;
|
|
23
|
+
return Math.floor(diff / oneDay);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Calcule le combinedDay pour une date donnee
|
|
27
|
+
*/
|
|
28
|
+
export function computeCombinedDay(date) {
|
|
29
|
+
const yearPart = date.getFullYear() % YEAR_MODULO;
|
|
30
|
+
const dayPart = getDayOfYear(date) % DAY_MODULO;
|
|
31
|
+
return (yearPart * DAY_MODULO) + dayPart;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Extrait le combinedDay (annee + jour encodes, 0-127) d'un numero de ticket
|
|
35
|
+
*/
|
|
36
|
+
export function extractCombinedDayFromTicket(ticketNumber) {
|
|
37
|
+
const value = typeof ticketNumber === 'string' ? parseInt(ticketNumber, 10) : ticketNumber;
|
|
38
|
+
return Math.floor(value / DAY_MULTIPLIER);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Extrait le jour encode (0-31) d'un numero de ticket
|
|
42
|
+
*/
|
|
43
|
+
export function extractDayFromTicket(ticketNumber) {
|
|
44
|
+
const combinedDay = extractCombinedDayFromTicket(ticketNumber);
|
|
45
|
+
return combinedDay % DAY_MODULO;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Extrait l'annee encodee (0-3) d'un numero de ticket
|
|
49
|
+
*/
|
|
50
|
+
export function extractYearFromTicket(ticketNumber) {
|
|
51
|
+
const combinedDay = extractCombinedDayFromTicket(ticketNumber);
|
|
52
|
+
return Math.floor(combinedDay / DAY_MODULO);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extrait la sequence d'un numero de ticket
|
|
56
|
+
*/
|
|
57
|
+
export function extractSequenceFromTicket(ticketNumber) {
|
|
58
|
+
const value = typeof ticketNumber === 'string' ? parseInt(ticketNumber, 10) : ticketNumber;
|
|
59
|
+
return value % DAY_MULTIPLIER;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Verifie si un ticket correspond au jour et annee actuels (anti-replay)
|
|
63
|
+
*/
|
|
64
|
+
export function isTicketFromToday(ticketNumber) {
|
|
65
|
+
const ticketCombinedDay = extractCombinedDayFromTicket(ticketNumber);
|
|
66
|
+
const todayCombinedDay = computeCombinedDay(new Date());
|
|
67
|
+
return ticketCombinedDay === todayCombinedDay;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Verifie si un numero de ticket est valide (dans les limites 24-bit)
|
|
71
|
+
*/
|
|
72
|
+
export function isValidTicketFormat(ticketNumber) {
|
|
73
|
+
const value = typeof ticketNumber === 'string' ? parseInt(ticketNumber, 10) : ticketNumber;
|
|
74
|
+
return !isNaN(value) && value >= 1 && value <= MAX_TICKET_VALUE;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=ticket-number.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ticket-number.js","sourceRoot":"","sources":["../../lib/ticket-number.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,8 +27,18 @@ export interface TicketDTO {
|
|
|
27
27
|
}
|
|
28
28
|
export declare class TicketRepository extends BaseRepository<TicketDTO> {
|
|
29
29
|
constructor(dialect: IDialect);
|
|
30
|
-
/**
|
|
31
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Generate next ticket number in Wiegand 24-bit format.
|
|
32
|
+
*
|
|
33
|
+
* Format: Ticket = ((Annee % 4) x 32 + (JourAnnee % 32)) x 131072 + Sequence
|
|
34
|
+
*
|
|
35
|
+
* Cross-dialect: uses only BaseRepository.upsert() + BaseRepository.increment()
|
|
36
|
+
* which are implemented by all @mostajs/orm dialects (Mongo, SQLite, Postgres, etc.)
|
|
37
|
+
*
|
|
38
|
+
* @param date - Date to encode in ticket (default: today)
|
|
39
|
+
* @returns Numeric ticket number as string (e.g. "7077889")
|
|
40
|
+
*/
|
|
41
|
+
getNextTicketNumber(date?: Date): Promise<string>;
|
|
32
42
|
/** Create ticket with auto-generated ticketNumber and code */
|
|
33
43
|
createWithAutoFields(data: Partial<TicketDTO>): Promise<TicketDTO>;
|
|
34
44
|
/** Find by code value (QR, barcode, etc.) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticket.repository.d.ts","sourceRoot":"","sources":["../../repositories/ticket.repository.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"ticket.repository.d.ts","sourceRoot":"","sources":["../../repositories/ticket.repository.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAS9C,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,GAAG,CAAC;IAClB,QAAQ,EAAE,GAAG,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,GAAG,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC;IACpD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,gBAAiB,SAAQ,cAAc,CAAC,SAAS,CAAC;gBACjD,OAAO,EAAE,QAAQ;IAI7B;;;;;;;;;;OAUG;IACG,mBAAmB,CAAC,IAAI,GAAE,IAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkCnE,8DAA8D;IACxD,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;IAgBxE,6CAA6C;IACvC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAIzD,gCAAgC;IAC1B,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAIlF,6CAA6C;IACvC,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5D,8DAA8D;IACxD,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAOzF,0BAA0B;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;CAOzE"}
|
|
@@ -5,18 +5,40 @@ import { randomUUID } from 'crypto';
|
|
|
5
5
|
import { BaseRepository } from '@mostajs/orm';
|
|
6
6
|
import { TicketSchema } from '../schemas/ticket.schema';
|
|
7
7
|
import { CounterSchema } from '../schemas/counter.schema';
|
|
8
|
+
import { computeCombinedDay, DAY_MULTIPLIER, MAX_SEQUENCE, MAX_TICKET_VALUE, } from '../lib/ticket-number';
|
|
8
9
|
export class TicketRepository extends BaseRepository {
|
|
9
10
|
constructor(dialect) {
|
|
10
11
|
super(TicketSchema, dialect);
|
|
11
12
|
}
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Generate next ticket number in Wiegand 24-bit format.
|
|
15
|
+
*
|
|
16
|
+
* Format: Ticket = ((Annee % 4) x 32 + (JourAnnee % 32)) x 131072 + Sequence
|
|
17
|
+
*
|
|
18
|
+
* Cross-dialect: uses only BaseRepository.upsert() + BaseRepository.increment()
|
|
19
|
+
* which are implemented by all @mostajs/orm dialects (Mongo, SQLite, Postgres, etc.)
|
|
20
|
+
*
|
|
21
|
+
* @param date - Date to encode in ticket (default: today)
|
|
22
|
+
* @returns Numeric ticket number as string (e.g. "7077889")
|
|
23
|
+
*/
|
|
24
|
+
async getNextTicketNumber(date = new Date()) {
|
|
25
|
+
const combinedDay = computeCombinedDay(date);
|
|
26
|
+
const dateStr = date.toISOString().split('T')[0];
|
|
27
|
+
const counterName = `ticket-${dateStr}`;
|
|
16
28
|
const counterRepo = new BaseRepository(CounterSchema, this.dialect);
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
29
|
+
// 1. Ensure counter exists (cross-dialect: Mongo=findOneAndUpdate, SQL=findOne+create/update)
|
|
30
|
+
const ensured = await counterRepo.upsert({ name: counterName }, { name: counterName, seq: 0 });
|
|
31
|
+
// 2. Atomic increment with the real id returned by the dialect
|
|
32
|
+
const updated = await counterRepo.increment(ensured.id, 'seq', 1);
|
|
33
|
+
const seqNum = updated?.seq ?? 1;
|
|
34
|
+
if (seqNum > MAX_SEQUENCE) {
|
|
35
|
+
throw new Error(`Capacite depassee pour ${dateStr}: ${seqNum} > ${MAX_SEQUENCE}`);
|
|
36
|
+
}
|
|
37
|
+
const ticketValue = (combinedDay * DAY_MULTIPLIER) + seqNum;
|
|
38
|
+
if (ticketValue > MAX_TICKET_VALUE) {
|
|
39
|
+
throw new Error(`Ticket hors limite 24-bit: ${ticketValue} > ${MAX_TICKET_VALUE}`);
|
|
40
|
+
}
|
|
41
|
+
return String(ticketValue);
|
|
20
42
|
}
|
|
21
43
|
/** Create ticket with auto-generated ticketNumber and code */
|
|
22
44
|
async createWithAutoFields(data) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticket.repository.js","sourceRoot":"","sources":["../../repositories/ticket.repository.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,qBAAqB;AACrB,wCAAwC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"ticket.repository.js","sourceRoot":"","sources":["../../repositories/ticket.repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"counter.schema.d.ts","sourceRoot":"","sources":["../../schemas/counter.schema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,eAAO,MAAM,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"counter.schema.d.ts","sourceRoot":"","sources":["../../schemas/counter.schema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,eAAO,MAAM,aAAa,EAAE,YAa3B,CAAC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export const CounterSchema = {
|
|
2
|
-
name: '
|
|
3
|
-
collection: '
|
|
2
|
+
name: 'TicketCounter',
|
|
3
|
+
collection: 'ticket_counters',
|
|
4
4
|
timestamps: false,
|
|
5
5
|
fields: {
|
|
6
|
+
name: { type: 'string', required: true, unique: true },
|
|
6
7
|
seq: { type: 'number', default: 0 },
|
|
7
8
|
},
|
|
8
9
|
relations: {},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"counter.schema.js","sourceRoot":"","sources":["../../schemas/counter.schema.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,aAAa,GAAiB;IACzC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"counter.schema.js","sourceRoot":"","sources":["../../schemas/counter.schema.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,aAAa,GAAiB;IACzC,IAAI,EAAE,eAAe;IACrB,UAAU,EAAE,iBAAiB;IAC7B,UAAU,EAAE,KAAK;IAEjB,MAAM,EAAE;QACN,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QACtD,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE;KACpC;IAED,SAAS,EAAE,EAAE;IAEb,OAAO,EAAE,EAAE;CACZ,CAAC"}
|
package/package.json
CHANGED