@voyant-travel/catalog 0.117.2
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/LICENSE +201 -0
- package/README.md +190 -0
- package/dist/adapter/booking-forwarding.d.ts +2 -0
- package/dist/adapter/booking-forwarding.d.ts.map +1 -0
- package/dist/adapter/booking-forwarding.js +1 -0
- package/dist/adapter/channel-push-contracts.d.ts +2 -0
- package/dist/adapter/channel-push-contracts.d.ts.map +1 -0
- package/dist/adapter/channel-push-contracts.js +1 -0
- package/dist/adapter/contract.d.ts +2 -0
- package/dist/adapter/contract.d.ts.map +1 -0
- package/dist/adapter/contract.js +1 -0
- package/dist/adapter/contract.test.d.ts +2 -0
- package/dist/adapter/contract.test.d.ts.map +1 -0
- package/dist/adapter/contract.test.js +390 -0
- package/dist/adapter/provider-contracts.d.ts +2 -0
- package/dist/adapter/provider-contracts.d.ts.map +1 -0
- package/dist/adapter/provider-contracts.js +1 -0
- package/dist/adapter/provider-contracts.test.d.ts +2 -0
- package/dist/adapter/provider-contracts.test.d.ts.map +1 -0
- package/dist/adapter/provider-contracts.test.js +206 -0
- package/dist/adapter/schemas.d.ts +2 -0
- package/dist/adapter/schemas.d.ts.map +1 -0
- package/dist/adapter/schemas.js +1 -0
- package/dist/adapter/schemas.test.d.ts +2 -0
- package/dist/adapter/schemas.test.d.ts.map +1 -0
- package/dist/adapter/schemas.test.js +344 -0
- package/dist/booking-engine/book.d.ts +124 -0
- package/dist/booking-engine/book.d.ts.map +1 -0
- package/dist/booking-engine/book.js +311 -0
- package/dist/booking-engine/cancel.d.ts +40 -0
- package/dist/booking-engine/cancel.d.ts.map +1 -0
- package/dist/booking-engine/cancel.js +56 -0
- package/dist/booking-engine/checkout-finalize.d.ts +146 -0
- package/dist/booking-engine/checkout-finalize.d.ts.map +1 -0
- package/dist/booking-engine/checkout-finalize.js +132 -0
- package/dist/booking-engine/contracts.d.ts +9 -0
- package/dist/booking-engine/contracts.d.ts.map +1 -0
- package/dist/booking-engine/contracts.js +8 -0
- package/dist/booking-engine/contracts.test.d.ts +2 -0
- package/dist/booking-engine/contracts.test.d.ts.map +1 -0
- package/dist/booking-engine/contracts.test.js +116 -0
- package/dist/booking-engine/draft-shape.d.ts +10 -0
- package/dist/booking-engine/draft-shape.d.ts.map +1 -0
- package/dist/booking-engine/draft-shape.js +9 -0
- package/dist/booking-engine/draft-shape.test.d.ts +2 -0
- package/dist/booking-engine/draft-shape.test.d.ts.map +1 -0
- package/dist/booking-engine/draft-shape.test.js +74 -0
- package/dist/booking-engine/drafts-schema.d.ts +302 -0
- package/dist/booking-engine/drafts-schema.d.ts.map +1 -0
- package/dist/booking-engine/drafts-schema.js +53 -0
- package/dist/booking-engine/drafts-service.d.ts +41 -0
- package/dist/booking-engine/drafts-service.d.ts.map +1 -0
- package/dist/booking-engine/drafts-service.js +108 -0
- package/dist/booking-engine/errors.d.ts +81 -0
- package/dist/booking-engine/errors.d.ts.map +1 -0
- package/dist/booking-engine/errors.js +113 -0
- package/dist/booking-engine/index.d.ts +36 -0
- package/dist/booking-engine/index.d.ts.map +1 -0
- package/dist/booking-engine/index.js +34 -0
- package/dist/booking-engine/orders.d.ts +41 -0
- package/dist/booking-engine/orders.d.ts.map +1 -0
- package/dist/booking-engine/orders.js +49 -0
- package/dist/booking-engine/owned-handler.d.ts +166 -0
- package/dist/booking-engine/owned-handler.d.ts.map +1 -0
- package/dist/booking-engine/owned-handler.js +50 -0
- package/dist/booking-engine/owned-handler.test.d.ts +2 -0
- package/dist/booking-engine/owned-handler.test.d.ts.map +1 -0
- package/dist/booking-engine/owned-handler.test.js +63 -0
- package/dist/booking-engine/promotions-contract.d.ts +8 -0
- package/dist/booking-engine/promotions-contract.d.ts.map +1 -0
- package/dist/booking-engine/promotions-contract.js +7 -0
- package/dist/booking-engine/quote-enricher.test.d.ts +12 -0
- package/dist/booking-engine/quote-enricher.test.d.ts.map +1 -0
- package/dist/booking-engine/quote-enricher.test.js +138 -0
- package/dist/booking-engine/quote.d.ts +163 -0
- package/dist/booking-engine/quote.d.ts.map +1 -0
- package/dist/booking-engine/quote.js +259 -0
- package/dist/booking-engine/registry.d.ts +85 -0
- package/dist/booking-engine/registry.d.ts.map +1 -0
- package/dist/booking-engine/registry.js +118 -0
- package/dist/booking-engine/registry.test.d.ts +2 -0
- package/dist/booking-engine/registry.test.d.ts.map +1 -0
- package/dist/booking-engine/registry.test.js +132 -0
- package/dist/booking-engine/routes-contracts.d.ts +169 -0
- package/dist/booking-engine/routes-contracts.d.ts.map +1 -0
- package/dist/booking-engine/routes-contracts.js +63 -0
- package/dist/booking-engine/routes.d.ts +7 -0
- package/dist/booking-engine/routes.d.ts.map +1 -0
- package/dist/booking-engine/routes.js +443 -0
- package/dist/booking-engine/routes.test.d.ts +2 -0
- package/dist/booking-engine/routes.test.d.ts.map +1 -0
- package/dist/booking-engine/routes.test.js +304 -0
- package/dist/booking-engine/schema.d.ts +455 -0
- package/dist/booking-engine/schema.d.ts.map +1 -0
- package/dist/booking-engine/schema.js +75 -0
- package/dist/booking-engine/snapshot-content.d.ts +120 -0
- package/dist/booking-engine/snapshot-content.d.ts.map +1 -0
- package/dist/booking-engine/snapshot-content.js +110 -0
- package/dist/booking-engine/snapshot-content.test.d.ts +2 -0
- package/dist/booking-engine/snapshot-content.test.d.ts.map +1 -0
- package/dist/booking-engine/snapshot-content.test.js +213 -0
- package/dist/booking-engine/sync.d.ts +136 -0
- package/dist/booking-engine/sync.d.ts.map +1 -0
- package/dist/booking-engine/sync.js +177 -0
- package/dist/booking-engine/sync.test.d.ts +2 -0
- package/dist/booking-engine/sync.test.d.ts.map +1 -0
- package/dist/booking-engine/sync.test.js +377 -0
- package/dist/contract.d.ts +2 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +1 -0
- package/dist/contract.test.d.ts +2 -0
- package/dist/contract.test.d.ts.map +1 -0
- package/dist/contract.test.js +107 -0
- package/dist/drift/events.d.ts +2 -0
- package/dist/drift/events.d.ts.map +1 -0
- package/dist/drift/events.js +1 -0
- package/dist/drift/events.test.d.ts +2 -0
- package/dist/drift/events.test.d.ts.map +1 -0
- package/dist/drift/events.test.js +100 -0
- package/dist/embeddings/contract.d.ts +85 -0
- package/dist/embeddings/contract.d.ts.map +1 -0
- package/dist/embeddings/contract.js +42 -0
- package/dist/embeddings/contract.test.d.ts +2 -0
- package/dist/embeddings/contract.test.d.ts.map +1 -0
- package/dist/embeddings/contract.test.js +30 -0
- package/dist/embeddings/gemini.d.ts +110 -0
- package/dist/embeddings/gemini.d.ts.map +1 -0
- package/dist/embeddings/gemini.js +118 -0
- package/dist/embeddings/gemini.test.d.ts +2 -0
- package/dist/embeddings/gemini.test.d.ts.map +1 -0
- package/dist/embeddings/gemini.test.js +132 -0
- package/dist/embeddings/model-registry.d.ts +62 -0
- package/dist/embeddings/model-registry.d.ts.map +1 -0
- package/dist/embeddings/model-registry.js +78 -0
- package/dist/embeddings/model-registry.test.d.ts +2 -0
- package/dist/embeddings/model-registry.test.d.ts.map +1 -0
- package/dist/embeddings/model-registry.test.js +81 -0
- package/dist/embeddings/openai.d.ts +81 -0
- package/dist/embeddings/openai.d.ts.map +1 -0
- package/dist/embeddings/openai.js +123 -0
- package/dist/embeddings/openai.test.d.ts +2 -0
- package/dist/embeddings/openai.test.d.ts.map +1 -0
- package/dist/embeddings/openai.test.js +164 -0
- package/dist/events/taxonomy.d.ts +158 -0
- package/dist/events/taxonomy.d.ts.map +1 -0
- package/dist/events/taxonomy.js +99 -0
- package/dist/events/taxonomy.test.d.ts +2 -0
- package/dist/events/taxonomy.test.d.ts.map +1 -0
- package/dist/events/taxonomy.test.js +48 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/indexer/contract.d.ts +203 -0
- package/dist/indexer/contract.d.ts.map +1 -0
- package/dist/indexer/contract.js +16 -0
- package/dist/indexer/typesense-search-query.d.ts +31 -0
- package/dist/indexer/typesense-search-query.d.ts.map +1 -0
- package/dist/indexer/typesense-search-query.js +185 -0
- package/dist/indexer/typesense.d.ts +105 -0
- package/dist/indexer/typesense.d.ts.map +1 -0
- package/dist/indexer/typesense.js +394 -0
- package/dist/indexer/typesense.test.d.ts +2 -0
- package/dist/indexer/typesense.test.d.ts.map +1 -0
- package/dist/indexer/typesense.test.js +253 -0
- package/dist/overlay/resolver.d.ts +101 -0
- package/dist/overlay/resolver.d.ts.map +1 -0
- package/dist/overlay/resolver.js +167 -0
- package/dist/overlay/resolver.test.d.ts +2 -0
- package/dist/overlay/resolver.test.d.ts.map +1 -0
- package/dist/overlay/resolver.test.js +179 -0
- package/dist/overlay/schema.d.ts +266 -0
- package/dist/overlay/schema.d.ts.map +1 -0
- package/dist/overlay/schema.js +71 -0
- package/dist/provenance.d.ts +2 -0
- package/dist/provenance.d.ts.map +1 -0
- package/dist/provenance.js +1 -0
- package/dist/schema-sourced-entries.d.ts +344 -0
- package/dist/schema-sourced-entries.d.ts.map +1 -0
- package/dist/schema-sourced-entries.js +75 -0
- package/dist/schema.d.ts +21 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +20 -0
- package/dist/search/federate.d.ts +58 -0
- package/dist/search/federate.d.ts.map +1 -0
- package/dist/search/federate.js +103 -0
- package/dist/search/federate.test.d.ts +2 -0
- package/dist/search/federate.test.d.ts.map +1 -0
- package/dist/search/federate.test.js +146 -0
- package/dist/search/rerank.d.ts +77 -0
- package/dist/search/rerank.d.ts.map +1 -0
- package/dist/search/rerank.js +68 -0
- package/dist/search/rerank.test.d.ts +2 -0
- package/dist/search/rerank.test.d.ts.map +1 -0
- package/dist/search/rerank.test.js +60 -0
- package/dist/search/routes.d.ts +144 -0
- package/dist/search/routes.d.ts.map +1 -0
- package/dist/search/routes.js +288 -0
- package/dist/search/routes.test.d.ts +2 -0
- package/dist/search/routes.test.d.ts.map +1 -0
- package/dist/search/routes.test.js +322 -0
- package/dist/search/semantic.d.ts +63 -0
- package/dist/search/semantic.d.ts.map +1 -0
- package/dist/search/semantic.js +75 -0
- package/dist/search/semantic.test.d.ts +2 -0
- package/dist/search/semantic.test.d.ts.map +1 -0
- package/dist/search/semantic.test.js +143 -0
- package/dist/services/build-indexer-document.test.d.ts +2 -0
- package/dist/services/build-indexer-document.test.d.ts.map +1 -0
- package/dist/services/build-indexer-document.test.js +102 -0
- package/dist/services/content-service.d.ts +125 -0
- package/dist/services/content-service.d.ts.map +1 -0
- package/dist/services/content-service.js +139 -0
- package/dist/services/content-service.test.d.ts +2 -0
- package/dist/services/content-service.test.d.ts.map +1 -0
- package/dist/services/content-service.test.js +322 -0
- package/dist/services/indexer-service.d.ts +109 -0
- package/dist/services/indexer-service.d.ts.map +1 -0
- package/dist/services/indexer-service.js +123 -0
- package/dist/services/indexer-service.test.d.ts +2 -0
- package/dist/services/indexer-service.test.d.ts.map +1 -0
- package/dist/services/indexer-service.test.js +176 -0
- package/dist/services/overlay-service.d.ts +108 -0
- package/dist/services/overlay-service.d.ts.map +1 -0
- package/dist/services/overlay-service.js +211 -0
- package/dist/services/overlay-service.test.d.ts +2 -0
- package/dist/services/overlay-service.test.d.ts.map +1 -0
- package/dist/services/overlay-service.test.js +79 -0
- package/dist/services/snapshot-builder.test.d.ts +2 -0
- package/dist/services/snapshot-builder.test.d.ts.map +1 -0
- package/dist/services/snapshot-builder.test.js +93 -0
- package/dist/services/snapshot-service.d.ts +78 -0
- package/dist/services/snapshot-service.d.ts.map +1 -0
- package/dist/services/snapshot-service.js +165 -0
- package/dist/services/sourced-entry-service.d.ts +142 -0
- package/dist/services/sourced-entry-service.d.ts.map +1 -0
- package/dist/services/sourced-entry-service.js +203 -0
- package/dist/services/sourced-entry-service.test.d.ts +10 -0
- package/dist/services/sourced-entry-service.test.d.ts.map +1 -0
- package/dist/services/sourced-entry-service.test.js +66 -0
- package/dist/snapshot/schema.d.ts +362 -0
- package/dist/snapshot/schema.d.ts.map +1 -0
- package/dist/snapshot/schema.js +102 -0
- package/package.json +210 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catalog event taxonomy — names, payload shapes, and visibility-filtered
|
|
3
|
+
* payload builders.
|
|
4
|
+
*
|
|
5
|
+
* Catalog events ride Voyant's existing `@voyant-travel/core/events` envelope
|
|
6
|
+
* (`name`, `data`, `metadata`, `emittedAt`) and are dispatched via the
|
|
7
|
+
* existing webhook delivery pipeline (`infraWebhookSubscriptionsTable` +
|
|
8
|
+
* the delivery worker). The catalog plane defines only the taxonomy and
|
|
9
|
+
* payload-visibility rules; subscription storage, signing, retry, and
|
|
10
|
+
* delivery are reused, not reinvented.
|
|
11
|
+
*
|
|
12
|
+
* See `docs/architecture/catalog-architecture.md` §5.8 for the full design.
|
|
13
|
+
*/
|
|
14
|
+
import type { EventBus, EventCategory, EventMetadata } from "@voyant-travel/core/events";
|
|
15
|
+
import type { DriftSeverity, FieldPolicyRegistry, Visibility } from "../contract.js";
|
|
16
|
+
/**
|
|
17
|
+
* Catalog event names. Stable strings — exposed as a const enum-like
|
|
18
|
+
* lookup so consumers can subscribe by reference rather than typing
|
|
19
|
+
* the names by hand.
|
|
20
|
+
*/
|
|
21
|
+
export declare const CATALOG_EVENTS: {
|
|
22
|
+
readonly ENTITY_CREATED: "catalog.entity.created";
|
|
23
|
+
readonly ENTITY_UPDATED: "catalog.entity.updated";
|
|
24
|
+
readonly ENTITY_ARCHIVED: "catalog.entity.archived";
|
|
25
|
+
readonly ENTITY_DELETED: "catalog.entity.deleted";
|
|
26
|
+
readonly ENTITY_PRICE_CHANGED: "catalog.entity.price.changed";
|
|
27
|
+
readonly ENTITY_AVAILABILITY_CHANGED: "catalog.entity.availability.changed";
|
|
28
|
+
readonly ENTITY_OVERLAY_CHANGED: "catalog.entity.overlay.changed";
|
|
29
|
+
readonly ENTITY_DRIFT_DETECTED: "catalog.entity.drift.detected";
|
|
30
|
+
readonly ENTITY_REFERENCE_MISSING: "catalog.entity.reference.missing";
|
|
31
|
+
readonly BOOKING_COMMITTED: "catalog.booking.committed";
|
|
32
|
+
readonly BOOKING_CANCELLED: "catalog.booking.cancelled";
|
|
33
|
+
readonly SOURCE_DISCONNECTED: "catalog.source.disconnected";
|
|
34
|
+
readonly SOURCE_RECONNECTED: "catalog.source.reconnected";
|
|
35
|
+
};
|
|
36
|
+
export type CatalogEventName = (typeof CATALOG_EVENTS)[keyof typeof CATALOG_EVENTS];
|
|
37
|
+
/**
|
|
38
|
+
* Default category for each catalog event. `internal` events are not routed
|
|
39
|
+
* to external (non-staff) webhook subscribers by default; external
|
|
40
|
+
* subscribers may opt in only with `staff` audience scope.
|
|
41
|
+
*/
|
|
42
|
+
export declare const CATALOG_EVENT_CATEGORIES: Record<CatalogEventName, EventCategory>;
|
|
43
|
+
/** Common identity fields carried by every entity-scoped catalog event. */
|
|
44
|
+
export interface EntityScope {
|
|
45
|
+
entity_module: string;
|
|
46
|
+
entity_id: string;
|
|
47
|
+
}
|
|
48
|
+
/** Provenance fields denormalized into payloads so receivers can correlate. */
|
|
49
|
+
export interface ProvenanceFields {
|
|
50
|
+
source_kind: string;
|
|
51
|
+
source_ref?: string;
|
|
52
|
+
source_connection_id?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface EntityCreatedPayload extends EntityScope, ProvenanceFields {
|
|
55
|
+
occurred_at: string;
|
|
56
|
+
}
|
|
57
|
+
export interface EntityUpdatedPayload extends EntityScope, ProvenanceFields {
|
|
58
|
+
/** Field paths that changed. */
|
|
59
|
+
changed_fields: string[];
|
|
60
|
+
/** Field-keyed before/after — visibility-filtered before emit. */
|
|
61
|
+
before?: Record<string, unknown>;
|
|
62
|
+
after?: Record<string, unknown>;
|
|
63
|
+
occurred_at: string;
|
|
64
|
+
}
|
|
65
|
+
export interface EntityArchivedPayload extends EntityScope, ProvenanceFields {
|
|
66
|
+
reason?: string;
|
|
67
|
+
occurred_at: string;
|
|
68
|
+
}
|
|
69
|
+
export interface EntityPriceChangedPayload extends EntityScope, ProvenanceFields {
|
|
70
|
+
/** The volatile-indexed price field path that changed (e.g. "from_price"). */
|
|
71
|
+
field_path: string;
|
|
72
|
+
before?: number;
|
|
73
|
+
after?: number;
|
|
74
|
+
currency?: string;
|
|
75
|
+
occurred_at: string;
|
|
76
|
+
}
|
|
77
|
+
export interface EntityAvailabilityChangedPayload extends EntityScope, ProvenanceFields {
|
|
78
|
+
field_path: string;
|
|
79
|
+
before?: unknown;
|
|
80
|
+
after?: unknown;
|
|
81
|
+
occurred_at: string;
|
|
82
|
+
}
|
|
83
|
+
export interface EntityOverlayChangedPayload extends EntityScope {
|
|
84
|
+
field_path: string;
|
|
85
|
+
locale: string;
|
|
86
|
+
audience: string;
|
|
87
|
+
market: string;
|
|
88
|
+
occurred_at: string;
|
|
89
|
+
}
|
|
90
|
+
export interface EntityDriftDetectedPayload extends EntityScope {
|
|
91
|
+
source_kind: string;
|
|
92
|
+
source_connection_id: string;
|
|
93
|
+
max_severity: DriftSeverity;
|
|
94
|
+
drifted_fields: string[];
|
|
95
|
+
occurred_at: string;
|
|
96
|
+
}
|
|
97
|
+
export interface EntityReferenceMissingPayload extends EntityScope {
|
|
98
|
+
/** Module + id of the parent entity that references the now-missing one. */
|
|
99
|
+
referencing_module: string;
|
|
100
|
+
referencing_entity_id: string;
|
|
101
|
+
occurred_at: string;
|
|
102
|
+
}
|
|
103
|
+
export interface BookingCommittedPayload extends EntityScope, ProvenanceFields {
|
|
104
|
+
booking_id: string;
|
|
105
|
+
occurred_at: string;
|
|
106
|
+
}
|
|
107
|
+
export interface BookingCancelledPayload extends EntityScope, ProvenanceFields {
|
|
108
|
+
booking_id: string;
|
|
109
|
+
occurred_at: string;
|
|
110
|
+
}
|
|
111
|
+
export interface SourceDisconnectedPayload {
|
|
112
|
+
source_kind: string;
|
|
113
|
+
source_connection_id: string;
|
|
114
|
+
affected_entity_count: number;
|
|
115
|
+
occurred_at: string;
|
|
116
|
+
}
|
|
117
|
+
export interface SourceReconnectedPayload {
|
|
118
|
+
source_kind: string;
|
|
119
|
+
source_connection_id: string;
|
|
120
|
+
restored_entity_count: number;
|
|
121
|
+
occurred_at: string;
|
|
122
|
+
}
|
|
123
|
+
/** Map of event name → payload shape, for type-safe emit/subscribe wrappers. */
|
|
124
|
+
export interface CatalogEventPayloads {
|
|
125
|
+
[CATALOG_EVENTS.ENTITY_CREATED]: EntityCreatedPayload;
|
|
126
|
+
[CATALOG_EVENTS.ENTITY_UPDATED]: EntityUpdatedPayload;
|
|
127
|
+
[CATALOG_EVENTS.ENTITY_ARCHIVED]: EntityArchivedPayload;
|
|
128
|
+
[CATALOG_EVENTS.ENTITY_DELETED]: EntityArchivedPayload;
|
|
129
|
+
[CATALOG_EVENTS.ENTITY_PRICE_CHANGED]: EntityPriceChangedPayload;
|
|
130
|
+
[CATALOG_EVENTS.ENTITY_AVAILABILITY_CHANGED]: EntityAvailabilityChangedPayload;
|
|
131
|
+
[CATALOG_EVENTS.ENTITY_OVERLAY_CHANGED]: EntityOverlayChangedPayload;
|
|
132
|
+
[CATALOG_EVENTS.ENTITY_DRIFT_DETECTED]: EntityDriftDetectedPayload;
|
|
133
|
+
[CATALOG_EVENTS.ENTITY_REFERENCE_MISSING]: EntityReferenceMissingPayload;
|
|
134
|
+
[CATALOG_EVENTS.BOOKING_COMMITTED]: BookingCommittedPayload;
|
|
135
|
+
[CATALOG_EVENTS.BOOKING_CANCELLED]: BookingCancelledPayload;
|
|
136
|
+
[CATALOG_EVENTS.SOURCE_DISCONNECTED]: SourceDisconnectedPayload;
|
|
137
|
+
[CATALOG_EVENTS.SOURCE_RECONNECTED]: SourceReconnectedPayload;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Filters a record of field-keyed values by the field-policy `visibility[]`
|
|
141
|
+
* for the requesting audience. Fields whose policy hides them from the
|
|
142
|
+
* audience are dropped entirely from the payload — never sent to the wire.
|
|
143
|
+
*
|
|
144
|
+
* Used to scope `before` / `after` blobs in `entity.updated` events so that
|
|
145
|
+
* cross-deployment partner subscribers do not receive staff-only fields.
|
|
146
|
+
*/
|
|
147
|
+
export declare function filterByVisibility(fields: Record<string, unknown>, registry: FieldPolicyRegistry, audience: Visibility): Record<string, unknown>;
|
|
148
|
+
/**
|
|
149
|
+
* Emit a catalog event through `@voyant-travel/core/events`. Stamps the metadata
|
|
150
|
+
* with the canonical category for the event name and adds a `source: "service"`
|
|
151
|
+
* marker.
|
|
152
|
+
*
|
|
153
|
+
* Visibility-filtered payloads should be constructed via `filterByVisibility`
|
|
154
|
+
* before calling this — the emitter does not re-filter; the payload as
|
|
155
|
+
* passed is what subscribers receive.
|
|
156
|
+
*/
|
|
157
|
+
export declare function emitCatalogEvent<TName extends CatalogEventName>(bus: EventBus, name: TName, data: CatalogEventPayloads[TName], metadata?: Omit<EventMetadata, "category">): Promise<void>;
|
|
158
|
+
//# sourceMappingURL=taxonomy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taxonomy.d.ts","sourceRoot":"","sources":["../../src/events/taxonomy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catalog event taxonomy — names, payload shapes, and visibility-filtered
|
|
3
|
+
* payload builders.
|
|
4
|
+
*
|
|
5
|
+
* Catalog events ride Voyant's existing `@voyant-travel/core/events` envelope
|
|
6
|
+
* (`name`, `data`, `metadata`, `emittedAt`) and are dispatched via the
|
|
7
|
+
* existing webhook delivery pipeline (`infraWebhookSubscriptionsTable` +
|
|
8
|
+
* the delivery worker). The catalog plane defines only the taxonomy and
|
|
9
|
+
* payload-visibility rules; subscription storage, signing, retry, and
|
|
10
|
+
* delivery are reused, not reinvented.
|
|
11
|
+
*
|
|
12
|
+
* See `docs/architecture/catalog-architecture.md` §5.8 for the full design.
|
|
13
|
+
*/
|
|
14
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15
|
+
// Event names
|
|
16
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* Catalog event names. Stable strings — exposed as a const enum-like
|
|
19
|
+
* lookup so consumers can subscribe by reference rather than typing
|
|
20
|
+
* the names by hand.
|
|
21
|
+
*/
|
|
22
|
+
export const CATALOG_EVENTS = {
|
|
23
|
+
ENTITY_CREATED: "catalog.entity.created",
|
|
24
|
+
ENTITY_UPDATED: "catalog.entity.updated",
|
|
25
|
+
ENTITY_ARCHIVED: "catalog.entity.archived",
|
|
26
|
+
ENTITY_DELETED: "catalog.entity.deleted",
|
|
27
|
+
ENTITY_PRICE_CHANGED: "catalog.entity.price.changed",
|
|
28
|
+
ENTITY_AVAILABILITY_CHANGED: "catalog.entity.availability.changed",
|
|
29
|
+
ENTITY_OVERLAY_CHANGED: "catalog.entity.overlay.changed",
|
|
30
|
+
ENTITY_DRIFT_DETECTED: "catalog.entity.drift.detected",
|
|
31
|
+
ENTITY_REFERENCE_MISSING: "catalog.entity.reference.missing",
|
|
32
|
+
BOOKING_COMMITTED: "catalog.booking.committed",
|
|
33
|
+
BOOKING_CANCELLED: "catalog.booking.cancelled",
|
|
34
|
+
SOURCE_DISCONNECTED: "catalog.source.disconnected",
|
|
35
|
+
SOURCE_RECONNECTED: "catalog.source.reconnected",
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Default category for each catalog event. `internal` events are not routed
|
|
39
|
+
* to external (non-staff) webhook subscribers by default; external
|
|
40
|
+
* subscribers may opt in only with `staff` audience scope.
|
|
41
|
+
*/
|
|
42
|
+
export const CATALOG_EVENT_CATEGORIES = {
|
|
43
|
+
[CATALOG_EVENTS.ENTITY_CREATED]: "domain",
|
|
44
|
+
[CATALOG_EVENTS.ENTITY_UPDATED]: "domain",
|
|
45
|
+
[CATALOG_EVENTS.ENTITY_ARCHIVED]: "domain",
|
|
46
|
+
[CATALOG_EVENTS.ENTITY_DELETED]: "domain",
|
|
47
|
+
[CATALOG_EVENTS.ENTITY_PRICE_CHANGED]: "domain",
|
|
48
|
+
[CATALOG_EVENTS.ENTITY_AVAILABILITY_CHANGED]: "domain",
|
|
49
|
+
[CATALOG_EVENTS.ENTITY_OVERLAY_CHANGED]: "internal",
|
|
50
|
+
[CATALOG_EVENTS.ENTITY_DRIFT_DETECTED]: "internal",
|
|
51
|
+
[CATALOG_EVENTS.ENTITY_REFERENCE_MISSING]: "domain",
|
|
52
|
+
[CATALOG_EVENTS.BOOKING_COMMITTED]: "domain",
|
|
53
|
+
[CATALOG_EVENTS.BOOKING_CANCELLED]: "domain",
|
|
54
|
+
[CATALOG_EVENTS.SOURCE_DISCONNECTED]: "domain",
|
|
55
|
+
[CATALOG_EVENTS.SOURCE_RECONNECTED]: "domain",
|
|
56
|
+
};
|
|
57
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
58
|
+
// Visibility filtering
|
|
59
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
60
|
+
/**
|
|
61
|
+
* Filters a record of field-keyed values by the field-policy `visibility[]`
|
|
62
|
+
* for the requesting audience. Fields whose policy hides them from the
|
|
63
|
+
* audience are dropped entirely from the payload — never sent to the wire.
|
|
64
|
+
*
|
|
65
|
+
* Used to scope `before` / `after` blobs in `entity.updated` events so that
|
|
66
|
+
* cross-deployment partner subscribers do not receive staff-only fields.
|
|
67
|
+
*/
|
|
68
|
+
export function filterByVisibility(fields, registry, audience) {
|
|
69
|
+
const result = {};
|
|
70
|
+
for (const [path, value] of Object.entries(fields)) {
|
|
71
|
+
const policy = registry.resolve(path);
|
|
72
|
+
if (!policy)
|
|
73
|
+
continue;
|
|
74
|
+
if (policy.visibility.includes(audience)) {
|
|
75
|
+
result[path] = value;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
81
|
+
// Emit helpers
|
|
82
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Emit a catalog event through `@voyant-travel/core/events`. Stamps the metadata
|
|
85
|
+
* with the canonical category for the event name and adds a `source: "service"`
|
|
86
|
+
* marker.
|
|
87
|
+
*
|
|
88
|
+
* Visibility-filtered payloads should be constructed via `filterByVisibility`
|
|
89
|
+
* before calling this — the emitter does not re-filter; the payload as
|
|
90
|
+
* passed is what subscribers receive.
|
|
91
|
+
*/
|
|
92
|
+
export async function emitCatalogEvent(bus, name, data, metadata) {
|
|
93
|
+
const category = CATALOG_EVENT_CATEGORIES[name];
|
|
94
|
+
await bus.emit(name, data, {
|
|
95
|
+
category,
|
|
96
|
+
source: "service",
|
|
97
|
+
...metadata,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taxonomy.test.d.ts","sourceRoot":"","sources":["../../src/events/taxonomy.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createFieldPolicyRegistry, defineFieldPolicy } from "../contract.js";
|
|
3
|
+
import { CATALOG_EVENT_CATEGORIES, CATALOG_EVENTS, filterByVisibility } from "./taxonomy.js";
|
|
4
|
+
describe("CATALOG_EVENTS / CATALOG_EVENT_CATEGORIES", () => {
|
|
5
|
+
it("declares an internal category for overlay-changed and drift-detected", () => {
|
|
6
|
+
expect(CATALOG_EVENT_CATEGORIES[CATALOG_EVENTS.ENTITY_OVERLAY_CHANGED]).toBe("internal");
|
|
7
|
+
expect(CATALOG_EVENT_CATEGORIES[CATALOG_EVENTS.ENTITY_DRIFT_DETECTED]).toBe("internal");
|
|
8
|
+
});
|
|
9
|
+
it("declares domain category for booking and source events", () => {
|
|
10
|
+
expect(CATALOG_EVENT_CATEGORIES[CATALOG_EVENTS.BOOKING_COMMITTED]).toBe("domain");
|
|
11
|
+
expect(CATALOG_EVENT_CATEGORIES[CATALOG_EVENTS.SOURCE_DISCONNECTED]).toBe("domain");
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
describe("filterByVisibility", () => {
|
|
15
|
+
const registry = createFieldPolicyRegistry(defineFieldPolicy([
|
|
16
|
+
{
|
|
17
|
+
path: "title",
|
|
18
|
+
class: "merchandisable",
|
|
19
|
+
merge: "replace",
|
|
20
|
+
editRole: "marketing",
|
|
21
|
+
overrideFriction: "none",
|
|
22
|
+
snapshot: "on-book",
|
|
23
|
+
visibility: ["staff", "customer", "partner"],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
path: "internal_notes",
|
|
27
|
+
class: "merchandisable",
|
|
28
|
+
merge: "replace",
|
|
29
|
+
editRole: "ops",
|
|
30
|
+
overrideFriction: "none",
|
|
31
|
+
snapshot: "never",
|
|
32
|
+
visibility: ["staff"],
|
|
33
|
+
},
|
|
34
|
+
]));
|
|
35
|
+
it("drops staff-only fields when filtering for a customer audience", () => {
|
|
36
|
+
const filtered = filterByVisibility({ title: "Hello", internal_notes: "secret" }, registry, "customer");
|
|
37
|
+
expect(filtered).toEqual({ title: "Hello" });
|
|
38
|
+
});
|
|
39
|
+
it("keeps all visible fields for a staff actor", () => {
|
|
40
|
+
const filtered = filterByVisibility({ title: "Hello", internal_notes: "secret" }, registry, "staff");
|
|
41
|
+
expect(filtered).toEqual({ title: "Hello", internal_notes: "secret" });
|
|
42
|
+
});
|
|
43
|
+
it("drops fields not in the registry", () => {
|
|
44
|
+
const filtered = filterByVisibility({ title: "Hello", phantom: "??" }, registry, "customer");
|
|
45
|
+
expect(filtered).toEqual({ title: "Hello" });
|
|
46
|
+
expect("phantom" in filtered).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export { ADAPTER_RATE_LIMITED, type AdapterCapabilities, AdapterRateLimitedError, type AvailabilityBadge, type AvailabilityBadgeKind, type AvailabilityProjection, type AvailabilityRowKind, type AvailabilityStatus, type AvailabilityUnitPrecision, CAPABILITY_NOT_SUPPORTED, type CancelRequest, type CancelResult, CapabilityNotSupportedError, type CapabilitySupport, type CatalogProjection, type ConnectionState, type DiscoveryCursor, type DiscoveryPage, type GetContentRequest, type GetContentResult, type GetReservationRequest, type GetReservationResult, type ListReservationsPage, type ListReservationsQuery, type LiveResolveRequest, type LiveResolveResult, type PromotionApplicability, type PromotionApplicabilityConstraint, type PromotionApplicabilityConstraintKind, type PromotionApplicabilityEvaluation, type PromotionApplicabilityResolution, type PromotionDisplayFields, type PromotionMediaAsset, type PromotionMediaKind, type PromotionPriceEffect, type PromotionStackingSemantics, type ProviderCapabilityDeclaration, type ProviderCapabilityKey, type ProviderPromotion, type PushAvailabilityRequest, type PushAvailabilityResult, type PushBookingRequest, type PushBookingResult, type PushContentRequest, type PushContentResult, type ReservationStatus, type ReserveRequest, type ReserveResult, type SourceAdapter, type SourceAdapterContext, type SourceAdapterRequestScope, } from "./adapter/contract.js";
|
|
2
|
+
export * from "./adapter/schemas.js";
|
|
3
|
+
export { type CatalogBookingAdapterContextInput, type CatalogBookingBookBody, type CatalogBookingBookTransformInput, type CatalogBookingCommittedEvent, type CatalogBookingContentScopeInput, type CatalogBookingDraftBody, type CatalogBookingDraftConsumedError, type CatalogBookingHoldPlaceBody, type CatalogBookingHoldReleaseBody, type CatalogBookingHoldTtlInput, type CatalogBookingProvenance, type CatalogBookingProvenanceInput, type CatalogBookingQuoteBody, type CatalogBookingQuoteTransformInput, type CatalogBookingRoutesOptions, createCatalogBookingHonoModule, createCatalogBookingRoutes, } from "./booking-engine/routes.js";
|
|
4
|
+
export * from "./contract.js";
|
|
5
|
+
export { blocksBookings, type CatalogDriftEvent, type ContentDriftEvent, type ContentDriftKind, type FieldDrift, maxDriftSeverity, } from "./drift/events.js";
|
|
6
|
+
export { chunkForBatch, EMBEDDING_BATCH_TOO_LARGE, EMBEDDING_INPUT_TOO_LONG, EMBEDDING_PROVIDER_ERROR, type EmbeddingProvider, type EmbeddingProviderCapabilities, EmbeddingProviderError, } from "./embeddings/contract.js";
|
|
7
|
+
export { createGeminiEmbeddingProvider, GEMINI_MODELS, type GeminiEmbeddingModel, type GeminiEmbeddingProviderOptions, type GeminiTaskType, } from "./embeddings/gemini.js";
|
|
8
|
+
export { type EmbeddingMigrationPlan, isActiveEmbeddingModel, planEmbeddingMigration, stampEmbeddingModelId, validateEmbeddingCompatibility, } from "./embeddings/model-registry.js";
|
|
9
|
+
export { createOpenAIEmbeddingProvider, embedBatched, OPENAI_MODELS, type OpenAIEmbeddingModel, type OpenAIEmbeddingProviderOptions, } from "./embeddings/openai.js";
|
|
10
|
+
export { type BookingCancelledPayload, type BookingCommittedPayload, CATALOG_EVENT_CATEGORIES, CATALOG_EVENTS, type CatalogEventName, type CatalogEventPayloads, type EntityArchivedPayload, type EntityAvailabilityChangedPayload, type EntityCreatedPayload, type EntityDriftDetectedPayload, type EntityOverlayChangedPayload, type EntityPriceChangedPayload, type EntityReferenceMissingPayload, type EntityScope, type EntityUpdatedPayload, emitCatalogEvent, filterByVisibility, type ProvenanceFields, type SourceDisconnectedPayload, type SourceReconnectedPayload, } from "./events/taxonomy.js";
|
|
11
|
+
export type { DocumentEmitter, FacetRequest, IndexerAdapter, IndexerCapabilities, IndexerDocument, IndexerSlice, SearchFacetBucket, SearchFilter, SearchHit, SearchMode, SearchPagination, SearchRequest, SearchResults, } from "./indexer/contract.js";
|
|
12
|
+
export { attachEmitter, buildCollectionSchema, buildDefaultTypesenseQueryBy, buildDefaultTypesenseSearchFields, buildSearchQuery, collectionName, createTypesenseIndexer, type TypesenseClient, type TypesenseCollectionSchema, type TypesenseFieldSchema, type TypesenseIndexerOptions, type TypesenseSearchHit, type TypesenseSearchQuery, type TypesenseSearchResponse, } from "./indexer/typesense.js";
|
|
13
|
+
export { applyMerge, isVisibleTo, type OverlayLookup, type ResolvedFieldProvenance, type ResolvedView, type ResolverOverlay, type ResolverScope, resolveOverlay, variantFallbackChain, } from "./overlay/resolver.js";
|
|
14
|
+
export { catalogOverlayTable, type InsertCatalogOverlay, OVERLAY_DEFAULT_SCOPE, type OverlayOrigin, overlayIdRef, type SelectCatalogOverlay, } from "./overlay/schema.js";
|
|
15
|
+
export * from "./provenance.js";
|
|
16
|
+
export { catalogSourcedEntriesTable, type InsertCatalogSourcedEntry, type SelectCatalogSourcedEntry, type SourcedEntryStatus, } from "./schema-sourced-entries.js";
|
|
17
|
+
export { type FederatedSearchOptions, federateAudienceSearch, mergeAndDedupe, } from "./search/federate.js";
|
|
18
|
+
export { type LivePriceFn, type LivePriceResult, type RerankedHit, type RerankOptions, type RerankParameters, rerank, } from "./search/rerank.js";
|
|
19
|
+
export { type CatalogSearchBody, type CatalogSearchExecuteInput, type CatalogSearchFallbackInput, type CatalogSearchRoutesOptions, type CatalogSearchRoutesWithSurfaceOptions, type CatalogSearchRuntime, type CatalogSearchSurface, createCatalogSearchHonoModule, createCatalogSearchRoutes, mountCatalogSearchRoutes, } from "./search/routes.js";
|
|
20
|
+
export { executeBYOVectorSearch, executeSemanticSearch, type SemanticSearchOptions, } from "./search/semantic.js";
|
|
21
|
+
export { applyJsonPointerOverlay, type BuiltDriftPredicate, buildDriftInvalidationPredicate, type ContentLocaleMatchKind, type ContentLocaleResolution, type ContentOverlay, type CreateInvalidateOnDriftOptions, createInvalidateOnDrift, type InvalidateOnDrift, isStale, JsonPointerError, type MergeOverlaysOptions, mergeOverlaysIntoContent, parseJsonPointer, pickBestCachedLocale, type VerticalContentInvalidatableTable, withContentRefreshLock, } from "./services/content-service.js";
|
|
22
|
+
export { buildIndexerDocument, createIndexerService, type DocumentBuilder, type IndexerService, type IndexerServiceOptions, } from "./services/indexer-service.js";
|
|
23
|
+
export { fetchOverlaysForEntities, fetchOverlaysForEntity, listOverlaysByOrigin, type OverlayOriginFilter, resolveEntityView, resolveEntityViewWithOverlays, restoreOverlay, softDeleteOverlay, type WriteOverlayInput, writeOverlay, } from "./services/overlay-service.js";
|
|
24
|
+
export { buildSnapshotInputFromView, type CaptureSnapshotInput, captureSnapshot, captureSnapshotGraph, fetchEntitySnapshot, fetchSnapshotsForBooking, viewToFrozenPayload, viewToOverlayState, } from "./services/snapshot-service.js";
|
|
25
|
+
export { createReadProvenance, markMissingSourcedEntriesWithdrawn, markSourcedEntryWithdrawn, type OwnedChecker, type ProvenanceReadResult, readSourcedEntry, type UpsertSourcedEntryInput, upsertSourcedEntry, } from "./services/sourced-entry-service.js";
|
|
26
|
+
export { bookingCatalogSnapshotTable, type InsertBookingCatalogSnapshot, type PricingBasis, readPricingBasis, type SelectBookingCatalogSnapshot, } from "./snapshot/schema.js";
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Field-policy contract — the load-bearing schema decision.
|
|
2
|
+
// Public source-adapter contract.
|
|
3
|
+
export { ADAPTER_RATE_LIMITED, AdapterRateLimitedError, CAPABILITY_NOT_SUPPORTED, CapabilityNotSupportedError, } from "./adapter/contract.js";
|
|
4
|
+
export * from "./adapter/schemas.js";
|
|
5
|
+
// BookingJourney HTTP contract — root export matches the Hono module pattern
|
|
6
|
+
// used by the vertical packages while keeping the ./booking-engine subpath.
|
|
7
|
+
export { createCatalogBookingHonoModule, createCatalogBookingRoutes, } from "./booking-engine/routes.js";
|
|
8
|
+
export * from "./contract.js";
|
|
9
|
+
// Drift events.
|
|
10
|
+
export { blocksBookings, maxDriftSeverity, } from "./drift/events.js";
|
|
11
|
+
// Embeddings + semantic search live in Catalog. Agent runtimes can wrap the
|
|
12
|
+
// HTTP APIs directly instead of depending on a separate catalog-MCP package.
|
|
13
|
+
export { chunkForBatch, EMBEDDING_BATCH_TOO_LARGE, EMBEDDING_INPUT_TOO_LONG, EMBEDDING_PROVIDER_ERROR, EmbeddingProviderError, } from "./embeddings/contract.js";
|
|
14
|
+
export { createGeminiEmbeddingProvider, GEMINI_MODELS, } from "./embeddings/gemini.js";
|
|
15
|
+
export { isActiveEmbeddingModel, planEmbeddingMigration, stampEmbeddingModelId, validateEmbeddingCompatibility, } from "./embeddings/model-registry.js";
|
|
16
|
+
export { createOpenAIEmbeddingProvider, embedBatched, OPENAI_MODELS, } from "./embeddings/openai.js";
|
|
17
|
+
// Catalog event taxonomy + visibility-filtered payload helpers.
|
|
18
|
+
export { CATALOG_EVENT_CATEGORIES, CATALOG_EVENTS, emitCatalogEvent, filterByVisibility, } from "./events/taxonomy.js";
|
|
19
|
+
export { attachEmitter, buildCollectionSchema, buildDefaultTypesenseQueryBy, buildDefaultTypesenseSearchFields, buildSearchQuery, collectionName, createTypesenseIndexer, } from "./indexer/typesense.js";
|
|
20
|
+
export { applyMerge, isVisibleTo, resolveOverlay, variantFallbackChain, } from "./overlay/resolver.js";
|
|
21
|
+
// Overlay store — editorial overrides keyed by (entity, field, locale, audience, market).
|
|
22
|
+
export { catalogOverlayTable, OVERLAY_DEFAULT_SCOPE, overlayIdRef, } from "./overlay/schema.js";
|
|
23
|
+
// Provenance — every CatalogEntry carries this tuple.
|
|
24
|
+
export * from "./provenance.js";
|
|
25
|
+
// Sourced-entry store — durable provenance + projection capture (sourced-content §2.5).
|
|
26
|
+
export { catalogSourcedEntriesTable, } from "./schema-sourced-entries.js";
|
|
27
|
+
export { federateAudienceSearch, mergeAndDedupe, } from "./search/federate.js";
|
|
28
|
+
export { rerank, } from "./search/rerank.js";
|
|
29
|
+
export { createCatalogSearchHonoModule, createCatalogSearchRoutes, mountCatalogSearchRoutes, } from "./search/routes.js";
|
|
30
|
+
export { executeBYOVectorSearch, executeSemanticSearch, } from "./search/semantic.js";
|
|
31
|
+
// Content-service primitives (sourced-content §3.4 / §3.5).
|
|
32
|
+
export { applyJsonPointerOverlay, buildDriftInvalidationPredicate, createInvalidateOnDrift, isStale, JsonPointerError, mergeOverlaysIntoContent, parseJsonPointer, pickBestCachedLocale, withContentRefreshLock, } from "./services/content-service.js";
|
|
33
|
+
export { buildIndexerDocument, createIndexerService, } from "./services/indexer-service.js";
|
|
34
|
+
// Runtime services — drizzle-bound entry points for verticals.
|
|
35
|
+
export { fetchOverlaysForEntities, fetchOverlaysForEntity, listOverlaysByOrigin, resolveEntityView, resolveEntityViewWithOverlays, restoreOverlay, softDeleteOverlay, writeOverlay, } from "./services/overlay-service.js";
|
|
36
|
+
export { buildSnapshotInputFromView, captureSnapshot, captureSnapshotGraph, fetchEntitySnapshot, fetchSnapshotsForBooking, viewToFrozenPayload, viewToOverlayState, } from "./services/snapshot-service.js";
|
|
37
|
+
export { createReadProvenance, markMissingSourcedEntriesWithdrawn, markSourcedEntryWithdrawn, readSourcedEntry, upsertSourcedEntry, } from "./services/sourced-entry-service.js";
|
|
38
|
+
// Booking snapshot graph — frozen views captured at booking commit.
|
|
39
|
+
export { bookingCatalogSnapshotTable, readPricingBasis, } from "./snapshot/schema.js";
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IndexerAdapter contract — engine-agnostic interface for the catalog plane's
|
|
3
|
+
* search index.
|
|
4
|
+
*
|
|
5
|
+
* Voyant ships native Typesense as the v1 default (see `./typesense.ts`).
|
|
6
|
+
* Deployments that prefer Algolia, Meilisearch, Postgres FTS, Elasticsearch,
|
|
7
|
+
* or any other engine substitute their own implementation by satisfying this
|
|
8
|
+
* contract.
|
|
9
|
+
*
|
|
10
|
+
* Storefront-side documents are scoped per `(vertical, locale, audience,
|
|
11
|
+
* market)`. Admin-side documents denormalize text fields across audiences for
|
|
12
|
+
* keyword matching (see §5.4.4); admin embedding remains audience-scoped.
|
|
13
|
+
*
|
|
14
|
+
* See `docs/architecture/catalog-architecture.md` §5.4 for the full design.
|
|
15
|
+
*/
|
|
16
|
+
import type { FieldPolicyRegistry, Visibility } from "../contract.js";
|
|
17
|
+
/** Identifies a single variant slice of an indexer collection. */
|
|
18
|
+
export interface IndexerSlice {
|
|
19
|
+
vertical: string;
|
|
20
|
+
locale: string;
|
|
21
|
+
audience: Visibility | "staff-admin";
|
|
22
|
+
market: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* One document in the search index. Carries structured fields, optional
|
|
26
|
+
* vector(s), and identity for upsert / delete.
|
|
27
|
+
*/
|
|
28
|
+
export interface IndexerDocument {
|
|
29
|
+
/** Document id — typically the entity id (entity_module + entity_id pair). */
|
|
30
|
+
id: string;
|
|
31
|
+
/** Field-keyed values. The shape matches the field-policy registry's
|
|
32
|
+
* indexed paths; engines store, index, and facet per their schema config. */
|
|
33
|
+
fields: Record<string, unknown>;
|
|
34
|
+
/**
|
|
35
|
+
* Optional embedding(s) keyed by name. Phase 1 ships keyword + hybrid only;
|
|
36
|
+
* Semantic catalog indexing populates this for vector and hybrid retrieval.
|
|
37
|
+
*/
|
|
38
|
+
embeddings?: Record<string, number[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Optional embedding model identifier. When present, the indexer scopes
|
|
41
|
+
* vector queries to documents using a compatible model. See
|
|
42
|
+
* the catalog semantic-search design.
|
|
43
|
+
*/
|
|
44
|
+
embedding_model_id?: string;
|
|
45
|
+
}
|
|
46
|
+
/** Search query mode. Phase 1 ships keyword + hybrid; semantic is Phase 2. */
|
|
47
|
+
export type SearchMode = "keyword" | "semantic" | "hybrid";
|
|
48
|
+
/**
|
|
49
|
+
* Storefront-safe sort options. Adapters translate these to engine fields
|
|
50
|
+
* that are present in the indexed slice instead of exposing raw field names.
|
|
51
|
+
*/
|
|
52
|
+
export type SearchSortOption = "relevance" | "price-asc" | "price-desc" | "departure-asc" | "newest";
|
|
53
|
+
/** Pagination shape. Cursor-based by default; page/offset is engine-dependent. */
|
|
54
|
+
export interface SearchPagination {
|
|
55
|
+
cursor?: string;
|
|
56
|
+
limit?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Filter expression. Engines translate this into their own filter DSL. Kept
|
|
60
|
+
* intentionally narrow — facet equality, range, set membership — so the
|
|
61
|
+
* contract works against any engine.
|
|
62
|
+
*/
|
|
63
|
+
export type SearchFilter = {
|
|
64
|
+
kind: "eq";
|
|
65
|
+
field: string;
|
|
66
|
+
value: string | number | boolean;
|
|
67
|
+
} | {
|
|
68
|
+
kind: "in";
|
|
69
|
+
field: string;
|
|
70
|
+
values: ReadonlyArray<string | number>;
|
|
71
|
+
} | {
|
|
72
|
+
kind: "range";
|
|
73
|
+
field: string;
|
|
74
|
+
gte?: number;
|
|
75
|
+
lte?: number;
|
|
76
|
+
} | {
|
|
77
|
+
kind: "and";
|
|
78
|
+
clauses: SearchFilter[];
|
|
79
|
+
} | {
|
|
80
|
+
kind: "or";
|
|
81
|
+
clauses: SearchFilter[];
|
|
82
|
+
};
|
|
83
|
+
/** A single facet aggregation request. */
|
|
84
|
+
export interface FacetRequest {
|
|
85
|
+
field: string;
|
|
86
|
+
/** Maximum bucket count returned. */
|
|
87
|
+
limit?: number;
|
|
88
|
+
}
|
|
89
|
+
export interface SearchRequest {
|
|
90
|
+
/** Free-text query. Empty string is "match everything subject to filters". */
|
|
91
|
+
query: string;
|
|
92
|
+
/** Optional caller-supplied query embedding (BYO vector). */
|
|
93
|
+
query_embedding?: number[];
|
|
94
|
+
mode: SearchMode;
|
|
95
|
+
sort?: SearchSortOption;
|
|
96
|
+
filters?: SearchFilter[];
|
|
97
|
+
facets?: FacetRequest[];
|
|
98
|
+
pagination?: SearchPagination;
|
|
99
|
+
/**
|
|
100
|
+
* Cross-audience federation — Phase 2 only. Staff actors may request
|
|
101
|
+
* results from a non-staff audience pool via this field. Customer / partner
|
|
102
|
+
* / supplier agents are pinned to their own audience by API authorization.
|
|
103
|
+
*/
|
|
104
|
+
search_audiences?: Visibility[];
|
|
105
|
+
/**
|
|
106
|
+
* Hybrid-mode rank-fusion weight. `0..1` — `0` is keyword-only, `1` is
|
|
107
|
+
* semantic-only. Engine default mid-point varies (Typesense weights
|
|
108
|
+
* keyword `0.7` / semantic `0.3`). Only meaningful when `mode` is
|
|
109
|
+
* `hybrid` or when both signals participate.
|
|
110
|
+
*/
|
|
111
|
+
alpha?: number;
|
|
112
|
+
/**
|
|
113
|
+
* Drop hits whose vector distance exceeds this threshold (cosine
|
|
114
|
+
* distance, range `0..2`). Useful in semantic mode to cut weak-similarity
|
|
115
|
+
* tail results. Ignored in keyword-only mode.
|
|
116
|
+
*/
|
|
117
|
+
distance_threshold?: number;
|
|
118
|
+
}
|
|
119
|
+
export interface SearchHit {
|
|
120
|
+
id: string;
|
|
121
|
+
score: number;
|
|
122
|
+
document: IndexerDocument;
|
|
123
|
+
}
|
|
124
|
+
export interface SearchFacetBucket {
|
|
125
|
+
value: string | number;
|
|
126
|
+
count: number;
|
|
127
|
+
}
|
|
128
|
+
export interface SearchResults {
|
|
129
|
+
hits: SearchHit[];
|
|
130
|
+
total: number;
|
|
131
|
+
next_cursor?: string;
|
|
132
|
+
facets?: Record<string, SearchFacetBucket[]>;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Capabilities declared by the engine. Lets the catalog plane fail fast on
|
|
136
|
+
* unsupported features rather than producing wrong results silently.
|
|
137
|
+
*
|
|
138
|
+
* Phase 1 deployments leave the `supports*Vector*` flags at `false` and
|
|
139
|
+
* `vectorDimensions` at `null`; Phase 2 deployments fill them in.
|
|
140
|
+
*/
|
|
141
|
+
export interface IndexerCapabilities {
|
|
142
|
+
/** Phase 1: keyword + hybrid keyword search. */
|
|
143
|
+
supportsKeywordSearch: boolean;
|
|
144
|
+
/** Phase 1+: blend keyword and vector scores in one query (when vectors land). */
|
|
145
|
+
supportsHybridSearch: boolean;
|
|
146
|
+
/** Phase 2: store and query vector fields. */
|
|
147
|
+
supportsVectorFields: boolean;
|
|
148
|
+
/** Required vector dimension for embedding compatibility, or null if unsupported. */
|
|
149
|
+
vectorDimensions: number | null;
|
|
150
|
+
/** Some engines cap vectors per document; null means unlimited. */
|
|
151
|
+
maxVectorsPerDocument: number | null;
|
|
152
|
+
/**
|
|
153
|
+
* Whether the engine can federate queries across multiple audience pools
|
|
154
|
+
* (collections / shards) and deduplicate by entity ID. Used by the
|
|
155
|
+
* cross-audience semantic-search pattern.
|
|
156
|
+
*/
|
|
157
|
+
supportsCrossAudienceFederation: boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Whether the engine efficiently supports admin documents with multiple
|
|
160
|
+
* weighted text fields (denormalized across audiences for keyword search,
|
|
161
|
+
* see §5.4.4). Engines without efficient multi-field weighted search can
|
|
162
|
+
* fall back to a flat concatenated text field with reduced expressiveness.
|
|
163
|
+
*/
|
|
164
|
+
supportsAdminDenormalization: boolean;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* The IndexerAdapter contract. One implementation per deployment (Typesense
|
|
168
|
+
* default). Verticals push documents through the indexer; storefronts and
|
|
169
|
+
* admin search query through it.
|
|
170
|
+
*/
|
|
171
|
+
export interface IndexerAdapter {
|
|
172
|
+
capabilities: IndexerCapabilities;
|
|
173
|
+
/**
|
|
174
|
+
* Set up or migrate the engine-side schema for one variant slice. Called
|
|
175
|
+
* at deployment startup or when the field-policy registry changes shape.
|
|
176
|
+
*/
|
|
177
|
+
ensureCollection(slice: IndexerSlice, registry: FieldPolicyRegistry): Promise<void>;
|
|
178
|
+
/** Upsert one or more documents into a slice. */
|
|
179
|
+
upsert(slice: IndexerSlice, documents: IndexerDocument[]): Promise<void>;
|
|
180
|
+
/** Delete documents from a slice by id. */
|
|
181
|
+
delete(slice: IndexerSlice, ids: string[]): Promise<void>;
|
|
182
|
+
/** Search a slice with the standard request shape. */
|
|
183
|
+
search(slice: IndexerSlice, request: SearchRequest): Promise<SearchResults>;
|
|
184
|
+
/**
|
|
185
|
+
* Cold-start / migration: bulk-reindex an entire slice from a stream of
|
|
186
|
+
* documents. Engines may parallelize internally.
|
|
187
|
+
*/
|
|
188
|
+
bulkReindex(slice: IndexerSlice, stream: AsyncIterable<IndexerDocument>, options?: {
|
|
189
|
+
forceReembed?: boolean;
|
|
190
|
+
}): Promise<void>;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Per-vertical document emitter — translates a vertical's resolved-view
|
|
194
|
+
* source rows into `IndexerDocument` shapes. Each vertical implements its
|
|
195
|
+
* own emitter; the catalog plane calls them at index time.
|
|
196
|
+
*/
|
|
197
|
+
export interface DocumentEmitter<TSource = unknown> {
|
|
198
|
+
/** The vertical this emitter handles (matches `entity_module`). */
|
|
199
|
+
vertical: string;
|
|
200
|
+
/** Convert a single source row into an indexer document. */
|
|
201
|
+
emit(source: TSource, slice: IndexerSlice): IndexerDocument;
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/indexer/contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IndexerAdapter contract — engine-agnostic interface for the catalog plane's
|
|
3
|
+
* search index.
|
|
4
|
+
*
|
|
5
|
+
* Voyant ships native Typesense as the v1 default (see `./typesense.ts`).
|
|
6
|
+
* Deployments that prefer Algolia, Meilisearch, Postgres FTS, Elasticsearch,
|
|
7
|
+
* or any other engine substitute their own implementation by satisfying this
|
|
8
|
+
* contract.
|
|
9
|
+
*
|
|
10
|
+
* Storefront-side documents are scoped per `(vertical, locale, audience,
|
|
11
|
+
* market)`. Admin-side documents denormalize text fields across audiences for
|
|
12
|
+
* keyword matching (see §5.4.4); admin embedding remains audience-scoped.
|
|
13
|
+
*
|
|
14
|
+
* See `docs/architecture/catalog-architecture.md` §5.4 for the full design.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|