/** * Quote-version proposal + Trip-snapshot HTTP routes, owned by the quotes * module. * * agent-quality: file-size exception -- the proposal lifecycle (admin send, * public get/accept/decline) plus the Trip-snapshot freeze form one cohesive * route family backed by the same quotes/trips services; splitting it would * scatter a single accept-under-lock contract. * * Admin proposal (mount at /v1/admin/quote-versions): * POST /:quoteVersionId/send * Public proposal (mount at /v1/public/proposals): * GET /:quoteVersionId * POST /:quoteVersionId/accept * POST /:quoteVersionId/decline * POST /:quoteVersionId/request-edits * Admin snapshot (mount at /v1/admin/trips): * POST /:envelopeId/quote-versions/:quoteVersionId/snapshot * * These shapes (validation, status codes, the accept-under-advisory-lock flow, * the snapshot↔proposal equivalence checks, and the pure * `tripSnapshotToQuoteVersionApply` mapper) are framework logic and live here. * * The deployment supplies the concrete db resolver, public proposal base URL, * public operator profile, and optional CRM feedback hook via * `QuoteProposalRoutesOptions` — all generic / structural so this package * stays free of operator types and CloudflareBindings. */ import { OpenAPIHono } from "@hono/zod-openapi"; import type { ApiExtension } from "@voyant-travel/hono/module"; import { type TripSnapshot } from "@voyant-travel/trips"; import type { PostgresJsDatabase } from "drizzle-orm/postgres-js"; import { type Context, Hono } from "hono"; import type { QuoteVersion, QuoteVersionLine } from "./schema.js"; import { quotesService } from "./service/index.js"; /** * Deployment-supplied dependencies for the quote proposal + snapshot routes. * * Generic / structural types keep the quotes package free of operator types and * CloudflareBindings — the deployment casts `c.get("db")` to its own concrete * type inside `resolveDb` and supplies the public operator profile. */ export interface QuoteProposalRoutesOptions { /** Resolve the concrete transactional db for a request. */ resolveDb(c: Context): PostgresJsDatabase; /** * Resolve the public base URL for proposal links (e.g. the customer dashboard * origin). Returns `null` to emit a root-relative path. */ resolvePublicProposalBaseUrl(c: Context): string | null; /** * Resolve the deployment's public operator profile, surfaced on the public * proposal payload. Returns `null` when no profile is configured. */ resolveOperatorProfile(db: PostgresJsDatabase): Promise; /** * Optional deployment hook for public customer feedback. Deployments can use * this to write CRM activity rows, trigger notifications/workflows, or both. */ recordPublicProposalFeedback?(db: PostgresJsDatabase, input: PublicProposalFeedbackInput, c: Context): Promise; } export declare const QUOTE_PROPOSAL_OPENAPI_API_IDS: { readonly admin: "@voyant-travel/quotes#proposal-extension.api.admin"; readonly public: "@voyant-travel/quotes#proposal-extension.api.public"; }; export declare const QUOTE_VERSION_SNAPSHOT_OPENAPI_API_ID = "@voyant-travel/quotes#quote-version-snapshot-extension.api"; export interface QuoteVersionSnapshotRoutesOptions { /** Resolve the concrete transactional db for a request. */ resolveDb(c: Context): PostgresJsDatabase; } type OperatorProposalRouteEnv = { Bindings: Record; Variables: { db: unknown; userId?: string; }; }; type OperatorQuoteVersionSnapshotRouteEnv = { Variables: { db: unknown; userId?: string; }; }; export interface PublicQuoteVersionProposal { title: string; status: QuoteVersion["status"]; currency: string; subtotalAmountCents: number; taxAmountCents: number; totalAmountCents: number; validUntil: string | null; notes: string | null; lines: PublicQuoteVersionProposalLine[]; media: PublicQuoteVersionProposalMedia[]; operator: unknown | null; proposalUrl: string; } export interface PublicQuoteVersionProposalMedia { url: string; name: string; altText: string | null; mediaType: string; } export interface PublicQuoteVersionProposalLine { description: string; quantity: number; unitPriceAmountCents: number; totalAmountCents: number; currency: string; } export interface SendQuoteVersionResult { quoteVersion: QuoteVersion; proposalUrl: string; } export interface DeclinePublicProposalResult { status: QuoteVersion["status"]; } export interface PublicProposalFeedbackInput { quoteId: string; quoteVersionId: string; message: string; proposalUrl: string; } export interface PublicProposalFeedbackRecord { id: string; } export interface RequestPublicProposalEditsResult { status: Extract; feedbackId: string | null; } export interface AcceptPublicProposalResult { status: Extract; currency: string; totalAmountCents: number; } export type ApplyTripSnapshotToQuoteVersionResult = { snapshot: TripSnapshot; quoteVersion: QuoteVersion; lines: QuoteVersionLine[]; }; type ApplyTripSnapshotPayload = Parameters[2]; /** Build a proposal URL — absolute when a base URL is supplied, else root-relative. */ export declare function buildQuoteVersionProposalUrl(quoteVersionId: string, options?: { baseUrl?: string | null; }): string; /** Build the admin proposal routes (relative paths; mount at `/v1/admin/quote-versions`). */ export declare function createQuoteProposalAdminRoutes(options: QuoteProposalRoutesOptions): Hono; /** Build the public proposal routes (relative paths; mount at `/v1/public/proposals`). */ export declare function createQuoteProposalPublicRoutes(options: QuoteProposalRoutesOptions): OpenAPIHono; /** Build the Trip-snapshot freeze route (relative path; mount at `/v1/admin/trips`). */ export declare function createQuoteVersionSnapshotRoutes(options: QuoteVersionSnapshotRoutesOptions): OpenAPIHono; /** Package-owned proposal extension descriptor; deployments inject cross-module readers. */ export declare function createQuoteProposalApiExtension(options: QuoteProposalRoutesOptions): ApiExtension; /** Package-owned Trip snapshot extension descriptor; deployments inject the db resolver. */ export declare function createQuoteVersionSnapshotApiExtension(options: QuoteVersionSnapshotRoutesOptions): ApiExtension; /** Package-owned graph adapter for the proposal extension. */ export declare const createQuoteProposalVoyantRuntime: import("@voyant-travel/core/project").VoyantGraphRuntimeFactory; /** Package-owned graph adapter for the quote-version snapshot extension. */ export declare const createQuoteVersionSnapshotVoyantRuntime: import("@voyant-travel/core/project").VoyantGraphRuntimeFactory; /** Map a frozen Trip snapshot's proposal into a quote-version apply payload. */ export declare function tripSnapshotToQuoteVersionApply(snapshot: TripSnapshot): ApplyTripSnapshotPayload; export {};