Skip to content

Conversation

@AlexVOiceover
Copy link
Contributor

Summary

This PR implements the cohort attendance metrics view (AP-26) along with several related improvements to the attendance tracking system.

Key Features

  • Cohort Attendance Page: View attendance metrics for one or multiple cohorts with filtering by term or custom date range
  • Attendance Trend Charts: Line charts showing attendance and lateness percentages over time (using Chart.js)
  • Improved Detail Page: Redesigned apprentice detail view with attendance stats card and inline status editing
  • Unified Login Flow: Consolidated staff/student login into a single endpoint

Changes

  • New Components:

    • AttendanceChart.svelte - Reusable chart component for attendance/lateness trends
    • AttendanceFilters.svelte - Reusable filters for term/date selection
    • ApprenticeAttendanceCard.svelte - Stats card showing attendance breakdown
  • Route Restructuring:

    • Flattened attendance routes (/admin/attendance and /admin/attendance/[id])
    • Removed redundant /admin/login route
    • Consolidated auth API endpoints
  • Attendance Improvements:

    • Multi-cohort and multi-term filtering
    • Custom date range filtering (mutually exclusive with term filter)
    • Renamed "Not Coming" status to "Absent"
    • Added "Excused" status support
    • Inline status editing with check-in time
  • Styling Consistency:

    • Aligned events page styling with attendance pages
    • Consistent card styling across admin pages (rounded-xl, shadow-sm)

Test Plan

  • Select a single cohort and verify apprentice list loads
  • Select multiple cohorts and verify combined data
  • Apply term filter and verify date filtering works
  • Apply custom date range and verify it overrides term filter
  • Navigate to apprentice detail and verify stats card
  • Edit attendance status inline and verify it saves
  • Verify attendance trend chart displays correctly
  • Test login flow for both staff and students

AlexVOiceover and others added 30 commits January 6, 2026 12:10
- Add /evaluate-report slash command with smart change detection
- Create report-evaluator skill with evaluation framework
- Enhance plan-iterator to mandate report evaluation after each task
- Self-contained command includes all evaluation guidelines
- Auto-detects indicators (TypeScript files, tests, keywords)
- Maps technical decisions to assessment criteria

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…ions

Testing System:
- Add /evaluate-tests slash command with smart change detection
- Create test-evaluator skill with framework for unit/API/integration tests
- Integrate Postman MCP for API test automation
- Add mandatory test evaluation to plan-iterator workflow

Plan-Iterator Optimizations:
- Fix counting bugs: now correctly counts both main tasks and subtasks
- Implement load-once pattern: single file read instead of 6+ reads
- Add combined regex patterns with -E flag for efficiency
- Remove unnecessary processes (head -1, redundant greps)
- Reduce file I/O from O(N²) to O(1) for most operations

Performance gains: ~75% fewer process spawns, single memory load

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Complete AWK rewrite of plan-iterator for O(1) performance
- Add comprehensive report and test evaluation systems
- Fix counting logic to track only actionable leaf tasks
- Improve cross-platform compatibility with portable sed
- Add git commit message sanitization and length limits
- Enhance evaluation commands with robust error handling

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add Terms table integration with proper start/end date fields
- Replace single-term dropdown with multi-checkbox selection interface
- Show actual date periods (DD/MM/YYYY) in term filter labels
- Remove incorrect 6-month duration assumption, use real Airtable end dates
- Support filtering attendance data by multiple overlapping term periods
- Add backend date range filtering for apprentice attendance statistics
- Simplify UI by removing redundant cohorts page, enhance apprentices page instead

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…tion

- Replace checkbox list with dropdown multi-select similar to event creation
- Add staged selection to prevent immediate fetches on each term change
- Display selected term names in button text instead of count
- Add Apply button that only triggers fetch when user confirms changes
- Add Select All button for bulk term selection
- Improve performance by avoiding expensive API calls during term browsing
- Add click outside detection and proper accessibility attributes

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add radio button toggle between Terms and Custom Date Range filters
- Implement custom date range picker with start and end date inputs
- Add staged date selection with Apply button for performance consistency
- Ensure mutual exclusion - only one filter type can be active at once
- Update server to accept startDate/endDate URL parameters
- Prioritize custom date range over term-based filtering when both present
- Add proper state management for filter mode switching
- Clear opposing filter when switching filter types
- Maintain consistent UX with staged selection and Apply patterns

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…bugging

- Fix calculateStats to count missing events as 'Absent' for consistency with history display
- Remove hardcoded 'Missed' status throughout system, use only official ATTENDANCE_STATUSES
- Add manual status change functionality to individual apprentice pages
- Update AttendanceHistoryEntry interface to include attendanceId for editing
- Add comprehensive logging for debugging status change errors
- Create attendance system migration plan for future explicit model consideration

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add shared AttendanceFilters type with termIds and dateRange options
- Add parseFiltersFromParams() and filtersToParams() utilities
- Document attendance system in attendance.md
- Create refactor plan in docs/plan.md
- Add getEventsForCohort() helper for filtering events by cohort and date range
- Add filterAttendanceToEvents() helper to ensure attendance matches events
- Add Math.max(0, ...) guard in calculateStats() to prevent negative absent counts
- Add calculateAttendanceRate() helper function
- Add getApprenticeStats() that always filters to cohort events
- Export new function from sveltekit-wrapper
- Mark old functions as deprecated (getApprenticeAttendanceStats,
  getApprenticeAttendanceStatsWithDateFilter)

This fixes the negative absent count bug by ensuring attendance
records are always filtered to the apprentice's cohort events.
- Remove block that added events from other cohorts to history
- Add optional date range filtering parameter
- Use helper functions (getEventsForCohort, filterAttendanceToEvents)
- Add name field to EventForStats interface
- Now consistent with getApprenticeStats (same cohort filtering)
- Extracts filter UI from apprentices list page
- Supports term multi-select with staged selection
- Supports custom date range filter
- Mutually exclusive: terms OR date range
- Emits changes via onFiltersChange callback
- Ready for use on both list and detail pages
- Use getApprenticeStats instead of deprecated functions
- Use AttendanceFilters component instead of inline filter UI
- Simplify state management (remove redundant filter state)
- Add handleFiltersChange to bridge component to URL navigation
- Fix lint errors (brace-style, trailing commas)
- Parse filters from URL params in server loader
- Use getApprenticeStats and getApprenticeAttendanceHistory with date options
- Load terms for the filter component
- Add AttendanceFilters component to the page
- Preserve filters when navigating from list to detail
- Remove getApprenticeAttendanceStats function (~100 lines)
- Remove getApprenticeAttendanceStatsWithDateFilter function (~100 lines)
- Remove deprecated exports from sveltekit-wrapper
- Update tests to use getApprenticeStats
- Update tests: "Missed" → "Absent" status
- Fix test for events without attendance (uses cohort now)
- Add 'All' radio button to show unfiltered data
- Increase term dropdown height from max-h-48 to max-h-72
… Late

- Move Attended box to second row, spanning under Present and Late
- Add "(Present + Late)" label for clarity
- Use blue styling with top border to visually connect the relationship
…atus

When changing an attendance status to Present or Late, the check-in time
field now auto-populates with the event's scheduled start time. This saves
time for admins and ensures a reasonable default is always set.
The status badge is already clickable to edit, so the separate Actions
column with Edit button was redundant. Save/cancel buttons now appear
inline with the check-in time field when editing.
- Added Excused box between Late and Absent (now 5 columns)
- Changed Attended color from blue to indigo to avoid conflict with Excused
- Excused uses blue to match the status badge color
Rename the 'Not Coming' attendance status to 'Absent' across the entire
codebase for clearer terminology:

- Update types, constants, and field comments
- Rename API endpoint from /api/checkin/not-coming to /api/checkin/absent
- Update UI labels, CSS classes, and error messages
- Update all documentation files
- Update tests

This change aligns with the Airtable schema update where the status
field option was renamed from 'Not Coming' to 'Absent'.
Add 'Missed' aggregate (Not Check-in + Absent) to mirror the 'Attended'
group (Present + Late) for clearer attendance visualization.
Staff members who are also apprentices can now check in using their
apprentice profile via the Apprentice Link field in the Staff table.
This enables staff to see their cohort events and mark themselves absent.

Also consolidates attendance status styles into a single source of truth
in src/lib/types/attendance.ts for consistency across components.
- Merge staff and student login into single /login page
- Create unified /api/auth/login endpoint (checks Staff first, then Apprentices)
- Redirect students to /checkin instead of / after login
- Make / redirect to login or landing page based on auth state
- Delete /admin/login route and separate staff/student API endpoints
- Add symmetrical navigation: Admin ↔ Check In links between pages
- Update hooks, tests, and README to reflect new auth flow
- Flatten routes: /admin/attendance/apprentices → /admin/attendance
- Rename page title to "Attendance", remove descriptive texts
- Move Load Selected and Select All buttons to top of section
- Replace "Show All Apprentices" modal with toggle Select All/None button
- Add dynamic title: "Attendance" for selection, "Cohort Attendance" when viewing data
- Remove subcohort counter from group headers
- Apply consistent card styling with rounded-xl borders and shadows
- Wrap data table in styled card container
- Add transition effects to buttons, table headers, and rows
- Remove Trend column from cohort attendance table
- Preserve cohort selection in back link from detail page
- Add loading overlay when navigating back to cohort list
- Update page title to "Name - Attendance" format
- Simplify ApprenticeAttendanceCard by removing unused elements
- Add "Attendance Stats" header with percentage on same row
- Redesign stats layout with clear Attended/Missed groupings
- Wrap history table in styled card matching other pages
- Add cursor-pointer to clickable status badges
- Remove dash placeholder when editing non-Present/Late statuses
- Create AttendanceChart component using Chart.js (svelte-chartjs incompatible with Svelte 5)
- Add calculateMonthlyAttendance function to aggregate history by month
- Integrate chart on both Cohort Attendance and Detail pages
- Fix effect_update_depth_exceeded by using regular variable for chart instance
- Add yellow lateness line showing Late/Total percentage
- Lateness line only appears when there's late data
- Show legend when both lines are present
- Update tooltip to display dataset labels
- Use rounded-xl shadow-sm for table and calendar cards
- Change table header to bg-gray-50
- Add transition-colors to row hover states
@AlexVOiceover AlexVOiceover merged commit 2826fbe into main Jan 7, 2026
2 checks passed
@AlexVOiceover AlexVOiceover deleted the feature/ap-26-cohort-attendance-metrics-view branch January 7, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants