@voyant-travel/distribution 0.109.8

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 (168) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +42 -0
  3. package/dist/booking-extension.d.ts +168 -0
  4. package/dist/booking-extension.d.ts.map +1 -0
  5. package/dist/booking-extension.js +102 -0
  6. package/dist/channel-push/admin-routes.d.ts +31 -0
  7. package/dist/channel-push/admin-routes.d.ts.map +1 -0
  8. package/dist/channel-push/admin-routes.js +165 -0
  9. package/dist/channel-push/availability-push.d.ts +76 -0
  10. package/dist/channel-push/availability-push.d.ts.map +1 -0
  11. package/dist/channel-push/availability-push.js +236 -0
  12. package/dist/channel-push/booking-push-helpers.d.ts +36 -0
  13. package/dist/channel-push/booking-push-helpers.d.ts.map +1 -0
  14. package/dist/channel-push/booking-push-helpers.js +169 -0
  15. package/dist/channel-push/booking-push.d.ts +108 -0
  16. package/dist/channel-push/booking-push.d.ts.map +1 -0
  17. package/dist/channel-push/booking-push.js +335 -0
  18. package/dist/channel-push/boundary-sql.d.ts +23 -0
  19. package/dist/channel-push/boundary-sql.d.ts.map +1 -0
  20. package/dist/channel-push/boundary-sql.js +75 -0
  21. package/dist/channel-push/content-push.d.ts +60 -0
  22. package/dist/channel-push/content-push.d.ts.map +1 -0
  23. package/dist/channel-push/content-push.js +252 -0
  24. package/dist/channel-push/index.d.ts +15 -0
  25. package/dist/channel-push/index.d.ts.map +1 -0
  26. package/dist/channel-push/index.js +18 -0
  27. package/dist/channel-push/plugin.d.ts +18 -0
  28. package/dist/channel-push/plugin.d.ts.map +1 -0
  29. package/dist/channel-push/plugin.js +21 -0
  30. package/dist/channel-push/reconciler.d.ts +85 -0
  31. package/dist/channel-push/reconciler.d.ts.map +1 -0
  32. package/dist/channel-push/reconciler.js +179 -0
  33. package/dist/channel-push/subscriber.d.ts +40 -0
  34. package/dist/channel-push/subscriber.d.ts.map +1 -0
  35. package/dist/channel-push/subscriber.js +199 -0
  36. package/dist/channel-push/types.d.ts +43 -0
  37. package/dist/channel-push/types.d.ts.map +1 -0
  38. package/dist/channel-push/types.js +32 -0
  39. package/dist/channel-push/workflows.d.ts +56 -0
  40. package/dist/channel-push/workflows.d.ts.map +1 -0
  41. package/dist/channel-push/workflows.js +100 -0
  42. package/dist/external-refs/index.d.ts +11 -0
  43. package/dist/external-refs/index.d.ts.map +1 -0
  44. package/dist/external-refs/index.js +12 -0
  45. package/dist/external-refs/routes.d.ts +253 -0
  46. package/dist/external-refs/routes.d.ts.map +1 -0
  47. package/dist/external-refs/routes.js +52 -0
  48. package/dist/external-refs/schema.d.ts +251 -0
  49. package/dist/external-refs/schema.d.ts.map +1 -0
  50. package/dist/external-refs/schema.js +32 -0
  51. package/dist/external-refs/service.d.ts +82 -0
  52. package/dist/external-refs/service.d.ts.map +1 -0
  53. package/dist/external-refs/service.js +112 -0
  54. package/dist/external-refs/validation.d.ts +91 -0
  55. package/dist/external-refs/validation.d.ts.map +1 -0
  56. package/dist/external-refs/validation.js +40 -0
  57. package/dist/index.d.ts +21 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +20 -0
  60. package/dist/interface-types.d.ts +128 -0
  61. package/dist/interface-types.d.ts.map +1 -0
  62. package/dist/interface-types.js +1 -0
  63. package/dist/interface.d.ts +10 -0
  64. package/dist/interface.d.ts.map +1 -0
  65. package/dist/interface.js +286 -0
  66. package/dist/rate-limit.d.ts +69 -0
  67. package/dist/rate-limit.d.ts.map +1 -0
  68. package/dist/rate-limit.js +135 -0
  69. package/dist/routes/batch.d.ts +200 -0
  70. package/dist/routes/batch.d.ts.map +1 -0
  71. package/dist/routes/batch.js +52 -0
  72. package/dist/routes/env.d.ts +8 -0
  73. package/dist/routes/env.d.ts.map +1 -0
  74. package/dist/routes/env.js +1 -0
  75. package/dist/routes/inventory.d.ts +604 -0
  76. package/dist/routes/inventory.d.ts.map +1 -0
  77. package/dist/routes/inventory.js +138 -0
  78. package/dist/routes/settlements.d.ts +1649 -0
  79. package/dist/routes/settlements.d.ts.map +1 -0
  80. package/dist/routes/settlements.js +265 -0
  81. package/dist/routes.d.ts +3909 -0
  82. package/dist/routes.d.ts.map +1 -0
  83. package/dist/routes.js +323 -0
  84. package/dist/schema-automation.d.ts +680 -0
  85. package/dist/schema-automation.d.ts.map +1 -0
  86. package/dist/schema-automation.js +76 -0
  87. package/dist/schema-core.d.ts +1674 -0
  88. package/dist/schema-core.d.ts.map +1 -0
  89. package/dist/schema-core.js +227 -0
  90. package/dist/schema-finance.d.ts +1372 -0
  91. package/dist/schema-finance.d.ts.map +1 -0
  92. package/dist/schema-finance.js +153 -0
  93. package/dist/schema-inventory.d.ts +855 -0
  94. package/dist/schema-inventory.d.ts.map +1 -0
  95. package/dist/schema-inventory.js +102 -0
  96. package/dist/schema-push-intents.d.ts +387 -0
  97. package/dist/schema-push-intents.d.ts.map +1 -0
  98. package/dist/schema-push-intents.js +77 -0
  99. package/dist/schema-relations.d.ts +95 -0
  100. package/dist/schema-relations.d.ts.map +1 -0
  101. package/dist/schema-relations.js +196 -0
  102. package/dist/schema-shared.d.ts +24 -0
  103. package/dist/schema-shared.d.ts.map +1 -0
  104. package/dist/schema-shared.js +123 -0
  105. package/dist/schema.d.ts +9 -0
  106. package/dist/schema.d.ts.map +1 -0
  107. package/dist/schema.js +8 -0
  108. package/dist/service/channels.d.ts +167 -0
  109. package/dist/service/channels.d.ts.map +1 -0
  110. package/dist/service/channels.js +305 -0
  111. package/dist/service/commercial.d.ts +385 -0
  112. package/dist/service/commercial.d.ts.map +1 -0
  113. package/dist/service/commercial.js +248 -0
  114. package/dist/service/helpers.d.ts +10 -0
  115. package/dist/service/helpers.d.ts.map +1 -0
  116. package/dist/service/helpers.js +7 -0
  117. package/dist/service/inventory.d.ts +193 -0
  118. package/dist/service/inventory.d.ts.map +1 -0
  119. package/dist/service/inventory.js +154 -0
  120. package/dist/service/settlement-policies.d.ts +325 -0
  121. package/dist/service/settlement-policies.d.ts.map +1 -0
  122. package/dist/service/settlement-policies.js +272 -0
  123. package/dist/service/settlements.d.ts +357 -0
  124. package/dist/service/settlements.d.ts.map +1 -0
  125. package/dist/service/settlements.js +319 -0
  126. package/dist/service/types.d.ts +60 -0
  127. package/dist/service/types.d.ts.map +1 -0
  128. package/dist/service/types.js +1 -0
  129. package/dist/service.d.ts +1418 -0
  130. package/dist/service.d.ts.map +1 -0
  131. package/dist/service.js +17 -0
  132. package/dist/suppliers/index.d.ts +15 -0
  133. package/dist/suppliers/index.d.ts.map +1 -0
  134. package/dist/suppliers/index.js +23 -0
  135. package/dist/suppliers/routes.d.ts +1202 -0
  136. package/dist/suppliers/routes.d.ts.map +1 -0
  137. package/dist/suppliers/routes.js +290 -0
  138. package/dist/suppliers/schema.d.ts +1272 -0
  139. package/dist/suppliers/schema.d.ts.map +1 -0
  140. package/dist/suppliers/schema.js +219 -0
  141. package/dist/suppliers/service-aggregates.d.ts +23 -0
  142. package/dist/suppliers/service-aggregates.d.ts.map +1 -0
  143. package/dist/suppliers/service-aggregates.js +51 -0
  144. package/dist/suppliers/service-core.d.ts +89 -0
  145. package/dist/suppliers/service-core.d.ts.map +1 -0
  146. package/dist/suppliers/service-core.js +164 -0
  147. package/dist/suppliers/service-identity.d.ts +162 -0
  148. package/dist/suppliers/service-identity.d.ts.map +1 -0
  149. package/dist/suppliers/service-identity.js +101 -0
  150. package/dist/suppliers/service-operations.d.ts +1500 -0
  151. package/dist/suppliers/service-operations.d.ts.map +1 -0
  152. package/dist/suppliers/service-operations.js +157 -0
  153. package/dist/suppliers/service-shared.d.ts +45 -0
  154. package/dist/suppliers/service-shared.d.ts.map +1 -0
  155. package/dist/suppliers/service-shared.js +294 -0
  156. package/dist/suppliers/service.d.ts +41 -0
  157. package/dist/suppliers/service.d.ts.map +1 -0
  158. package/dist/suppliers/service.js +40 -0
  159. package/dist/suppliers/validation.d.ts +2 -0
  160. package/dist/suppliers/validation.d.ts.map +1 -0
  161. package/dist/suppliers/validation.js +1 -0
  162. package/dist/validation.d.ts +1371 -0
  163. package/dist/validation.d.ts.map +1 -0
  164. package/dist/validation.js +445 -0
  165. package/dist/webhook-deliveries.d.ts +86 -0
  166. package/dist/webhook-deliveries.d.ts.map +1 -0
  167. package/dist/webhook-deliveries.js +296 -0
  168. package/package.json +71 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/suppliers/routes.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAqBjE,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAmBD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAsavB,CAAA;AAEJ,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAA"}
@@ -0,0 +1,290 @@
1
+ import { aggregateSnapshotKey, readThroughAggregateSnapshot, } from "@voyant-travel/db/aggregate-snapshots";
2
+ import { parseJsonBody, parseQuery, requireUserId } from "@voyant-travel/hono";
3
+ import { insertAddressForEntitySchema, insertContactPointForEntitySchema, insertNamedContactForEntitySchema, updateAddressSchema as updateIdentityAddressSchema, updateContactPointSchema as updateIdentityContactPointSchema, updateNamedContactSchema as updateIdentityNamedContactSchema, } from "@voyant-travel/identity/validation";
4
+ import { Hono } from "hono";
5
+ import { z } from "zod";
6
+ import { suppliersService } from "./service.js";
7
+ import { availabilityQuerySchema, insertAvailabilitySchema, insertContractSchema, insertRateSchema, insertServiceSchema, insertSupplierNoteSchema, insertSupplierSchema, supplierAggregatesQuerySchema, supplierListQuerySchema, updateContractSchema, updateRateSchema, updateServiceSchema, updateSupplierSchema, } from "./validation.js";
8
+ const DASHBOARD_AGGREGATES_CACHE_CONTROL = "private, max-age=30";
9
+ /** Server-side snapshot TTL — see readThroughAggregateSnapshot (#1629). */
10
+ const DASHBOARD_AGGREGATES_TTL_SECONDS = 60;
11
+ function cacheDashboardAggregates(c) {
12
+ c.header("Cache-Control", DASHBOARD_AGGREGATES_CACHE_CONTROL);
13
+ c.header("Vary", "Authorization", { append: true });
14
+ c.header("Vary", "Cookie", { append: true });
15
+ }
16
+ // ==========================================================================
17
+ // Suppliers — method-chained for Hono RPC type inference
18
+ // ==========================================================================
19
+ export const supplierRoutes = new Hono()
20
+ // ========================================================================
21
+ // Dashboard aggregates
22
+ // ========================================================================
23
+ // GET /aggregates — dashboard KPIs (before /:id so the matcher doesn't
24
+ // swallow it). Served from a read-through TTL snapshot (#1629).
25
+ .get("/aggregates", async (c) => {
26
+ const query = parseQuery(c, supplierAggregatesQuerySchema);
27
+ cacheDashboardAggregates(c);
28
+ const snapshot = await readThroughAggregateSnapshot(c.get("db"), {
29
+ key: aggregateSnapshotKey("suppliers", "aggregates", query),
30
+ ttlSeconds: DASHBOARD_AGGREGATES_TTL_SECONDS,
31
+ compute: () => suppliersService.getSupplierAggregates(c.get("db"), query),
32
+ });
33
+ return c.json({ data: snapshot.data });
34
+ })
35
+ // ========================================================================
36
+ // Suppliers CRUD
37
+ // ========================================================================
38
+ // GET / — List suppliers
39
+ .get("/", async (c) => {
40
+ const query = parseQuery(c, supplierListQuerySchema);
41
+ return c.json(await suppliersService.listSuppliers(c.get("db"), query));
42
+ })
43
+ // PATCH /contact-points/:contactPointId — Update supplier contact point
44
+ .patch("/contact-points/:contactPointId", async (c) => {
45
+ const row = await suppliersService.updateContactPoint(c.get("db"), c.req.param("contactPointId"), await parseJsonBody(c, updateIdentityContactPointSchema));
46
+ if (!row) {
47
+ return c.json({ error: "Contact point not found" }, 404);
48
+ }
49
+ return c.json({ data: row });
50
+ })
51
+ // PATCH /contacts/:contactId — Update supplier named contact
52
+ .patch("/contacts/:contactId", async (c) => {
53
+ const row = await suppliersService.updateNamedContact(c.get("db"), c.req.param("contactId"), await parseJsonBody(c, updateIdentityNamedContactSchema));
54
+ if (!row) {
55
+ return c.json({ error: "Contact not found" }, 404);
56
+ }
57
+ return c.json({ data: row });
58
+ })
59
+ // DELETE /contacts/:contactId — Delete supplier named contact
60
+ .delete("/contacts/:contactId", async (c) => {
61
+ const row = await suppliersService.deleteNamedContact(c.get("db"), c.req.param("contactId"));
62
+ if (!row) {
63
+ return c.json({ error: "Contact not found" }, 404);
64
+ }
65
+ return c.json({ success: true }, 200);
66
+ })
67
+ // DELETE /contact-points/:contactPointId — Delete supplier contact point
68
+ .delete("/contact-points/:contactPointId", async (c) => {
69
+ const row = await suppliersService.deleteContactPoint(c.get("db"), c.req.param("contactPointId"));
70
+ if (!row) {
71
+ return c.json({ error: "Contact point not found" }, 404);
72
+ }
73
+ return c.json({ success: true }, 200);
74
+ })
75
+ // PATCH /addresses/:addressId — Update supplier address
76
+ .patch("/addresses/:addressId", async (c) => {
77
+ const row = await suppliersService.updateAddress(c.get("db"), c.req.param("addressId"), await parseJsonBody(c, updateIdentityAddressSchema));
78
+ if (!row) {
79
+ return c.json({ error: "Address not found" }, 404);
80
+ }
81
+ return c.json({ data: row });
82
+ })
83
+ // DELETE /addresses/:addressId — Delete supplier address
84
+ .delete("/addresses/:addressId", async (c) => {
85
+ const row = await suppliersService.deleteAddress(c.get("db"), c.req.param("addressId"));
86
+ if (!row) {
87
+ return c.json({ error: "Address not found" }, 404);
88
+ }
89
+ return c.json({ success: true }, 200);
90
+ })
91
+ // GET /:id — Get single supplier
92
+ .get("/:id", async (c) => {
93
+ const row = await suppliersService.getSupplierById(c.get("db"), c.req.param("id"));
94
+ if (!row) {
95
+ return c.json({ error: "Supplier not found" }, 404);
96
+ }
97
+ return c.json({ data: row });
98
+ })
99
+ // POST / — Create supplier
100
+ .post("/", async (c) => {
101
+ const data = await parseJsonBody(c, insertSupplierSchema);
102
+ return c.json({ data: await suppliersService.createSupplier(c.get("db"), data) }, 201);
103
+ })
104
+ // PATCH /:id — Update supplier
105
+ .patch("/:id", async (c) => {
106
+ const row = await suppliersService.updateSupplier(c.get("db"), c.req.param("id"), await parseJsonBody(c, updateSupplierSchema));
107
+ if (!row) {
108
+ return c.json({ error: "Supplier not found" }, 404);
109
+ }
110
+ return c.json({ data: row });
111
+ })
112
+ // DELETE /:id — Delete supplier
113
+ .delete("/:id", async (c) => {
114
+ const row = await suppliersService.deleteSupplier(c.get("db"), c.req.param("id"));
115
+ if (!row) {
116
+ return c.json({ error: "Supplier not found" }, 404);
117
+ }
118
+ return c.json({ success: true }, 200);
119
+ })
120
+ // GET /:id/contact-points — List shared contact points for a supplier
121
+ .get("/:id/contact-points", async (c) => {
122
+ return c.json({
123
+ data: await suppliersService.listContactPoints(c.get("db"), c.req.param("id")),
124
+ });
125
+ })
126
+ // POST /:id/contact-points — Create shared contact point for a supplier
127
+ .post("/:id/contact-points", async (c) => {
128
+ const row = await suppliersService.createContactPoint(c.get("db"), c.req.param("id"), await parseJsonBody(c, insertContactPointForEntitySchema));
129
+ if (!row) {
130
+ return c.json({ error: "Supplier not found" }, 404);
131
+ }
132
+ return c.json({ data: row }, 201);
133
+ })
134
+ // GET /:id/contacts — List shared named contacts for a supplier
135
+ .get("/:id/contacts", async (c) => {
136
+ return c.json({
137
+ data: await suppliersService.listNamedContacts(c.get("db"), c.req.param("id")),
138
+ });
139
+ })
140
+ // POST /:id/contacts — Create shared named contact for a supplier
141
+ .post("/:id/contacts", async (c) => {
142
+ const row = await suppliersService.createNamedContact(c.get("db"), c.req.param("id"), await parseJsonBody(c, insertNamedContactForEntitySchema));
143
+ if (!row) {
144
+ return c.json({ error: "Supplier not found" }, 404);
145
+ }
146
+ return c.json({ data: row }, 201);
147
+ })
148
+ // GET /:id/addresses — List shared addresses for a supplier
149
+ .get("/:id/addresses", async (c) => {
150
+ return c.json({ data: await suppliersService.listAddresses(c.get("db"), c.req.param("id")) });
151
+ })
152
+ // POST /:id/addresses — Create shared address for a supplier
153
+ .post("/:id/addresses", async (c) => {
154
+ const row = await suppliersService.createAddress(c.get("db"), c.req.param("id"), await parseJsonBody(c, insertAddressForEntitySchema));
155
+ if (!row) {
156
+ return c.json({ error: "Supplier not found" }, 404);
157
+ }
158
+ return c.json({ data: row }, 201);
159
+ })
160
+ // ========================================================================
161
+ // Services
162
+ // ========================================================================
163
+ // GET /:id/services — List services for a supplier
164
+ .get("/:id/services", async (c) => {
165
+ return c.json({ data: await suppliersService.listServices(c.get("db"), c.req.param("id")) });
166
+ })
167
+ // POST /:id/services — Add service to supplier
168
+ .post("/:id/services", async (c) => {
169
+ const row = await suppliersService.createService(c.get("db"), c.req.param("id"), await parseJsonBody(c, insertServiceSchema));
170
+ if (!row) {
171
+ return c.json({ error: "Supplier not found" }, 404);
172
+ }
173
+ return c.json({ data: row }, 201);
174
+ })
175
+ // PATCH /:id/services/:serviceId — Update service
176
+ .patch("/:id/services/:serviceId", async (c) => {
177
+ const row = await suppliersService.updateService(c.get("db"), c.req.param("serviceId"), await parseJsonBody(c, updateServiceSchema));
178
+ if (!row) {
179
+ return c.json({ error: "Service not found" }, 404);
180
+ }
181
+ return c.json({ data: row });
182
+ })
183
+ // DELETE /:id/services/:serviceId — Delete service
184
+ .delete("/:id/services/:serviceId", async (c) => {
185
+ const row = await suppliersService.deleteService(c.get("db"), c.req.param("serviceId"));
186
+ if (!row) {
187
+ return c.json({ error: "Service not found" }, 404);
188
+ }
189
+ return c.json({ success: true }, 200);
190
+ })
191
+ // ========================================================================
192
+ // Rates
193
+ // ========================================================================
194
+ // GET /:id/services/:serviceId/rates — List rates for a service
195
+ .get("/:id/services/:serviceId/rates", async (c) => {
196
+ return c.json({
197
+ data: await suppliersService.listRates(c.get("db"), c.req.param("serviceId")),
198
+ });
199
+ })
200
+ // POST /:id/services/:serviceId/rates — Add rate to service
201
+ .post("/:id/services/:serviceId/rates", async (c) => {
202
+ const row = await suppliersService.createRate(c.get("db"), c.req.param("serviceId"), await parseJsonBody(c, insertRateSchema));
203
+ if (!row) {
204
+ return c.json({ error: "Service not found" }, 404);
205
+ }
206
+ return c.json({ data: row }, 201);
207
+ })
208
+ // PATCH /:id/services/:serviceId/rates/:rateId — Update rate
209
+ .patch("/:id/services/:serviceId/rates/:rateId", async (c) => {
210
+ const row = await suppliersService.updateRate(c.get("db"), c.req.param("rateId"), await parseJsonBody(c, updateRateSchema));
211
+ if (!row) {
212
+ return c.json({ error: "Rate not found" }, 404);
213
+ }
214
+ return c.json({ data: row });
215
+ })
216
+ // DELETE /:id/services/:serviceId/rates/:rateId — Delete rate
217
+ .delete("/:id/services/:serviceId/rates/:rateId", async (c) => {
218
+ const row = await suppliersService.deleteRate(c.get("db"), c.req.param("rateId"));
219
+ if (!row) {
220
+ return c.json({ error: "Rate not found" }, 404);
221
+ }
222
+ return c.json({ success: true }, 200);
223
+ })
224
+ // ========================================================================
225
+ // Notes
226
+ // ========================================================================
227
+ // GET /:id/notes — List notes for supplier
228
+ .get("/:id/notes", async (c) => {
229
+ return c.json({ data: await suppliersService.listNotes(c.get("db"), c.req.param("id")) });
230
+ })
231
+ // POST /:id/notes — Add note to supplier
232
+ .post("/:id/notes", async (c) => {
233
+ const userId = requireUserId(c);
234
+ const row = await suppliersService.createNote(c.get("db"), c.req.param("id"), userId, await parseJsonBody(c, insertSupplierNoteSchema));
235
+ if (!row) {
236
+ return c.json({ error: "Supplier not found" }, 404);
237
+ }
238
+ return c.json({ data: row }, 201);
239
+ })
240
+ // ========================================================================
241
+ // Availability
242
+ // ========================================================================
243
+ // GET /:id/availability — List availability entries
244
+ .get("/:id/availability", async (c) => {
245
+ const query = parseQuery(c, availabilityQuerySchema);
246
+ return c.json({
247
+ data: await suppliersService.listAvailability(c.get("db"), c.req.param("id"), query),
248
+ });
249
+ })
250
+ // POST /:id/availability — Add availability entries (bulk)
251
+ .post("/:id/availability", async (c) => {
252
+ const body = await parseJsonBody(c, z.union([z.array(insertAvailabilitySchema), insertAvailabilitySchema]));
253
+ const entries = Array.isArray(body) ? body : [body];
254
+ const row = await suppliersService.createAvailability(c.get("db"), c.req.param("id"), entries);
255
+ if (!row) {
256
+ return c.json({ error: "Supplier not found" }, 404);
257
+ }
258
+ return c.json({ data: row }, 201);
259
+ })
260
+ // ========================================================================
261
+ // Contracts
262
+ // ========================================================================
263
+ // GET /:id/contracts — List contracts
264
+ .get("/:id/contracts", async (c) => {
265
+ return c.json({ data: await suppliersService.listContracts(c.get("db"), c.req.param("id")) });
266
+ })
267
+ // POST /:id/contracts — Create contract
268
+ .post("/:id/contracts", async (c) => {
269
+ const row = await suppliersService.createContract(c.get("db"), c.req.param("id"), await parseJsonBody(c, insertContractSchema));
270
+ if (!row) {
271
+ return c.json({ error: "Supplier not found" }, 404);
272
+ }
273
+ return c.json({ data: row }, 201);
274
+ })
275
+ // PATCH /:id/contracts/:contractId — Update contract
276
+ .patch("/:id/contracts/:contractId", async (c) => {
277
+ const row = await suppliersService.updateContract(c.get("db"), c.req.param("contractId"), await parseJsonBody(c, updateContractSchema));
278
+ if (!row) {
279
+ return c.json({ error: "Contract not found" }, 404);
280
+ }
281
+ return c.json({ data: row });
282
+ })
283
+ // DELETE /:id/contracts/:contractId — Delete contract
284
+ .delete("/:id/contracts/:contractId", async (c) => {
285
+ const row = await suppliersService.deleteContract(c.get("db"), c.req.param("contractId"));
286
+ if (!row) {
287
+ return c.json({ error: "Contract not found" }, 404);
288
+ }
289
+ return c.json({ success: true }, 200);
290
+ });