mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 07:41:16 +00:00
feat: data surfacing — intake labels, service metrics, honest capacity
- booking views gain intakeLabels (declared key→label join); dashboard modal + manage view render real question labels with slug fallback - GET /v1/metrics/services aggregates bookings/completed/cancelled/ revenue per service + classBookings; service-report.csv delegates to the same ServiceMetrics aggregation and gains a completed column - services page gains a Service performance card (per-service stat grid, locale CZK revenue, class-bookings footer); demo rows match the fabricated service list - staff capacity utilization subtracts blocked days — tenant-wide and staff-scoped blocks remove that day's rule minutes via blockedAt - tests: blocked-day capacity (tenant + staff scope), service aggregation Authored By: TDvorak <[email protected]> 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
34becc1bf4
commit
5c860a1264
16 files changed
+560
-69
No files matched your search
@@ -1545,6 +1545,33 @@ paths:
|
||||
$ref: "#/components/schemas/StaffMetricsResponse"
|
||||
"404":
|
||||
description: Tenant membership not found
|
||||
/v1/metrics/services:
|
||||
get:
|
||||
tags: [Metrics]
|
||||
operationId: getServiceMetrics
|
||||
security:
|
||||
- bearerAuth: []
|
||||
summary: Per-service appointment metrics over a trailing window
|
||||
description: >-
|
||||
Bookings, completions, cancellations, and revenue per catalog service.
|
||||
Every service appears, including zero rows. Class bookings carry no
|
||||
service or price and are counted separately in `classBookings`.
|
||||
parameters:
|
||||
- name: days
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 30
|
||||
maximum: 365
|
||||
responses:
|
||||
"200":
|
||||
description: Per-service metrics
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ServiceMetricsResponse"
|
||||
"404":
|
||||
description: Tenant membership not found
|
||||
/v1/export/bookings.csv:
|
||||
get:
|
||||
tags: [Export]
|
||||
@@ -2219,6 +2246,11 @@ components:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Structured intake answers keyed by the service's declared intakeFields keys
|
||||
intakeLabels:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Maps intake answer keys to the service's declared field labels; absent for services without intake
|
||||
classSessionId:
|
||||
type: string
|
||||
format: uuid
|
||||
@@ -2266,6 +2298,11 @@ components:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
intakeLabels:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Maps intake answer keys to the service's declared field labels; absent for services without intake
|
||||
waitlistPosition:
|
||||
type: integer
|
||||
description: 1-based queue spot for waitlisted class bookings; absent otherwise
|
||||
@@ -2408,6 +2445,42 @@ components:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/StaffMetric"
|
||||
ServiceMetric:
|
||||
type: object
|
||||
required: [serviceId, name, bookings, completed, cancelled, revenueCents]
|
||||
properties:
|
||||
serviceId:
|
||||
type: string
|
||||
format: uuid
|
||||
name:
|
||||
type: string
|
||||
bookings:
|
||||
type: integer
|
||||
completed:
|
||||
type: integer
|
||||
cancelled:
|
||||
type: integer
|
||||
revenueCents:
|
||||
type: integer
|
||||
format: int64
|
||||
description: Sum of the service's price for non-cancelled bookings
|
||||
ServiceMetricsResponse:
|
||||
type: object
|
||||
required: [from, to, services, classBookings]
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
format: date-time
|
||||
to:
|
||||
type: string
|
||||
format: date-time
|
||||
services:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/ServiceMetric"
|
||||
classBookings:
|
||||
type: integer
|
||||
description: Session bookings in the window; reported separately since they carry no service or price
|
||||
DashboardBookingRequest:
|
||||
type: object
|
||||
required: [customerName, customerEmail, startsAt]
|
||||
|
||||
Reference in new issue
Block a user