mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 15:51:15 +00:00
feat(intake): structured per-service intake questions
Services declare up to 8 intake fields (text/yesno, required) stored as JSONB; shared/intake.go is the single normalization point — slug keys, label/dup/unknown-key rules, yes/no canonicalization. Booking create validates answers against the service declaration (missing required -> 400), unknown keys are dropped before persist. Answers surface on UpcomingBooking and CustomerBookingView; the services page gains a compact editor and the public form renders declared questions under contact details. Verified live end-to-end. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
ad60167a31
commit
33b6e2a2a6
20 files changed
+598
-41
No files matched your search
@@ -1413,6 +1413,10 @@ export interface components {
|
||||
customerName: string;
|
||||
/** Format: date-time */
|
||||
endsAt: string;
|
||||
/** @description Structured intake answers keyed by the service's declared intakeFields keys */
|
||||
intake?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Format: uuid */
|
||||
locationId?: string;
|
||||
notes?: string;
|
||||
@@ -1475,6 +1479,9 @@ export interface components {
|
||||
customerName?: string;
|
||||
/** Format: date-time */
|
||||
endsAt?: string;
|
||||
intake?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
location?: string;
|
||||
notes?: string;
|
||||
reference?: string;
|
||||
@@ -1547,6 +1554,15 @@ export interface components {
|
||||
/** @example ok */
|
||||
status: string;
|
||||
};
|
||||
IntakeField: {
|
||||
/** @description Slug key (lowercase alnum + underscore); JSON key in booking intake answers */
|
||||
key: string;
|
||||
/** @description Customer-facing question text */
|
||||
label: string;
|
||||
required?: boolean;
|
||||
/** @enum {string} */
|
||||
type: "text" | "yesno";
|
||||
};
|
||||
Location: {
|
||||
address?: string;
|
||||
capacity?: number;
|
||||
@@ -1626,6 +1642,7 @@ export interface components {
|
||||
durationMinutes: number;
|
||||
/** Format: uuid */
|
||||
id: string;
|
||||
intakeFields?: components["schemas"]["IntakeField"][];
|
||||
name: string;
|
||||
priceCents: number;
|
||||
};
|
||||
@@ -1645,6 +1662,8 @@ export interface components {
|
||||
durationMinutes: number;
|
||||
/** Format: uuid */
|
||||
id: string;
|
||||
/** @description Structured intake questions asked at booking time (max 8) */
|
||||
intakeFields?: components["schemas"]["IntakeField"][];
|
||||
name: string;
|
||||
/** @description Price in the tenant's currency minor units */
|
||||
priceCents: number;
|
||||
@@ -1822,6 +1841,10 @@ export interface components {
|
||||
endsAt?: string;
|
||||
/** Format: uuid */
|
||||
id?: string;
|
||||
/** @description Structured intake answers keyed by the service's declared intakeFields keys */
|
||||
intake?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
label?: string;
|
||||
location?: string;
|
||||
notes?: string;
|
||||
@@ -1883,6 +1906,7 @@ export interface components {
|
||||
bufferAfterMinutes?: number;
|
||||
bufferBeforeMinutes?: number;
|
||||
durationMinutes: number;
|
||||
intakeFields?: components["schemas"]["IntakeField"][];
|
||||
name: string;
|
||||
priceCents?: number;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user