@fonderie/customers 6.1.3 → 6.1.5

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.
@@ -117,7 +117,7 @@ new CustomerAddressModel(store: IStoreAdapter): CustomerAddressModel
117
117
  .add(opts: { customerId: string; countryIso: string; subdivision1Iso?: string | null; subdivision2Iso?: string | null; zipPostalCode: string; unit?: string | null; line1?: string | null; line2?: string | null; labelId: string; isPrimary?: boolean; }): Promise<...>
118
118
  .updateLabel(addrId: string, customerId: string, labelId: string): Promise<ICustomerAddress>
119
119
  .setPrimary(addrId: string, customerId: string): Promise<void>
120
- .remove(addrId: string, customerId: string): Promise<void>
120
+ .remove(addrId: string, customerId: string): Promise<boolean>
121
121
 
122
122
  new CustomerEmailModel(store: IStoreAdapter): CustomerEmailModel
123
123
  .list(customerId: string): Promise<ICustomerEmail[]>
package/dist/index.cjs CHANGED
@@ -944,16 +944,18 @@ var CustomerAddressModel = class {
944
944
  );
945
945
  });
946
946
  }
947
+ /** Returns false when the address is not linked to THIS customer (no-op). */
947
948
  async remove(addrId, customerId) {
948
- await this.store.transaction(async (tx) => {
949
+ return this.store.transaction(async (tx) => {
949
950
  const [deleted] = await tx.query(
950
951
  `DELETE FROM fonderie_customer_addresses
951
952
  WHERE addr_id = $1 AND customer_id = $2
952
953
  RETURNING is_primary AS "isPrimary"`,
953
954
  [addrId, customerId]
954
955
  );
956
+ if (!deleted) return false;
955
957
  await tx.query(`DELETE FROM fonderie_addresses WHERE id = $1`, [addrId]);
956
- if (deleted?.isPrimary) {
958
+ if (deleted.isPrimary) {
957
959
  await tx.query(
958
960
  `UPDATE fonderie_customer_addresses
959
961
  SET is_primary = true
@@ -966,6 +968,7 @@ var CustomerAddressModel = class {
966
968
  [customerId]
967
969
  );
968
970
  }
971
+ return true;
969
972
  });
970
973
  }
971
974
  };
@@ -1075,11 +1078,23 @@ var CustomerLabelModel = class {
1075
1078
  [type]
1076
1079
  );
1077
1080
  }
1078
- remove(id) {
1079
- return this.store.query(
1080
- `DELETE FROM fonderie_customer_labels WHERE id = $1`,
1081
+ /**
1082
+ * Returns false when the label is still referenced. Labels are a SHARED
1083
+ * table (no workspace column), so an unconditional delete would let one
1084
+ * tenant destroy a label other tenants' emails/phones/addresses point at.
1085
+ * Until labels are workspace-scoped, only an unreferenced label may go.
1086
+ */
1087
+ async remove(id) {
1088
+ const rows = await this.store.query(
1089
+ `DELETE FROM fonderie_customer_labels l
1090
+ WHERE l.id = $1
1091
+ AND NOT EXISTS (SELECT 1 FROM fonderie_customer_emails WHERE label_id = l.id)
1092
+ AND NOT EXISTS (SELECT 1 FROM fonderie_customer_phones WHERE label_id = l.id)
1093
+ AND NOT EXISTS (SELECT 1 FROM fonderie_customer_addresses WHERE label_id = l.id)
1094
+ RETURNING l.id`,
1081
1095
  [id]
1082
- ).then(() => void 0);
1096
+ );
1097
+ return rows.length > 0;
1083
1098
  }
1084
1099
  async findOrCreate(type, raw) {
1085
1100
  const value = raw.trim().toLowerCase();
@@ -1769,7 +1784,10 @@ function customerAddressController(store) {
1769
1784
  if (!isUuid(addrId)) {
1770
1785
  return (0, import_core3.setApiResponse)(import_core3.HTTP.UNPROCESSABLE, "INVALID_PARAMETER", "addrId must be a valid UUID");
1771
1786
  }
1772
- await addresses.remove(addrId, r.customer.id);
1787
+ const removed = await addresses.remove(addrId, r.customer.id);
1788
+ if (!removed) {
1789
+ return (0, import_core3.setApiResponse)(import_core3.HTTP.NOT_FOUND, "NOT_FOUND", "Address not found");
1790
+ }
1773
1791
  return (0, import_core3.setApiResponse)(import_core3.HTTP.OK, "ADDRESS_REMOVED", "Address removed successfully.");
1774
1792
  }
1775
1793
  };
@@ -2189,7 +2207,14 @@ function customerLabelController(store) {
2189
2207
  if (!isUuid(labelId)) {
2190
2208
  return (0, import_core8.setApiResponse)(import_core8.HTTP.UNPROCESSABLE, "INVALID_PARAMETER", "labelId must be a valid UUID");
2191
2209
  }
2192
- await labels.remove(labelId);
2210
+ const removed = await labels.remove(labelId);
2211
+ if (!removed) {
2212
+ return (0, import_core8.setApiResponse)(
2213
+ import_core8.HTTP.CONFLICT,
2214
+ "LABEL_IN_USE",
2215
+ "Label is still referenced by customer records and cannot be deleted."
2216
+ );
2217
+ }
2193
2218
  return (0, import_core8.setApiResponse)(import_core8.HTTP.OK, "LABEL_DELETED", "Label deleted successfully.");
2194
2219
  }
2195
2220
  };