@voyant-travel/quotes 0.121.0 → 0.122.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.
@@ -50,9 +50,24 @@ export interface PublicQuoteVersionProposal {
50
50
  taxAmountCents: number;
51
51
  totalAmountCents: number;
52
52
  validUntil: string | null;
53
+ notes: string | null;
53
54
  lines: PublicQuoteVersionProposalLine[];
55
+ media: PublicQuoteVersionProposalMedia[];
54
56
  operator: unknown | null;
55
57
  proposalUrl: string;
58
+ /**
59
+ * Whether the client can accept this proposal. Acceptance reserves a frozen
60
+ * Trip snapshot, so product-only proposals (no `tripSnapshotId`) are
61
+ * review-only — the client can decline but the Accept action is hidden to
62
+ * avoid a guaranteed 409 ("Proposal has no frozen Trip snapshot").
63
+ */
64
+ acceptable: boolean;
65
+ }
66
+ export interface PublicQuoteVersionProposalMedia {
67
+ url: string;
68
+ name: string;
69
+ altText: string | null;
70
+ mediaType: string;
56
71
  }
57
72
  export interface PublicQuoteVersionProposalLine {
58
73
  description: string;
@@ -1 +1 @@
1
- {"version":3,"file":"proposal-routes.d.ts","sourceRoot":"","sources":["../src/proposal-routes.ts"],"names":[],"mappings":"AA4BA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAGtB,KAAK,YAAY,EAIlB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAGzC,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,EAA6B,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAG7E;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IACzC,2DAA2D;IAC3D,SAAS,CAAC,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAAA;IACzC;;;OAGG;IACH,4BAA4B,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAA;IACvD,+EAA+E;IAC/E,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,eAAe,CAAA;IAC5C,4EAA4E;IAC5E,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAA;IAChD;;;OAGG;IACH,sBAAsB,CAAC,EAAE,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;CACxE;AAED,KAAK,wBAAwB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,SAAS,EAAE;QACT,EAAE,EAAE,OAAO,CAAA;QACX,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,KAAK,oCAAoC,GAAG;IAC1C,SAAS,EAAE;QACT,EAAE,EAAE,OAAO,CAAA;QACX,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,cAAc,EAAE,MAAM,CAAA;IACtB,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,KAAK,EAAE,8BAA8B,EAAE,CAAA;IACvC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;IACxB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,8BAA8B;IAC7C,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,YAAY,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,CAAA;IACnD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,MAAM,qCAAqC,GAAG;IAClD,QAAQ,EAAE,YAAY,CAAA;IACtB,YAAY,EAAE,YAAY,CAAA;IAC1B,KAAK,EAAE,gBAAgB,EAAE,CAAA;CAC1B,CAAA;AAED,KAAK,wBAAwB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAC,CAAA;AA0BnG,uFAAuF;AACvF,wBAAgB,4BAA4B,CAC1C,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,UAK1C;AAgCD,6FAA6F;AAC7F,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,0BAA0B,GAClC,IAAI,CAAC,wBAAwB,CAAC,CAIhC;AAED,0FAA0F;AAC1F,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,0BAA0B,GAClC,IAAI,CAAC,wBAAwB,CAAC,CAMhC;AAED,wFAAwF;AACxF,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,0BAA0B,GAClC,IAAI,CAAC,oCAAoC,CAAC,CAM5C;AA6bD,gFAAgF;AAChF,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,YAAY,GAAG,wBAAwB,CAUhG"}
1
+ {"version":3,"file":"proposal-routes.d.ts","sourceRoot":"","sources":["../src/proposal-routes.ts"],"names":[],"mappings":"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"}
@@ -55,6 +55,7 @@ function toPublicQuoteVersionProposal(proposal, options) {
55
55
  taxAmountCents: quoteVersion.taxAmountCents,
56
56
  totalAmountCents: quoteVersion.totalAmountCents,
57
57
  validUntil: quoteVersion.validUntil,
58
+ notes: quoteVersion.notes,
58
59
  lines: proposal.lines.map((line) => ({
59
60
  description: line.description,
60
61
  quantity: line.quantity,
@@ -62,14 +63,23 @@ function toPublicQuoteVersionProposal(proposal, options) {
62
63
  totalAmountCents: line.totalAmountCents,
63
64
  currency: line.currency,
64
65
  })),
66
+ media: (options.media ?? []).map((item) => ({
67
+ url: item.url,
68
+ name: item.name,
69
+ altText: item.altText,
70
+ mediaType: item.mediaType,
71
+ })),
65
72
  operator: options.operator,
66
73
  proposalUrl: options.proposalUrl,
74
+ // Only Trip-snapshot-backed versions can be reserved on accept.
75
+ acceptable: quoteVersion.tripSnapshotId !== null,
67
76
  };
68
77
  }
69
78
  /** Build the admin proposal routes (relative paths; mount at `/v1/admin/quote-versions`). */
70
79
  export function createQuoteProposalAdminRoutes(options) {
71
80
  const app = new Hono();
72
81
  app.post("/:quoteVersionId/send", (c) => handleSendQuoteVersion(c, options));
82
+ app.get("/:quoteVersionId/proposal-link", (c) => handleGetQuoteVersionProposalLink(c, options));
73
83
  return app;
74
84
  }
75
85
  /** Build the public proposal routes (relative paths; mount at `/v1/public/proposals`). */
@@ -110,6 +120,20 @@ async function handleSendQuoteVersion(c, options) {
110
120
  throw error;
111
121
  }
112
122
  }
123
+ async function handleGetQuoteVersionProposalLink(c, options) {
124
+ const quoteVersionId = c.req.param("quoteVersionId");
125
+ if (!quoteVersionId)
126
+ return c.json({ error: "Quote Version id is required" }, 400);
127
+ // Resolve the deployment's public proposal URL without any side effects
128
+ // (no view tracking, no status change) so operators can re-copy the link.
129
+ return c.json({
130
+ data: {
131
+ proposalUrl: buildQuoteVersionProposalUrl(quoteVersionId, {
132
+ baseUrl: options.resolvePublicProposalBaseUrl(c),
133
+ }),
134
+ },
135
+ });
136
+ }
113
137
  async function handleGetPublicProposal(c, options) {
114
138
  const quoteVersionId = c.req.param("quoteVersionId");
115
139
  if (!quoteVersionId)
@@ -128,10 +152,12 @@ async function handleGetPublicProposal(c, options) {
128
152
  ? await quotesService.markQuoteVersionViewed(db, quoteVersionId)
129
153
  : proposal.quoteVersion;
130
154
  const operator = await options.resolveOperatorProfile(db);
155
+ const media = await quotesService.listQuoteMedia(db, proposal.quote.id);
131
156
  return c.json({
132
157
  data: toPublicQuoteVersionProposal(proposal, {
133
158
  quoteVersion: viewedQuoteVersion,
134
159
  operator: operator ?? null,
160
+ media,
135
161
  proposalUrl: buildQuoteVersionProposalUrl(quoteVersionId, {
136
162
  baseUrl: options.resolvePublicProposalBaseUrl(c),
137
163
  }),
@@ -304,6 +304,7 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
304
304
  acceptedVersionId: string | null;
305
305
  valueAmountCents: number | null;
306
306
  valueCurrency: string | null;
307
+ paxCount: number | null;
307
308
  expectedCloseDate: string | null;
308
309
  source: string | null;
309
310
  sourceRef: string | null;
@@ -312,6 +313,9 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
312
313
  customFields: {
313
314
  [x: string]: import("hono/utils/types").JSONValue;
314
315
  };
316
+ description: string | null;
317
+ createdBy: string | null;
318
+ updatedBy: string | null;
315
319
  createdAt: string;
316
320
  updatedAt: string;
317
321
  stageChangedAt: string;
@@ -336,8 +340,10 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
336
340
  status: "open" | "won" | "lost" | "archived";
337
341
  createdAt: string;
338
342
  tags: string[];
343
+ description: string | null;
339
344
  updatedAt: string;
340
345
  organizationId: string | null;
346
+ createdBy: string | null;
341
347
  title: string;
342
348
  pipelineId: string;
343
349
  personId: string | null;
@@ -346,12 +352,14 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
346
352
  acceptedVersionId: string | null;
347
353
  valueAmountCents: number | null;
348
354
  valueCurrency: string | null;
355
+ paxCount: number | null;
349
356
  expectedCloseDate: string | null;
350
357
  sourceRef: string | null;
351
358
  lostReason: string | null;
352
359
  customFields: {
353
360
  [x: string]: import("hono/utils/types").JSONValue;
354
361
  };
362
+ updatedBy: string | null;
355
363
  stageChangedAt: string;
356
364
  closedAt: string | null;
357
365
  } | undefined;
@@ -392,6 +400,7 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
392
400
  acceptedVersionId: string | null;
393
401
  valueAmountCents: number | null;
394
402
  valueCurrency: string | null;
403
+ paxCount: number | null;
395
404
  expectedCloseDate: string | null;
396
405
  source: string | null;
397
406
  sourceRef: string | null;
@@ -400,6 +409,9 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
400
409
  customFields: {
401
410
  [x: string]: import("hono/utils/types").JSONValue;
402
411
  };
412
+ description: string | null;
413
+ createdBy: string | null;
414
+ updatedBy: string | null;
403
415
  createdAt: string;
404
416
  updatedAt: string;
405
417
  stageChangedAt: string;
@@ -442,6 +454,7 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
442
454
  acceptedVersionId: string | null;
443
455
  valueAmountCents: number | null;
444
456
  valueCurrency: string | null;
457
+ paxCount: number | null;
445
458
  expectedCloseDate: string | null;
446
459
  source: string | null;
447
460
  sourceRef: string | null;
@@ -450,6 +463,9 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
450
463
  customFields: {
451
464
  [x: string]: import("hono/utils/types").JSONValue;
452
465
  };
466
+ description: string | null;
467
+ createdBy: string | null;
468
+ updatedBy: string | null;
453
469
  createdAt: string;
454
470
  updatedAt: string;
455
471
  stageChangedAt: string;
@@ -680,6 +696,88 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
680
696
  status: import("hono/utils/http-status").ContentfulStatusCode;
681
697
  };
682
698
  };
699
+ } & {
700
+ "/quotes/:id/media": {
701
+ $get: {
702
+ input: {
703
+ param: {
704
+ id: string;
705
+ };
706
+ };
707
+ output: {
708
+ data: {
709
+ id: string;
710
+ quoteId: string;
711
+ mediaType: string;
712
+ name: string;
713
+ url: string;
714
+ storageKey: string | null;
715
+ mimeType: string | null;
716
+ fileSize: number | null;
717
+ altText: string | null;
718
+ sortOrder: number;
719
+ createdAt: string;
720
+ updatedAt: string;
721
+ }[];
722
+ };
723
+ outputFormat: "json";
724
+ status: import("hono/utils/http-status").ContentfulStatusCode;
725
+ };
726
+ };
727
+ } & {
728
+ "/quotes/:id/media": {
729
+ $post: {
730
+ input: {
731
+ param: {
732
+ id: string;
733
+ };
734
+ };
735
+ output: {
736
+ data: {
737
+ id: string;
738
+ name: string;
739
+ createdAt: string;
740
+ updatedAt: string;
741
+ url: string;
742
+ storageKey: string | null;
743
+ quoteId: string;
744
+ sortOrder: number;
745
+ mediaType: string;
746
+ mimeType: string | null;
747
+ fileSize: number | null;
748
+ altText: string | null;
749
+ } | undefined;
750
+ };
751
+ outputFormat: "json";
752
+ status: 201;
753
+ };
754
+ };
755
+ } & {
756
+ "/quote-media/:id": {
757
+ $delete: {
758
+ input: {
759
+ param: {
760
+ id: string;
761
+ };
762
+ };
763
+ output: {
764
+ error: string;
765
+ };
766
+ outputFormat: "json";
767
+ status: 404;
768
+ } | {
769
+ input: {
770
+ param: {
771
+ id: string;
772
+ };
773
+ };
774
+ output: {
775
+ success: true;
776
+ };
777
+ outputFormat: "json";
778
+ status: import("hono/utils/http-status").ContentfulStatusCode;
779
+ };
780
+ };
683
781
  }, "/"> | import("hono/types").MergeSchemaPath<{
684
782
  "/quote-versions": {
685
783
  $get: {
@@ -758,6 +856,96 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
758
856
  status: 409;
759
857
  };
760
858
  };
859
+ } & {
860
+ "/quote-versions/:id/validity": {
861
+ $patch: {
862
+ input: {
863
+ param: {
864
+ id: string;
865
+ };
866
+ };
867
+ output: {
868
+ error: string;
869
+ };
870
+ outputFormat: "json";
871
+ status: 404;
872
+ } | {
873
+ input: {
874
+ param: {
875
+ id: string;
876
+ };
877
+ };
878
+ output: {
879
+ data: {
880
+ id: string;
881
+ quoteId: string;
882
+ label: string | null;
883
+ status: "expired" | "draft" | "sent" | "accepted" | "declined" | "superseded";
884
+ supersedesId: string | null;
885
+ tripSnapshotId: string | null;
886
+ validUntil: string | null;
887
+ currency: string;
888
+ subtotalAmountCents: number;
889
+ taxAmountCents: number;
890
+ totalAmountCents: number;
891
+ notes: string | null;
892
+ sentAt: string | null;
893
+ viewedAt: string | null;
894
+ decidedAt: string | null;
895
+ createdAt: string;
896
+ updatedAt: string;
897
+ archivedAt: string | null;
898
+ };
899
+ };
900
+ outputFormat: "json";
901
+ status: import("hono/utils/http-status").ContentfulStatusCode;
902
+ };
903
+ };
904
+ } & {
905
+ "/quotes/:id/versions/snapshot": {
906
+ $post: {
907
+ input: {
908
+ param: {
909
+ id: string;
910
+ };
911
+ };
912
+ output: {
913
+ error: string;
914
+ };
915
+ outputFormat: "json";
916
+ status: 404;
917
+ } | {
918
+ input: {
919
+ param: {
920
+ id: string;
921
+ };
922
+ };
923
+ output: {
924
+ data: {
925
+ currency: string;
926
+ id: string;
927
+ status: "expired" | "draft" | "sent" | "accepted" | "declined" | "superseded";
928
+ createdAt: string;
929
+ updatedAt: string;
930
+ notes: string | null;
931
+ quoteId: string;
932
+ label: string | null;
933
+ supersedesId: string | null;
934
+ tripSnapshotId: string | null;
935
+ validUntil: string | null;
936
+ subtotalAmountCents: number;
937
+ taxAmountCents: number;
938
+ totalAmountCents: number;
939
+ sentAt: string | null;
940
+ viewedAt: string | null;
941
+ decidedAt: string | null;
942
+ archivedAt: string | null;
943
+ };
944
+ };
945
+ outputFormat: "json";
946
+ status: 201;
947
+ };
948
+ };
761
949
  } & {
762
950
  "/quote-versions/expire": {
763
951
  $post: {
@@ -1125,8 +1313,10 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
1125
1313
  status: "open" | "won" | "lost" | "archived";
1126
1314
  createdAt: string;
1127
1315
  tags: string[];
1316
+ description: string | null;
1128
1317
  updatedAt: string;
1129
1318
  organizationId: string | null;
1319
+ createdBy: string | null;
1130
1320
  title: string;
1131
1321
  pipelineId: string;
1132
1322
  personId: string | null;
@@ -1135,12 +1325,14 @@ export declare const quotesRoutes: import("hono/hono-base").HonoBase<Env, import
1135
1325
  acceptedVersionId: string | null;
1136
1326
  valueAmountCents: number | null;
1137
1327
  valueCurrency: string | null;
1328
+ paxCount: number | null;
1138
1329
  expectedCloseDate: string | null;
1139
1330
  sourceRef: string | null;
1140
1331
  lostReason: string | null;
1141
1332
  customFields: {
1142
1333
  [x: string]: import("hono/utils/types").JSONValue;
1143
1334
  };
1335
+ updatedBy: string | null;
1144
1336
  stageChangedAt: string;
1145
1337
  closedAt: string | null;
1146
1338
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAOjE,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAGQ,CAAA;AAEjC,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAOjE,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAGQ,CAAA;AAEjC,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAA"}
@@ -83,6 +83,96 @@ export declare const quoteVersionRoutes: import("hono/hono-base").HonoBase<Env,
83
83
  status: 409;
84
84
  };
85
85
  };
86
+ } & {
87
+ "/quote-versions/:id/validity": {
88
+ $patch: {
89
+ input: {
90
+ param: {
91
+ id: string;
92
+ };
93
+ };
94
+ output: {
95
+ error: string;
96
+ };
97
+ outputFormat: "json";
98
+ status: 404;
99
+ } | {
100
+ input: {
101
+ param: {
102
+ id: string;
103
+ };
104
+ };
105
+ output: {
106
+ data: {
107
+ id: string;
108
+ quoteId: string;
109
+ label: string | null;
110
+ status: "expired" | "draft" | "sent" | "accepted" | "declined" | "superseded";
111
+ supersedesId: string | null;
112
+ tripSnapshotId: string | null;
113
+ validUntil: string | null;
114
+ currency: string;
115
+ subtotalAmountCents: number;
116
+ taxAmountCents: number;
117
+ totalAmountCents: number;
118
+ notes: string | null;
119
+ sentAt: string | null;
120
+ viewedAt: string | null;
121
+ decidedAt: string | null;
122
+ createdAt: string;
123
+ updatedAt: string;
124
+ archivedAt: string | null;
125
+ };
126
+ };
127
+ outputFormat: "json";
128
+ status: import("hono/utils/http-status").ContentfulStatusCode;
129
+ };
130
+ };
131
+ } & {
132
+ "/quotes/:id/versions/snapshot": {
133
+ $post: {
134
+ input: {
135
+ param: {
136
+ id: string;
137
+ };
138
+ };
139
+ output: {
140
+ error: string;
141
+ };
142
+ outputFormat: "json";
143
+ status: 404;
144
+ } | {
145
+ input: {
146
+ param: {
147
+ id: string;
148
+ };
149
+ };
150
+ output: {
151
+ data: {
152
+ currency: string;
153
+ id: string;
154
+ status: "expired" | "draft" | "sent" | "accepted" | "declined" | "superseded";
155
+ createdAt: string;
156
+ updatedAt: string;
157
+ notes: string | null;
158
+ quoteId: string;
159
+ label: string | null;
160
+ supersedesId: string | null;
161
+ tripSnapshotId: string | null;
162
+ validUntil: string | null;
163
+ subtotalAmountCents: number;
164
+ taxAmountCents: number;
165
+ totalAmountCents: number;
166
+ sentAt: string | null;
167
+ viewedAt: string | null;
168
+ decidedAt: string | null;
169
+ archivedAt: string | null;
170
+ };
171
+ };
172
+ outputFormat: "json";
173
+ status: 201;
174
+ };
175
+ };
86
176
  } & {
87
177
  "/quote-versions/expire": {
88
178
  $post: {
@@ -450,8 +540,10 @@ export declare const quoteVersionRoutes: import("hono/hono-base").HonoBase<Env,
450
540
  status: "open" | "won" | "lost" | "archived";
451
541
  createdAt: string;
452
542
  tags: string[];
543
+ description: string | null;
453
544
  updatedAt: string;
454
545
  organizationId: string | null;
546
+ createdBy: string | null;
455
547
  title: string;
456
548
  pipelineId: string;
457
549
  personId: string | null;
@@ -460,12 +552,14 @@ export declare const quoteVersionRoutes: import("hono/hono-base").HonoBase<Env,
460
552
  acceptedVersionId: string | null;
461
553
  valueAmountCents: number | null;
462
554
  valueCurrency: string | null;
555
+ paxCount: number | null;
463
556
  expectedCloseDate: string | null;
464
557
  sourceRef: string | null;
465
558
  lostReason: string | null;
466
559
  customFields: {
467
560
  [x: string]: import("hono/utils/types").JSONValue;
468
561
  };
562
+ updatedBy: string | null;
469
563
  stageChangedAt: string;
470
564
  closedAt: string | null;
471
565
  };
@@ -1 +1 @@
1
- {"version":3,"file":"quote-versions.d.ts","sourceRoot":"","sources":["../../src/routes/quote-versions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAiBjE,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAsL3B,CAAA"}
1
+ {"version":3,"file":"quote-versions.d.ts","sourceRoot":"","sources":["../../src/routes/quote-versions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAkBjE,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAwM3B,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { parseJsonBody, parseOptionalJsonBody, parseQuery } from "@voyant-travel/hono";
2
2
  import { Hono } from "hono";
3
+ import { z } from "zod";
3
4
  import { quotesService } from "../service/index.js";
4
5
  import { QuoteVersionConflictError } from "../service/quote-versions.js";
5
6
  import { acceptQuoteVersionSchema, applyTripSnapshotToQuoteVersionSchema, declineQuoteVersionSchema, expireQuoteVersionsSchema, insertQuoteVersionLineSchema, insertQuoteVersionSchema, quoteVersionListQuerySchema, sendQuoteVersionSchema, updateQuoteVersionLineSchema, updateQuoteVersionSchema, } from "../validation.js";
@@ -24,6 +25,19 @@ export const quoteVersionRoutes = new Hono()
24
25
  }
25
26
  throw error;
26
27
  }
28
+ })
29
+ .patch("/quote-versions/:id/validity", async (c) => {
30
+ const body = await parseJsonBody(c, z.object({ validUntil: z.string().date().nullable() }));
31
+ const row = await quotesService.setQuoteVersionValidUntil(c.get("db"), c.req.param("id"), body.validUntil);
32
+ if (!row)
33
+ return c.json({ error: "Quote version not found" }, 404);
34
+ return c.json({ data: row });
35
+ })
36
+ .post("/quotes/:id/versions/snapshot", async (c) => {
37
+ const version = await quotesService.createVersionSnapshotFromQuote(c.get("db"), c.req.param("id"));
38
+ if (!version)
39
+ return c.json({ error: "Quote not found" }, 404);
40
+ return c.json({ data: version }, 201);
27
41
  })
28
42
  .post("/quote-versions/expire", async (c) => {
29
43
  return c.json({