mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 15:51:15 +00:00
feat: scheduled report digests + per-session capacity (M33)
POST /v1/internal/jobs/reports/dispatch emails each tenant owner a trailing-window digest (bookings, revenue, per-service and per-staff breakdown) localized to the tenant locale; zero-activity tenants are skipped. Metrics cores extracted to tenant-scoped variants so the job needs no principal. PATCH /v1/catalog/class-sessions/:id sets a session's seat count with a confirmed-bookings floor — shrinking below it needs allowOverCapacity, matching the waitlist-promotion convention. Session rows gain an inline capacity editor with an overbook confirm state. 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
e6f1ec38a4
commit
e680e0c2b8
14 files changed
+808
-10
No files matched your search
@@ -2,6 +2,8 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
const classTemplateColumns = "id, tenant_id, title, duration_minutes, capacity, created_at"
|
||||
@@ -132,3 +134,14 @@ func (r *PGRepository) DeleteClassSession(ctx context.Context, sessionID string)
|
||||
_, err := r.pool.Exec(ctx, `DELETE FROM class_sessions WHERE id = $1`, sessionID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *PGRepository) UpdateClassSessionCapacity(ctx context.Context, sessionID string, capacity int) (ClassSessionRecord, error) {
|
||||
tag, err := r.pool.Exec(ctx, `UPDATE class_sessions SET capacity = $2 WHERE id = $1`, sessionID, capacity)
|
||||
if err != nil {
|
||||
return ClassSessionRecord{}, err
|
||||
}
|
||||
if tag.RowsAffected() == 0 {
|
||||
return ClassSessionRecord{}, pgx.ErrNoRows
|
||||
}
|
||||
return r.GetClassSessionByID(ctx, sessionID)
|
||||
}
|
||||
@@ -30,6 +30,9 @@ type Repository interface {
|
||||
GetClassSessionByID(ctx context.Context, sessionID string) (ClassSessionRecord, error)
|
||||
CreateClassSession(ctx context.Context, params CreateClassSessionParams) (ClassSessionRecord, error)
|
||||
DeleteClassSession(ctx context.Context, sessionID string) error
|
||||
// UpdateClassSessionCapacity sets the session's seat count; the caller
|
||||
// checks tenancy and the booked-seats floor.
|
||||
UpdateClassSessionCapacity(ctx context.Context, sessionID string, capacity int) (ClassSessionRecord, error)
|
||||
ListClassTemplatesByTenant(ctx context.Context, tenantID string) ([]ClassTemplateRecord, error)
|
||||
GetClassTemplateByID(ctx context.Context, templateID string) (ClassTemplateRecord, error)
|
||||
CreateClassTemplate(ctx context.Context, params CreateClassTemplateParams) (ClassTemplateRecord, error)
|
||||
@@ -1539,6 +1542,16 @@ func (r *MemoryRepository) DeleteClassSession(_ context.Context, sessionID strin
|
||||
return pgx.ErrNoRows
|
||||
}
|
||||
|
||||
func (r *MemoryRepository) UpdateClassSessionCapacity(_ context.Context, sessionID string, capacity int) (ClassSessionRecord, error) {
|
||||
for i := range r.classSessions {
|
||||
if r.classSessions[i].ID == sessionID {
|
||||
r.classSessions[i].Capacity = int32(capacity)
|
||||
return r.classSessions[i], nil
|
||||
}
|
||||
}
|
||||
return ClassSessionRecord{}, pgx.ErrNoRows
|
||||
}
|
||||
|
||||
func (r *MemoryRepository) ListClassSchedulesByTenant(_ context.Context, tenantID string) ([]ClassScheduleRecord, error) {
|
||||
if tenantID != r.tenant.ID {
|
||||
return nil, nil
|
||||
|
||||
Reference in new issue
Block a user