Skip to content

Latest commit

 

History

History
948 lines (798 loc) · 31 KB

File metadata and controls

948 lines (798 loc) · 31 KB

ShiftIQ - Technical Reference Guide

Last Updated: November 2, 2025
Version: 1.5.0

This document provides a comprehensive technical overview of the ShiftIQ system architecture, codebase organization, and key implementation details. Use this as a reference when resuming development or onboarding new team members.

Latest Updates (v1.5.0):

  • ✅ Added complete database schema documentation for AuditLogs, EmailQueue, and SystemSettings tables
  • ✅ Documented all database constraints (CHECK, CASCADE behaviors, UNIQUE)
  • ✅ Added comprehensive performance index documentation
  • ✅ Complete enumeration value mappings for all enums
  • ✅ Enhanced database file information with data type specifications

📁 Project Structure

C:\ROTA\
├── src/                                    # Backend .NET solution
│   ├── StaffRota.Core/                     # Domain layer
│   │   ├── Entities/                       # Database entities
│   │   ├── Enums/                          # Enumerations (UserRole, ShiftStatus, etc.)
│   │   └── Interfaces/                     # Service and repository interfaces
│   ├── StaffRota.Business/                 # Business logic layer
│   │   ├── Services/                       # Business services
│   │   │   ├── ApprovalWorkflowService.cs  # Approval workflow engine
│   │   │   └── EmailService.cs             # Email notification system
│   │   └── Models/                         # Business models
│   ├── StaffRota.Data/                     # Data access layer
│   │   └── Repositories/                   # Repository implementations
│   ├── StaffRota.Web/                      # Web API layer
│   │   ├── Controllers/                    # API controllers
│   │   ├── Models/                         # DTOs and view models
│   │   ├── Services/                       # Web-specific services
│   │   ├── Middleware/                     # Custom middleware
│   │   ├── appsettings.json               # Configuration
│   │   └── StaffRotaDb.sqlite             # SQLite database file
│   └── StaffRota.Tests/                    # Unit tests
├── frontend/staff-rota-ui/                 # React frontend
│   ├── src/
│   │   ├── components/
│   │   │   ├── layout/                     # Layout components (Header, Sidebar)
│   │   │   ├── pages/                      # Page components
│   │   │   └── settings/                   # Settings components
│   │   ├── theme/                          # Theme configuration
│   │   │   ├── createTheme.ts             # MUI theme factory
│   │   │   ├── ThemeProvider.tsx          # Theme context provider
│   │   │   └── types.ts                   # Theme type definitions & defaults
│   │   ├── api/                           # API client functions
│   │   ├── services/                      # Frontend services
│   │   ├── contexts/                      # React contexts
│   │   ├── types/                         # TypeScript type definitions
│   │   └── App.tsx                        # Main app component
│   └── package.json                       # npm dependencies
├── reset_and_populate_db.sql              # Test data population script
└── README.md                              # Project documentation


🎨 Theme System

Location

  • Configuration: frontend/staff-rota-ui/src/theme/types.ts
  • Factory: frontend/staff-rota-ui/src/theme/createTheme.ts
  • Provider: frontend/staff-rota-ui/src/theme/ThemeProvider.tsx

Corporate Color Scheme

// Default theme configuration (types.ts)
brandColors: {
  primary: '#1D1F48',     // Primary - Navy
  secondary: '#B21A53',   // Secondary - Raspberry
  accent: '#9bcd4e',      // Accent - Core Green
  success: '#9bcd4e',     // Success - Core Green
  warning: '#ed6c02',     // Warning - Orange (standard)
  error: '#B21A53',       // Error - Raspberry
  info: '#43C5B8',        // Info - Eggplant (Teal)
  titleColor: '#1D1F48',  // Page title color - Navy
}

Corporate Color Palette (Full)

  • Primary - Eggplant: #43C5B8 (R 67, G 197, B 184) - Used for info
  • Primary - Navy: #1D1F48 (R 29, G 31, B 72) - Main primary color
  • Secondary - Raspberry: #B21A53 (R 178, G 26, B 83) - Secondary color
  • Secondary - Charcoal: #303040 (R 48, G 48, B 64) - Available
  • Secondary - Gray: #E6E7E8 (R 230, G 231, B 232) - Available
  • Tertiary - Black: #000000 - Available
  • Tertiary - White: #FFFFFF - Available
  • Accent - Core Green: #9bcd4e (R 155, G 205, B 78) - Success/accent

Theme Features

  • Dynamic theme switching: Light/dark mode support
  • Persistent storage: Theme saved to localStorage
  • CSS custom properties: Theme values available as CSS variables
  • Admin configurable: Colors can be changed via Settings → Color Schemes
  • Component overrides: Custom styling for MUI components (Button, Card, Paper, TextField, TableHead)

Using Theme Colors in Components

import { useTheme } from '@mui/material';

const MyComponent = () => {
  const theme = useTheme();
  
  // Access theme colors
  const primaryColor = theme.palette.primary.main;
  const secondaryColor = theme.palette.secondary.main;
  
  // Convert hex to rgba for opacity
  const hexToRgba = (hex: string, alpha: number) => {
    const r = parseInt(hex.slice(1, 3), 16);
    const g = parseInt(hex.slice(3, 5), 16);
    const b = parseInt(hex.slice(5, 7), 16);
    return `rgba(${r}, ${g}, ${b}, ${alpha})`;
  };
  
  return (
    <Box sx={{
      background: `linear-gradient(135deg, 
        ${hexToRgba(theme.palette.primary.main, 0.15)} 0%, 
        ${hexToRgba(theme.palette.secondary.main, 0.15)} 100%)`
    }}>
      Content
    </Box>
  );
};

🔐 Authentication System

Backend (JWT)

  • Location: src/StaffRota.Web/Controllers/AuthController.cs
  • Token Generation: JWT tokens with user ID, email, and role claims
  • Configuration: appsettings.json → JwtSettings section
  • Middleware: JWT Bearer authentication in Program.cs

Frontend

  • Service: frontend/staff-rota-ui/src/services/authService.ts
  • Storage: JWT token stored in localStorage as shiftiq_token
  • API Headers: Token sent as Authorization: Bearer <token>

User Roles (Enum Values)

// src/StaffRota.Core/Enums/UserRole.cs
public enum UserRole {
    TeamMember = 1,  // Standard staff member
    TeamLead = 2,    // Team manager/lead
    TeamAdmin = 3    // System administrator
}

Test Accounts

  • Admin: test@admin.com / Test123!
    • Password Hash: $2a$12$YLtHMLFGSH9sFQqPBsd/AO992UD8KXmLcoNaqK/Mex.NNzxdDYskG
    • Role: 3 (TeamAdmin)
  • All Test Users: Password is Password123!

📊 Database Schema

Key Tables

Users

  • Primary Key: Id (INTEGER)
  • Important Fields:
    • Email (UNIQUE), Username (UNIQUE)
    • PasswordHash - Hashed password
    • Role - UserRole enum (1=TeamMember, 2=TeamLead, 3=TeamAdmin)
    • TeamId - Foreign key to Teams
    • FirstName, LastName, JobTitle
    • PhoneNumber, HourlyRate
    • IsActive - Soft delete flag
    • PreferredTimezone - User timezone (default 'UTC')

Teams

  • Primary Key: Id (INTEGER)
  • Important Fields:
    • Name (UNIQUE)
    • ManagerId - Foreign key to Users (team lead)
    • LocationId - Foreign key to Locations
    • IsActive - Soft delete flag

Locations

  • Primary Key: Id (INTEGER)
  • Important Fields:
    • Name (UNIQUE)
    • Address, Capacity
    • IsActive - Soft delete flag

Shifts

  • Primary Key: Id (INTEGER)
  • Important Fields:
    • Title, Description
    • StartDateTime, EndDateTime (TEXT in ISO format)
    • LocationId, TeamId - Foreign keys
    • Status - ShiftStatus enum
    • Priority - Integer priority level
    • RequiredStaff - Number of staff needed
    • RecurrencePatternId - NULL for one-time shifts
    • PayRate - Decimal hourly rate

RecurrencePatterns

  • Primary Key: Id (INTEGER)
  • Important Fields:
    • Type - RecurrenceType enum (0=Daily, 1=Weekly, 2=Monthly)
    • Interval - Repeat every N days/weeks/months
    • DaysOfWeek - Comma-separated (e.g., "1,3,5" for Mon/Wed/Fri)
    • StartDate, EndDate (datetime2)
    • MaxOccurrences - Optional limit on repetitions

ShiftAssignments

  • Primary Key: Id (INTEGER)
  • Unique Constraint: (ShiftId, UserId) - One assignment per user per shift
  • Important Fields:
    • ShiftId, UserId - Foreign keys
    • AssignedByUserId - Who made the assignment
    • IsConfirmed - Boolean confirmation status
    • Status - Assignment status enum

ApprovalRequests

  • Primary Key: Id (INTEGER)
  • Important Fields:
    • Type - ApprovalRequestType enum
    • Status - ApprovalStatus enum (Pending, Approved, Rejected)
    • RequesterId, ApproverId - Foreign keys to Users
    • ShiftId, SwapRequestId - Foreign keys to related entities
    • RequestData - JSON serialized request details
    • Priority - Request priority (1=Low to 5=Critical)

AuditLogs

  • Primary Key: Id (INTEGER)
  • Purpose: Complete audit trail for all system actions
  • Important Fields:
    • UserId - Foreign key to Users (who performed the action)
    • Action - Action performed (e.g., "Create", "Update", "Delete")
    • EntityType - Type of entity affected (e.g., "Shift", "User")
    • EntityId - ID of the affected entity
    • Changes - Summary of changes made
    • OldValues - JSON of previous values
    • NewValues - JSON of new values
    • Timestamp - When the action occurred
    • IpAddress - Client IP address
    • UserAgent - Browser/client information
    • Notes - Additional context
  • Indexes: Action, EntityType, EntityId, Timestamp, UserId
  • Use Cases: Security auditing, compliance, debugging, change history

EmailQueue

  • Primary Key: Id (INTEGER)
  • Purpose: Email queuing system with retry logic and priority support
  • Important Fields:
    • ToAddress, FromAddress - Email addresses
    • Subject, Body - Email content (HTML)
    • PlainTextBody - Plain text version (optional)
    • Status - EmailStatus enum (1=Queued, 2=Processing, 3=Sent, 4=Failed, 5=FailedPermanently)
    • CreatedAt - When email was queued
    • SentAt - When email was successfully sent
    • RetryCount - Number of send attempts (default: 0)
    • MaxRetries - Maximum retry attempts (default: 3)
    • LastError - Error message from last failed attempt
    • Priority - Email priority (1=Critical to 5=Low, default: 3)
    • ScheduledAt - When to send (for scheduled emails)
    • TemplateName - Email template identifier
    • TemplateData - JSON data for template rendering
  • Constraints:
    • CK_EmailQueue_MaxRetries - MaxRetries >= 0
    • CK_EmailQueue_Priority - Priority BETWEEN 1 AND 5
    • CK_EmailQueue_RetryCount - RetryCount >= 0
  • Indexes: Status, Priority, CreatedAt, ScheduledAt, ToAddress
  • Composite Index: IX_EmailQueue_Processing (Status, Priority, CreatedAt) for efficient queue processing

SystemSettings

  • Primary Key: Key (TEXT)
  • Purpose: Dynamic system configuration with type validation and encryption support
  • Important Fields:
    • Key - Unique setting identifier (e.g., "EmailProvider.SmtpHost")
    • Value - Current setting value
    • Description - Human-readable description
    • Category - Grouping category (default: "General")
    • DataType - Expected data type (default: "string")
    • ModifiedAt - Last modification timestamp
    • ModifiedByUserId - Foreign key to Users (who last changed it)
    • IsEncrypted - Whether value is encrypted (for sensitive data)
    • IsReadOnly - Prevents UI modification of system-critical settings
    • DefaultValue - Factory default for reset functionality
    • ValidationRules - JSON schema for value validation
  • Indexes: Category, ModifiedAt, ModifiedByUserId
  • Use Cases: Application configuration, feature flags, email settings, theme customization

Database Constraints

Check Constraints

  • Shifts:
    • CK_Shifts_EndAfterStart - Ensures EndDateTime > StartDateTime
    • CK_Shifts_PayRate - Ensures PayRate >= 0
  • SwapRequests:
    • CK_SwapRequests_DifferentUsers - Prevents RequestingUserId = TargetUserId (no self-swaps)
  • EmailQueue:
    • CK_EmailQueue_MaxRetries - Ensures MaxRetries >= 0
    • CK_EmailQueue_Priority - Ensures Priority BETWEEN 1 AND 5
    • CK_EmailQueue_RetryCount - Ensures RetryCount >= 0

Foreign Key Cascade Behaviors

  • ON DELETE CASCADE: RecurrencePatterns → Shifts (deleting pattern removes all occurrences)
  • ON DELETE RESTRICT: Prevents deletion of Users who created shifts/requests (preserves audit trail)
  • ON DELETE SET NULL: Most foreign keys (allows entity deletion while preserving records)

Unique Constraints

  • Users: Email (IX_Users_Email), Username (IX_Users_Username)
  • Teams: Name
  • Locations: Name

Performance Indexes

Composite Indexes (Multi-column)

  • Shifts: IX_Shifts_DateRange (StartDateTime, EndDateTime) - Range queries
  • ApprovalRequests:
    • IX_ApprovalRequests_Status_ApproverId - Manager approval dashboards
    • IX_ApprovalRequests_Status_Priority - Priority-sorted pending queues
    • IX_ApprovalRequests_Status_RequesterId - User request tracking
  • EmailQueue: IX_EmailQueue_Processing (Status, Priority, CreatedAt) - Queue processing

Single-Column Indexes

  • High-traffic query fields: UserId, TeamId, LocationId, Status, StartDateTime, EndDateTime
  • Foreign keys: All foreign key columns for JOIN performance
  • Filter fields: IsActive, Role, Status enums

Enumeration Values

UserRole (src/StaffRota.Core/Enums/UserRole.cs)

TeamMember = 1   - Standard staff member
TeamLead = 2     - Team manager/lead
TeamAdmin = 3    - System administrator

ShiftStatus (src/StaffRota.Core/Enums/ShiftStatus.cs)

Draft = 1           - Created but not published
Published = 2       - Visible to team members
Active = 3          - Ready for assignment
Assigned = 4        - Assigned to team member
SwapRequested = 5   - Swap request pending
Completed = 6       - Shift completed
Cancelled = 7       - Shift cancelled

AssignmentStatus (src/StaffRota.Core/Enums/AssignmentStatus.cs)

Assigned = 0    - Assigned but not confirmed
Confirmed = 1   - User confirmed attendance
Declined = 2    - User declined assignment
Cancelled = 3   - Manager cancelled assignment
NoShow = 4      - User didn't show up
Completed = 5   - Shift completed successfully

ApprovalStatus (src/StaffRota.Core/Enums/ApprovalStatus.cs)

Pending = 1     - Awaiting review
Approved = 2    - Approved by manager
Rejected = 3    - Rejected by manager
Cancelled = 4   - Cancelled by requester
Expired = 5     - Expired (time limit exceeded)

ApprovalType (src/StaffRota.Core/Enums/ApprovalStatus.cs)

ShiftCreation = 1      - Request to create shift
ShiftModification = 2  - Request to modify shift
ShiftCancellation = 3  - Request to cancel shift
ShiftSwap = 4          - Request to swap shifts
OvertimeRequest = 5    - Request for overtime
TimeOffRequest = 6     - Request for time off

SwapRequestStatus (src/StaffRota.Core/Enums/SwapRequestStatus.cs)

Pending = 1     - Awaiting target user response
Accepted = 2    - Target accepted, awaiting approval
Declined = 3    - Target declined request
Approved = 4    - Team Lead approved swap
Rejected = 5    - Team Lead rejected swap
Cancelled = 6   - Requester cancelled

EmailStatus (src/StaffRota.Core/Enums/EmailStatus.cs)

Queued = 1             - Queued for sending
Processing = 2         - Currently being sent
Sent = 3               - Successfully sent
Failed = 4             - Failed, will retry
FailedPermanently = 5  - Failed after max retries

Priority (src/StaffRota.Core/Enums/Priority.cs)

Low = 1      - Can be processed when convenient
Medium = 2   - Standard processing time
High = 3     - Should be processed quickly
Urgent = 4   - Requires immediate attention

ShiftPriority (src/StaffRota.Core/Enums/ShiftPriority.cs)

Low = 0       - Low priority shift
Normal = 1    - Normal priority (default)
High = 2      - High priority shift
Critical = 3  - Critical priority shift

RecurrenceType (Referenced in RecurrencePatterns)

Daily = 0     - Repeat daily
Weekly = 1    - Repeat weekly (use DaysOfWeek)
Monthly = 2   - Repeat monthly

NotificationType (src/StaffRota.Core/Enums/NotificationType.cs)

# Shift Management Notifications
ShiftAssigned = 1             - User assigned to shift
ShiftUnassigned = 2           - User removed from shift
ShiftCancelled = 3            - Shift cancelled
ShiftModified = 4             - Shift details changed
ShiftReminder = 5             - Upcoming shift reminder

# Swap Request Notifications
SwapRequested = 10            - Swap request received
SwapApproved = 11             - Swap approved by manager
SwapRejected = 12             - Swap rejected by manager
SwapCancelled = 13            - Swap cancelled by requester

# Schedule Notifications
SchedulePublished = 20        - Schedule published
ScheduleModified = 21         - Schedule changed
WeeklyScheduleReminder = 22   - Weekly schedule reminder

# Administrative Notifications
AccountCreated = 30           - New account created
PasswordReset = 31            - Password reset link
AccountDeactivated = 32       - Account deactivated
RoleChanged = 33              - User role changed

# Approval Workflow Notifications
ShiftApprovalRequired = 40    - Shift needs approval
ShiftApproved = 41            - Shift approved
ShiftRejected = 42            - Shift rejected
OvertimeApprovalRequired = 43 - Overtime needs approval

# System Notifications
SystemMaintenance = 50        - Scheduled maintenance
SystemUpdate = 51             - System update notice
TestNotification = 52         - Test notification

Database File

  • Location: src/StaffRota.Web/StaffRotaDb.sqlite
  • Type: SQLite database
  • Data Types:
    • DateTime fields: Stored as TEXT in ISO 8601 format
    • Decimal fields: decimal(8,2) for currency/rates
    • Boolean fields: INTEGER (0=false, 1=true)
  • Migrations: Entity Framework Core migrations in StaffRota.Data
  • Note: SQLite limitations - concurrent writes may cause locking (not suitable for high-traffic production)

Test Data Script

  • File: database-scripts/reset_and_populate_db.sql
  • Documentation: See database-scripts/README.md for details
  • What it does:
    1. Preserves test@admin.com account
    2. Deletes all other data (users, teams, locations, shifts)
    3. Creates 6 locations, 13 teams, 44 users
    4. Creates 47 shifts (41 one-time + 6 recurring)
    5. Assigns some staff to shifts

Run script:

cd C:\ROTA\src\StaffRota.Web
Get-Content ..\..\database-scripts\reset_and_populate_db.sql | sqlite3 StaffRotaDb.sqlite

🎯 Key Components & Pages

Frontend Pages (All in frontend/staff-rota-ui/src/components/pages/)

LiveDashboard.tsx

  • Route: /dashboard
  • Purpose: Main landing page after login
  • Layout: 3-column Box flexbox layout
    • Left Column: Recent Shifts (placeholder)
    • Middle Column: Upcoming Shifts
      • Grouped by week (startOfWeek/endOfWeek)
      • Shows first week only
      • Day/date display: format(parseISO(shift.startTime), 'EEE').toUpperCase() + date number
      • Alternating row backgrounds with theme gradient (15% opacity)
    • Right Column: Stat cards (YTD, This Month, Unassigned, Pending Approval, TBC x2)
  • Features:
    • Auto-updating timestamp (updates every 60 seconds)
    • Shift details dialog (two-column layout)
    • Fetches from /api/shifts/my-shifts
    • Filters for upcoming shifts only

Dashboard.tsx

  • Route: /dashboard-mock
  • Status: Mock version, not actively used
  • Note: LiveDashboard.tsx is the actual dashboard

MyShifts.tsx

  • Route: /my-shifts
  • Purpose: User's personal shift schedule
  • Views:
    • All Shifts - 2-column card grid layout
    • Weekly View - Calendar-style week view
    • Monthly Views - This/Next/Last month tabs
  • Features:
    • Shift details dialog
    • Swap shift functionality
    • Filter by time period

MonthlyTimeline.tsx

  • Route: /monthly-timeline
  • Purpose: Monthly shift overview
  • Layout: Weekly list view grouped by weeks
    • Shows all weeks in the month (including cross-month weeks)
    • Day/date display (MON 21, TUE 22, etc.)
    • Alternating row backgrounds

ApprovalDashboard.tsx

  • Route: /approvals
  • Purpose: Shift swap approval workflow
  • Tabs:
    • Pending Approvals (for managers)
    • My Requests (user's submitted requests)
    • History (processed requests)
  • Layout: Two-column (65%/35% split)
    • Left: Request list
    • Right: Shift details panel
  • Features:
    • Self-approval prevention
    • Coverage impact warnings
    • Decision comments
    • Badge notifications

TeamManagement.tsx

  • Route: /team-management
  • Access: TeamLead and TeamAdmin roles
  • Features:
    • TeamLeads: Manage only their team members
    • Admins: Accordion view of all teams
    • Expand/collapse all functionality
    • Create users with team/role assignment

Layout Components

Header.tsx

  • Location: frontend/staff-rota-ui/src/components/layout/Header.tsx
  • Features:
    • ShiftIQ logo and branding
    • "Team Member" badge (Core Green background)
    • User profile menu
    • Notifications icon
    • Sign out functionality

Sidebar.tsx (if exists)

  • Navigation menu
  • Role-based menu items

🔄 API Endpoints

Authentication

  • POST /api/auth/login - User login, returns JWT token
  • POST /api/auth/register - User registration
  • POST /api/auth/refresh - Refresh JWT token

Users

  • GET /api/users - Get all users (Admin only)
  • GET /api/users/{id} - Get user by ID
  • GET /api/users/my-team-members - Get team members (role-based filtering)
  • POST /api/users - Create new user
  • PUT /api/users/{id} - Update user
  • DELETE /api/users/{id} - Delete user (soft delete)
  • GET /api/users/by-role/{role} - Get users by role

Shifts

  • GET /api/shifts - Get all shifts
  • GET /api/shifts/{id} - Get shift by ID
  • GET /api/shifts/my-shifts - Get current user's shifts
  • POST /api/shifts - Create new shift
  • PUT /api/shifts/{id} - Update shift
  • DELETE /api/shifts/{id} - Delete shift
  • POST /api/shifts/recurring - Create recurring shift pattern

Teams

  • GET /api/teams - Get all teams
  • GET /api/teams/{id} - Get team by ID
  • POST /api/teams - Create team
  • PUT /api/teams/{id} - Update team
  • DELETE /api/teams/{id} - Delete team

Locations

  • GET /api/locations - Get all locations
  • GET /api/locations/{id} - Get location by ID
  • POST /api/locations - Create location
  • PUT /api/locations/{id} - Update location
  • DELETE /api/locations/{id} - Delete location

Approvals

  • GET /api/approvals/pending - Get pending approval requests
  • GET /api/approvals/my-requests - Get user's submitted requests
  • GET /api/approvals/history - Get processed requests
  • POST /api/approvals/approve/{id} - Approve request
  • POST /api/approvals/reject/{id} - Reject request

Swap Requests

  • GET /api/swap-requests - Get all swap requests
  • POST /api/swap-requests - Create swap request
  • PUT /api/swap-requests/{id}/approve - Approve swap
  • PUT /api/swap-requests/{id}/reject - Reject swap

🛠️ Development Workflow

Starting the Application

Backend

cd C:\ROTA\src\StaffRota.Web
dotnet restore    # First time only
dotnet run
  • Backend runs on https://localhost:5001
  • Swagger UI available at https://localhost:5001/swagger

Frontend

cd C:\ROTA\frontend\staff-rota-ui
npm install      # First time only
npm start
  • Frontend runs on http://localhost:3000
  • Auto-opens in browser

Common Development Commands

Backend

# Run migrations
dotnet ef database update

# Create new migration
dotnet ef migrations add MigrationName

# Build solution
dotnet build

# Run tests
cd src\StaffRota.Tests
dotnet test

Frontend

# Install dependencies
npm install

# Start dev server
npm start

# Build for production
npm run build

# Run linter
npm run lint

Database Operations

View data

cd C:\ROTA\src\StaffRota.Web
sqlite3 StaffRotaDb.sqlite
# Inside sqlite3:
.tables                  # List all tables
.schema Users           # Show table schema
SELECT * FROM Users;    # Query data
.exit                   # Exit sqlite3

Reset and populate test data

cd C:\ROTA\src\StaffRota.Web
Get-Content ..\..\reset_and_populate_db.sql | sqlite3 StaffRotaDb.sqlite

🎨 UI/UX Patterns

Page Header Standard

All pages should follow this pattern:

<Box sx={{ p: 3 }}>
  <Box sx={{ mb: 4 }}>
    <Typography 
      variant="h4" 
      sx={{ 
        fontWeight: 700,
        color: 'primary.main'  // Uses theme titleColor
      }}
    >
      Page Title
    </Typography>
    <Typography variant="body1" color="text.secondary">
      Page subtitle or description
    </Typography>
  </Box>
  
  {/* Page content */}
</Box>

Action Buttons

Right-aligned buttons with consistent spacing:

<Box sx={{ display: 'flex', justifyContent: 'flex-end', gap: 2, mb: 3 }}>
  <Button variant="outlined">Cancel</Button>
  <Button variant="contained">Save</Button>
</Box>

Alternating Row Gradients

For list views with subtle color distinction:

const theme = useTheme();

const hexToRgba = (hex: string, alpha: number) => {
  const r = parseInt(hex.slice(1, 3), 16);
  const g = parseInt(hex.slice(3, 5), 16);
  const b = parseInt(hex.slice(5, 7), 16);
  return `rgba(${r}, ${g}, ${b}, ${alpha})`;
};

// In map:
<Box sx={{
  background: index % 2 === 0 
    ? `linear-gradient(135deg, 
        ${hexToRgba(theme.palette.primary.main, 0.15)} 0%, 
        ${hexToRgba(theme.palette.secondary.main, 0.15)} 100%)`
    : 'transparent'
}}>
  {/* Row content */}
</Box>

Material-UI Version

  • Version: MUI v7
  • Note: Grid2 API not compatible - use Box/Stack with flexbox instead
  • Example:
// Don't use Grid2:
// <Grid2 container spacing={2}>

// Use Box with flexbox:
<Box sx={{ display: 'flex', gap: 2 }}>
  <Box sx={{ flex: 1 }}>Column 1</Box>
  <Box sx={{ flex: 1 }}>Column 2</Box>
</Box>

🔍 Troubleshooting

Common Issues

"Unknown" Roles

  • Cause: Role enum values incorrect (using 0 instead of 1)
  • Fix: Run UPDATE Users SET Role = 1 WHERE Role = 0; in SQLite

Theme Colors Not Showing

  • Cause: Need to restart frontend after theme changes
  • Fix: Stop npm (Ctrl+C) and run npm start again

CORS Errors

  • Location: src/StaffRota.Web/Program.cs
  • Check: CORS policy allows http://localhost:3000

JWT Token Expired

  • Fix: Log out and log in again
  • Location: Token stored in localStorage.shiftiq_token

Database Locked

  • Cause: Multiple connections to SQLite
  • Fix: Close all sqlite3 sessions and restart backend

Important File Locations

Configuration Files

  • Backend config: src/StaffRota.Web/appsettings.json
  • Frontend config: frontend/staff-rota-ui/package.json
  • Theme defaults: frontend/staff-rota-ui/src/theme/types.ts

Database Files

  • Main DB: src/StaffRota.Web/StaffRotaDb.sqlite
  • Write-ahead log: src/StaffRota.Web/StaffRotaDb.sqlite-wal
  • Shared memory: src/StaffRota.Web/StaffRotaDb.sqlite-shm

📦 Dependencies

Backend (NuGet)

  • Microsoft.AspNetCore.Authentication.JwtBearer - JWT authentication
  • Microsoft.EntityFrameworkCore.Sqlite - SQLite provider
  • Microsoft.EntityFrameworkCore.Tools - EF migrations
  • Swashbuckle.AspNetCore - Swagger/OpenAPI

Frontend (npm)

  • react ^18.0.0 - UI library
  • @mui/material ^7.x - Material-UI components
  • @mui/icons-material - Material icons
  • date-fns - Date manipulation
  • react-router-dom - Routing
  • typescript - Type safety

🚀 Recent Major Changes

v1.5.0 (Latest - November 2, 2025)

  • Complete database schema documentation
    • Added AuditLogs table (audit trail system)
    • Added EmailQueue table (email queuing with retry logic)
    • Added SystemSettings table (dynamic configuration)
    • Documented all database constraints (CHECK, CASCADE, UNIQUE)
    • Comprehensive performance index documentation
  • Complete enumeration reference
    • All enum values mapped with descriptions
    • ShiftStatus, AssignmentStatus, ApprovalStatus/Type
    • SwapRequestStatus, EmailStatus, Priority levels
    • RecurrenceType documentation
  • Enhanced technical details
    • SQLite data type specifications
    • Foreign key cascade behavior documentation
    • Composite and single-column index strategies

v1.4.0

  • Corporate color scheme implementation
  • Theme-based dynamic gradients
  • Comprehensive test data script
  • Fixed user role enum values

v1.3.0

  • Team Management interface for TeamLeads/Admins
  • Configurable title color system
  • UI consistency across all pages

v1.2.0

  • Complete approval workflow system
  • Self-approval prevention
  • Email notification system

v1.1.0

  • All Shifts 2-column layout
  • Monthly calendar views
  • Space optimization

📝 Code Conventions

TypeScript/React

  • Use functional components with hooks
  • Props interfaces named {Component}Props
  • Use const for component definitions
  • Theme access via useTheme() hook

C#

  • Async/await for all async operations
  • Repository pattern for data access
  • Service layer for business logic
  • DTOs for API responses

File Naming

  • React components: PascalCase (e.g., MyComponent.tsx)
  • Services: camelCase (e.g., authService.ts)
  • C# files: PascalCase matching class name

🎯 Next Steps / Future Enhancements

Planned Features

  • Recent Shifts section population in LiveDashboard
  • Actual data for YTD, Unassigned, Pending Approval stats
  • TBC placeholder card functionality
  • Weekly view optimization (2-week display)
  • Enhanced mobile responsiveness
  • Real-time push notifications
  • Advanced reporting and analytics

Known Limitations

  • SQLite not suitable for high-concurrency production
  • Email service requires SMTP configuration
  • No real-time updates (polling only)
  • Limited offline support

📞 Support & Resources

Documentation Files

  • README.md - Project overview and quick start
  • TECHNICAL_REFERENCE.md - This file
  • Project.md - Detailed project specifications
  • TEST_PLAN.md - Testing documentation
  • APPROVAL_WORKFLOW_TEST_PLAN.md - Approval system tests

GitHub Repository

Key Contact Points

  • Database: SQLite at src/StaffRota.Web/StaffRotaDb.sqlite
  • Admin Account: test@admin.com / Test123!
    • Password Hash: $2a$12$YLtHMLFGSH9sFQqPBsd/AO992UD8KXmLcoNaqK/Mex.NNzxdDYskG
  • API Base URL: https://localhost:5001
  • Frontend URL: http://localhost:3000

Document Version: 1.0
Last Updated: November 2, 2025
Maintainer: Development Team