@webwaka/core 1.3.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 (151) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/ai.d.ts +25 -0
  3. package/dist/ai.d.ts.map +1 -0
  4. package/dist/ai.js +53 -0
  5. package/dist/ai.js.map +1 -0
  6. package/dist/core/ai/AIEngine.d.ts +69 -0
  7. package/dist/core/ai/AIEngine.d.ts.map +1 -0
  8. package/dist/core/ai/AIEngine.js +185 -0
  9. package/dist/core/ai/AIEngine.js.map +1 -0
  10. package/dist/core/auth/index.d.ts +183 -0
  11. package/dist/core/auth/index.d.ts.map +1 -0
  12. package/dist/core/auth/index.js +369 -0
  13. package/dist/core/auth/index.js.map +1 -0
  14. package/dist/core/billing/index.d.ts +52 -0
  15. package/dist/core/billing/index.d.ts.map +1 -0
  16. package/dist/core/billing/index.js +91 -0
  17. package/dist/core/billing/index.js.map +1 -0
  18. package/dist/core/booking/index.d.ts +38 -0
  19. package/dist/core/booking/index.d.ts.map +1 -0
  20. package/dist/core/booking/index.js +60 -0
  21. package/dist/core/booking/index.js.map +1 -0
  22. package/dist/core/chat/index.d.ts +48 -0
  23. package/dist/core/chat/index.d.ts.map +1 -0
  24. package/dist/core/chat/index.js +83 -0
  25. package/dist/core/chat/index.js.map +1 -0
  26. package/dist/core/document/index.d.ts +41 -0
  27. package/dist/core/document/index.d.ts.map +1 -0
  28. package/dist/core/document/index.js +68 -0
  29. package/dist/core/document/index.js.map +1 -0
  30. package/dist/core/events/index.d.ts +64 -0
  31. package/dist/core/events/index.d.ts.map +1 -0
  32. package/dist/core/events/index.js +60 -0
  33. package/dist/core/events/index.js.map +1 -0
  34. package/dist/core/geolocation/index.d.ts +32 -0
  35. package/dist/core/geolocation/index.d.ts.map +1 -0
  36. package/dist/core/geolocation/index.js +50 -0
  37. package/dist/core/geolocation/index.js.map +1 -0
  38. package/dist/core/kyc/index.d.ts +37 -0
  39. package/dist/core/kyc/index.d.ts.map +1 -0
  40. package/dist/core/kyc/index.js +60 -0
  41. package/dist/core/kyc/index.js.map +1 -0
  42. package/dist/core/logger/index.d.ts +60 -0
  43. package/dist/core/logger/index.d.ts.map +1 -0
  44. package/dist/core/logger/index.js +91 -0
  45. package/dist/core/logger/index.js.map +1 -0
  46. package/dist/core/notifications/index.d.ts +41 -0
  47. package/dist/core/notifications/index.d.ts.map +1 -0
  48. package/dist/core/notifications/index.js +111 -0
  49. package/dist/core/notifications/index.js.map +1 -0
  50. package/dist/core/rbac/index.d.ts +43 -0
  51. package/dist/core/rbac/index.d.ts.map +1 -0
  52. package/dist/core/rbac/index.js +66 -0
  53. package/dist/core/rbac/index.js.map +1 -0
  54. package/dist/events.d.ts +23 -0
  55. package/dist/events.d.ts.map +1 -0
  56. package/dist/events.js +22 -0
  57. package/dist/events.js.map +1 -0
  58. package/dist/index.d.ts +33 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +56 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/kyc.d.ts +12 -0
  63. package/dist/kyc.d.ts.map +1 -0
  64. package/dist/kyc.js +2 -0
  65. package/dist/kyc.js.map +1 -0
  66. package/dist/nanoid.d.ts +8 -0
  67. package/dist/nanoid.d.ts.map +1 -0
  68. package/dist/nanoid.js +15 -0
  69. package/dist/nanoid.js.map +1 -0
  70. package/dist/ndpr.d.ts +13 -0
  71. package/dist/ndpr.d.ts.map +1 -0
  72. package/dist/ndpr.js +19 -0
  73. package/dist/ndpr.js.map +1 -0
  74. package/dist/optimistic-lock.d.ts +11 -0
  75. package/dist/optimistic-lock.d.ts.map +1 -0
  76. package/dist/optimistic-lock.js +24 -0
  77. package/dist/optimistic-lock.js.map +1 -0
  78. package/dist/payment.d.ts +41 -0
  79. package/dist/payment.d.ts.map +1 -0
  80. package/dist/payment.js +116 -0
  81. package/dist/payment.js.map +1 -0
  82. package/dist/pin.d.ts +6 -0
  83. package/dist/pin.d.ts.map +1 -0
  84. package/dist/pin.js +18 -0
  85. package/dist/pin.js.map +1 -0
  86. package/dist/query-helpers.d.ts +18 -0
  87. package/dist/query-helpers.d.ts.map +1 -0
  88. package/dist/query-helpers.js +22 -0
  89. package/dist/query-helpers.js.map +1 -0
  90. package/dist/rate-limit.d.ts +13 -0
  91. package/dist/rate-limit.d.ts.map +1 -0
  92. package/dist/rate-limit.js +16 -0
  93. package/dist/rate-limit.js.map +1 -0
  94. package/dist/sms.d.ts +23 -0
  95. package/dist/sms.d.ts.map +1 -0
  96. package/dist/sms.js +60 -0
  97. package/dist/sms.js.map +1 -0
  98. package/dist/tax.d.ts +25 -0
  99. package/dist/tax.d.ts.map +1 -0
  100. package/dist/tax.js +31 -0
  101. package/dist/tax.js.map +1 -0
  102. package/package.json +99 -0
  103. package/src/ai.test.ts +146 -0
  104. package/src/ai.ts +75 -0
  105. package/src/core/ai/AIEngine.test.ts +386 -0
  106. package/src/core/ai/AIEngine.ts +281 -0
  107. package/src/core/auth/index.test.ts +268 -0
  108. package/src/core/auth/index.ts +570 -0
  109. package/src/core/billing/index.test.ts +154 -0
  110. package/src/core/billing/index.ts +132 -0
  111. package/src/core/booking/index.test.ts +153 -0
  112. package/src/core/booking/index.ts +91 -0
  113. package/src/core/chat/index.test.ts +159 -0
  114. package/src/core/chat/index.ts +130 -0
  115. package/src/core/document/index.test.ts +106 -0
  116. package/src/core/document/index.ts +99 -0
  117. package/src/core/events/index.test.ts +91 -0
  118. package/src/core/events/index.ts +91 -0
  119. package/src/core/geolocation/index.test.ts +70 -0
  120. package/src/core/geolocation/index.ts +69 -0
  121. package/src/core/kyc/index.test.ts +105 -0
  122. package/src/core/kyc/index.ts +86 -0
  123. package/src/core/logger/index.test.ts +110 -0
  124. package/src/core/logger/index.ts +127 -0
  125. package/src/core/notifications/index.test.ts +85 -0
  126. package/src/core/notifications/index.ts +136 -0
  127. package/src/core/rbac/index.test.ts +81 -0
  128. package/src/core/rbac/index.ts +85 -0
  129. package/src/events.test.ts +43 -0
  130. package/src/events.ts +23 -0
  131. package/src/index.test.ts +123 -0
  132. package/src/index.ts +97 -0
  133. package/src/kyc.ts +23 -0
  134. package/src/nanoid.test.ts +43 -0
  135. package/src/nanoid.ts +16 -0
  136. package/src/ndpr.test.ts +68 -0
  137. package/src/ndpr.ts +49 -0
  138. package/src/optimistic-lock.test.ts +75 -0
  139. package/src/optimistic-lock.ts +36 -0
  140. package/src/payment.test.ts +152 -0
  141. package/src/payment.ts +163 -0
  142. package/src/pin.test.ts +57 -0
  143. package/src/pin.ts +38 -0
  144. package/src/query-helpers.test.ts +98 -0
  145. package/src/query-helpers.ts +36 -0
  146. package/src/rate-limit.test.ts +98 -0
  147. package/src/rate-limit.ts +33 -0
  148. package/src/sms.test.ts +112 -0
  149. package/src/sms.ts +85 -0
  150. package/src/tax.test.ts +85 -0
  151. package/src/tax.ts +57 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ * CORE-13: Real-Time Chat & Communication
3
+ * Blueprint Reference: Part 10 (All Verticals)
4
+ *
5
+ * In-app messaging system with offline sync support.
6
+ *
7
+ * Tenant Isolation: every mutating and querying method requires a tenantId.
8
+ * Channels and messages are scoped per tenant — cross-tenant leakage is impossible
9
+ * by construction.
10
+ */
11
+ export interface Message {
12
+ id: string;
13
+ tenantId: string;
14
+ channelId: string;
15
+ senderId: string;
16
+ content: string;
17
+ type: 'text' | 'image' | 'system';
18
+ status: 'sent' | 'delivered' | 'read';
19
+ createdAt: Date;
20
+ }
21
+ export interface ChatChannel {
22
+ id: string;
23
+ tenantId: string;
24
+ participants: string[];
25
+ metadata: Record<string, any>;
26
+ createdAt: Date;
27
+ }
28
+ export declare class ChatEngine {
29
+ private channels;
30
+ private messages;
31
+ /**
32
+ * Creates a new chat channel between participants within a tenant.
33
+ */
34
+ createChannel(tenantId: string, participants: string[], metadata?: Record<string, any>): ChatChannel;
35
+ /**
36
+ * Sends a message to a channel, validating the channel belongs to the tenant.
37
+ */
38
+ sendMessage(tenantId: string, channelId: string, senderId: string, content: string, type?: 'text' | 'image' | 'system'): Message;
39
+ /**
40
+ * Retrieves messages for a channel, scoped to the tenant.
41
+ */
42
+ getMessages(tenantId: string, channelId: string, limit?: number, offset?: number): Message[];
43
+ /**
44
+ * Marks messages as read, scoped to the tenant.
45
+ */
46
+ markAsRead(tenantId: string, channelId: string, messageIds: string[]): void;
47
+ }
48
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/chat/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAClC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACtC,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,QAAQ,CAAqC;IAErD;;OAEG;IACH,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EAAE,EACtB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GACjC,WAAW;IAiBd;;OAEG;IACH,WAAW,CACT,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,GAAG,OAAO,GAAG,QAAiB,GACzC,OAAO;IA8BV;;OAEG;IACH,WAAW,CACT,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,SAAK,EACV,MAAM,SAAI,GACT,OAAO,EAAE;IAUZ;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;CAW5E"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * CORE-13: Real-Time Chat & Communication
3
+ * Blueprint Reference: Part 10 (All Verticals)
4
+ *
5
+ * In-app messaging system with offline sync support.
6
+ *
7
+ * Tenant Isolation: every mutating and querying method requires a tenantId.
8
+ * Channels and messages are scoped per tenant — cross-tenant leakage is impossible
9
+ * by construction.
10
+ */
11
+ export class ChatEngine {
12
+ channels = new Map();
13
+ messages = new Map();
14
+ /**
15
+ * Creates a new chat channel between participants within a tenant.
16
+ */
17
+ createChannel(tenantId, participants, metadata = {}) {
18
+ const channel = {
19
+ id: `ch_${crypto.randomUUID()}`,
20
+ tenantId,
21
+ participants,
22
+ metadata,
23
+ createdAt: new Date(),
24
+ };
25
+ this.channels.set(channel.id, channel);
26
+ this.messages.set(channel.id, []);
27
+ // eventBus.publish(WebWakaEventType.CHAT_CHANNEL_CREATED, createEvent(WebWakaEventType.CHAT_CHANNEL_CREATED, tenantId, channel));
28
+ return channel;
29
+ }
30
+ /**
31
+ * Sends a message to a channel, validating the channel belongs to the tenant.
32
+ */
33
+ sendMessage(tenantId, channelId, senderId, content, type = 'text') {
34
+ const channel = this.channels.get(channelId);
35
+ if (!channel || channel.tenantId !== tenantId) {
36
+ throw new Error('Channel not found');
37
+ }
38
+ if (!channel.participants.includes(senderId) && type !== 'system') {
39
+ throw new Error('Sender is not a participant in this channel');
40
+ }
41
+ const message = {
42
+ id: `msg_${crypto.randomUUID()}`,
43
+ tenantId,
44
+ channelId,
45
+ senderId,
46
+ content,
47
+ type,
48
+ status: 'sent',
49
+ createdAt: new Date(),
50
+ };
51
+ const channelMessages = this.messages.get(channelId) ?? [];
52
+ channelMessages.push(message);
53
+ this.messages.set(channelId, channelMessages);
54
+ // eventBus.publish(WebWakaEventType.CHAT_MESSAGE_SENT, createEvent(WebWakaEventType.CHAT_MESSAGE_SENT, tenantId, message));
55
+ return message;
56
+ }
57
+ /**
58
+ * Retrieves messages for a channel, scoped to the tenant.
59
+ */
60
+ getMessages(tenantId, channelId, limit = 50, offset = 0) {
61
+ const channel = this.channels.get(channelId);
62
+ if (!channel || channel.tenantId !== tenantId) {
63
+ return [];
64
+ }
65
+ const channelMessages = this.messages.get(channelId) ?? [];
66
+ return [...channelMessages].reverse().slice(offset, offset + limit);
67
+ }
68
+ /**
69
+ * Marks messages as read, scoped to the tenant.
70
+ */
71
+ markAsRead(tenantId, channelId, messageIds) {
72
+ const channel = this.channels.get(channelId);
73
+ if (!channel || channel.tenantId !== tenantId)
74
+ return;
75
+ const channelMessages = this.messages.get(channelId) ?? [];
76
+ for (const msg of channelMessages) {
77
+ if (messageIds.includes(msg.id)) {
78
+ msg.status = 'read';
79
+ }
80
+ }
81
+ }
82
+ }
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/chat/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * CORE-11: Document & Contract Management
3
+ * Blueprint Reference: Part 10.5 (Real Estate), Part 10.12 (Legal)
4
+ *
5
+ * Secure system for generating, signing, and storing legal documents.
6
+ *
7
+ * Tenant Isolation: every mutating and querying method requires a tenantId.
8
+ * Documents are scoped per tenant — cross-tenant leakage is impossible by construction.
9
+ */
10
+ export interface Document {
11
+ id: string;
12
+ tenantId: string;
13
+ title: string;
14
+ content: string;
15
+ status: 'draft' | 'pending_signature' | 'signed';
16
+ signatures: Signature[];
17
+ createdAt: Date;
18
+ }
19
+ export interface Signature {
20
+ userId: string;
21
+ timestamp: Date;
22
+ ipAddress: string;
23
+ hash: string;
24
+ }
25
+ export declare class DocumentEngine {
26
+ private documents;
27
+ /**
28
+ * Creates a new document from a template, scoped to the tenant.
29
+ */
30
+ createDocument(tenantId: string, title: string, content: string): Document;
31
+ /**
32
+ * Requests signatures for a document, scoped to the tenant.
33
+ */
34
+ requestSignatures(tenantId: string, documentId: string): Document;
35
+ /**
36
+ * Signs a document, scoped to the tenant.
37
+ */
38
+ signDocument(tenantId: string, documentId: string, userId: string, ipAddress: string): Document;
39
+ private generateSignatureHash;
40
+ }
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/document/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,mBAAmB,GAAG,QAAQ,CAAC;IACjD,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAoC;IAErD;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ;IAc1E;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,QAAQ;IAYjE;;OAEG;IACH,YAAY,CACV,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,QAAQ;IAyBX,OAAO,CAAC,qBAAqB;CAG9B"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * CORE-11: Document & Contract Management
3
+ * Blueprint Reference: Part 10.5 (Real Estate), Part 10.12 (Legal)
4
+ *
5
+ * Secure system for generating, signing, and storing legal documents.
6
+ *
7
+ * Tenant Isolation: every mutating and querying method requires a tenantId.
8
+ * Documents are scoped per tenant — cross-tenant leakage is impossible by construction.
9
+ */
10
+ export class DocumentEngine {
11
+ documents = new Map();
12
+ /**
13
+ * Creates a new document from a template, scoped to the tenant.
14
+ */
15
+ createDocument(tenantId, title, content) {
16
+ const doc = {
17
+ id: `doc_${crypto.randomUUID()}`,
18
+ tenantId,
19
+ title,
20
+ content,
21
+ status: 'draft',
22
+ signatures: [],
23
+ createdAt: new Date(),
24
+ };
25
+ this.documents.set(doc.id, doc);
26
+ return doc;
27
+ }
28
+ /**
29
+ * Requests signatures for a document, scoped to the tenant.
30
+ */
31
+ requestSignatures(tenantId, documentId) {
32
+ const doc = this.documents.get(documentId);
33
+ if (!doc || doc.tenantId !== tenantId)
34
+ throw new Error('Document not found');
35
+ if (doc.status !== 'draft') {
36
+ throw new Error('Document must be in draft status to request signatures');
37
+ }
38
+ doc.status = 'pending_signature';
39
+ return doc;
40
+ }
41
+ /**
42
+ * Signs a document, scoped to the tenant.
43
+ */
44
+ signDocument(tenantId, documentId, userId, ipAddress) {
45
+ const doc = this.documents.get(documentId);
46
+ if (!doc || doc.tenantId !== tenantId)
47
+ throw new Error('Document not found');
48
+ if (doc.status !== 'pending_signature') {
49
+ throw new Error('Document is not pending signature');
50
+ }
51
+ if (doc.signatures.some(s => s.userId === userId)) {
52
+ throw new Error('User has already signed this document');
53
+ }
54
+ const signature = {
55
+ userId,
56
+ timestamp: new Date(),
57
+ ipAddress,
58
+ hash: this.generateSignatureHash(doc.content, userId, ipAddress),
59
+ };
60
+ doc.signatures.push(signature);
61
+ doc.status = 'signed';
62
+ return doc;
63
+ }
64
+ generateSignatureHash(content, userId, ipAddress) {
65
+ return `hash_${userId}_${Date.now()}`;
66
+ }
67
+ }
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/document/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmBH,MAAM,OAAO,cAAc;IACjB,SAAS,GAA0B,IAAI,GAAG,EAAE,CAAC;IAErD;;OAEG;IACH,cAAc,CAAC,QAAgB,EAAE,KAAa,EAAE,OAAe;QAC7D,MAAM,GAAG,GAAa;YACpB,EAAE,EAAE,OAAO,MAAM,CAAC,UAAU,EAAE,EAAE;YAChC,QAAQ;YACR,KAAK;YACL,OAAO;YACP,MAAM,EAAE,OAAO;YACf,UAAU,EAAE,EAAE;YACd,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,QAAgB,EAAE,UAAkB;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAE7E,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;QAED,GAAG,CAAC,MAAM,GAAG,mBAAmB,CAAC;QACjC,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;OAEG;IACH,YAAY,CACV,QAAgB,EAChB,UAAkB,EAClB,MAAc,EACd,SAAiB;QAEjB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAE7E,IAAI,GAAG,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,SAAS,GAAc;YAC3B,MAAM;YACN,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,SAAS;YACT,IAAI,EAAE,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC;SACjE,CAAC;QAEF,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAC;QAEtB,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,qBAAqB,CAAC,OAAe,EAAE,MAAc,EAAE,SAAiB;QAC9E,OAAO,QAAQ,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * CORE-14: Event Bus Primitives
3
+ * Blueprint Reference: Part 2 (Platform Architecture — "Event-Driven: NO direct inter-DB access")
4
+ *
5
+ * Canonical event contracts for the entire WebWaka OS v4 platform.
6
+ * Every domain emits typed DomainEvents; consumers subscribe by event type.
7
+ *
8
+ * This module defines shapes and constants only.
9
+ * Actual queue/bus wiring (Cloudflare Queues) is a separate concern.
10
+ */
11
+ /**
12
+ * Well-known event type names for all WebWaka OS v4 domains.
13
+ *
14
+ * Consumers MUST use these constants — never raw string literals — so that
15
+ * renaming an event causes a compile-time error instead of a silent mismatch.
16
+ */
17
+ export declare enum WebWakaEventType {
18
+ AUTH_USER_LOGIN = "auth.user.login",
19
+ AUTH_USER_LOGOUT = "auth.user.logout",
20
+ AUTH_TOKEN_REFRESHED = "auth.token.refreshed",
21
+ KYC_SUBMITTED = "kyc.submitted",
22
+ KYC_VERIFIED = "kyc.verified",
23
+ KYC_REJECTED = "kyc.rejected",
24
+ BOOKING_CONFIRMED = "booking.confirmed",
25
+ BOOKING_CANCELLED = "booking.cancelled",
26
+ CHAT_MESSAGE_SENT = "chat.message.sent",
27
+ CHAT_CHANNEL_CREATED = "chat.channel.created",
28
+ DOCUMENT_CREATED = "document.created",
29
+ DOCUMENT_SIGNED = "document.signed",
30
+ BILLING_DEBIT_RECORDED = "billing.debit.recorded",
31
+ BILLING_CREDIT_RECORDED = "billing.credit.recorded",
32
+ NOTIFICATION_SENT = "notification.sent",
33
+ NOTIFICATION_FAILED = "notification.failed"
34
+ }
35
+ /**
36
+ * Envelope wrapping every domain event published on the platform bus.
37
+ *
38
+ * `type` is constrained to `WebWakaEventType` — arbitrary strings are rejected
39
+ * at compile time, preventing undeclared event names from entering the bus.
40
+ *
41
+ * @template T The event-specific payload type.
42
+ */
43
+ export interface DomainEvent<T = unknown> {
44
+ /** Unique event identifier (UUID v4). */
45
+ id: string;
46
+ /** Canonical event type — must be a WebWakaEventType constant. */
47
+ type: WebWakaEventType;
48
+ /** The tenant that owns this event. */
49
+ tenantId: string;
50
+ /** Wall-clock time the event was created. */
51
+ occurredAt: Date;
52
+ /** Domain-specific payload. */
53
+ payload: T;
54
+ }
55
+ /**
56
+ * Factory that creates a well-formed DomainEvent with a generated id and
57
+ * current timestamp.
58
+ *
59
+ * @param type A WebWakaEventType constant.
60
+ * @param tenantId Tenant that owns the event.
61
+ * @param payload Domain-specific payload.
62
+ */
63
+ export declare function createEvent<T>(type: WebWakaEventType, tenantId: string, payload: T): DomainEvent<T>;
64
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/events/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,oBAAY,gBAAgB;IAE1B,eAAe,oBAAoB;IACnC,gBAAgB,qBAAqB;IACrC,oBAAoB,yBAAyB;IAG7C,aAAa,kBAAkB;IAC/B,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAG7B,iBAAiB,sBAAsB;IACvC,iBAAiB,sBAAsB;IAGvC,iBAAiB,sBAAsB;IACvC,oBAAoB,yBAAyB;IAG7C,gBAAgB,qBAAqB;IACrC,eAAe,oBAAoB;IAGnC,sBAAsB,2BAA2B;IACjD,uBAAuB,4BAA4B;IAGnD,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;CAC5C;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,kEAAkE;IAClE,IAAI,EAAE,gBAAgB,CAAC;IACvB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,UAAU,EAAE,IAAI,CAAC;IACjB,+BAA+B;IAC/B,OAAO,EAAE,CAAC,CAAC;CACZ;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,IAAI,EAAE,gBAAgB,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,GACT,WAAW,CAAC,CAAC,CAAC,CAQhB"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * CORE-14: Event Bus Primitives
3
+ * Blueprint Reference: Part 2 (Platform Architecture — "Event-Driven: NO direct inter-DB access")
4
+ *
5
+ * Canonical event contracts for the entire WebWaka OS v4 platform.
6
+ * Every domain emits typed DomainEvents; consumers subscribe by event type.
7
+ *
8
+ * This module defines shapes and constants only.
9
+ * Actual queue/bus wiring (Cloudflare Queues) is a separate concern.
10
+ */
11
+ /**
12
+ * Well-known event type names for all WebWaka OS v4 domains.
13
+ *
14
+ * Consumers MUST use these constants — never raw string literals — so that
15
+ * renaming an event causes a compile-time error instead of a silent mismatch.
16
+ */
17
+ export var WebWakaEventType;
18
+ (function (WebWakaEventType) {
19
+ // ─── Auth ──────────────────────────────────────────────────────────────────
20
+ WebWakaEventType["AUTH_USER_LOGIN"] = "auth.user.login";
21
+ WebWakaEventType["AUTH_USER_LOGOUT"] = "auth.user.logout";
22
+ WebWakaEventType["AUTH_TOKEN_REFRESHED"] = "auth.token.refreshed";
23
+ // ─── KYC ───────────────────────────────────────────────────────────────────
24
+ WebWakaEventType["KYC_SUBMITTED"] = "kyc.submitted";
25
+ WebWakaEventType["KYC_VERIFIED"] = "kyc.verified";
26
+ WebWakaEventType["KYC_REJECTED"] = "kyc.rejected";
27
+ // ─── Booking ───────────────────────────────────────────────────────────────
28
+ WebWakaEventType["BOOKING_CONFIRMED"] = "booking.confirmed";
29
+ WebWakaEventType["BOOKING_CANCELLED"] = "booking.cancelled";
30
+ // ─── Chat ──────────────────────────────────────────────────────────────────
31
+ WebWakaEventType["CHAT_MESSAGE_SENT"] = "chat.message.sent";
32
+ WebWakaEventType["CHAT_CHANNEL_CREATED"] = "chat.channel.created";
33
+ // ─── Document ──────────────────────────────────────────────────────────────
34
+ WebWakaEventType["DOCUMENT_CREATED"] = "document.created";
35
+ WebWakaEventType["DOCUMENT_SIGNED"] = "document.signed";
36
+ // ─── Billing ───────────────────────────────────────────────────────────────
37
+ WebWakaEventType["BILLING_DEBIT_RECORDED"] = "billing.debit.recorded";
38
+ WebWakaEventType["BILLING_CREDIT_RECORDED"] = "billing.credit.recorded";
39
+ // ─── Notification ──────────────────────────────────────────────────────────
40
+ WebWakaEventType["NOTIFICATION_SENT"] = "notification.sent";
41
+ WebWakaEventType["NOTIFICATION_FAILED"] = "notification.failed";
42
+ })(WebWakaEventType || (WebWakaEventType = {}));
43
+ /**
44
+ * Factory that creates a well-formed DomainEvent with a generated id and
45
+ * current timestamp.
46
+ *
47
+ * @param type A WebWakaEventType constant.
48
+ * @param tenantId Tenant that owns the event.
49
+ * @param payload Domain-specific payload.
50
+ */
51
+ export function createEvent(type, tenantId, payload) {
52
+ return {
53
+ id: crypto.randomUUID(),
54
+ type,
55
+ tenantId,
56
+ occurredAt: new Date(),
57
+ payload,
58
+ };
59
+ }
60
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/events/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,MAAM,CAAN,IAAY,gBA8BX;AA9BD,WAAY,gBAAgB;IAC1B,8EAA8E;IAC9E,uDAAmC,CAAA;IACnC,yDAAqC,CAAA;IACrC,iEAA6C,CAAA;IAE7C,8EAA8E;IAC9E,mDAA+B,CAAA;IAC/B,iDAA6B,CAAA;IAC7B,iDAA6B,CAAA;IAE7B,8EAA8E;IAC9E,2DAAuC,CAAA;IACvC,2DAAuC,CAAA;IAEvC,8EAA8E;IAC9E,2DAAuC,CAAA;IACvC,iEAA6C,CAAA;IAE7C,8EAA8E;IAC9E,yDAAqC,CAAA;IACrC,uDAAmC,CAAA;IAEnC,8EAA8E;IAC9E,qEAAiD,CAAA;IACjD,uEAAmD,CAAA;IAEnD,8EAA8E;IAC9E,2DAAuC,CAAA;IACvC,+DAA2C,CAAA;AAC7C,CAAC,EA9BW,gBAAgB,KAAhB,gBAAgB,QA8B3B;AAuBD;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CACzB,IAAsB,EACtB,QAAgB,EAChB,OAAU;IAEV,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,IAAI;QACJ,QAAQ;QACR,UAAU,EAAE,IAAI,IAAI,EAAE;QACtB,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * CORE-9: Geolocation & Mapping Engine
3
+ * Blueprint Reference: Part 10.3 (Transport), Part 10.4 (Logistics)
4
+ *
5
+ * Vendor-neutral abstraction layer for maps, routing, and geocoding.
6
+ */
7
+ export interface Coordinates {
8
+ lat: number;
9
+ lng: number;
10
+ }
11
+ export interface Route {
12
+ distanceMeters: number;
13
+ durationSeconds: number;
14
+ polyline: string;
15
+ }
16
+ export declare class GeolocationEngine {
17
+ private provider;
18
+ constructor(provider?: 'google' | 'mapbox' | 'osm');
19
+ /**
20
+ * Calculates the distance and ETA between two points.
21
+ */
22
+ calculateRoute(origin: Coordinates, destination: Coordinates): Promise<Route>;
23
+ /**
24
+ * Checks if a coordinate is within a specific geofence (radius in meters).
25
+ */
26
+ isWithinGeofence(point: Coordinates, center: Coordinates, radiusMeters: number): boolean;
27
+ /**
28
+ * Haversine formula to calculate distance between two coordinates in meters.
29
+ */
30
+ private calculateStraightLineDistance;
31
+ }
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/geolocation/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,KAAK;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAA8B;gBAElC,QAAQ,GAAE,QAAQ,GAAG,QAAQ,GAAG,KAAa;IAIzD;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC;IAenF;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO;IAKxF;;OAEG;IACH,OAAO,CAAC,6BAA6B;CActC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * CORE-9: Geolocation & Mapping Engine
3
+ * Blueprint Reference: Part 10.3 (Transport), Part 10.4 (Logistics)
4
+ *
5
+ * Vendor-neutral abstraction layer for maps, routing, and geocoding.
6
+ */
7
+ export class GeolocationEngine {
8
+ provider;
9
+ constructor(provider = 'osm') {
10
+ this.provider = provider;
11
+ }
12
+ /**
13
+ * Calculates the distance and ETA between two points.
14
+ */
15
+ async calculateRoute(origin, destination) {
16
+ // In a real implementation, this would call the respective provider's API
17
+ // For now, we return a mock calculation based on straight-line distance
18
+ const distance = this.calculateStraightLineDistance(origin, destination);
19
+ // Assume average speed of 30 km/h (8.33 m/s) in city traffic
20
+ const duration = Math.floor(distance / 8.33);
21
+ return {
22
+ distanceMeters: Math.floor(distance),
23
+ durationSeconds: duration,
24
+ polyline: 'mock_polyline_data'
25
+ };
26
+ }
27
+ /**
28
+ * Checks if a coordinate is within a specific geofence (radius in meters).
29
+ */
30
+ isWithinGeofence(point, center, radiusMeters) {
31
+ const distance = this.calculateStraightLineDistance(point, center);
32
+ return distance <= radiusMeters;
33
+ }
34
+ /**
35
+ * Haversine formula to calculate distance between two coordinates in meters.
36
+ */
37
+ calculateStraightLineDistance(coord1, coord2) {
38
+ const R = 6371e3; // Earth's radius in meters
39
+ const φ1 = coord1.lat * Math.PI / 180;
40
+ const φ2 = coord2.lat * Math.PI / 180;
41
+ const Δφ = (coord2.lat - coord1.lat) * Math.PI / 180;
42
+ const Δλ = (coord2.lng - coord1.lng) * Math.PI / 180;
43
+ const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
44
+ Math.cos(φ1) * Math.cos(φ2) *
45
+ Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
46
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
47
+ return R * c;
48
+ }
49
+ }
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/geolocation/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,OAAO,iBAAiB;IACpB,QAAQ,CAA8B;IAE9C,YAAY,WAAwC,KAAK;QACvD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,MAAmB,EAAE,WAAwB;QAChE,0EAA0E;QAC1E,wEAAwE;QAExE,MAAM,QAAQ,GAAG,IAAI,CAAC,6BAA6B,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACzE,6DAA6D;QAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;QAE7C,OAAO;YACL,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YACpC,eAAe,EAAE,QAAQ;YACzB,QAAQ,EAAE,oBAAoB;SAC/B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,KAAkB,EAAE,MAAmB,EAAE,YAAoB;QAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,6BAA6B,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACnE,OAAO,QAAQ,IAAI,YAAY,CAAC;IAClC,CAAC;IAED;;OAEG;IACK,6BAA6B,CAAC,MAAmB,EAAE,MAAmB;QAC5E,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,2BAA2B;QAC7C,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;QACtC,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;QACtC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;QACrD,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;QAErD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAEzD,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * CORE-12: Universal KYC/KYB Verification
3
+ * Blueprint Reference: Part 10.11 (Fintech), Part 10.3 (Transport)
4
+ *
5
+ * Centralized identity verification system with Nigeria-First integrations.
6
+ *
7
+ * Tenant Isolation: every mutating and querying method requires a tenantId.
8
+ * KYC requests are scoped per tenant — cross-tenant leakage is impossible by construction.
9
+ */
10
+ export interface KYCRequest {
11
+ id: string;
12
+ tenantId: string;
13
+ userId: string;
14
+ documentType: 'NIN' | 'BVN' | 'PASSPORT' | 'DRIVERS_LICENSE';
15
+ documentNumber: string;
16
+ status: 'pending' | 'verified' | 'rejected';
17
+ verifiedAt?: Date;
18
+ rejectionReason?: string;
19
+ }
20
+ export declare class KYCEngine {
21
+ private requests;
22
+ /**
23
+ * Submits a new KYC verification request, scoped to the tenant.
24
+ */
25
+ submitVerification(tenantId: string, userId: string, documentType: 'NIN' | 'BVN' | 'PASSPORT' | 'DRIVERS_LICENSE', documentNumber: string): KYCRequest;
26
+ /**
27
+ * Processes a verification request, scoped to the tenant.
28
+ * Mocks external API calls to NIMC (NIN) / NIBSS (BVN).
29
+ */
30
+ processVerification(tenantId: string, requestId: string): Promise<KYCRequest>;
31
+ /**
32
+ * Retrieves all verification requests for a user, scoped to the tenant.
33
+ */
34
+ getUserVerificationStatus(tenantId: string, userId: string): KYCRequest[];
35
+ private mockExternalVerification;
36
+ }
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/kyc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,KAAK,GAAG,KAAK,GAAG,UAAU,GAAG,iBAAiB,CAAC;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;IAC5C,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAsC;IAEtD;;OAEG;IACH,kBAAkB,CAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,KAAK,GAAG,KAAK,GAAG,UAAU,GAAG,iBAAiB,EAC5D,cAAc,EAAE,MAAM,GACrB,UAAU;IAcb;;;OAGG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAuBnF;;OAEG;IACH,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;IAMzE,OAAO,CAAC,wBAAwB;CAGjC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * CORE-12: Universal KYC/KYB Verification
3
+ * Blueprint Reference: Part 10.11 (Fintech), Part 10.3 (Transport)
4
+ *
5
+ * Centralized identity verification system with Nigeria-First integrations.
6
+ *
7
+ * Tenant Isolation: every mutating and querying method requires a tenantId.
8
+ * KYC requests are scoped per tenant — cross-tenant leakage is impossible by construction.
9
+ */
10
+ export class KYCEngine {
11
+ requests = new Map();
12
+ /**
13
+ * Submits a new KYC verification request, scoped to the tenant.
14
+ */
15
+ submitVerification(tenantId, userId, documentType, documentNumber) {
16
+ const request = {
17
+ id: `kyc_${crypto.randomUUID()}`,
18
+ tenantId,
19
+ userId,
20
+ documentType,
21
+ documentNumber,
22
+ status: 'pending',
23
+ };
24
+ this.requests.set(request.id, request);
25
+ return request;
26
+ }
27
+ /**
28
+ * Processes a verification request, scoped to the tenant.
29
+ * Mocks external API calls to NIMC (NIN) / NIBSS (BVN).
30
+ */
31
+ async processVerification(tenantId, requestId) {
32
+ const request = this.requests.get(requestId);
33
+ if (!request || request.tenantId !== tenantId) {
34
+ throw new Error('KYC request not found');
35
+ }
36
+ if (request.status !== 'pending') {
37
+ throw new Error('Request is already processed');
38
+ }
39
+ const isValid = this.mockExternalVerification(request.documentNumber);
40
+ if (isValid) {
41
+ request.status = 'verified';
42
+ request.verifiedAt = new Date();
43
+ }
44
+ else {
45
+ request.status = 'rejected';
46
+ request.rejectionReason = 'Document verification failed against national database';
47
+ }
48
+ return request;
49
+ }
50
+ /**
51
+ * Retrieves all verification requests for a user, scoped to the tenant.
52
+ */
53
+ getUserVerificationStatus(tenantId, userId) {
54
+ return Array.from(this.requests.values()).filter(r => r.tenantId === tenantId && r.userId === userId);
55
+ }
56
+ mockExternalVerification(documentNumber) {
57
+ return !documentNumber.startsWith('000');
58
+ }
59
+ }
60
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/kyc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,MAAM,OAAO,SAAS;IACZ,QAAQ,GAA4B,IAAI,GAAG,EAAE,CAAC;IAEtD;;OAEG;IACH,kBAAkB,CAChB,QAAgB,EAChB,MAAc,EACd,YAA4D,EAC5D,cAAsB;QAEtB,MAAM,OAAO,GAAe;YAC1B,EAAE,EAAE,OAAO,MAAM,CAAC,UAAU,EAAE,EAAE;YAChC,QAAQ;YACR,MAAM;YACN,YAAY;YACZ,cAAc;YACd,MAAM,EAAE,SAAS;SAClB,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACvC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,mBAAmB,CAAC,QAAgB,EAAE,SAAiB;QAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEtE,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC;YAC5B,OAAO,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC;YAC5B,OAAO,CAAC,eAAe,GAAG,wDAAwD,CAAC;QACrF,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,yBAAyB,CAAC,QAAgB,EAAE,MAAc;QACxD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAC9C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CACpD,CAAC;IACJ,CAAC;IAEO,wBAAwB,CAAC,cAAsB;QACrD,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;CACF"}