@mostajs/ticketing 1.0.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.
Files changed (82) hide show
  1. package/README.md +479 -0
  2. package/dist/api/scan.route.d.ts +16 -0
  3. package/dist/api/scan.route.d.ts.map +1 -0
  4. package/dist/api/scan.route.js +75 -0
  5. package/dist/api/scan.route.js.map +1 -0
  6. package/dist/api/tickets.route.d.ts +15 -0
  7. package/dist/api/tickets.route.d.ts.map +1 -0
  8. package/dist/api/tickets.route.js +91 -0
  9. package/dist/api/tickets.route.js.map +1 -0
  10. package/dist/index.d.ts +11 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +14 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/lib/quota-manager.d.ts +18 -0
  15. package/dist/lib/quota-manager.d.ts.map +1 -0
  16. package/dist/lib/quota-manager.js +31 -0
  17. package/dist/lib/quota-manager.js.map +1 -0
  18. package/dist/lib/scan-processor.d.ts +39 -0
  19. package/dist/lib/scan-processor.d.ts.map +1 -0
  20. package/dist/lib/scan-processor.js +168 -0
  21. package/dist/lib/scan-processor.js.map +1 -0
  22. package/dist/lib/validity-checker.d.ts +19 -0
  23. package/dist/lib/validity-checker.d.ts.map +1 -0
  24. package/dist/lib/validity-checker.js +45 -0
  25. package/dist/lib/validity-checker.js.map +1 -0
  26. package/dist/repositories/activity.repository.d.ts +38 -0
  27. package/dist/repositories/activity.repository.d.ts.map +1 -0
  28. package/dist/repositories/activity.repository.js +23 -0
  29. package/dist/repositories/activity.repository.js.map +1 -0
  30. package/dist/repositories/client-access.repository.d.ts +31 -0
  31. package/dist/repositories/client-access.repository.d.ts.map +1 -0
  32. package/dist/repositories/client-access.repository.js +31 -0
  33. package/dist/repositories/client-access.repository.js.map +1 -0
  34. package/dist/repositories/index.d.ts +11 -0
  35. package/dist/repositories/index.d.ts.map +1 -0
  36. package/dist/repositories/index.js +8 -0
  37. package/dist/repositories/index.js.map +1 -0
  38. package/dist/repositories/scan-log.repository.d.ts +32 -0
  39. package/dist/repositories/scan-log.repository.d.ts.map +1 -0
  40. package/dist/repositories/scan-log.repository.js +48 -0
  41. package/dist/repositories/scan-log.repository.js.map +1 -0
  42. package/dist/repositories/subscription-plan.repository.d.ts +27 -0
  43. package/dist/repositories/subscription-plan.repository.d.ts.map +1 -0
  44. package/dist/repositories/subscription-plan.repository.js +19 -0
  45. package/dist/repositories/subscription-plan.repository.js.map +1 -0
  46. package/dist/repositories/ticket.repository.d.ts +48 -0
  47. package/dist/repositories/ticket.repository.d.ts.map +1 -0
  48. package/dist/repositories/ticket.repository.js +65 -0
  49. package/dist/repositories/ticket.repository.js.map +1 -0
  50. package/dist/schemas/activity.schema.d.ts +3 -0
  51. package/dist/schemas/activity.schema.d.ts.map +1 -0
  52. package/dist/schemas/activity.schema.js +39 -0
  53. package/dist/schemas/activity.schema.js.map +1 -0
  54. package/dist/schemas/client-access.schema.d.ts +3 -0
  55. package/dist/schemas/client-access.schema.d.ts.map +1 -0
  56. package/dist/schemas/client-access.schema.js +25 -0
  57. package/dist/schemas/client-access.schema.js.map +1 -0
  58. package/dist/schemas/counter.schema.d.ts +3 -0
  59. package/dist/schemas/counter.schema.d.ts.map +1 -0
  60. package/dist/schemas/counter.schema.js +11 -0
  61. package/dist/schemas/counter.schema.js.map +1 -0
  62. package/dist/schemas/index.d.ts +7 -0
  63. package/dist/schemas/index.d.ts.map +1 -0
  64. package/dist/schemas/index.js +9 -0
  65. package/dist/schemas/index.js.map +1 -0
  66. package/dist/schemas/scan-log.schema.d.ts +3 -0
  67. package/dist/schemas/scan-log.schema.d.ts.map +1 -0
  68. package/dist/schemas/scan-log.schema.js +26 -0
  69. package/dist/schemas/scan-log.schema.js.map +1 -0
  70. package/dist/schemas/subscription-plan.schema.d.ts +3 -0
  71. package/dist/schemas/subscription-plan.schema.d.ts.map +1 -0
  72. package/dist/schemas/subscription-plan.schema.js +29 -0
  73. package/dist/schemas/subscription-plan.schema.js.map +1 -0
  74. package/dist/schemas/ticket.schema.d.ts +3 -0
  75. package/dist/schemas/ticket.schema.d.ts.map +1 -0
  76. package/dist/schemas/ticket.schema.js +35 -0
  77. package/dist/schemas/ticket.schema.js.map +1 -0
  78. package/dist/types/index.d.ts +99 -0
  79. package/dist/types/index.d.ts.map +1 -0
  80. package/dist/types/index.js +4 -0
  81. package/dist/types/index.js.map +1 -0
  82. package/package.json +84 -0
@@ -0,0 +1,48 @@
1
+ // ScanLogRepository
2
+ // @mostajs/ticketing
3
+ // Author: Dr Hamid MADANI drmdh@msn.com
4
+ import { BaseRepository } from '@mostajs/orm';
5
+ import { ScanLogSchema } from '../schemas/scan-log.schema';
6
+ export class ScanLogRepository extends BaseRepository {
7
+ constructor(dialect) {
8
+ super(ScanLogSchema, dialect);
9
+ }
10
+ /** Find recent scan logs with ticket & scannedBy populated */
11
+ async findRecent(filter = {}, options) {
12
+ return this.findWithRelations(filter, ['ticket', 'scannedBy'], { sort: { timestamp: -1 }, ...options });
13
+ }
14
+ /** Find scan history for a specific client */
15
+ async findByClient(clientId, options) {
16
+ return this.findWithRelations({ client: clientId }, ['ticket', 'activity', 'scannedBy'], { sort: { timestamp: -1 }, ...options });
17
+ }
18
+ /** Count all scans for today */
19
+ async countToday() {
20
+ const start = new Date();
21
+ start.setHours(0, 0, 0, 0);
22
+ return this.count({ timestamp: { $gte: start } });
23
+ }
24
+ /** Count granted scans for today */
25
+ async countGrantedToday() {
26
+ const start = new Date();
27
+ start.setHours(0, 0, 0, 0);
28
+ return this.count({ result: 'granted', timestamp: { $gte: start } });
29
+ }
30
+ /** Get distinct clients with granted scans today (visitors present) */
31
+ async findDistinctClientsToday() {
32
+ const start = new Date();
33
+ start.setHours(0, 0, 0, 0);
34
+ return this.distinct('client', { result: 'granted', timestamp: { $gte: start } });
35
+ }
36
+ /** Check if a ticket was already scanned today (for day_reentry) */
37
+ async wasScannedToday(ticketId) {
38
+ const start = new Date();
39
+ start.setHours(0, 0, 0, 0);
40
+ const log = await this.findOne({
41
+ ticket: ticketId,
42
+ result: 'granted',
43
+ timestamp: { $gte: start },
44
+ });
45
+ return log !== null;
46
+ }
47
+ }
48
+ //# sourceMappingURL=scan-log.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-log.repository.js","sourceRoot":"","sources":["../../repositories/scan-log.repository.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,qBAAqB;AACrB,wCAAwC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAkB3D,MAAM,OAAO,iBAAkB,SAAQ,cAA0B;IAC/D,YAAY,OAAiB;QAC3B,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,8DAA8D;IAC9D,KAAK,CAAC,UAAU,CAAC,SAAkC,EAAE,EAAE,OAAsB;QAC3E,OAAO,IAAI,CAAC,iBAAiB,CAC3B,MAAM,EACN,CAAC,QAAQ,EAAE,WAAW,CAAC,EACvB,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,CACxC,CAAC;IACJ,CAAC;IAED,8CAA8C;IAC9C,KAAK,CAAC,YAAY,CAAC,QAAgB,EAAE,OAAsB;QACzD,OAAO,IAAI,CAAC,iBAAiB,CAC3B,EAAE,MAAM,EAAE,QAAQ,EAAE,EACpB,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,EACnC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,CACxC,CAAC;IACJ,CAAC;IAED,gCAAgC;IAChC,KAAK,CAAC,UAAU;QACd,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,oCAAoC;IACpC,KAAK,CAAC,iBAAiB;QACrB,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,wBAAwB;QAC5B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,oEAAoE;IACpE,KAAK,CAAC,eAAe,CAAC,QAAgB;QACpC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;YAC7B,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;SAC3B,CAAC,CAAC;QACH,OAAO,GAAG,KAAK,IAAI,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1,27 @@
1
+ import { BaseRepository } from '@mostajs/orm';
2
+ import type { IDialect } from '@mostajs/orm';
3
+ export interface PlanActivityDTO {
4
+ activity: any;
5
+ sessionsCount: number | null;
6
+ }
7
+ export interface SubscriptionPlanDTO {
8
+ id: string;
9
+ name: string;
10
+ description?: string;
11
+ type: 'temporal' | 'usage' | 'mixed';
12
+ duration: number | null;
13
+ activities: PlanActivityDTO[];
14
+ price: number;
15
+ currency: string;
16
+ isActive: boolean;
17
+ createdAt: string;
18
+ updatedAt: string;
19
+ }
20
+ export declare class SubscriptionPlanRepository extends BaseRepository<SubscriptionPlanDTO> {
21
+ constructor(dialect: IDialect);
22
+ /** Find all plans, newest first */
23
+ findAllWithActivities(): Promise<SubscriptionPlanDTO[]>;
24
+ /** Find active plans only */
25
+ findActive(): Promise<SubscriptionPlanDTO[]>;
26
+ }
27
+ //# sourceMappingURL=subscription-plan.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-plan.repository.d.ts","sourceRoot":"","sources":["../../repositories/subscription-plan.repository.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,GAAG,CAAC;IACd,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;IACrC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,0BAA2B,SAAQ,cAAc,CAAC,mBAAmB,CAAC;gBACrE,OAAO,EAAE,QAAQ;IAI7B,mCAAmC;IAC7B,qBAAqB,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAI7D,6BAA6B;IACvB,UAAU,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;CAGnD"}
@@ -0,0 +1,19 @@
1
+ // SubscriptionPlanRepository
2
+ // @mostajs/ticketing
3
+ // Author: Dr Hamid MADANI drmdh@msn.com
4
+ import { BaseRepository } from '@mostajs/orm';
5
+ import { SubscriptionPlanSchema } from '../schemas/subscription-plan.schema';
6
+ export class SubscriptionPlanRepository extends BaseRepository {
7
+ constructor(dialect) {
8
+ super(SubscriptionPlanSchema, dialect);
9
+ }
10
+ /** Find all plans, newest first */
11
+ async findAllWithActivities() {
12
+ return this.findAll({}, { sort: { createdAt: -1 } });
13
+ }
14
+ /** Find active plans only */
15
+ async findActive() {
16
+ return this.findAll({ isActive: true }, { sort: { createdAt: -1 } });
17
+ }
18
+ }
19
+ //# sourceMappingURL=subscription-plan.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-plan.repository.js","sourceRoot":"","sources":["../../repositories/subscription-plan.repository.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,qBAAqB;AACrB,wCAAwC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAsB7E,MAAM,OAAO,0BAA2B,SAAQ,cAAmC;IACjF,YAAY,OAAiB;QAC3B,KAAK,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,mCAAmC;IACnC,KAAK,CAAC,qBAAqB;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,6BAA6B;IAC7B,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ import { BaseRepository } from '@mostajs/orm';
2
+ import type { IDialect, QueryOptions } from '@mostajs/orm';
3
+ import type { CodeFormat } from '../types/index';
4
+ export interface TicketDTO {
5
+ id: string;
6
+ ticketNumber: string;
7
+ client: any;
8
+ clientAccess: any;
9
+ activity: any;
10
+ ticketType: string;
11
+ sourceClient: any;
12
+ code: string;
13
+ codeFormat: CodeFormat;
14
+ clientName: string;
15
+ activityName: string;
16
+ validityMode: string;
17
+ validUntil: string | null;
18
+ status: 'active' | 'used' | 'expired' | 'cancelled';
19
+ scannedAt: string | null;
20
+ scannedBy: any;
21
+ amount: number;
22
+ currency: string;
23
+ printCount: number;
24
+ createdBy: string;
25
+ createdAt: string;
26
+ updatedAt: string;
27
+ }
28
+ export declare class TicketRepository extends BaseRepository<TicketDTO> {
29
+ constructor(dialect: IDialect);
30
+ /** Generate next ticket number: TKT-20260228-0001 */
31
+ getNextTicketNumber(prefix?: string): Promise<string>;
32
+ /** Create ticket with auto-generated ticketNumber and code */
33
+ createWithAutoFields(data: Partial<TicketDTO>): Promise<TicketDTO>;
34
+ /** Find by code value (QR, barcode, etc.) */
35
+ findByCode(code: string): Promise<TicketDTO | null>;
36
+ /** Find tickets for a client */
37
+ findByClient(clientId: string, options?: QueryOptions): Promise<TicketDTO[]>;
38
+ /** Count tickets for a given clientAccess */
39
+ countByAccess(clientAccessId: string): Promise<number>;
40
+ /** Count tickets grouped by clientAccess (for access grid) */
41
+ countsByAccess(accessIds: string[]): Promise<{
42
+ accessId: string;
43
+ count: number;
44
+ }[]>;
45
+ /** Mark ticket as used */
46
+ markUsed(id: string, scannedBy: string): Promise<TicketDTO | null>;
47
+ }
48
+ //# sourceMappingURL=ticket.repository.d.ts.map
@@ -0,0 +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;AAG9C,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,qDAAqD;IAC/C,mBAAmB,CAAC,MAAM,SAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAS1D,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"}
@@ -0,0 +1,65 @@
1
+ // TicketRepository
2
+ // @mostajs/ticketing
3
+ // Author: Dr Hamid MADANI drmdh@msn.com
4
+ import { randomUUID } from 'crypto';
5
+ import { BaseRepository } from '@mostajs/orm';
6
+ import { TicketSchema } from '../schemas/ticket.schema';
7
+ import { CounterSchema } from '../schemas/counter.schema';
8
+ export class TicketRepository extends BaseRepository {
9
+ constructor(dialect) {
10
+ super(TicketSchema, dialect);
11
+ }
12
+ /** Generate next ticket number: TKT-20260228-0001 */
13
+ async getNextTicketNumber(prefix = 'TKT') {
14
+ const today = new Date();
15
+ const dateStr = today.toISOString().slice(0, 10).replace(/-/g, '');
16
+ const counterRepo = new BaseRepository(CounterSchema, this.dialect);
17
+ const counter = await counterRepo.increment(`ticket-${dateStr}`, 'seq', 1);
18
+ const seq = counter?.seq ?? 1;
19
+ return `${prefix}-${dateStr}-${String(seq).padStart(4, '0')}`;
20
+ }
21
+ /** Create ticket with auto-generated ticketNumber and code */
22
+ async createWithAutoFields(data) {
23
+ if (!data.ticketNumber) {
24
+ data.ticketNumber = await this.getNextTicketNumber();
25
+ }
26
+ if (!data.codeFormat) {
27
+ data.codeFormat = 'qrcode';
28
+ }
29
+ const created = await this.create(data);
30
+ if (!data.code) {
31
+ const uuid = randomUUID();
32
+ await this.update(created.id, { code: uuid });
33
+ created.code = uuid;
34
+ }
35
+ return created;
36
+ }
37
+ /** Find by code value (QR, barcode, etc.) */
38
+ async findByCode(code) {
39
+ return this.findOne({ code });
40
+ }
41
+ /** Find tickets for a client */
42
+ async findByClient(clientId, options) {
43
+ return this.findAll({ client: clientId }, { sort: { createdAt: -1 }, ...options });
44
+ }
45
+ /** Count tickets for a given clientAccess */
46
+ async countByAccess(clientAccessId) {
47
+ return this.count({ clientAccess: clientAccessId });
48
+ }
49
+ /** Count tickets grouped by clientAccess (for access grid) */
50
+ async countsByAccess(accessIds) {
51
+ return this.aggregate([
52
+ { $match: { clientAccess: { $in: accessIds } } },
53
+ { $group: { _by: 'clientAccess', count: { $sum: 1 } } },
54
+ ]);
55
+ }
56
+ /** Mark ticket as used */
57
+ async markUsed(id, scannedBy) {
58
+ return this.update(id, {
59
+ status: 'used',
60
+ scannedAt: new Date(),
61
+ scannedBy,
62
+ });
63
+ }
64
+ }
65
+ //# sourceMappingURL=ticket.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket.repository.js","sourceRoot":"","sources":["../../repositories/ticket.repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { EntitySchema } from '@mostajs/orm';
2
+ export declare const ActivitySchema: EntitySchema;
3
+ //# sourceMappingURL=activity.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.schema.d.ts","sourceRoot":"","sources":["../../schemas/activity.schema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,eAAO,MAAM,cAAc,EAAE,YAwC5B,CAAC"}
@@ -0,0 +1,39 @@
1
+ export const ActivitySchema = {
2
+ name: 'Activity',
3
+ collection: 'activities',
4
+ timestamps: true,
5
+ fields: {
6
+ name: { type: 'string', required: true },
7
+ slug: { type: 'string', required: true, unique: true, lowercase: true },
8
+ description: { type: 'string' },
9
+ icon: { type: 'string' },
10
+ color: { type: 'string' },
11
+ capacity: { type: 'number' },
12
+ currentOccupancy: { type: 'number', default: 0 },
13
+ schedule: {
14
+ type: 'array',
15
+ arrayOf: {
16
+ kind: 'embedded',
17
+ fields: {
18
+ dayOfWeek: { type: 'number', required: true },
19
+ openTime: { type: 'string', required: true },
20
+ closeTime: { type: 'string', required: true },
21
+ isOpen: { type: 'boolean', default: true },
22
+ },
23
+ },
24
+ },
25
+ ticketValidityMode: { type: 'string', enum: ['day_reentry', 'single_use', 'time_slot', 'unlimited'], default: 'single_use' },
26
+ ticketDuration: { type: 'number', default: null },
27
+ price: { type: 'number', required: true, default: 0 },
28
+ currency: { type: 'string', default: 'DA' },
29
+ status: { type: 'string', enum: ['active', 'inactive', 'maintenance'], default: 'active' },
30
+ sortOrder: { type: 'number', default: 0 },
31
+ },
32
+ relations: {
33
+ createdBy: { target: 'User', type: 'many-to-one', nullable: true },
34
+ },
35
+ indexes: [
36
+ { fields: { status: 'asc' } },
37
+ ],
38
+ };
39
+ //# sourceMappingURL=activity.schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.schema.js","sourceRoot":"","sources":["../../schemas/activity.schema.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,IAAI,EAAE,UAAU;IAChB,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,IAAI;IAEhB,MAAM,EAAE;QACN,IAAI,EAAgB,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QACtD,IAAI,EAAgB,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;QACrF,WAAW,EAAS,EAAE,IAAI,EAAE,QAAQ,EAAE;QACtC,IAAI,EAAgB,EAAE,IAAI,EAAE,QAAQ,EAAE;QACtC,KAAK,EAAe,EAAE,IAAI,EAAE,QAAQ,EAAE;QACtC,QAAQ,EAAY,EAAE,IAAI,EAAE,QAAQ,EAAE;QACtC,gBAAgB,EAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE;QAClD,QAAQ,EAAY;YAClB,IAAI,EAAE,OAAO;YACb,OAAO,EAAE;gBACP,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE;oBACN,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC7C,QAAQ,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC7C,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC7C,MAAM,EAAK,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE;iBAC9C;aACF;SACF;QACD,kBAAkB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE;QAC5H,cAAc,EAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;QACrD,KAAK,EAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE;QAClE,QAAQ,EAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;QACrD,MAAM,EAAc,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE;QACtG,SAAS,EAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE;KACnD;IAED,SAAS,EAAE;QACT,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;KACnE;IAED,OAAO,EAAE;QACP,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;KAC9B;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { EntitySchema } from '@mostajs/orm';
2
+ export declare const ClientAccessSchema: EntitySchema;
3
+ //# sourceMappingURL=client-access.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-access.schema.d.ts","sourceRoot":"","sources":["../../schemas/client-access.schema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,eAAO,MAAM,kBAAkB,EAAE,YA0BhC,CAAC"}
@@ -0,0 +1,25 @@
1
+ export const ClientAccessSchema = {
2
+ name: 'ClientAccess',
3
+ collection: 'client_accesses',
4
+ timestamps: true,
5
+ fields: {
6
+ accessType: { type: 'string', enum: ['unlimited', 'count', 'temporal', 'mixed'], required: true },
7
+ totalQuota: { type: 'number', default: null },
8
+ remainingQuota: { type: 'number', default: null },
9
+ startDate: { type: 'date', required: true },
10
+ endDate: { type: 'date', default: null },
11
+ status: { type: 'string', enum: ['active', 'expired', 'blocked', 'depleted'], default: 'active' },
12
+ },
13
+ relations: {
14
+ client: { target: 'Client', type: 'many-to-one', required: true },
15
+ plan: { target: 'SubscriptionPlan', type: 'many-to-one', nullable: true },
16
+ activity: { target: 'Activity', type: 'many-to-one', required: true },
17
+ createdBy: { target: 'User', type: 'many-to-one', required: true },
18
+ },
19
+ indexes: [
20
+ { fields: { client: 'asc', activity: 'asc' } },
21
+ { fields: { client: 'asc', status: 'asc' } },
22
+ { fields: { status: 'asc' } },
23
+ ],
24
+ };
25
+ //# sourceMappingURL=client-access.schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-access.schema.js","sourceRoot":"","sources":["../../schemas/client-access.schema.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,kBAAkB,GAAiB;IAC9C,IAAI,EAAE,cAAc;IACpB,UAAU,EAAE,iBAAiB;IAC7B,UAAU,EAAE,IAAI;IAEhB,MAAM,EAAE;QACN,UAAU,EAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;QACrG,UAAU,EAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;QACjD,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;QACjD,SAAS,EAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;QAChD,OAAO,EAAS,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QAC/C,MAAM,EAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE;KAC1G;IAED,SAAS,EAAE;QACT,MAAM,EAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QACpE,IAAI,EAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC9E,QAAQ,EAAG,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QACtE,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;KACnE;IAED,OAAO,EAAE;QACP,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAC9C,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;QAC5C,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;KAC9B;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { EntitySchema } from '@mostajs/orm';
2
+ export declare const CounterSchema: EntitySchema;
3
+ //# sourceMappingURL=counter.schema.d.ts.map
@@ -0,0 +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,YAY3B,CAAC"}
@@ -0,0 +1,11 @@
1
+ export const CounterSchema = {
2
+ name: 'Counter',
3
+ collection: 'counters',
4
+ timestamps: false,
5
+ fields: {
6
+ seq: { type: 'number', default: 0 },
7
+ },
8
+ relations: {},
9
+ indexes: [],
10
+ };
11
+ //# sourceMappingURL=counter.schema.js.map
@@ -0,0 +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,SAAS;IACf,UAAU,EAAE,UAAU;IACtB,UAAU,EAAE,KAAK;IAEjB,MAAM,EAAE;QACN,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE;KACpC;IAED,SAAS,EAAE,EAAE;IAEb,OAAO,EAAE,EAAE;CACZ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { TicketSchema } from './ticket.schema';
2
+ export { ClientAccessSchema } from './client-access.schema';
3
+ export { ScanLogSchema } from './scan-log.schema';
4
+ export { SubscriptionPlanSchema } from './subscription-plan.schema';
5
+ export { ActivitySchema } from './activity.schema';
6
+ export { CounterSchema } from './counter.schema';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../schemas/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,9 @@
1
+ // @mostajs/ticketing — Schemas barrel
2
+ // Author: Dr Hamid MADANI drmdh@msn.com
3
+ export { TicketSchema } from './ticket.schema';
4
+ export { ClientAccessSchema } from './client-access.schema';
5
+ export { ScanLogSchema } from './scan-log.schema';
6
+ export { SubscriptionPlanSchema } from './subscription-plan.schema';
7
+ export { ActivitySchema } from './activity.schema';
8
+ export { CounterSchema } from './counter.schema';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../schemas/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,wCAAwC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { EntitySchema } from '@mostajs/orm';
2
+ export declare const ScanLogSchema: EntitySchema;
3
+ //# sourceMappingURL=scan-log.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-log.schema.d.ts","sourceRoot":"","sources":["../../schemas/scan-log.schema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,eAAO,MAAM,aAAa,EAAE,YA2B3B,CAAC"}
@@ -0,0 +1,26 @@
1
+ export const ScanLogSchema = {
2
+ name: 'ScanLog',
3
+ collection: 'scan_logs',
4
+ timestamps: false,
5
+ fields: {
6
+ scanMethod: { type: 'string', enum: ['webcam', 'pwa_camera'], default: 'webcam' },
7
+ result: { type: 'string', enum: ['granted', 'denied'], required: true },
8
+ denyReason: { type: 'string', default: null },
9
+ quotaBefore: { type: 'number', default: null },
10
+ quotaAfter: { type: 'number', default: null },
11
+ isReentry: { type: 'boolean', default: false },
12
+ timestamp: { type: 'date', default: 'now' },
13
+ },
14
+ relations: {
15
+ ticket: { target: 'Ticket', type: 'many-to-one', nullable: true },
16
+ client: { target: 'Client', type: 'many-to-one', nullable: true },
17
+ activity: { target: 'Activity', type: 'many-to-one', nullable: true },
18
+ scannedBy: { target: 'User', type: 'many-to-one', required: true },
19
+ },
20
+ indexes: [
21
+ { fields: { client: 'asc' } },
22
+ { fields: { timestamp: 'desc' } },
23
+ { fields: { result: 'asc' } },
24
+ ],
25
+ };
26
+ //# sourceMappingURL=scan-log.schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-log.schema.js","sourceRoot":"","sources":["../../schemas/scan-log.schema.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,aAAa,GAAiB;IACzC,IAAI,EAAE,SAAS;IACf,UAAU,EAAE,WAAW;IACvB,UAAU,EAAE,KAAK;IAEjB,MAAM,EAAE;QACN,UAAU,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE;QAClF,MAAM,EAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC5E,UAAU,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;QAC9C,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;QAC9C,UAAU,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;QAC9C,SAAS,EAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;QAChD,SAAS,EAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE;KAC9C;IAED,SAAS,EAAE;QACT,MAAM,EAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QACpE,MAAM,EAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QACpE,QAAQ,EAAG,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QACtE,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;KACnE;IAED,OAAO,EAAE;QACP,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;QAC7B,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;QACjC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;KAC9B;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { EntitySchema } from '@mostajs/orm';
2
+ export declare const SubscriptionPlanSchema: EntitySchema;
3
+ //# sourceMappingURL=subscription-plan.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-plan.schema.d.ts","sourceRoot":"","sources":["../../schemas/subscription-plan.schema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,eAAO,MAAM,sBAAsB,EAAE,YA8BpC,CAAC"}
@@ -0,0 +1,29 @@
1
+ export const SubscriptionPlanSchema = {
2
+ name: 'SubscriptionPlan',
3
+ collection: 'subscription_plans',
4
+ timestamps: true,
5
+ fields: {
6
+ name: { type: 'string', required: true },
7
+ description: { type: 'string' },
8
+ type: { type: 'string', enum: ['temporal', 'usage', 'mixed'], required: true },
9
+ duration: { type: 'number', default: null },
10
+ activities: {
11
+ type: 'array',
12
+ arrayOf: {
13
+ kind: 'embedded',
14
+ fields: {
15
+ activity: { type: 'string', required: true },
16
+ sessionsCount: { type: 'number', default: null },
17
+ },
18
+ },
19
+ },
20
+ price: { type: 'number', required: true },
21
+ currency: { type: 'string', default: 'DA' },
22
+ isActive: { type: 'boolean', default: true },
23
+ },
24
+ relations: {},
25
+ indexes: [
26
+ { fields: { isActive: 'asc' } },
27
+ ],
28
+ };
29
+ //# sourceMappingURL=subscription-plan.schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-plan.schema.js","sourceRoot":"","sources":["../../schemas/subscription-plan.schema.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,sBAAsB,GAAiB;IAClD,IAAI,EAAE,kBAAkB;IACxB,UAAU,EAAE,oBAAoB;IAChC,UAAU,EAAE,IAAI;IAEhB,MAAM,EAAE;QACN,IAAI,EAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC/C,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC/B,IAAI,EAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;QACrF,QAAQ,EAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;QAC9C,UAAU,EAAG;YACX,IAAI,EAAE,OAAO;YACb,OAAO,EAAE;gBACP,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE;oBACN,QAAQ,EAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACjD,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;iBACjD;aACF;SACF;QACD,KAAK,EAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC/C,QAAQ,EAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;QAC9C,QAAQ,EAAK,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE;KAChD;IAED,SAAS,EAAE,EAAE;IAEb,OAAO,EAAE;QACP,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;KAChC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { EntitySchema } from '@mostajs/orm';
2
+ export declare const TicketSchema: EntitySchema;
3
+ //# sourceMappingURL=ticket.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket.schema.d.ts","sourceRoot":"","sources":["../../schemas/ticket.schema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,eAAO,MAAM,YAAY,EAAE,YAoC1B,CAAC"}
@@ -0,0 +1,35 @@
1
+ export const TicketSchema = {
2
+ name: 'Ticket',
3
+ collection: 'tickets',
4
+ timestamps: true,
5
+ fields: {
6
+ ticketNumber: { type: 'string', unique: true },
7
+ ticketType: { type: 'string', default: 'standard' },
8
+ code: { type: 'string', unique: true },
9
+ codeFormat: { type: 'string', enum: ['qrcode', 'code128', 'code39', 'ean13', 'ean8', 'upc_a', 'itf', 'pdf417', 'datamatrix', 'aztec'], default: 'qrcode' },
10
+ clientName: { type: 'string', required: true },
11
+ activityName: { type: 'string', required: true },
12
+ validityMode: { type: 'string', required: true },
13
+ validUntil: { type: 'date', default: null },
14
+ status: { type: 'string', enum: ['active', 'used', 'expired', 'cancelled'], default: 'active' },
15
+ scannedAt: { type: 'date', default: null },
16
+ amount: { type: 'number', required: true, default: 0 },
17
+ currency: { type: 'string', default: 'DA' },
18
+ printCount: { type: 'number', default: 0 },
19
+ },
20
+ relations: {
21
+ client: { target: 'Client', type: 'many-to-one', required: true },
22
+ clientAccess: { target: 'ClientAccess', type: 'many-to-one', required: true },
23
+ activity: { target: 'Activity', type: 'many-to-one', required: true },
24
+ sourceClient: { target: 'Client', type: 'many-to-one', nullable: true },
25
+ scannedBy: { target: 'User', type: 'many-to-one', nullable: true },
26
+ createdBy: { target: 'User', type: 'many-to-one', required: true },
27
+ },
28
+ indexes: [
29
+ { fields: { client: 'asc' } },
30
+ { fields: { status: 'asc' } },
31
+ { fields: { validUntil: 'asc' } },
32
+ { fields: { codeFormat: 'asc' } },
33
+ ],
34
+ };
35
+ //# sourceMappingURL=ticket.schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket.schema.js","sourceRoot":"","sources":["../../schemas/ticket.schema.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,YAAY,GAAiB;IACxC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,IAAI;IAEhB,MAAM,EAAE;QACN,YAAY,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE;QAC/C,UAAU,EAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE;QACtD,IAAI,EAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE;QAC/C,UAAU,EAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE;QAC7J,UAAU,EAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QACjD,YAAY,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QACjD,YAAY,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QACjD,UAAU,EAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QAC9C,MAAM,EAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE;QACtG,SAAS,EAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QAC9C,MAAM,EAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE;QAC7D,QAAQ,EAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE;QAChD,UAAU,EAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE;KAC9C;IAED,SAAS,EAAE;QACT,MAAM,EAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QACvE,YAAY,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC7E,QAAQ,EAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QACzE,YAAY,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QACvE,SAAS,EAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;QACrE,SAAS,EAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE;KACtE;IAED,OAAO,EAAE;QACP,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;QAC7B,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;QAC7B,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE;QACjC,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE;KAClC;CACF,CAAC"}
@@ -0,0 +1,99 @@
1
+ export type CodeFormat = 'qrcode' | 'code128' | 'code39' | 'ean13' | 'ean8' | 'upc_a' | 'itf' | 'pdf417' | 'datamatrix' | 'aztec';
2
+ export type ValidityMode = 'day_reentry' | 'single_use' | 'time_slot' | 'unlimited';
3
+ export type TicketStatus = 'active' | 'used' | 'expired' | 'cancelled';
4
+ export type ScanResult = 'granted' | 'denied';
5
+ export type ScanMethod = 'webcam' | 'pwa_camera' | 'handheld_scanner' | 'nfc';
6
+ export type AccessType = 'unlimited' | 'count' | 'temporal' | 'mixed';
7
+ export type AccessStatus = 'active' | 'expired' | 'blocked' | 'depleted';
8
+ export type ActivityStatus = 'active' | 'inactive' | 'maintenance';
9
+ export type PlanType = 'temporal' | 'usage' | 'mixed';
10
+ export type DenyReason = 'invalid_ticket' | 'ticket_already_used' | 'ticket_expired' | 'ticket_cancelled' | 'quota_depleted' | 'access_expired' | 'client_suspended';
11
+ export interface ScanInput {
12
+ code: string;
13
+ scanMethod?: ScanMethod;
14
+ scannedBy: string;
15
+ }
16
+ export interface ScanGrantedResult {
17
+ result: 'granted';
18
+ isReentry: boolean;
19
+ ticket: TicketInfo;
20
+ client: ClientInfo;
21
+ access: AccessInfo;
22
+ }
23
+ export interface ScanDeniedResult {
24
+ result: 'denied';
25
+ reason: DenyReason;
26
+ ticket?: TicketInfo;
27
+ }
28
+ export type ScanOutput = ScanGrantedResult | ScanDeniedResult;
29
+ export interface TicketInfo {
30
+ ticketNumber: string;
31
+ clientName: string;
32
+ activityName: string;
33
+ ticketType: string;
34
+ validityMode: string;
35
+ status: string;
36
+ }
37
+ export interface ClientInfo {
38
+ id: string;
39
+ name: string;
40
+ clientNumber?: string;
41
+ photo?: string;
42
+ [key: string]: unknown;
43
+ }
44
+ export interface AccessInfo {
45
+ remainingQuota: number | null;
46
+ totalQuota: number | null;
47
+ endDate: string | null;
48
+ status: AccessStatus;
49
+ }
50
+ export interface CreateTicketInput {
51
+ clientId: string;
52
+ activityId: string;
53
+ ticketType?: string;
54
+ sourceClientId?: string;
55
+ amount?: number;
56
+ codeFormat?: CodeFormat;
57
+ }
58
+ export interface ScanHandlerConfig {
59
+ getRepositories: () => Promise<{
60
+ ticketRepo: any;
61
+ clientAccessRepo: any;
62
+ scanLogRepo: any;
63
+ clientRepo: any;
64
+ }>;
65
+ checkAuth: (req: Request) => Promise<{
66
+ error: Response | null;
67
+ userId: string;
68
+ }>;
69
+ onGranted?: (data: {
70
+ ticket: any;
71
+ client: any;
72
+ access: any;
73
+ isReentry: boolean;
74
+ userId: string;
75
+ }) => Promise<void>;
76
+ onDenied?: (data: {
77
+ reason: string;
78
+ ticket?: any;
79
+ userId: string;
80
+ }) => Promise<void>;
81
+ }
82
+ export interface TicketsHandlerConfig {
83
+ getRepositories: () => Promise<{
84
+ ticketRepo: any;
85
+ clientRepo: any;
86
+ clientAccessRepo: any;
87
+ activityRepo: any;
88
+ }>;
89
+ checkAuth: (req: Request, permission: string) => Promise<{
90
+ error: Response | null;
91
+ userId: string;
92
+ }>;
93
+ onCreated?: (data: {
94
+ ticket: any;
95
+ userId: string;
96
+ }) => Promise<void>;
97
+ defaultCodeFormat?: CodeFormat;
98
+ }
99
+ //# sourceMappingURL=index.d.ts.map