Staff Notes
The staff notes system allows course staff to create and manage notes associated with tee times, slots, and bookings.
Architecture
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Admin UI │────▶│ StaffNotes │────▶│ TeeSheet │
│ (slot drawer) │ │ Controller │ │ Prisma │
└─────────────────┘ └──────────────────┘ └─────────────────┘
Source: libs/tee-time-services/src/lib/staff-notes/staff-notes.service.ts
Note Associations
Notes can be linked to multiple entities:
| Association | Required | Description |
|---|---|---|
| Tee Time | Yes | Primary association (required) |
| Slot | Optional | Specific slot within tee time |
| Booking | Optional | Specific player booking |
Data Model
interface StaffNote {
id: string;
tenantId: string;
courseId: string;
teeTimeId: string;
slotId?: string;
bookingId?: string;
note: string;
createdBy: string; // User ID who created
createdAt: Date;
updatedAt: Date;
}
API Endpoints
Create Note
POST /admin/courses/:courseId/tee-times/:teeTimeId/staff-notes
// Request
{
"note": "Player requested early morning slot",
"slotId": "slot-123", // Optional
"bookingId": "booking-456" // Optional
}
// Response
{
"id": "note-789",
"tenantId": "tenant-abc",
"courseId": "course-123",
"teeTimeId": "teetime-456",
"slotId": "slot-123",
"bookingId": "booking-456",
"note": "Player requested early morning slot",
"createdBy": "user-xyz",
"createdAt": "2025-12-15T08:00:00Z"
}
List Notes
GET /admin/courses/:courseId/tee-times/:teeTimeId/staff-notes
// Response
[
{
"id": "note-789",
"note": "Player requested early morning slot",
"slotId": "slot-123",
"createdBy": "user-xyz",
"createdAt": "2025-12-15T08:00:00Z"
},
{
"id": "note-790",
"note": "VIP player - courtesy cart",
"createdBy": "user-abc",
"createdAt": "2025-12-15T07:30:00Z"
}
]
Validation Rules
Tee Time Validation
- Tee time must exist
- Tee time must belong to specified course
- Tee time must belong to user's tenant
Slot Validation (if provided)
- Slot must exist
- Slot must belong to the specified tee time
Booking Validation (if provided)
- Booking must exist
- Booking must have slots in the specified tee time
- Booking must belong to user's tenant
Note Content
- Required field
- Trimmed of whitespace
- Empty notes (after trim) rejected
Access Control
Required Permission
ClubPermissionGuard(CLUB_PERMISSIONS.TEE_SHEET_EDIT)
Authentication
JwtAuthGuardrequired- Tenant ID extracted from authenticated user
- Notes scoped to user's tenant
Audit Trail
createdByfield tracks user who created notecreatedAttimestamp for audit
Use Cases
Slot-Level Notes
// Note specific to a slot
{
"teeTimeId": "teetime-123",
"slotId": "slot-456",
"note": "Reserved for tournament marshal"
}
Booking-Level Notes
// Note specific to a booking/player
{
"teeTimeId": "teetime-123",
"bookingId": "booking-789",
"note": "VIP guest - CEO of sponsor company"
}
General Tee Time Notes
// Note for entire tee time
{
"teeTimeId": "teetime-123",
"note": "Pace of play check required"
}
Display Order
Notes are returned ordered by createdAt descending (newest first).
Tenant Isolation
- Notes are filtered by
tenantId - Cross-tenant access prevented
- Tenant resolved from JWT token
Error Handling
| Error | Cause |
|---|---|
NotFoundException | Tee time not found |
BadRequestException | Tee time belongs to different course |
BadRequestException | Slot doesn't belong to tee time |
BadRequestException | Booking not associated with tee time |
BadRequestException | Empty note content |
Integration
Tee Sheet Dashboard
Notes displayed in slot drawer when viewing tee time details.
Starter View
Notes visible to starters for player check-in context.
Admin Reports
Notes available in booking history and audit logs.
Troubleshooting
Note Not Saving
- Verify tee time exists
- Check slot/booking associations are valid
- Ensure note content is not empty
- Verify user has TEE_SHEET_EDIT permission
Notes Not Displaying
- Check tenant ID matches
- Verify tee time ID is correct
- Check user has TEE_SHEET_VIEW permission