@voyantjs/finance 0.46.0 → 0.47.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.
- package/README.md +14 -0
- package/dist/routes-public.d.ts +92 -0
- package/dist/routes-public.d.ts.map +1 -1
- package/dist/routes-public.js +7 -0
- package/dist/service-public.d.ts +1 -0
- package/dist/service-public.d.ts.map +1 -1
- package/dist/service-public.js +40 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -59,6 +59,20 @@ The event does not include rendered document bodies or signed download URLs.
|
|
|
59
59
|
Subscriber failures do not roll back the rendition write; use a durable job or
|
|
60
60
|
workflow when a downstream reaction needs retries.
|
|
61
61
|
|
|
62
|
+
## Customer-Safe Document Lookup
|
|
63
|
+
|
|
64
|
+
Public finance routes include booking-scoped document lookup for customer
|
|
65
|
+
portal and checkout surfaces:
|
|
66
|
+
|
|
67
|
+
- `GET /v1/public/finance/bookings/:bookingId/documents`
|
|
68
|
+
- `GET /v1/public/finance/bookings/:bookingId/documents/by-reference?reference=...`
|
|
69
|
+
- `GET /v1/public/finance/documents/by-reference?reference=...`
|
|
70
|
+
|
|
71
|
+
Booking-scoped routes require a checkout capability for the requested booking.
|
|
72
|
+
The by-reference variant resolves invoice numbers and payment reference numbers
|
|
73
|
+
only inside that booking, so a valid capability for one booking cannot retrieve
|
|
74
|
+
documents from another booking.
|
|
75
|
+
|
|
62
76
|
## Exports
|
|
63
77
|
|
|
64
78
|
| Entry | Description |
|
package/dist/routes-public.d.ts
CHANGED
|
@@ -194,6 +194,52 @@ export declare function createPublicFinanceRoutes(options?: PublicFinanceRouteOp
|
|
|
194
194
|
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
195
195
|
};
|
|
196
196
|
};
|
|
197
|
+
} & {
|
|
198
|
+
"/bookings/:bookingId/documents/by-reference": {
|
|
199
|
+
$get: {
|
|
200
|
+
input: {
|
|
201
|
+
param: {
|
|
202
|
+
bookingId: string;
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
output: {
|
|
206
|
+
error: string;
|
|
207
|
+
};
|
|
208
|
+
outputFormat: "json";
|
|
209
|
+
status: 404;
|
|
210
|
+
} | {
|
|
211
|
+
input: {
|
|
212
|
+
param: {
|
|
213
|
+
bookingId: string;
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
output: {
|
|
217
|
+
data: {
|
|
218
|
+
invoiceId: string;
|
|
219
|
+
invoiceNumber: string;
|
|
220
|
+
invoiceType: "invoice" | "proforma" | "credit_note";
|
|
221
|
+
invoiceStatus: "void" | "draft" | "sent" | "partially_paid" | "paid" | "overdue";
|
|
222
|
+
currency: string;
|
|
223
|
+
totalCents: number;
|
|
224
|
+
paidCents: number;
|
|
225
|
+
balanceDueCents: number;
|
|
226
|
+
issueDate: string;
|
|
227
|
+
dueDate: string;
|
|
228
|
+
renditionId: string | null;
|
|
229
|
+
documentStatus: "pending" | "failed" | "ready" | "stale" | "missing";
|
|
230
|
+
format: "json" | "pdf" | "html" | "xml" | null;
|
|
231
|
+
language: string | null;
|
|
232
|
+
generatedAt: string | null;
|
|
233
|
+
fileSize: number | null;
|
|
234
|
+
checksum: string | null;
|
|
235
|
+
downloadUrl: string | null;
|
|
236
|
+
bookingId: string;
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
outputFormat: "json";
|
|
240
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
241
|
+
};
|
|
242
|
+
};
|
|
197
243
|
} & {
|
|
198
244
|
"/bookings/:bookingId/payments": {
|
|
199
245
|
$get: {
|
|
@@ -750,6 +796,52 @@ export declare const publicFinanceRoutes: import("hono/hono-base").HonoBase<Env,
|
|
|
750
796
|
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
751
797
|
};
|
|
752
798
|
};
|
|
799
|
+
} & {
|
|
800
|
+
"/bookings/:bookingId/documents/by-reference": {
|
|
801
|
+
$get: {
|
|
802
|
+
input: {
|
|
803
|
+
param: {
|
|
804
|
+
bookingId: string;
|
|
805
|
+
};
|
|
806
|
+
};
|
|
807
|
+
output: {
|
|
808
|
+
error: string;
|
|
809
|
+
};
|
|
810
|
+
outputFormat: "json";
|
|
811
|
+
status: 404;
|
|
812
|
+
} | {
|
|
813
|
+
input: {
|
|
814
|
+
param: {
|
|
815
|
+
bookingId: string;
|
|
816
|
+
};
|
|
817
|
+
};
|
|
818
|
+
output: {
|
|
819
|
+
data: {
|
|
820
|
+
invoiceId: string;
|
|
821
|
+
invoiceNumber: string;
|
|
822
|
+
invoiceType: "invoice" | "proforma" | "credit_note";
|
|
823
|
+
invoiceStatus: "void" | "draft" | "sent" | "partially_paid" | "paid" | "overdue";
|
|
824
|
+
currency: string;
|
|
825
|
+
totalCents: number;
|
|
826
|
+
paidCents: number;
|
|
827
|
+
balanceDueCents: number;
|
|
828
|
+
issueDate: string;
|
|
829
|
+
dueDate: string;
|
|
830
|
+
renditionId: string | null;
|
|
831
|
+
documentStatus: "pending" | "failed" | "ready" | "stale" | "missing";
|
|
832
|
+
format: "json" | "pdf" | "html" | "xml" | null;
|
|
833
|
+
language: string | null;
|
|
834
|
+
generatedAt: string | null;
|
|
835
|
+
fileSize: number | null;
|
|
836
|
+
checksum: string | null;
|
|
837
|
+
downloadUrl: string | null;
|
|
838
|
+
bookingId: string;
|
|
839
|
+
};
|
|
840
|
+
};
|
|
841
|
+
outputFormat: "json";
|
|
842
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
843
|
+
};
|
|
844
|
+
};
|
|
753
845
|
} & {
|
|
754
846
|
"/bookings/:bookingId/payments": {
|
|
755
847
|
$get: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes-public.d.ts","sourceRoot":"","sources":["../src/routes-public.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,GAAG,EAA2B,MAAM,oBAAoB,CAAA;AAStE,MAAM,WAAW,yBAAyB;IACxC,0BAA0B,CAAC,EAAE,CAC3B,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAA;CAC5C;AA+CD,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,yBAA8B
|
|
1
|
+
{"version":3,"file":"routes-public.d.ts","sourceRoot":"","sources":["../src/routes-public.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,GAAG,EAA2B,MAAM,oBAAoB,CAAA;AAStE,MAAM,WAAW,yBAAyB;IACxC,0BAA0B,CAAC,EAAE,CAC3B,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAA;CAC5C;AA+CD,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,yBAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gDAwJhF;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+CAA8B,CAAA;AAE9D,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAA"}
|
package/dist/routes-public.js
CHANGED
|
@@ -63,6 +63,13 @@ export function createPublicFinanceRoutes(options = {}) {
|
|
|
63
63
|
resolveDocumentDownloadUrl: (storageKey) => resolveDocumentDownloadUrl(c.env, storageKey),
|
|
64
64
|
});
|
|
65
65
|
return documents ? c.json({ data: documents }) : notFound(c, "Booking documents not found");
|
|
66
|
+
})
|
|
67
|
+
.get("/bookings/:bookingId/documents/by-reference", async (c) => {
|
|
68
|
+
await requireBookingCheckoutCapability(c, c.req.param("bookingId"), "payment:read");
|
|
69
|
+
const document = await publicFinanceService.getBookingDocumentByReference(c.get("db"), c.req.param("bookingId"), parseQuery(c, publicFinanceDocumentLookupQuerySchema).reference, {
|
|
70
|
+
resolveDocumentDownloadUrl: (storageKey) => resolveDocumentDownloadUrl(c.env, storageKey),
|
|
71
|
+
});
|
|
72
|
+
return document ? c.json({ data: document }) : notFound(c, "Finance document not found");
|
|
66
73
|
})
|
|
67
74
|
.get("/bookings/:bookingId/payments", async (c) => {
|
|
68
75
|
await requireBookingCheckoutCapability(c, c.req.param("bookingId"), "payment:read");
|
package/dist/service-public.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface PublicFinanceRuntimeOptions {
|
|
|
6
6
|
export declare const publicFinanceService: {
|
|
7
7
|
getBookingDocuments(db: PostgresJsDatabase, bookingId: string, runtime?: PublicFinanceRuntimeOptions): Promise<PublicBookingFinanceDocuments | null>;
|
|
8
8
|
getDocumentByReference(db: PostgresJsDatabase, reference: string, runtime?: PublicFinanceRuntimeOptions): Promise<PublicFinanceDocumentLookup | null>;
|
|
9
|
+
getBookingDocumentByReference(db: PostgresJsDatabase, bookingId: string, reference: string, runtime?: PublicFinanceRuntimeOptions): Promise<PublicFinanceDocumentLookup | null>;
|
|
9
10
|
getBookingPaymentOptions(db: PostgresJsDatabase, bookingId: string, query: PublicPaymentOptionsQuery): Promise<{
|
|
10
11
|
bookingId: string;
|
|
11
12
|
accounts: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-public.d.ts","sourceRoot":"","sources":["../src/service-public.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAYjE,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAE5B,2BAA2B,EAC3B,yBAAyB,EACzB,8BAA8B,EAC9B,0BAA0B,EAC3B,MAAM,wBAAwB,CAAA;AAE/B,MAAM,WAAW,2BAA2B;IAC1C,0BAA0B,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAA;CAC5F;AA+HD,eAAO,MAAM,oBAAoB;4BAEzB,kBAAkB,aACX,MAAM,YACR,2BAA2B,GACnC,OAAO,CAAC,6BAA6B,GAAG,IAAI,CAAC;+BA6C1C,kBAAkB,aACX,MAAM,YACR,2BAA2B,GACnC,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"service-public.d.ts","sourceRoot":"","sources":["../src/service-public.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAYjE,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAE5B,2BAA2B,EAC3B,yBAAyB,EACzB,8BAA8B,EAC9B,0BAA0B,EAC3B,MAAM,wBAAwB,CAAA;AAE/B,MAAM,WAAW,2BAA2B;IAC1C,0BAA0B,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAA;CAC5F;AA+HD,eAAO,MAAM,oBAAoB;4BAEzB,kBAAkB,aACX,MAAM,YACR,2BAA2B,GACnC,OAAO,CAAC,6BAA6B,GAAG,IAAI,CAAC;+BA6C1C,kBAAkB,aACX,MAAM,YACR,2BAA2B,GACnC,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC;sCA0CxC,kBAAkB,aACX,MAAM,aACN,MAAM,YACR,2BAA2B,GACnC,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC;iCA+CxC,kBAAkB,aACX,MAAM,SACV,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAoH5B,kBAAkB,aACX,MAAM,GAChB,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC;0BA2DnB,kBAAkB,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAKnC,kBAAkB,aAAa,MAAM;2CAW7D,kBAAkB,aACX,MAAM,cACL,MAAM,SACX,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;4CA4BjC,kBAAkB,aACX,MAAM,eACJ,MAAM,SACZ,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAuBjC,kBAAkB,aACX,MAAM,SACV,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAMb,kBAAkB,SAAS,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEhF,CAAA"}
|
package/dist/service-public.js
CHANGED
|
@@ -172,6 +172,46 @@ export const publicFinanceService = {
|
|
|
172
172
|
...(await mapInvoiceDocument(invoice, renditions, runtime)),
|
|
173
173
|
};
|
|
174
174
|
},
|
|
175
|
+
async getBookingDocumentByReference(db, bookingId, reference, runtime = {}) {
|
|
176
|
+
const [invoiceMatch, paymentMatch] = await Promise.all([
|
|
177
|
+
db
|
|
178
|
+
.select()
|
|
179
|
+
.from(invoices)
|
|
180
|
+
.where(and(eq(invoices.bookingId, bookingId), eq(invoices.invoiceNumber, reference)))
|
|
181
|
+
.orderBy(desc(invoices.createdAt))
|
|
182
|
+
.limit(1),
|
|
183
|
+
db
|
|
184
|
+
.select({
|
|
185
|
+
invoiceId: payments.invoiceId,
|
|
186
|
+
})
|
|
187
|
+
.from(payments)
|
|
188
|
+
.innerJoin(invoices, eq(payments.invoiceId, invoices.id))
|
|
189
|
+
.where(and(eq(invoices.bookingId, bookingId), eq(payments.referenceNumber, reference)))
|
|
190
|
+
.orderBy(desc(payments.createdAt))
|
|
191
|
+
.limit(1),
|
|
192
|
+
]);
|
|
193
|
+
const invoiceId = invoiceMatch[0]?.id ?? paymentMatch[0]?.invoiceId ?? null;
|
|
194
|
+
if (!invoiceId) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
const [invoice] = await db
|
|
198
|
+
.select()
|
|
199
|
+
.from(invoices)
|
|
200
|
+
.where(and(eq(invoices.id, invoiceId), eq(invoices.bookingId, bookingId)))
|
|
201
|
+
.limit(1);
|
|
202
|
+
if (!invoice?.bookingId) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
const renditions = await db
|
|
206
|
+
.select()
|
|
207
|
+
.from(invoiceRenditions)
|
|
208
|
+
.where(eq(invoiceRenditions.invoiceId, invoice.id))
|
|
209
|
+
.orderBy(desc(invoiceRenditions.createdAt));
|
|
210
|
+
return {
|
|
211
|
+
bookingId: invoice.bookingId,
|
|
212
|
+
...(await mapInvoiceDocument(invoice, renditions, runtime)),
|
|
213
|
+
};
|
|
214
|
+
},
|
|
175
215
|
async getBookingPaymentOptions(db, bookingId, query) {
|
|
176
216
|
const [booking] = await db
|
|
177
217
|
.select({ id: bookings.id })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/finance",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.47.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
"drizzle-orm": "^0.45.2",
|
|
40
40
|
"hono": "^4.12.10",
|
|
41
41
|
"zod": "^4.3.6",
|
|
42
|
-
"@voyantjs/bookings": "0.
|
|
43
|
-
"@voyantjs/core": "0.
|
|
44
|
-
"@voyantjs/db": "0.
|
|
45
|
-
"@voyantjs/hono": "0.
|
|
46
|
-
"@voyantjs/utils": "0.
|
|
47
|
-
"@voyantjs/storage": "0.
|
|
42
|
+
"@voyantjs/bookings": "0.47.0",
|
|
43
|
+
"@voyantjs/core": "0.47.0",
|
|
44
|
+
"@voyantjs/db": "0.47.0",
|
|
45
|
+
"@voyantjs/hono": "0.47.0",
|
|
46
|
+
"@voyantjs/utils": "0.47.0",
|
|
47
|
+
"@voyantjs/storage": "0.47.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"typescript": "^6.0.2",
|