@porulle/core 0.1.0 → 0.5.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 (165) hide show
  1. package/dist/auth/middleware.d.ts.map +1 -1
  2. package/dist/auth/middleware.js +17 -1
  3. package/dist/config/define-config.d.ts.map +1 -1
  4. package/dist/config/define-config.js +6 -0
  5. package/dist/config/types.d.ts +12 -0
  6. package/dist/config/types.d.ts.map +1 -1
  7. package/dist/hooks/checkout.d.ts +3 -3
  8. package/dist/hooks/checkout.js +4 -4
  9. package/dist/index.d.ts +9 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +6 -1
  12. package/dist/interfaces/rest/audit-middleware.d.ts +46 -0
  13. package/dist/interfaces/rest/audit-middleware.d.ts.map +1 -0
  14. package/dist/interfaces/rest/audit-middleware.js +82 -0
  15. package/dist/interfaces/rest/parse-json.d.ts +39 -0
  16. package/dist/interfaces/rest/parse-json.d.ts.map +1 -0
  17. package/dist/interfaces/rest/parse-json.js +45 -0
  18. package/dist/interfaces/rest/routes/catalog.d.ts.map +1 -1
  19. package/dist/interfaces/rest/routes/catalog.js +17 -2
  20. package/dist/interfaces/rest/routes/customers.d.ts.map +1 -1
  21. package/dist/interfaces/rest/routes/customers.js +59 -4
  22. package/dist/interfaces/rest/routes/inventory.d.ts.map +1 -1
  23. package/dist/interfaces/rest/routes/inventory.js +4 -2
  24. package/dist/interfaces/rest/routes/media.d.ts.map +1 -1
  25. package/dist/interfaces/rest/routes/media.js +6 -0
  26. package/dist/interfaces/rest/routes/orders.d.ts.map +1 -1
  27. package/dist/interfaces/rest/routes/orders.js +23 -1
  28. package/dist/interfaces/rest/routes/promotions.d.ts.map +1 -1
  29. package/dist/interfaces/rest/routes/promotions.js +21 -1
  30. package/dist/interfaces/rest/schemas/carts.d.ts +175 -0
  31. package/dist/interfaces/rest/schemas/carts.d.ts.map +1 -1
  32. package/dist/interfaces/rest/schemas/catalog.d.ts +1410 -0
  33. package/dist/interfaces/rest/schemas/catalog.d.ts.map +1 -1
  34. package/dist/interfaces/rest/schemas/catalog.js +28 -1
  35. package/dist/interfaces/rest/schemas/checkout.d.ts +35 -0
  36. package/dist/interfaces/rest/schemas/checkout.d.ts.map +1 -1
  37. package/dist/interfaces/rest/schemas/customer-portal.d.ts +280 -0
  38. package/dist/interfaces/rest/schemas/customer-portal.d.ts.map +1 -1
  39. package/dist/interfaces/rest/schemas/customers.d.ts +863 -0
  40. package/dist/interfaces/rest/schemas/customers.d.ts.map +1 -1
  41. package/dist/interfaces/rest/schemas/customers.js +88 -0
  42. package/dist/interfaces/rest/schemas/inventory.d.ts +182 -1
  43. package/dist/interfaces/rest/schemas/inventory.d.ts.map +1 -1
  44. package/dist/interfaces/rest/schemas/media.d.ts +105 -0
  45. package/dist/interfaces/rest/schemas/media.d.ts.map +1 -1
  46. package/dist/interfaces/rest/schemas/orders.d.ts +136 -0
  47. package/dist/interfaces/rest/schemas/orders.d.ts.map +1 -1
  48. package/dist/interfaces/rest/schemas/orders.js +20 -0
  49. package/dist/interfaces/rest/schemas/pricing.d.ts +70 -0
  50. package/dist/interfaces/rest/schemas/pricing.d.ts.map +1 -1
  51. package/dist/interfaces/rest/schemas/promotions.d.ts +298 -0
  52. package/dist/interfaces/rest/schemas/promotions.d.ts.map +1 -1
  53. package/dist/interfaces/rest/schemas/promotions.js +25 -1
  54. package/dist/interfaces/rest/schemas/shared.d.ts +47 -0
  55. package/dist/interfaces/rest/schemas/shared.d.ts.map +1 -1
  56. package/dist/interfaces/rest/schemas/shared.js +8 -0
  57. package/dist/interfaces/rest/schemas/webhooks.d.ts +70 -0
  58. package/dist/interfaces/rest/schemas/webhooks.d.ts.map +1 -1
  59. package/dist/kernel/database/adapter.d.ts +6 -0
  60. package/dist/kernel/database/adapter.d.ts.map +1 -1
  61. package/dist/kernel/database/adapter.js +62 -1
  62. package/dist/kernel/database/migrate.d.ts +22 -2
  63. package/dist/kernel/database/migrate.d.ts.map +1 -1
  64. package/dist/kernel/database/migrate.js +42 -2
  65. package/dist/modules/analytics/hooks.d.ts +5 -5
  66. package/dist/modules/analytics/hooks.js +5 -5
  67. package/dist/modules/analytics/repository/index.d.ts.map +1 -1
  68. package/dist/modules/catalog/category-service.d.ts +6 -1
  69. package/dist/modules/catalog/category-service.d.ts.map +1 -1
  70. package/dist/modules/catalog/category-service.js +35 -5
  71. package/dist/modules/catalog/schema.d.ts +17 -0
  72. package/dist/modules/catalog/schema.d.ts.map +1 -1
  73. package/dist/modules/catalog/schema.js +2 -0
  74. package/dist/modules/catalog/service.d.ts +11 -2
  75. package/dist/modules/catalog/service.d.ts.map +1 -1
  76. package/dist/modules/catalog/service.js +8 -2
  77. package/dist/modules/customers/repository/index.d.ts +8 -1
  78. package/dist/modules/customers/repository/index.d.ts.map +1 -1
  79. package/dist/modules/customers/repository/index.js +42 -2
  80. package/dist/modules/customers/schema.d.ts +162 -0
  81. package/dist/modules/customers/schema.d.ts.map +1 -1
  82. package/dist/modules/customers/schema.js +18 -0
  83. package/dist/modules/customers/service.d.ts +32 -2
  84. package/dist/modules/customers/service.d.ts.map +1 -1
  85. package/dist/modules/customers/service.js +119 -3
  86. package/dist/modules/inventory/schemas.d.ts +7 -1
  87. package/dist/modules/inventory/schemas.d.ts.map +1 -1
  88. package/dist/modules/inventory/schemas.js +6 -1
  89. package/dist/modules/inventory/service.d.ts +18 -0
  90. package/dist/modules/inventory/service.d.ts.map +1 -1
  91. package/dist/modules/inventory/service.js +58 -21
  92. package/dist/modules/media/noop-adapter.d.ts +11 -0
  93. package/dist/modules/media/noop-adapter.d.ts.map +1 -0
  94. package/dist/modules/media/noop-adapter.js +31 -0
  95. package/dist/modules/orders/repository/index.d.ts +19 -0
  96. package/dist/modules/orders/repository/index.d.ts.map +1 -1
  97. package/dist/modules/orders/repository/index.js +42 -1
  98. package/dist/modules/orders/service.d.ts +31 -0
  99. package/dist/modules/orders/service.d.ts.map +1 -1
  100. package/dist/modules/orders/service.js +52 -2
  101. package/dist/modules/payments/repository/index.d.ts.map +1 -1
  102. package/dist/modules/promotions/schemas.d.ts +46 -0
  103. package/dist/modules/promotions/schemas.d.ts.map +1 -1
  104. package/dist/modules/promotions/schemas.js +19 -8
  105. package/dist/modules/promotions/service.d.ts +8 -2
  106. package/dist/modules/promotions/service.d.ts.map +1 -1
  107. package/dist/modules/promotions/service.js +74 -9
  108. package/dist/modules/search/repository/index.d.ts.map +1 -1
  109. package/dist/modules/shipping/repository/index.d.ts.map +1 -1
  110. package/dist/modules/tax/repository/index.d.ts.map +1 -1
  111. package/dist/runtime/client-ip.d.ts +31 -0
  112. package/dist/runtime/client-ip.d.ts.map +1 -0
  113. package/dist/runtime/client-ip.js +31 -0
  114. package/dist/runtime/server.d.ts +4 -0
  115. package/dist/runtime/server.d.ts.map +1 -1
  116. package/dist/runtime/server.js +35 -19
  117. package/dist/test-utils/create-plugin-test-app.d.ts.map +1 -1
  118. package/dist/test-utils/create-plugin-test-app.js +4 -1
  119. package/dist/test-utils/test-actors.d.ts +3 -2
  120. package/dist/test-utils/test-actors.d.ts.map +1 -1
  121. package/dist/test-utils/test-actors.js +3 -2
  122. package/package.json +4 -4
  123. package/src/auth/middleware.ts +18 -1
  124. package/src/config/define-config.ts +7 -0
  125. package/src/config/types.ts +12 -0
  126. package/src/hooks/checkout.ts +4 -4
  127. package/src/index.ts +18 -1
  128. package/src/interfaces/rest/audit-middleware.ts +110 -0
  129. package/src/interfaces/rest/parse-json.ts +81 -0
  130. package/src/interfaces/rest/routes/catalog.ts +21 -1
  131. package/src/interfaces/rest/routes/customers.ts +64 -3
  132. package/src/interfaces/rest/routes/inventory.ts +4 -2
  133. package/src/interfaces/rest/routes/media.ts +7 -0
  134. package/src/interfaces/rest/routes/orders.ts +21 -1
  135. package/src/interfaces/rest/routes/promotions.ts +22 -1
  136. package/src/interfaces/rest/schemas/catalog.ts +30 -1
  137. package/src/interfaces/rest/schemas/customers.ts +99 -0
  138. package/src/interfaces/rest/schemas/orders.ts +21 -0
  139. package/src/interfaces/rest/schemas/promotions.ts +32 -1
  140. package/src/interfaces/rest/schemas/shared.ts +9 -0
  141. package/src/kernel/database/adapter.ts +64 -1
  142. package/src/kernel/database/migrate.ts +50 -2
  143. package/src/modules/analytics/hooks.ts +5 -5
  144. package/src/modules/analytics/repository/index.ts +0 -1
  145. package/src/modules/catalog/category-service.ts +26 -5
  146. package/src/modules/catalog/schema.ts +2 -0
  147. package/src/modules/catalog/service.ts +25 -3
  148. package/src/modules/customers/repository/index.ts +55 -1
  149. package/src/modules/customers/schema.ts +19 -0
  150. package/src/modules/customers/service.ts +137 -2
  151. package/src/modules/inventory/schemas.ts +6 -1
  152. package/src/modules/inventory/service.ts +84 -29
  153. package/src/modules/media/noop-adapter.ts +36 -0
  154. package/src/modules/orders/repository/index.ts +63 -1
  155. package/src/modules/orders/service.ts +86 -3
  156. package/src/modules/payments/repository/index.ts +0 -1
  157. package/src/modules/promotions/schemas.ts +21 -4
  158. package/src/modules/promotions/service.ts +90 -18
  159. package/src/modules/search/repository/index.ts +0 -1
  160. package/src/modules/shipping/repository/index.ts +0 -1
  161. package/src/modules/tax/repository/index.ts +0 -1
  162. package/src/runtime/client-ip.ts +49 -0
  163. package/src/runtime/server.ts +39 -18
  164. package/src/test-utils/create-plugin-test-app.ts +3 -1
  165. package/src/test-utils/test-actors.ts +3 -2
@@ -1,8 +1,10 @@
1
1
  import type { TxContext } from "../../../kernel/database/tx-context.js";
2
2
  import type { DrizzleDatabase } from "../../../kernel/database/drizzle-db.js";
3
- import { customers, customerAddresses, customerGroups, customerGroupMembers } from "../schema.js";
3
+ import { customers, customerAddresses, customerGroups, customerGroupMembers, customerInteractions } from "../schema.js";
4
4
  export type Customer = typeof customers.$inferSelect;
5
5
  export type CustomerInsert = typeof customers.$inferInsert;
6
+ export type CustomerInteraction = typeof customerInteractions.$inferSelect;
7
+ export type CustomerInteractionInsert = typeof customerInteractions.$inferInsert;
6
8
  export type CustomerAddress = typeof customerAddresses.$inferSelect;
7
9
  export type CustomerAddressInsert = typeof customerAddresses.$inferInsert;
8
10
  export type CustomerGroup = typeof customerGroups.$inferSelect;
@@ -25,6 +27,11 @@ export declare class CustomersRepository {
25
27
  findByPosPin(orgId: string, hashedPin: string, ctx?: TxContext): Promise<Customer | undefined>;
26
28
  findAll(orgId: string, ctx?: TxContext): Promise<Customer[]>;
27
29
  create(data: CustomerInsert, ctx?: TxContext): Promise<Customer>;
30
+ listInteractions(orgId: string, customerId: string, ctx?: TxContext): Promise<CustomerInteraction[]>;
31
+ findInteractionById(orgId: string, id: string, ctx?: TxContext): Promise<CustomerInteraction | undefined>;
32
+ createInteraction(data: CustomerInteractionInsert, ctx?: TxContext): Promise<CustomerInteraction>;
33
+ updateInteraction(orgId: string, id: string, data: Partial<Omit<CustomerInteractionInsert, "id" | "organizationId" | "customerId">>, ctx?: TxContext): Promise<CustomerInteraction | undefined>;
34
+ deleteInteraction(orgId: string, id: string, ctx?: TxContext): Promise<boolean>;
28
35
  update(id: string, data: Partial<Omit<CustomerInsert, "id">>, ctx?: TxContext): Promise<Customer | undefined>;
29
36
  delete(id: string, ctx?: TxContext): Promise<boolean>;
30
37
  findAddressById(id: string, ctx?: TxContext): Promise<CustomerAddress | undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/customers/repository/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/customers/repository/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { eq, and } from "drizzle-orm";
2
- import { customers, customerAddresses, customerGroups, customerGroupMembers, } from "../schema.js";
1
+ import { eq, and, desc } from "drizzle-orm";
2
+ import { customers, customerAddresses, customerGroups, customerGroupMembers, customerInteractions, } from "../schema.js";
3
3
  /**
4
4
  * CustomersRepository provides type-safe database operations for customers.
5
5
  *
@@ -61,6 +61,46 @@ export class CustomersRepository {
61
61
  const rows = await db.insert(customers).values(data).returning();
62
62
  return rows[0];
63
63
  }
64
+ // ─── Customer interactions ───────────────────────────────────────────────
65
+ async listInteractions(orgId, customerId, ctx) {
66
+ const db = this.getDb(ctx);
67
+ return db
68
+ .select()
69
+ .from(customerInteractions)
70
+ .where(and(eq(customerInteractions.organizationId, orgId), eq(customerInteractions.customerId, customerId)))
71
+ .orderBy(desc(customerInteractions.at));
72
+ }
73
+ async findInteractionById(orgId, id, ctx) {
74
+ const db = this.getDb(ctx);
75
+ const rows = await db
76
+ .select()
77
+ .from(customerInteractions)
78
+ .where(and(eq(customerInteractions.organizationId, orgId), eq(customerInteractions.id, id)))
79
+ .limit(1);
80
+ return rows[0];
81
+ }
82
+ async createInteraction(data, ctx) {
83
+ const db = this.getDb(ctx);
84
+ const rows = await db.insert(customerInteractions).values(data).returning();
85
+ return rows[0];
86
+ }
87
+ async updateInteraction(orgId, id, data, ctx) {
88
+ const db = this.getDb(ctx);
89
+ const rows = await db
90
+ .update(customerInteractions)
91
+ .set(data)
92
+ .where(and(eq(customerInteractions.organizationId, orgId), eq(customerInteractions.id, id)))
93
+ .returning();
94
+ return rows[0];
95
+ }
96
+ async deleteInteraction(orgId, id, ctx) {
97
+ const db = this.getDb(ctx);
98
+ const rows = await db
99
+ .delete(customerInteractions)
100
+ .where(and(eq(customerInteractions.organizationId, orgId), eq(customerInteractions.id, id)))
101
+ .returning();
102
+ return rows.length > 0;
103
+ }
64
104
  async update(id, data, ctx) {
65
105
  const db = this.getDb(ctx);
66
106
  const rows = await db
@@ -557,4 +557,166 @@ export declare const customerGroupMembers: import("drizzle-orm/pg-core").PgTable
557
557
  };
558
558
  dialect: "pg";
559
559
  }>;
560
+ export declare const customerInteractions: import("drizzle-orm/pg-core").PgTableWithColumns<{
561
+ name: "customer_interactions";
562
+ schema: undefined;
563
+ columns: {
564
+ id: import("drizzle-orm/pg-core").PgColumn<{
565
+ name: "id";
566
+ tableName: "customer_interactions";
567
+ dataType: "string";
568
+ columnType: "PgUUID";
569
+ data: string;
570
+ driverParam: string;
571
+ notNull: true;
572
+ hasDefault: true;
573
+ isPrimaryKey: true;
574
+ isAutoincrement: false;
575
+ hasRuntimeDefault: false;
576
+ enumValues: undefined;
577
+ baseColumn: never;
578
+ identity: undefined;
579
+ generated: undefined;
580
+ }, {}, {}>;
581
+ organizationId: import("drizzle-orm/pg-core").PgColumn<{
582
+ name: "organization_id";
583
+ tableName: "customer_interactions";
584
+ dataType: "string";
585
+ columnType: "PgText";
586
+ data: string;
587
+ driverParam: string;
588
+ notNull: true;
589
+ hasDefault: false;
590
+ isPrimaryKey: false;
591
+ isAutoincrement: false;
592
+ hasRuntimeDefault: false;
593
+ enumValues: [string, ...string[]];
594
+ baseColumn: never;
595
+ identity: undefined;
596
+ generated: undefined;
597
+ }, {}, {}>;
598
+ customerId: import("drizzle-orm/pg-core").PgColumn<{
599
+ name: "customer_id";
600
+ tableName: "customer_interactions";
601
+ dataType: "string";
602
+ columnType: "PgUUID";
603
+ data: string;
604
+ driverParam: string;
605
+ notNull: true;
606
+ hasDefault: false;
607
+ isPrimaryKey: false;
608
+ isAutoincrement: false;
609
+ hasRuntimeDefault: false;
610
+ enumValues: undefined;
611
+ baseColumn: never;
612
+ identity: undefined;
613
+ generated: undefined;
614
+ }, {}, {}>;
615
+ actorUserId: import("drizzle-orm/pg-core").PgColumn<{
616
+ name: "actor_user_id";
617
+ tableName: "customer_interactions";
618
+ dataType: "string";
619
+ columnType: "PgText";
620
+ data: string;
621
+ driverParam: string;
622
+ notNull: false;
623
+ hasDefault: false;
624
+ isPrimaryKey: false;
625
+ isAutoincrement: false;
626
+ hasRuntimeDefault: false;
627
+ enumValues: [string, ...string[]];
628
+ baseColumn: never;
629
+ identity: undefined;
630
+ generated: undefined;
631
+ }, {}, {}>;
632
+ kind: import("drizzle-orm/pg-core").PgColumn<{
633
+ name: "kind";
634
+ tableName: "customer_interactions";
635
+ dataType: "string";
636
+ columnType: "PgText";
637
+ data: string;
638
+ driverParam: string;
639
+ notNull: true;
640
+ hasDefault: false;
641
+ isPrimaryKey: false;
642
+ isAutoincrement: false;
643
+ hasRuntimeDefault: false;
644
+ enumValues: [string, ...string[]];
645
+ baseColumn: never;
646
+ identity: undefined;
647
+ generated: undefined;
648
+ }, {}, {}>;
649
+ notes: import("drizzle-orm/pg-core").PgColumn<{
650
+ name: "notes";
651
+ tableName: "customer_interactions";
652
+ dataType: "string";
653
+ columnType: "PgText";
654
+ data: string;
655
+ driverParam: string;
656
+ notNull: true;
657
+ hasDefault: false;
658
+ isPrimaryKey: false;
659
+ isAutoincrement: false;
660
+ hasRuntimeDefault: false;
661
+ enumValues: [string, ...string[]];
662
+ baseColumn: never;
663
+ identity: undefined;
664
+ generated: undefined;
665
+ }, {}, {}>;
666
+ relatedEntityId: import("drizzle-orm/pg-core").PgColumn<{
667
+ name: "related_entity_id";
668
+ tableName: "customer_interactions";
669
+ dataType: "string";
670
+ columnType: "PgUUID";
671
+ data: string;
672
+ driverParam: string;
673
+ notNull: false;
674
+ hasDefault: false;
675
+ isPrimaryKey: false;
676
+ isAutoincrement: false;
677
+ hasRuntimeDefault: false;
678
+ enumValues: undefined;
679
+ baseColumn: never;
680
+ identity: undefined;
681
+ generated: undefined;
682
+ }, {}, {}>;
683
+ metadata: import("drizzle-orm/pg-core").PgColumn<{
684
+ name: "metadata";
685
+ tableName: "customer_interactions";
686
+ dataType: "json";
687
+ columnType: "PgJsonb";
688
+ data: Record<string, unknown>;
689
+ driverParam: unknown;
690
+ notNull: false;
691
+ hasDefault: true;
692
+ isPrimaryKey: false;
693
+ isAutoincrement: false;
694
+ hasRuntimeDefault: false;
695
+ enumValues: undefined;
696
+ baseColumn: never;
697
+ identity: undefined;
698
+ generated: undefined;
699
+ }, {}, {
700
+ $type: Record<string, unknown>;
701
+ }>;
702
+ at: import("drizzle-orm/pg-core").PgColumn<{
703
+ name: "at";
704
+ tableName: "customer_interactions";
705
+ dataType: "date";
706
+ columnType: "PgTimestamp";
707
+ data: Date;
708
+ driverParam: string;
709
+ notNull: true;
710
+ hasDefault: true;
711
+ isPrimaryKey: false;
712
+ isAutoincrement: false;
713
+ hasRuntimeDefault: false;
714
+ enumValues: undefined;
715
+ baseColumn: never;
716
+ identity: undefined;
717
+ generated: undefined;
718
+ }, {}, {}>;
719
+ };
720
+ dialect: "pg";
721
+ }>;
560
722
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/modules/customers/schema.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBnB,CAAC;AAEJ,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkB5B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASxB,CAAC;AAEJ,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAW/B,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/modules/customers/schema.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBnB,CAAC;AAEJ,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkB5B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASxB,CAAC;AAEJ,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAW/B,CAAC;AAIH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe/B,CAAC"}
@@ -58,3 +58,21 @@ export const customerGroupMembers = pgTable("customer_group_members", {
58
58
  index("idx_group_members_group_id").on(table.groupId),
59
59
  uniqueIndex("customer_group_members_customer_group_unique").on(table.customerId, table.groupId),
60
60
  ]);
61
+ // Non-transactional clienteling interactions: visits, calls, inquiries,
62
+ // fittings, follow-ups, messages. Distinct from the audit log (accountability).
63
+ export const customerInteractions = pgTable("customer_interactions", {
64
+ id: uuid("id").defaultRandom().primaryKey(),
65
+ organizationId: text("organization_id").notNull().references(() => organization.id, { onDelete: "cascade" }),
66
+ customerId: uuid("customer_id")
67
+ .references(() => customers.id, { onDelete: "cascade" })
68
+ .notNull(),
69
+ actorUserId: text("actor_user_id"),
70
+ kind: text("kind").notNull(),
71
+ notes: text("notes").notNull(),
72
+ relatedEntityId: uuid("related_entity_id"),
73
+ metadata: jsonb("metadata").$type().default({}),
74
+ at: timestamp("at", { withTimezone: true }).defaultNow().notNull(),
75
+ }, (table) => [
76
+ index("idx_customer_interactions_customer_id").on(table.customerId),
77
+ index("idx_customer_interactions_org").on(table.organizationId),
78
+ ]);
@@ -3,7 +3,7 @@ import type { HookRegistry } from "../../kernel/hooks/registry.js";
3
3
  import { type Result } from "../../kernel/result.js";
4
4
  import type { DatabaseAdapter } from "../../kernel/database/adapter.js";
5
5
  import type { TxContext } from "../../kernel/database/tx-context.js";
6
- import type { CustomersRepository, Customer, CustomerAddress, CustomerAddressInsert } from "./repository/index.js";
6
+ import type { CustomersRepository, Customer, CustomerAddress, CustomerAddressInsert, CustomerInteraction } from "./repository/index.js";
7
7
  interface CustomerServiceDeps {
8
8
  repository: CustomersRepository;
9
9
  hooks: HookRegistry;
@@ -14,11 +14,41 @@ export declare class CustomerService {
14
14
  private deps;
15
15
  private readonly repo;
16
16
  constructor(deps: CustomerServiceDeps);
17
+ /**
18
+ * Create a customer. `userId` is optional: for walk-in / point-of-sale
19
+ * customers who never log in, omit it and a synthetic `anonymous_<uuid>` id
20
+ * is generated and the customer is flagged `metadata.walkIn = true`. This
21
+ * keeps non-account contacts out of the auth users table.
22
+ */
23
+ createWalkIn(input: {
24
+ userId?: string | undefined;
25
+ firstName?: string | undefined;
26
+ lastName?: string | undefined;
27
+ phone?: string | undefined;
28
+ email?: string | undefined;
29
+ metadata?: Record<string, unknown> | undefined;
30
+ }, actor?: Actor | null, ctx?: TxContext): Promise<Result<Customer>>;
31
+ listInteractions(customerId: string, actor?: Actor | null, ctx?: TxContext): Promise<Result<CustomerInteraction[]>>;
32
+ createInteraction(customerId: string, input: {
33
+ kind: string;
34
+ notes: string;
35
+ relatedEntityId?: string | null | undefined;
36
+ metadata?: Record<string, unknown> | undefined;
37
+ }, actor?: Actor | null, ctx?: TxContext): Promise<Result<CustomerInteraction>>;
38
+ updateInteraction(customerId: string, interactionId: string, input: {
39
+ kind?: string | undefined;
40
+ notes?: string | undefined;
41
+ relatedEntityId?: string | null | undefined;
42
+ metadata?: Record<string, unknown> | undefined;
43
+ }, actor?: Actor | null, ctx?: TxContext): Promise<Result<CustomerInteraction>>;
44
+ deleteInteraction(customerId: string, interactionId: string, actor?: Actor | null, ctx?: TxContext): Promise<Result<void>>;
17
45
  private getOrCreateByUserId;
18
46
  list(actor?: Actor | null, ctx?: TxContext): Promise<Result<Customer[]>>;
19
47
  getById(id: string, actor?: Actor | null, ctx?: TxContext): Promise<Result<Customer>>;
20
48
  getByUserId(userId: string, actor?: Actor | null, ctx?: TxContext): Promise<Result<Customer>>;
21
- update(id: string, updates: Partial<Omit<Customer, "id" | "userId" | "createdAt" | "updatedAt">>, actor?: Actor | null, ctx?: TxContext): Promise<Result<Customer>>;
49
+ update(id: string, updates: Partial<Omit<Customer, "id" | "userId" | "createdAt" | "updatedAt">>, actor?: Actor | null, ctx?: TxContext, options?: {
50
+ replaceMetadata?: boolean;
51
+ }): Promise<Result<Customer>>;
22
52
  updateByUserId(userId: string, updates: Partial<Omit<Customer, "id" | "userId" | "createdAt" | "updatedAt">>, actor?: Actor | null, ctx?: TxContext): Promise<Result<Customer>>;
23
53
  getAddresses(userId: string, actor?: Actor | null, ctx?: TxContext): Promise<Result<CustomerAddress[]>>;
24
54
  addAddress(userId: string, input: Omit<CustomerAddressInsert, "id" | "customerId">, actor?: Actor | null, ctx?: TxContext): Promise<Result<CustomerAddress>>;
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/customers/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/customers/service.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { resolveOrgId } from "../../auth/org.js";
2
- import { CommerceNotFoundError } from "../../kernel/errors.js";
2
+ import { assertPermission } from "../../auth/permissions.js";
3
+ import { CommerceNotFoundError, toCommerceError } from "../../kernel/errors.js";
3
4
  import { runAfterHooks } from "../../kernel/hooks/executor.js";
4
5
  import { createHookContext } from "../../kernel/hooks/create-context.js";
5
6
  import { Err, Ok } from "../../kernel/result.js";
@@ -21,6 +22,109 @@ export class CustomerService {
21
22
  this.deps = deps;
22
23
  this.repo = deps.repository;
23
24
  }
25
+ /**
26
+ * Create a customer. `userId` is optional: for walk-in / point-of-sale
27
+ * customers who never log in, omit it and a synthetic `anonymous_<uuid>` id
28
+ * is generated and the customer is flagged `metadata.walkIn = true`. This
29
+ * keeps non-account contacts out of the auth users table.
30
+ */
31
+ async createWalkIn(input, actor, ctx) {
32
+ try {
33
+ assertPermission(actor ?? null, "customers:create");
34
+ }
35
+ catch (error) {
36
+ return Err(toCommerceError(error));
37
+ }
38
+ const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
39
+ const isWalkIn = input.userId === undefined;
40
+ const userId = input.userId ?? `anonymous_${crypto.randomUUID()}`;
41
+ const metadata = {
42
+ ...(input.metadata ?? {}),
43
+ ...(isWalkIn ? { walkIn: true } : {}),
44
+ };
45
+ const customer = await this.repo.create({
46
+ organizationId: orgId,
47
+ userId,
48
+ metadata,
49
+ ...(input.firstName !== undefined ? { firstName: input.firstName } : {}),
50
+ ...(input.lastName !== undefined ? { lastName: input.lastName } : {}),
51
+ ...(input.phone !== undefined ? { phone: input.phone } : {}),
52
+ ...(input.email !== undefined ? { email: input.email } : {}),
53
+ }, ctx);
54
+ const afterHooks = this.deps.hooks.resolve("customers.afterCreate");
55
+ const hctx = hookContext(actor ?? null, this.deps.services, this.deps.database, ctx?.tx ?? null);
56
+ await runAfterHooks(afterHooks, null, customer, "create", hctx);
57
+ return Ok(customer);
58
+ }
59
+ // ─── Customer interactions (clienteling notes / visits / calls) ──────────
60
+ async listInteractions(customerId, actor, ctx) {
61
+ try {
62
+ assertPermission(actor ?? null, "customers:read");
63
+ }
64
+ catch (error) {
65
+ return Err(toCommerceError(error));
66
+ }
67
+ const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
68
+ return Ok(await this.repo.listInteractions(orgId, customerId, ctx));
69
+ }
70
+ async createInteraction(customerId, input, actor, ctx) {
71
+ try {
72
+ assertPermission(actor ?? null, "customers:update");
73
+ }
74
+ catch (error) {
75
+ return Err(toCommerceError(error));
76
+ }
77
+ const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
78
+ const customer = await this.repo.findById(orgId, customerId, ctx);
79
+ if (!customer)
80
+ return Err(new CommerceNotFoundError("Customer not found."));
81
+ const interaction = await this.repo.createInteraction({
82
+ organizationId: orgId,
83
+ customerId,
84
+ kind: input.kind,
85
+ notes: input.notes,
86
+ actorUserId: actor?.userId ?? null,
87
+ relatedEntityId: input.relatedEntityId ?? null,
88
+ metadata: input.metadata ?? {},
89
+ }, ctx);
90
+ return Ok(interaction);
91
+ }
92
+ async updateInteraction(customerId, interactionId, input, actor, ctx) {
93
+ try {
94
+ assertPermission(actor ?? null, "customers:update");
95
+ }
96
+ catch (error) {
97
+ return Err(toCommerceError(error));
98
+ }
99
+ const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
100
+ const existing = await this.repo.findInteractionById(orgId, interactionId, ctx);
101
+ if (!existing || existing.customerId !== customerId)
102
+ return Err(new CommerceNotFoundError("Interaction not found."));
103
+ const patch = {
104
+ ...(input.kind !== undefined ? { kind: input.kind } : {}),
105
+ ...(input.notes !== undefined ? { notes: input.notes } : {}),
106
+ ...(input.relatedEntityId !== undefined ? { relatedEntityId: input.relatedEntityId } : {}),
107
+ ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),
108
+ };
109
+ const updated = await this.repo.updateInteraction(orgId, interactionId, patch, ctx);
110
+ if (!updated)
111
+ return Err(new CommerceNotFoundError("Interaction not found."));
112
+ return Ok(updated);
113
+ }
114
+ async deleteInteraction(customerId, interactionId, actor, ctx) {
115
+ try {
116
+ assertPermission(actor ?? null, "customers:update");
117
+ }
118
+ catch (error) {
119
+ return Err(toCommerceError(error));
120
+ }
121
+ const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
122
+ const existing = await this.repo.findInteractionById(orgId, interactionId, ctx);
123
+ if (!existing || existing.customerId !== customerId)
124
+ return Err(new CommerceNotFoundError("Interaction not found."));
125
+ await this.repo.deleteInteraction(orgId, interactionId, ctx);
126
+ return Ok(undefined);
127
+ }
24
128
  async getOrCreateByUserId(orgId, userId, actor, ctx) {
25
129
  const existing = await this.repo.findByUserId(orgId, userId, ctx);
26
130
  if (existing) {
@@ -54,12 +158,24 @@ export class CustomerService {
54
158
  const customer = await this.getOrCreateByUserId(orgId, userId, resolvedActor, ctx);
55
159
  return Ok(customer);
56
160
  }
57
- async update(id, updates, actor, ctx) {
161
+ async update(id, updates, actor, ctx, options) {
58
162
  const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
59
163
  const existing = await this.repo.findById(orgId, id, ctx);
60
164
  if (!existing)
61
165
  return Err(new CommerceNotFoundError("Customer not found."));
62
- const updated = await this.repo.update(id, updates, ctx);
166
+ // Shallow-merge metadata by default (top-level keys) so a single-key edit
167
+ // doesn't clobber the rest of the blob. Pass replaceMetadata to overwrite.
168
+ let finalUpdates = updates;
169
+ if (updates.metadata !== undefined && !options?.replaceMetadata) {
170
+ finalUpdates = {
171
+ ...updates,
172
+ metadata: {
173
+ ...(existing.metadata ?? {}),
174
+ ...updates.metadata,
175
+ },
176
+ };
177
+ }
178
+ const updated = await this.repo.update(id, finalUpdates, ctx);
63
179
  if (!updated)
64
180
  return Err(new CommerceNotFoundError("Customer not found."));
65
181
  const afterHooks = this.deps.hooks.resolve("customers.afterUpdate");
@@ -3,7 +3,13 @@ export declare const InventoryAdjustBodySchema: z.ZodObject<{
3
3
  entityId: z.ZodString;
4
4
  variantId: z.ZodOptional<z.ZodString>;
5
5
  warehouseId: z.ZodOptional<z.ZodString>;
6
- adjustment: z.ZodNumber;
6
+ adjustment: z.ZodOptional<z.ZodNumber>;
7
+ mode: z.ZodOptional<z.ZodEnum<{
8
+ set: "set";
9
+ add: "add";
10
+ remove: "remove";
11
+ }>>;
12
+ amount: z.ZodOptional<z.ZodNumber>;
7
13
  reason: z.ZodString;
8
14
  performedBy: z.ZodOptional<z.ZodString>;
9
15
  referenceType: z.ZodOptional<z.ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/modules/inventory/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAItC,eAAO,MAAM,yBAAyB;;;;;;;;;iBASF,CAAC;AAErC,eAAO,MAAM,0BAA0B;;;;;;;iBAOF,CAAC;AAEtC,eAAO,MAAM,0BAA0B;;;;;;;iBAOF,CAAC;AAItC,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC7E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC/E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/modules/inventory/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAItC,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;iBAcF,CAAC;AAErC,eAAO,MAAM,0BAA0B;;;;;;;iBAOF,CAAC;AAEtC,eAAO,MAAM,0BAA0B;;;;;;;iBAOF,CAAC;AAItC,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC7E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC/E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
@@ -4,7 +4,12 @@ export const InventoryAdjustBodySchema = z.object({
4
4
  entityId: z.string().openapi({ example: "550e8400-e29b-41d4-a716-446655440000" }),
5
5
  variantId: z.string().optional().openapi({ example: "variant-uuid" }),
6
6
  warehouseId: z.string().optional().openapi({ example: "warehouse-uuid" }),
7
- adjustment: z.number().int().refine((v) => v !== 0, { message: "Adjustment cannot be zero" }).openapi({ example: 10 }),
7
+ // Signed-delta form (legacy/default). Required when `mode` is omitted.
8
+ adjustment: z.number().int().refine((v) => v !== 0, { message: "Adjustment cannot be zero" }).optional().openapi({ example: 10 }),
9
+ // Mode form. `add`/`remove`/`set` operate on the unsigned `amount`.
10
+ // `remove` clamps at 0; `set` writes the absolute quantity.
11
+ mode: z.enum(["add", "remove", "set"]).optional().openapi({ example: "add" }),
12
+ amount: z.number().int().min(0).optional().openapi({ example: 5 }),
8
13
  reason: z.string().openapi({ example: "Restock from supplier" }),
9
14
  performedBy: z.string().optional(),
10
15
  referenceType: z.string().optional(),
@@ -31,6 +31,24 @@ export declare class InventoryService {
31
31
  getLevelsByEntityId(entityId: string, ctx?: TxContext, actor?: Actor | null): Promise<Result<InventoryLevel[]>>;
32
32
  reserve(input: InventoryReserveInput, actor?: Actor | null, ctx?: TxContext): Promise<Result<void>>;
33
33
  release(input: InventoryReleaseInput, actor?: Actor | null, ctx?: TxContext): Promise<Result<void>>;
34
+ /**
35
+ * Adjust inventory with optional add/remove/set modes, returning before /
36
+ * after / delta and the movement id. `mode` omitted ⇒ signed-delta (legacy)
37
+ * behavior using `adjustment`. `remove` clamps at 0; `set` writes an absolute
38
+ * value. The lock, compute, write, and movement all happen in one transaction
39
+ * so concurrent adjustments can't lose updates.
40
+ */
41
+ adjustDetailed(input: InventoryAdjustInput, actor?: Actor | null, ctx?: TxContext): Promise<Result<{
42
+ level: InventoryLevel;
43
+ before: number;
44
+ after: number;
45
+ delta: number;
46
+ movementId: string;
47
+ }>>;
48
+ /**
49
+ * Back-compat wrapper: adjust inventory and return just the level. Existing
50
+ * callers and the signed-delta `adjustment` form are unchanged.
51
+ */
34
52
  adjust(input: InventoryAdjustInput, actor?: Actor | null, ctx?: TxContext): Promise<Result<InventoryLevel>>;
35
53
  /**
36
54
  * Set inventory to an absolute quantity (not a delta).
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/inventory/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/inventory/service.ts"],"names":[],"mappings":"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"}