@voyantjs/finance 0.5.0 → 0.6.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.
@@ -1,3 +1,4 @@
1
+ import { parseJsonBody, parseQuery } from "@voyantjs/hono";
1
2
  import { Hono } from "hono";
2
3
  import { notFound } from "./routes-shared.js";
3
4
  import { publicFinanceService } from "./service-public.js";
@@ -8,57 +9,67 @@ function paymentConflictError(error) {
8
9
  }
9
10
  return "Unable to start payment session";
10
11
  }
11
- export const publicFinanceRoutes = new Hono()
12
- .post("/vouchers/validate", async (c) => {
13
- const result = await publicFinanceService.validateVoucher(c.get("db"), publicValidateVoucherSchema.parse(await c.req.json()));
14
- return c.json({ data: result });
15
- })
16
- .get("/documents/by-reference", async (c) => {
17
- const document = await publicFinanceService.getDocumentByReference(c.get("db"), publicFinanceDocumentLookupQuerySchema.parse(Object.fromEntries(new URL(c.req.url).searchParams)).reference);
18
- return document ? c.json({ data: document }) : notFound(c, "Finance document not found");
19
- })
20
- .get("/bookings/:bookingId/documents", async (c) => {
21
- const documents = await publicFinanceService.getBookingDocuments(c.get("db"), c.req.param("bookingId"));
22
- return documents ? c.json({ data: documents }) : notFound(c, "Booking documents not found");
23
- })
24
- .get("/bookings/:bookingId/payments", async (c) => {
25
- const payments = await publicFinanceService.getBookingPayments(c.get("db"), c.req.param("bookingId"));
26
- return payments ? c.json({ data: payments }) : notFound(c, "Booking payments not found");
27
- })
28
- .get("/bookings/:bookingId/payment-options", async (c) => {
29
- const options = await publicFinanceService.getBookingPaymentOptions(c.get("db"), c.req.param("bookingId"), publicPaymentOptionsQuerySchema.parse(Object.fromEntries(new URL(c.req.url).searchParams)));
30
- return options ? c.json({ data: options }) : notFound(c, "Booking payment options not found");
31
- })
32
- .get("/payment-sessions/:sessionId", async (c) => {
33
- const session = await publicFinanceService.getPaymentSession(c.get("db"), c.req.param("sessionId"));
34
- return session ? c.json({ data: session }) : notFound(c, "Payment session not found");
35
- })
36
- .post("/bookings/:bookingId/payment-schedules/:scheduleId/payment-session", async (c) => {
37
- try {
38
- const session = await publicFinanceService.startBookingSchedulePaymentSession(c.get("db"), c.req.param("bookingId"), c.req.param("scheduleId"), publicStartPaymentSessionSchema.parse(await c.req.json()));
39
- return session
40
- ? c.json({ data: session }, 201)
41
- : notFound(c, "Booking payment schedule not found");
42
- }
43
- catch (error) {
44
- return c.json({ error: paymentConflictError(error) }, 409);
45
- }
46
- })
47
- .post("/bookings/:bookingId/guarantees/:guaranteeId/payment-session", async (c) => {
48
- try {
49
- const session = await publicFinanceService.startBookingGuaranteePaymentSession(c.get("db"), c.req.param("bookingId"), c.req.param("guaranteeId"), publicStartPaymentSessionSchema.parse(await c.req.json()));
50
- return session ? c.json({ data: session }, 201) : notFound(c, "Booking guarantee not found");
51
- }
52
- catch (error) {
53
- return c.json({ error: paymentConflictError(error) }, 409);
54
- }
55
- })
56
- .post("/invoices/:invoiceId/payment-session", async (c) => {
57
- try {
58
- const session = await publicFinanceService.startInvoicePaymentSession(c.get("db"), c.req.param("invoiceId"), publicStartPaymentSessionSchema.parse(await c.req.json()));
59
- return session ? c.json({ data: session }, 201) : notFound(c, "Invoice not found");
60
- }
61
- catch (error) {
62
- return c.json({ error: paymentConflictError(error) }, 409);
63
- }
64
- });
12
+ export function createPublicFinanceRoutes(options = {}) {
13
+ const resolveDocumentDownloadUrl = (bindings, storageKey) => options.resolveDocumentDownloadUrl?.(bindings, storageKey) ?? null;
14
+ return new Hono()
15
+ .post("/vouchers/validate", async (c) => {
16
+ const result = await publicFinanceService.validateVoucher(c.get("db"), await parseJsonBody(c, publicValidateVoucherSchema));
17
+ return c.json({ data: result });
18
+ })
19
+ .get("/documents/by-reference", async (c) => {
20
+ const document = await publicFinanceService.getDocumentByReference(c.get("db"), parseQuery(c, publicFinanceDocumentLookupQuerySchema).reference, {
21
+ resolveDocumentDownloadUrl: (storageKey) => resolveDocumentDownloadUrl(c.env, storageKey),
22
+ });
23
+ return document ? c.json({ data: document }) : notFound(c, "Finance document not found");
24
+ })
25
+ .get("/bookings/:bookingId/documents", async (c) => {
26
+ const documents = await publicFinanceService.getBookingDocuments(c.get("db"), c.req.param("bookingId"), {
27
+ resolveDocumentDownloadUrl: (storageKey) => resolveDocumentDownloadUrl(c.env, storageKey),
28
+ });
29
+ return documents ? c.json({ data: documents }) : notFound(c, "Booking documents not found");
30
+ })
31
+ .get("/bookings/:bookingId/payments", async (c) => {
32
+ const payments = await publicFinanceService.getBookingPayments(c.get("db"), c.req.param("bookingId"));
33
+ return payments ? c.json({ data: payments }) : notFound(c, "Booking payments not found");
34
+ })
35
+ .get("/bookings/:bookingId/payment-options", async (c) => {
36
+ const paymentOptions = await publicFinanceService.getBookingPaymentOptions(c.get("db"), c.req.param("bookingId"), parseQuery(c, publicPaymentOptionsQuerySchema));
37
+ return paymentOptions
38
+ ? c.json({ data: paymentOptions })
39
+ : notFound(c, "Booking payment options not found");
40
+ })
41
+ .get("/payment-sessions/:sessionId", async (c) => {
42
+ const session = await publicFinanceService.getPaymentSession(c.get("db"), c.req.param("sessionId"));
43
+ return session ? c.json({ data: session }) : notFound(c, "Payment session not found");
44
+ })
45
+ .post("/bookings/:bookingId/payment-schedules/:scheduleId/payment-session", async (c) => {
46
+ try {
47
+ const session = await publicFinanceService.startBookingSchedulePaymentSession(c.get("db"), c.req.param("bookingId"), c.req.param("scheduleId"), await parseJsonBody(c, publicStartPaymentSessionSchema));
48
+ return session
49
+ ? c.json({ data: session }, 201)
50
+ : notFound(c, "Booking payment schedule not found");
51
+ }
52
+ catch (error) {
53
+ return c.json({ error: paymentConflictError(error) }, 409);
54
+ }
55
+ })
56
+ .post("/bookings/:bookingId/guarantees/:guaranteeId/payment-session", async (c) => {
57
+ try {
58
+ const session = await publicFinanceService.startBookingGuaranteePaymentSession(c.get("db"), c.req.param("bookingId"), c.req.param("guaranteeId"), await parseJsonBody(c, publicStartPaymentSessionSchema));
59
+ return session ? c.json({ data: session }, 201) : notFound(c, "Booking guarantee not found");
60
+ }
61
+ catch (error) {
62
+ return c.json({ error: paymentConflictError(error) }, 409);
63
+ }
64
+ })
65
+ .post("/invoices/:invoiceId/payment-session", async (c) => {
66
+ try {
67
+ const session = await publicFinanceService.startInvoicePaymentSession(c.get("db"), c.req.param("invoiceId"), await parseJsonBody(c, publicStartPaymentSessionSchema));
68
+ return session ? c.json({ data: session }, 201) : notFound(c, "Invoice not found");
69
+ }
70
+ catch (error) {
71
+ return c.json({ error: paymentConflictError(error) }, 409);
72
+ }
73
+ });
74
+ }
75
+ export const publicFinanceRoutes = createPublicFinanceRoutes();
@@ -1,8 +1,9 @@
1
- import type { EventBus } from "@voyantjs/core";
1
+ import type { EventBus, ModuleContainer } from "@voyantjs/core";
2
2
  import { type InvoiceSettlementPoller } from "./service-settlement.js";
3
3
  type Env = {
4
4
  Bindings: Record<string, unknown>;
5
5
  Variables: {
6
+ container: ModuleContainer;
6
7
  db: import("drizzle-orm/postgres-js").PostgresJsDatabase;
7
8
  userId?: string;
8
9
  };
@@ -35,7 +36,7 @@ export declare function createFinanceAdminSettlementRoutes(options?: FinanceSett
35
36
  output: {
36
37
  data: {
37
38
  invoiceId: string;
38
- invoiceStatus: "draft" | "sent" | "partially_paid" | "paid" | "overdue" | "void";
39
+ invoiceStatus: "void" | "draft" | "sent" | "partially_paid" | "paid" | "overdue";
39
40
  paidCents: number;
40
41
  balanceDueCents: number;
41
42
  results: {
@@ -1 +1 @@
1
- {"version":3,"file":"routes-settlement.d.ts","sourceRoot":"","sources":["../src/routes-settlement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAG9C,OAAO,EAA4B,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAGhG,KAAK,GAAG,GAAG;IACT,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,SAAS,EAAE;QACT,EAAE,EAAE,OAAO,yBAAyB,EAAE,kBAAkB,CAAA;QACxD,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,MAAM,WAAW,6BAA6B;IAC5C,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAA;IAClE,+BAA+B,CAAC,EAAE,CAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC9B,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,GAAG,SAAS,CAAA;IACxD,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,QAAQ,GAAG,SAAS,CAAA;CAC9E;AAkBD,wBAAgB,kCAAkC,CAAC,OAAO,GAAE,6BAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAmB7F;AAED,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA"}
1
+ {"version":3,"file":"routes-settlement.d.ts","sourceRoot":"","sources":["../src/routes-settlement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAS/D,OAAO,EAA4B,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAGhG,KAAK,GAAG,GAAG;IACT,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,SAAS,EAAE;QACT,SAAS,EAAE,eAAe,CAAA;QAC1B,EAAE,EAAE,OAAO,yBAAyB,EAAE,kBAAkB,CAAA;QACxD,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,MAAM,WAAW,6BAA6B;IAC5C,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAA;IAClE,+BAA+B,CAAC,EAAE,CAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC9B,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,GAAG,SAAS,CAAA;IACxD,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,QAAQ,GAAG,SAAS,CAAA;CAC9E;AAaD,wBAAgB,kCAAkC,CAAC,OAAO,GAAE,6BAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAqB7F;AAED,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA"}
@@ -1,18 +1,19 @@
1
+ import { parseOptionalJsonBody } from "@voyantjs/hono";
1
2
  import { Hono } from "hono";
3
+ import { buildFinanceRouteRuntime, FINANCE_ROUTE_RUNTIME_CONTAINER_KEY, } from "./route-runtime.js";
2
4
  import { financeSettlementService } from "./service-settlement.js";
3
5
  import { pollInvoiceSettlementInputSchema } from "./validation.js";
4
- function resolveInvoiceSettlementPollers(options, bindings) {
5
- return (options?.resolveInvoiceSettlementPollers?.(bindings) ?? options?.invoiceSettlementPollers ?? {});
6
- }
7
- function resolveEventBus(options, bindings) {
8
- return options?.resolveEventBus?.(bindings) ?? options?.eventBus;
6
+ function getRuntime(options, bindings, resolveFromContainer) {
7
+ return (resolveFromContainer?.(FINANCE_ROUTE_RUNTIME_CONTAINER_KEY) ??
8
+ buildFinanceRouteRuntime(bindings, options));
9
9
  }
10
10
  export function createFinanceAdminSettlementRoutes(options = {}) {
11
11
  return new Hono().post("/invoices/:id/poll-settlement", async (c) => {
12
- const result = await financeSettlementService.pollInvoiceSettlement(c.get("db"), c.req.param("id"), pollInvoiceSettlementInputSchema.parse(await c.req.json().catch(() => ({}))), {
12
+ const runtime = getRuntime(options, c.env, (key) => c.var.container?.resolve(key));
13
+ const result = await financeSettlementService.pollInvoiceSettlement(c.get("db"), c.req.param("id"), await parseOptionalJsonBody(c, pollInvoiceSettlementInputSchema), {
13
14
  bindings: c.env,
14
- invoiceSettlementPollers: resolveInvoiceSettlementPollers(options, c.env),
15
- eventBus: resolveEventBus(options, c.env),
15
+ invoiceSettlementPollers: runtime.invoiceSettlementPollers,
16
+ eventBus: runtime.eventBus,
16
17
  });
17
18
  if ("status" in result && result.status === "not_found") {
18
19
  return c.json({ error: "Invoice not found" }, 404);