feat(metrics): per-staff performance view in dashboard

GET /v1/metrics/staff returns bookings, completed, cancelled,
utilization, and revenue per staff member over a trailing window
(default 30d, max 365d). Appointment bookings only — class sessions
have no staff assignment. All active staff appear, including
zero-booking rows.

Staff page gains a localized Performance panel; demo mode seeds
trailing-window bookings and matching metric rows.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-18 16:34:45 +02:00
1 parent 4674203502
commit 76e45d4178
11 files changed
+496 -3

No files matched your search

@@ -752,6 +752,26 @@ export interface paths {
patch?: never;
trace?: never;
};
"/v1/metrics/staff": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* Per-staff appointment metrics over a trailing window
* @description Bookings, completions, cancellations, utilization, and revenue per staff member. Only appointment bookings carry a staff assignment — class attendance is excluded by design. Every active staff member appears, including zero rows.
*/
get: operations["getStaffMetrics"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/public/bookings": {
parameters: {
query?: never;
@@ -1555,6 +1575,28 @@ export interface components {
/** Format: uuid */
tenantId: string;
};
StaffMetric: {
bookings: number;
cancelled: number;
completed: number;
displayName: string;
/**
* Format: int64
* @description Sum of linked service prices for non-cancelled bookings
*/
revenueCents: number;
/** Format: uuid */
staffId: string;
/** @description Share of bookings that stayed confirmed, 0-100 */
utilizationPercent: number;
};
StaffMetricsResponse: {
/** Format: date-time */
from: string;
staff: components["schemas"]["StaffMetric"][];
/** Format: date-time */
to: string;
};
SubscriptionSnapshot: {
cancelAtPeriodEnd: boolean;
checkoutUrlAvailable: boolean;
@@ -3532,6 +3574,35 @@ export interface operations {
};
};
};
getStaffMetrics: {
parameters: {
query?: {
days?: number;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Per-staff metrics */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["StaffMetricsResponse"];
};
};
/** @description Tenant membership not found */
404: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
createBooking: {
parameters: {
query?: never;