mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 23:51:17 +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
@@ -5,7 +5,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const serviceColumns = "id, tenant_id, name, duration_minutes, buffer_before_minutes, buffer_after_minutes, price_cents, created_at"
|
||||
const serviceColumns = "id, tenant_id, name, duration_minutes, buffer_before_minutes, buffer_after_minutes, price_cents, intake_fields::text, created_at"
|
||||
|
||||
func (r *PGRepository) ListServicesByTenant(ctx context.Context, tenantID string) ([]ServiceRecord, error) {
|
||||
rows, err := r.pool.Query(ctx, `
|
||||
@@ -30,6 +30,7 @@ func (r *PGRepository) ListServicesByTenant(ctx context.Context, tenantID string
|
||||
&record.BufferBeforeMinutes,
|
||||
&record.BufferAfterMinutes,
|
||||
&record.PriceCents,
|
||||
&record.IntakeFields,
|
||||
&record.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
@@ -53,6 +54,7 @@ func (r *PGRepository) GetServiceByID(ctx context.Context, serviceID string) (Se
|
||||
&record.BufferBeforeMinutes,
|
||||
&record.BufferAfterMinutes,
|
||||
&record.PriceCents,
|
||||
&record.IntakeFields,
|
||||
&record.CreatedAt,
|
||||
)
|
||||
return record, err
|
||||
@@ -61,10 +63,10 @@ func (r *PGRepository) GetServiceByID(ctx context.Context, serviceID string) (Se
|
||||
func (r *PGRepository) CreateService(ctx context.Context, params CreateServiceParams) (ServiceRecord, error) {
|
||||
var record ServiceRecord
|
||||
err := r.pool.QueryRow(ctx, `
|
||||
INSERT INTO services (tenant_id, name, duration_minutes, buffer_before_minutes, buffer_after_minutes, price_cents)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
INSERT INTO services (tenant_id, name, duration_minutes, buffer_before_minutes, buffer_after_minutes, price_cents, intake_fields)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)
|
||||
RETURNING `+serviceColumns+`
|
||||
`, params.TenantID, params.Name, params.DurationMinutes, params.BufferBeforeMinutes, params.BufferAfterMinutes, params.PriceCents).Scan(
|
||||
`, params.TenantID, params.Name, params.DurationMinutes, params.BufferBeforeMinutes, params.BufferAfterMinutes, params.PriceCents, params.IntakeFields).Scan(
|
||||
&record.ID,
|
||||
&record.TenantID,
|
||||
&record.Name,
|
||||
@@ -72,6 +74,7 @@ func (r *PGRepository) CreateService(ctx context.Context, params CreateServicePa
|
||||
&record.BufferBeforeMinutes,
|
||||
&record.BufferAfterMinutes,
|
||||
&record.PriceCents,
|
||||
&record.IntakeFields,
|
||||
&record.CreatedAt,
|
||||
)
|
||||
return record, err
|
||||
@@ -85,10 +88,11 @@ func (r *PGRepository) UpdateService(ctx context.Context, serviceID string, para
|
||||
duration_minutes = COALESCE($3, duration_minutes),
|
||||
buffer_before_minutes = COALESCE($4, buffer_before_minutes),
|
||||
buffer_after_minutes = COALESCE($5, buffer_after_minutes),
|
||||
price_cents = COALESCE($6, price_cents)
|
||||
price_cents = COALESCE($6, price_cents),
|
||||
intake_fields = COALESCE($7::jsonb, intake_fields)
|
||||
WHERE id = $1
|
||||
RETURNING `+serviceColumns+`
|
||||
`, serviceID, params.Name, params.DurationMinutes, params.BufferBeforeMinutes, params.BufferAfterMinutes, params.PriceCents).Scan(
|
||||
`, serviceID, params.Name, params.DurationMinutes, params.BufferBeforeMinutes, params.BufferAfterMinutes, params.PriceCents, params.IntakeFields).Scan(
|
||||
&record.ID,
|
||||
&record.TenantID,
|
||||
&record.Name,
|
||||
@@ -96,6 +100,7 @@ func (r *PGRepository) UpdateService(ctx context.Context, serviceID string, para
|
||||
&record.BufferBeforeMinutes,
|
||||
&record.BufferAfterMinutes,
|
||||
&record.PriceCents,
|
||||
&record.IntakeFields,
|
||||
&record.CreatedAt,
|
||||
)
|
||||
return record, err
|
||||
|
||||
Reference in new issue
Block a user