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

+14
View File
@@ -1296,6 +1296,20 @@ func NewServer(cfg config.Config, pools *db.Pools) (*Server, error) {
c.JSON(http.StatusOK, response)
})
protected.GET("/metrics/staff", func(c *gin.Context) {
days, _ := strconv.Atoi(c.DefaultQuery("days", "30"))
response, err := bookingService.StaffMetrics(c.Request.Context(), auth.PrincipalFromContext(c), days)
if err != nil {
status := http.StatusInternalServerError
if errors.Is(err, bookings.ErrTenantMembership) {
status = http.StatusNotFound
}
c.JSON(status, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, response)
})
protected.GET("/export/bookings.csv", func(c *gin.Context) {
from, to := exportRange(c)
var buf bytes.Buffer