Version: 1.0.0 | Status: Active | Last Updated: 2025-12-31 Purpose: Granular task breakdown (20-30 minute tasks) with user stories for systematic completion
- Overview
- Phase 1: Admin UI/UX Complete
- Phase 2: ETL Loader
- Phase 3: Teacher UI/UX Enhancements
- Phase 4: Student UI/UX
- Progress Tracking
Completed:
- ✅ Database schema (19 tables across 5 modules)
- ✅ Authentication & RLS policies (47 tests passing)
- ✅ Teacher: Attendance Register (with hash-chain verification)
- ✅ Teacher: AI Lesson Planner
- ✅ Teacher: Timetable View
- ✅ Admin: Dashboard (KPIs, alerts, work queue)
- ✅ Admin: User Management
In Progress:
- 🟡 Admin: Student Registry (components created, needs wiring)
To Complete:
- ❌ Admin: 19 remaining pages
- ❌ ETL Loader: Excel import with validation
- ❌ Teacher: Enhancements & quality improvements
- ❌ Student: All 4 pages
- Stability First - Use proven, stable solutions
- Non-Technical UX - Abstract complexity, simple workflows
- Functionality Over Features - Core operations must be rock-solid
- Minimal Maintenance - Self-contained, well-tested code
Goal: Complete all 19 remaining admin pages with full functionality Estimated Duration: 8-12 weeks (based on 20-30 min tasks) Priority: Highest - Foundation for all other work
Estimate: 25 minutes User Story:
GIVEN I am an admin user viewing /admin/students
WHEN the page loads
THEN I see a complete list of students with filters
AND the StudentRegistry component is properly wired
AND data loads from the database via RLS-protected APIFiles:
/admin/students/page.tsx- Wire StudentRegistry component/components/admin/students/StudentRegistry.tsx- Verify props
Acceptance:
- Student list displays with real data
- Filters work (name, level, status, programme)
- Pagination works (25 per page)
- Loading states shown
Estimate: 30 minutes User Story:
GIVEN I click on a student in the list
WHEN the detail drawer opens
THEN I see complete student information across all tabs
AND data is fetched from v_students_with_metadata view
AND RLS policies enforce admin access onlyFiles:
/components/admin/students/StudentDetailDrawer.tsx- Create
/api/admin/students/[id]/route.ts
Acceptance:
- Drawer opens with student data
- All 6 tabs load correctly
- API endpoint respects RLS
Estimate: 20 minutes User Story:
GIVEN I view a student's Personal Info tab
WHEN the tab loads
THEN I see name, DOB, contact details, emergency contact
AND fields are read-only (edit in separate task)
AND sensitive data is properly maskedFiles:
/components/admin/students/tabs/PersonalInfoTab.tsx
Acceptance:
- Display full name, email, phone
- Show DOB (formatted)
- Show emergency contact details
- Sensitive fields respect RLS
Estimate: 25 minutes User Story:
GIVEN I view Course History tab
WHEN the tab loads
THEN I see all enrollments (past and present)
AND each enrollment shows class, dates, status, level
AND I can see amendments (extensions, reductions)Files:
/components/admin/students/tabs/CourseHistoryTab.tsx- Query
enrollmentsandenrollmentAmendmentstables
Acceptance:
- List all enrollments
- Show enrollment status (active, completed, withdrawn)
- Display amendment history
Estimate: 25 minutes User Story:
GIVEN I view Attendance Summary tab
WHEN the tab loads
THEN I see attendance percentage and session breakdown
AND I can filter by date range or class
AND visa students show compliance statusFiles:
/components/admin/students/tabs/AttendanceSummaryTab.tsx- Query
attendancetable
Acceptance:
- Show attendance % (present/total)
- List recent sessions with status
- Highlight visa compliance issues
Estimate: 20 minutes User Story:
GIVEN I view Assessments tab
WHEN the tab loads
THEN I see all grades and submissions
AND I can filter by assignment or date
AND CEFR progress is visualizedFiles:
/components/admin/students/tabs/AssessmentsTab.tsx- Query
gradesandsubmissionstables
Acceptance:
- List all grades
- Show assignment titles and scores
- Display submission status
Estimate: 20 minutes User Story:
GIVEN I view Notes tab
WHEN the tab loads
THEN I see all administrative notes
AND I can add a new note
AND notes are timestamped with authorFiles:
/components/admin/students/tabs/NotesTab.tsx- Create notes table or use audit log
Acceptance:
- Display existing notes
- Form to add new note
- Notes saved to database
Estimate: 25 minutes User Story:
GIVEN I view Documents tab
WHEN the tab loads
THEN I see all uploaded documents (visa, ID, certificates)
AND I can download documents via signed URLs
AND URLs expire after 24 hoursFiles:
/components/admin/students/tabs/DocumentsTab.tsx- Integrate with Supabase Storage
Acceptance:
- List all documents
- Generate signed URLs for download
- Document types categorized
Estimate: 30 minutes User Story:
GIVEN I click "Create Student" button
WHEN I fill in the form and submit
THEN a new student record is created
AND a user account is created if needed
AND I'm redirected to the student detail pageFiles:
/components/admin/students/CreateStudentForm.tsx/app/admin/students/create/page.tsx/api/admin/students/route.ts(POST)
Acceptance:
- Form validation works (Zod schema)
- Student created in database
- User account created if email provided
- Success notification shown
Estimate: 25 minutes User Story:
GIVEN I click "Edit" on a student record
WHEN I modify fields and save
THEN the student record is updated
AND changes are logged in audit trail
AND I see a success notificationFiles:
- Add edit mode to
StudentDetailDrawer.tsx /api/admin/students/[id]/route.ts(PATCH)
Acceptance:
- Edit button toggles edit mode
- Save updates database
- Audit log entry created
- Validation prevents invalid data
Estimate: 25 minutes User Story:
GIVEN I am viewing /admin/classes
WHEN the page loads
THEN I see all classes with filters (teacher, level, status, dates)
AND I can sort by start date or name
AND pagination worksFiles:
/app/admin/classes/page.tsx/components/admin/ClassList.tsx
Acceptance:
- Filter by teacher (dropdown)
- Filter by CEFR level (A1-C2)
- Filter by status (scheduled, active, completed)
- Sorting works
Estimate: 30 minutes User Story:
GIVEN I click "Create Class"
WHEN I fill in name, level, teacher, dates, capacity
THEN a new class is created
AND sessions are automatically generated (optional)
AND I'm redirected to class detail pageFiles:
/components/admin/CreateClassForm.tsx/app/admin/classes/create/page.tsx
Acceptance:
- Form fields: name, CEFR level, teacher (dropdown), start/end dates, capacity
- Validation: end > start, capacity > 0
- Class saved to database
- Teacher assignment recorded
Estimate: 25 minutes User Story:
GIVEN I click on a class name
WHEN the detail page loads
THEN I see class info, enrolled students, sessions, materials
AND I can navigate to related pages (attendance, edit)Files:
/app/admin/classes/[id]/page.tsx
Acceptance:
- Display class metadata
- List enrolled students (with links)
- Show session schedule
- Link to attendance register
Estimate: 25 minutes User Story:
GIVEN I click "Edit" on a class
WHEN I modify fields and save
THEN the class is updated
AND changes are audited
AND students/sessions are not affected (unless specified)Files:
/components/admin/EditClassForm.tsx/app/admin/classes/[id]/edit/page.tsx
Acceptance:
- Form pre-populated with current data
- Update class metadata
- Audit log entry created
- Validation prevents orphaning students
Estimate: 30 minutes User Story:
GIVEN I create a class with start/end dates
WHEN I select "Generate Sessions" option
THEN sessions are auto-created based on schedule pattern
AND I can specify days of week and times
AND sessions appear in classSessions tableFiles:
- Add to
CreateClassForm.tsx - Create session generation utility
Acceptance:
- User specifies pattern (e.g., Mon/Wed/Fri 10am-12pm)
- Sessions generated for date range
- Sessions saved to database
Estimate: 25 minutes User Story:
GIVEN I visit /admin/enrolments
WHEN the page loads
THEN I see all enrollments with student name, class, dates, status
AND I can filter by student, class, status
AND I can sort by start dateFiles:
/app/admin/enrolments/page.tsx- Create
EnrollmentList.tsxcomponent
Acceptance:
- API endpoint created (
/api/admin/enrollments) - List view with columns: student, class, start/end dates, status
- Filters work
- Pagination implemented
Estimate: 30 minutes User Story:
GIVEN I click "Enroll Student"
WHEN I select student, class, and dates
THEN an enrollment record is created
AND student has access to class materials
AND capacity check is enforcedFiles:
- Create
EnrollStudentForm.tsx /api/admin/enrollments/route.ts
Acceptance:
- API endpoint with capacity validation
- Student dropdown (searchable)
- Class dropdown
- Start/end date pickers
- Validation: class not at capacity
- Enrollment created
Estimate: 25 minutes User Story:
GIVEN I view an enrollment
WHEN I click "Extend"
THEN I can specify new end date
AND an amendment record is created
AND enrollment end_date is updatedFiles:
- Create
AmendEnrollmentForm.tsx - Use
enrollmentAmendmentstable
Acceptance:
- Amendment API endpoint created
- Extension form with new end date
- Amendment type: EXTENSION
- Update enrollment record
- Audit log entry
Estimate: 20 minutes User Story:
GIVEN I view an enrollment
WHEN I click "Reduce"
THEN I can specify new (earlier) end date
AND an amendment record is created
AND enrollment is updatedFiles:
- Extend
AmendEnrollmentForm.tsx
Acceptance:
- Reduction form
- Amendment type: REDUCTION
- Validation: new end >= start
- Update enrollment
Estimate: 20 minutes User Story:
GIVEN a student's level has changed
WHEN I click "Change Level"
THEN I can record the level change
AND an amendment is created
AND future class suggestions reflect new levelFiles:
- Extend
AmendEnrollmentForm.tsx
Acceptance:
- Level change form (A1-C2)
- Amendment type: LEVEL_CHANGE
- Store old and new levels
- Update metadata
Estimate: 30 minutes User Story:
GIVEN a student needs to move to another class
WHEN I click "Transfer"
THEN I can select target class
AND original enrollment is marked transferred
AND new enrollment is created
AND attendance history is preservedFiles:
- Create
TransferStudentForm.tsx
Acceptance:
- Transfer form with target class
- Close original enrollment
- Create new enrollment
- Amendment type: TRANSFER
- Link records via transfer_id
Estimate: 25 minutes User Story:
GIVEN I visit /admin/attendance
WHEN the page loads
THEN I see attendance statistics across all classes
AND I can filter by date range, class, student
AND I see compliance alerts (visa students)Files:
/app/admin/attendance/page.tsx- Create
AttendanceOverview.tsxcomponent
Acceptance:
- Summary cards: total sessions, avg attendance %, alerts
- Recent sessions list
- Filter controls
- Link to session detail
Estimate: 20 minutes User Story:
GIVEN I click on a session
WHEN the attendance sheet loads
THEN I see the same register view as teachers
AND I can view historical attendance
AND hash-chain validation status is shownFiles:
/app/admin/attendance/[sessionId]/page.tsx- Reuse
AttendanceSheet.tsxcomponent
Acceptance:
- Display attendance register
- Show hash-chain status (valid/invalid)
- Read-only for completed sessions
- Edit requires admin override
Estimate: 30 minutes User Story:
GIVEN a teacher made an attendance error
WHEN I click "Request Correction"
THEN I can select session, student, correct status
AND correction is submitted for admin approval
AND audit trail shows original + correctionFiles:
- Create
AttendanceCorrectionForm.tsx - Implement approval workflow
Acceptance:
- Correction request form
- Store correction in pending state
- Admin can approve/reject
- Hash-chain appends new entry
Estimate: 25 minutes User Story:
GIVEN I need weekly attendance reports
WHEN I select date range and class
THEN I can export CSV or Excel
AND export includes hash column for verification
AND export completes in < 60sFiles:
- Enhance
/api/attendance/export - Add admin-specific export options
Acceptance:
- Date range picker
- Class filter (multi-select)
- Export format selector (CSV/XLSX)
- Hash column included
- Signed URL provided
Estimate: 25 minutes User Story:
GIVEN I visit /admin/finance/invoices
WHEN the page loads
THEN I see all invoices with student, amount, status, due date
AND I can filter by status (paid, pending, overdue)
AND I can sort by date or amountFiles:
/app/admin/finance/invoices/page.tsx- Create
InvoiceList.tsx
Acceptance:
- API endpoint created (
/api/admin/finance/invoices) - List invoices from database
- Status badges (paid, pending, overdue)
- Filters work
- Pagination
Estimate: 30 minutes User Story:
GIVEN I click "Create Invoice"
WHEN I fill in student, amount, due date, line items
THEN an invoice is generated
AND PDF is created and stored
AND student is notified (optional)Files:
/components/admin/CreateInvoiceForm.tsx/app/admin/finance/invoices/create/page.tsx
Acceptance:
- API endpoint with validation
- Form fields: student, amount, due date, description
- Line items support (add/remove rows)
- Invoice number auto-generated
- PDF generation (use library like pdf-lib or jsPDF)
Estimate: 20 minutes User Story:
GIVEN I click on an invoice
WHEN the detail page loads
THEN I see full invoice details and payment history
AND I can download PDF
AND I can record a paymentFiles:
/app/admin/finance/invoices/[id]/page.tsx
Acceptance:
- Display invoice metadata
- Show line items
- Payment history table
- Download PDF button
- Record payment button
Estimate: 25 minutes User Story:
GIVEN an invoice is pending
WHEN I click "Record Payment"
THEN I can enter amount, date, method, reference
AND payment is recorded
AND invoice status updates if fully paidFiles:
- Create
RecordPaymentForm.tsx /api/admin/finance/payments/route.ts
Acceptance:
- API endpoint created
- Payment form: amount, date, method, reference
- Validation: amount <= outstanding balance
- Payment saved to
paymentstable - Invoice status auto-updates
Estimate: 20 minutes User Story:
GIVEN I visit /admin/finance/payments
WHEN the page loads
THEN I see all payments with student, invoice, amount, date
AND I can filter by date range or student
AND I can export payment reportFiles:
/app/admin/finance/payments/page.tsx- Create
PaymentList.tsx
Acceptance:
- API endpoint created
- List payments
- Link to related invoice
- Filter by date range
- Export button (CSV)
Estimate: 25 minutes User Story:
GIVEN a payment was made in error
WHEN I click "Refund"
THEN I can specify refund amount and reason
AND a negative payment entry is created
AND invoice balance is adjustedFiles:
- Create
RefundPaymentForm.tsx
Acceptance:
- Refund form
- Validation: refund <= total payments
- Negative payment entry
- Audit log entry
Estimate: 25 minutes User Story:
GIVEN I visit /admin/compliance/visa
WHEN the page loads
THEN I see all students on visa with attendance compliance status
AND I see alerts for students below threshold (80%)
AND I can export compliance reportFiles:
/app/admin/compliance/visa/page.tsx- Create
VisaComplianceDashboard.tsx
Acceptance:
- List visa students
- Show attendance % for each
- Highlight non-compliant students
- Export report button
Estimate: 20 minutes User Story:
GIVEN a student has a visa
WHEN I view their profile
THEN I can see visa type, expiry date, conditions
AND I can update visa details
AND alerts trigger before expiryFiles:
- Add visa fields to student model
- Update
PersonalInfoTab.tsx
Acceptance:
- Visa type field
- Expiry date field
- Conditions/notes field
- Alert when expiry < 30 days
Estimate: 20 minutes User Story:
GIVEN I visit /admin/compliance/regulatory
WHEN the page loads
THEN I see compliance checklist (GDPR, ISO27001)
AND I can view recent audits
AND I can generate compliance packFiles:
/app/admin/compliance/regulatory/page.tsx
Acceptance:
- Checklist display
- Audit log integration
- Generate compliance pack button
Estimate: 20 minutes User Story:
GIVEN I visit /admin/programmes
WHEN the page loads
THEN I see all programmes (General English, Business English, etc.)
AND I can view programme details
AND I can create/edit programmesFiles:
/app/admin/programmes/page.tsx- Create
ProgrammeList.tsx
Acceptance:
- API endpoint created (
/api/admin/programmes) - Includes course count per programme
- List programmes from database
- Display name, description, duration
- Create button
- Edit links
Estimate: 25 minutes User Story:
GIVEN I click "Create Programme"
WHEN I fill in name, description, duration, levels
THEN a new programme is created
AND it appears in programme listFiles:
- Create
CreateProgrammeForm.tsx /api/admin/programmes/route.ts
Acceptance:
- API endpoint with validation
- Auto-generates programme code
- Form fields: name, description, duration, CEFR levels
- Validation
- Save to database
Estimate: 20 minutes User Story:
GIVEN I visit /admin/courses
WHEN the page loads
THEN I see all courses mapped to programmes
AND I can filter by programme or level
AND I can create/edit coursesFiles:
/app/admin/courses/page.tsx- Create
CourseList.tsx
Acceptance:
- API endpoint created (
/api/admin/courses) - Includes programme relationship
- List courses
- Show programme relationship
- CEFR level displayed
- Create/edit buttons
Estimate: 25 minutes User Story:
GIVEN I click "Create Course"
WHEN I fill in name, programme, level, objectives
THEN a new course is created
AND CEFR descriptors can be linkedFiles:
- Create
CreateCourseForm.tsx /api/admin/courses/route.ts
Acceptance:
- API endpoint with validation
- Auto-generates course code
- Form fields: name, programme (dropdown), CEFR level, objectives
- Descriptor linking (multi-select)
- Save to database
Estimate: 20 minutes User Story:
GIVEN I visit /admin/rooms
WHEN the page loads
THEN I see all rooms with name, capacity, facilities
AND I can create/edit roomsFiles:
/app/admin/rooms/page.tsx- Create
RoomList.tsx
Acceptance:
- List rooms from database (or create table if needed)
- Display name, capacity, equipment
- Create/edit functionality
Estimate: 20 minutes User Story:
GIVEN I click "Create Room"
WHEN I fill in name, capacity, facilities
THEN a new room is createdFiles:
- Create
CreateRoomForm.tsx
Acceptance:
- Form fields: name, capacity, equipment/facilities
- Save to database
Estimate: 25 minutes User Story:
GIVEN I view room allocations
WHEN I select a date
THEN I see which sessions are in which rooms
AND I can reassign rooms if conflicts occurFiles:
- Create
RoomAllocationView.tsx
Acceptance:
- Calendar/timeline view
- Show sessions per room
- Drag-drop reassignment (nice-to-have)
- Conflict detection
Estimate: 20 minutes User Story:
GIVEN I visit /admin/communications/email-logs
WHEN the page loads
THEN I see all sent emails with recipient, subject, status, timestamp
AND I can filter by date or recipientFiles:
/app/admin/communications/email-logs/page.tsx- Create
EmailLogsList.tsx
Implementation Plan:
- Data: add (or confirm)
email_logstable withtenant_id,recipient,subject,sent_at,status,source,external_id,provider,provider_message_id,headers,body_preview,error_message. - Query: server-side fetch scoped by tenant, with search on recipient/subject and date range (
from,to) from query params. - UI:
EmailLogsListtable with search input, date range inputs, status badges (sent/failed/pending), and empty state. - Detail: add link to
/admin/communications/email-logs/[id]for full body/headers; stub if detail page not in scope yet. - Integration: ensure
source+external_idallow CRM (e.g., Pipedrive) sync without conflicts.
Acceptance:
- List emails from logs
- Display recipient, subject, sent time, status
- Filter by date range
- Status badge colors: sent=green, failed=red, pending=yellow
- Link to view full email content/headers
Estimate: 20 minutes User Story:
GIVEN I visit /admin/communications/notifications
WHEN the page loads
THEN I see all system notifications sent to users
AND I can create manual notificationsFiles:
/app/admin/communications/notifications/page.tsx- Create
NotificationsList.tsx
Implementation Plan:
- Data: add
notificationstable plusnotification_recipientsfor user/role/broadcast targeting with read/unread status per recipient. - Query: list recent notifications with filters for status, type, and recipient scope; scope by tenant.
- UI:
NotificationsListtable with filters and "Create Notification" button. - Form: manual creation form with title/body, severity, target audience selector (user/role/all), and optional scheduling.
- Integration: include
source+external_idfor third-party announcements.
Acceptance:
- List notifications
- Create notification button
- Send to user/role/all
- Filters for status/type/recipient scope
- Read/unread indicators
Estimate: 25 minutes User Story:
GIVEN I visit /admin/enquiries
WHEN the page loads
THEN I see all enquiries with name, email, status, date
AND I can filter by status (new, contacted, converted, rejected)Files:
/app/admin/enquiries/page.tsx- Create
EnquiriesList.tsx - Create enquiries table if needed
Implementation Plan:
- Data: create
enquiriestable withtenant_id,name,email,phone,status,source,external_id,programme_interest,created_at,updated_at. - Query: list enquiries by tenant with multi-status filter and search (name/email).
- UI:
EnquiriesListtable with status badges, multi-select status filter, and "Create Enquiry" button. - Form: manual enquiry entry form (phone/walk-in) with status default
new. - Integration: store
source+external_idto support CRM ingestion later.
Acceptance:
- List enquiries
- Status filtering
- Create enquiry form (for manual entry)
- Status badges: new/contacted/converted/rejected
- Link to enquiry detail view
Estimate: 20 minutes User Story:
GIVEN I click on an enquiry
WHEN the detail view opens
THEN I see full enquiry details and communication history
AND I can update status
AND I can convert to studentFiles:
- Create
EnquiryDetail.tsx
Acceptance:
- Display enquiry fields
- Status update dropdown
- "Convert to Student" button
- Notes/communications log
Estimate: 20 minutes User Story:
GIVEN I visit /admin/data
WHEN the page loads
THEN I see options for bulk upload and exports
AND I see recent import/export jobsFiles:
- Create
/app/admin/data/page.tsx
Acceptance:
- Links to bulk upload and exports pages
- Recent jobs list
- Status indicators
Estimate: 20 minutes User Story:
GIVEN I visit /admin/data/bulk-upload
WHEN the page loads
THEN I see upload form and instructions
AND I can select file type (students, classes, etc.)Files:
/app/admin/data/bulk-upload/page.tsx
Acceptance:
- File upload component
- Entity type selector
- Instructions panel
- (Full implementation in Phase 2)
Estimate: 20 minutes User Story:
GIVEN I visit /admin/data/exports
WHEN the page loads
THEN I see all available export types
AND I can view past exports
AND I can download previous exportsFiles:
/app/admin/data/exports/page.tsx- Create
ExportsList.tsx
Acceptance:
- List export types (attendance, students, financial, etc.)
- Past exports table
- Download links (signed URLs)
Estimate: 25 minutes User Story:
GIVEN I visit /admin/timetable
WHEN the page loads
THEN I see organization-wide timetable
AND I can filter by teacher, room, class
AND I can switch between week/month viewFiles:
/app/admin/timetable/page.tsx- Create
AdminTimetableView.tsx
Acceptance:
- Week/month calendar view
- Display all sessions
- Filter controls
- Click to view session detail
Estimate: 20 minutes User Story:
GIVEN I visit /admin/teachers
WHEN the page loads
THEN I see all teachers with name, email, assigned classes
AND I can filter/searchFiles:
/app/admin/teachers/page.tsx- Create
TeacherList.tsx
Acceptance:
- API endpoint created (
/api/admin/teachers) - Includes assigned classes count
- List teachers
- Show assigned classes count
- Search/filter functionality
Estimate: 25 minutes User Story:
GIVEN I click on a teacher
WHEN the detail view loads
THEN I see teacher profile, qualifications, assigned classes, schedule
AND I can edit teacher detailsFiles:
- Create
TeacherDetail.tsx
Acceptance:
- API endpoint created (
/api/admin/teachers/[id]) - Fetches assigned classes
- Display teacher info
- List assigned classes
- Show timetable
- Edit button
Estimate: 30 minutes User Story:
GIVEN I visit /admin/search
WHEN I enter a search query
THEN I see results across students, teachers, classes
AND results are categorized by type
AND I can click to navigate to detail pagesFiles:
/app/admin/search/page.tsx- Create
/api/admin/search/route.ts
Acceptance:
- API endpoint created (multi-entity search)
- Searches students, teachers, classes
- Returns categorized results
- Search input with debounce
- Multi-entity search (students, teachers, classes)
- Categorized results
- Click to navigate
Estimate: 20 minutes User Story:
GIVEN I visit /admin/settings
WHEN the page loads
THEN I see tabs for different settings categories
AND I can navigate between tabsFiles:
/app/admin/settings/page.tsx
Acceptance:
- Tab navigation (General, Auth, Email, Billing, etc.)
- Settings organized by category
Estimate: 25 minutes User Story:
GIVEN I view General Settings
WHEN I update organization name, locale, timezone
THEN settings are saved to tenant configurationFiles:
- Create
GeneralSettingsTab.tsx
Acceptance:
- Org name field
- Locale selector
- Timezone selector
- Save button
Estimate: 20 minutes User Story:
GIVEN I view Email Settings
WHEN I configure SMTP settings or email templates
THEN email configuration is savedFiles:
- Create
EmailSettingsTab.tsx
Acceptance:
- SMTP configuration fields
- Test email button
- Template editor (basic)
Estimate: 25 minutes User Story:
GIVEN I visit /admin/audit-log
WHEN the page loads
THEN I see all audit log entries with timestamp, actor, action, entity
AND I can filter by date, user, action typeFiles:
/app/admin/audit-log/page.tsx- Create
AuditLogViewer.tsx
Acceptance:
- API endpoint created (
/api/admin/audit-log) - Includes user relationship
- Supports all filters
- Pagination implemented
- List audit logs from auditLogs table
- Display timestamp, user, action, entity
- Filters (date range, user, action)
- Pagination
Estimate: 20 minutes User Story:
GIVEN I click on an audit log entry
WHEN the detail view opens
THEN I see full context including before/after values
AND I can see related entriesFiles:
- Create
AuditLogDetail.tsx
Acceptance:
- API endpoint created (
/api/admin/audit-log/[id]) - Fetches related logs for same entity
- Display diff JSON
- Show before/after comparison
- Related entries timeline
Estimate: 20 minutes User Story:
GIVEN I visit /admin/progress
WHEN the page loads
THEN I see progress metrics across all students
AND I can filter by class or levelFiles:
/app/admin/progress/page.tsx
Acceptance:
- Aggregate progress statistics
- Charts/visualizations
- Filter by class/level
Estimate: 20 minutes User Story:
GIVEN I visit /admin/bookings
WHEN the page loads
THEN I see all course bookings with student, course, dates, statusFiles:
/app/admin/bookings/page.tsx- Create
BookingsList.tsx
Acceptance:
- List bookings
- Status filtering
- Create booking form
Estimate: 15 minutes User Story:
GIVEN I visit /admin/help
WHEN the page loads
THEN I see FAQs and help documentationFiles:
/app/admin/help/page.tsx
Acceptance:
- FAQ section
- Links to documentation
- Contact support option
Goal: Build robust Excel import system with validation and user confirmation Estimated Duration: 4-6 weeks Priority: High - Critical for data migration and bulk operations
Estimate: 30 minutes User Story:
GIVEN I need to track import jobs
WHEN I design the data model
THEN I have tables for: import_jobs, import_rows, import_errors
AND I can track status (pending, processing, completed, failed)Files:
- Create migration for ETL tables
/db/schema/etl.ts
Acceptance:
- import_jobs table (id, filename, type, status, created_at, created_by)
- import_rows table (job_id, row_number, data_json, status, error)
- import_errors table (row_id, field, error_message)
Estimate: 20 minutes User Story:
GIVEN an import is in progress
WHEN I view the import status
THEN I see progress (rows processed / total)
AND I see validation resultsFiles:
/api/admin/imports/[jobId]/status/route.ts
Acceptance:
- API endpoint returns job status
- Progress percentage
- Error count
- Validation summary
Estimate: 25 minutes User Story:
GIVEN I visit the bulk upload page
WHEN I select an Excel file (.xlsx)
THEN the file is uploaded to temporary storage
AND file metadata is extractedFiles:
/components/admin/data/ExcelUploader.tsx
Acceptance:
- File input accepts .xlsx, .xls
- File size validation (< 10MB)
- Upload to Supabase Storage or temp folder
- Return upload ID
Estimate: 30 minutes User Story:
GIVEN an uploaded Excel file
WHEN I parse the file
THEN I extract rows as JSON objects
AND I detect column headers
AND I return structured dataFiles:
/lib/etl/excelParser.ts- Use library:
xlsxorexceljs
Acceptance:
- Parse Excel to JSON
- Handle multiple sheets
- Detect headers from first row
- Return array of row objects
Estimate: 25 minutes User Story:
GIVEN I import student data
WHEN each row is validated
THEN I check: required fields, email format, DOB format, unique constraints
AND validation errors are collectedFiles:
/lib/etl/validators/studentValidator.ts- Use Zod for validation
Acceptance:
- Zod schema for student import
- Required fields: firstName, lastName, email
- Email validation
- DOB validation (format, age range)
- Unique email check
Estimate: 20 minutes User Story:
GIVEN I import class data
WHEN each row is validated
THEN I check: required fields, date ranges, teacher exists, capacityFiles:
/lib/etl/validators/classValidator.ts
Acceptance:
- Zod schema for class import
- Required fields: name, level, teacher_id, start_date
- Date validation (start < end)
- Teacher existence check
Estimate: 20 minutes User Story:
GIVEN I import enrollment data
WHEN each row is validated
THEN I check: student exists, class exists, dates valid, capacity not exceededFiles:
/lib/etl/validators/enrollmentValidator.ts
Acceptance:
- Student existence check
- Class existence check
- Date range validation
- Capacity check
Estimate: 30 minutes User Story:
GIVEN imported student data
WHEN I compare against existing records
THEN I detect: new students, updates, conflicts
AND I show differences to userFiles:
/lib/etl/diffEngine.ts
Acceptance:
- Match students by email
- Detect new records (no match)
- Detect updates (match + changes)
- Detect conflicts (duplicate emails)
- Generate diff report
Estimate: 25 minutes User Story:
GIVEN a validated import
WHEN I view the change summary
THEN I see: X new, Y updates, Z errors
AND I can drill down to see detailsFiles:
- Create
ImportSummary.tsxcomponent
Acceptance:
- Summary cards (new, updates, errors)
- Expandable sections for each category
- Row-level detail view
Estimate: 30 minutes User Story:
GIVEN an import job has been validated
WHEN I view the preview page
THEN I see all changes categorized
AND I can review each change
AND I can exclude specific rowsFiles:
/app/admin/data/imports/[jobId]/preview/page.tsx- Create
ImportPreview.tsx
Acceptance:
- Display new records list
- Display updates list (with before/after)
- Display errors list
- Checkboxes to include/exclude rows
- "Confirm Import" button
Estimate: 25 minutes User Story:
GIVEN I'm reviewing an import
WHEN I click on a row
THEN I see detailed before/after comparison
AND I can manually edit values
AND I can mark row for exclusionFiles:
- Create
ImportRowDetail.tsx
Acceptance:
- Before/after diff view
- Inline editing capability
- Exclude checkbox
- Save edited values
Estimate: 20 minutes User Story:
GIVEN I've reviewed all changes
WHEN I click "Approve All New" or "Approve All Updates"
THEN all rows in that category are marked approvedFiles:
- Add bulk actions to
ImportPreview.tsx
Acceptance:
- "Approve All New" button
- "Approve All Updates" button
- Bulk exclude errors button
- Confirmation dialog
Estimate: 30 minutes User Story:
GIVEN I confirm an import
WHEN execution starts
THEN all changes are applied in a single transaction
AND if any error occurs, entire import is rolled back
AND progress is trackedFiles:
/lib/etl/executor.ts/api/admin/imports/[jobId]/execute/route.ts
Acceptance:
- Wrap all inserts/updates in transaction
- Rollback on error
- Progress tracking (rows completed)
- Success/failure status
Estimate: 20 minutes User Story:
GIVEN approved new records
WHEN import executes
THEN new students/classes/enrollments are inserted
AND user accounts are created for students (if needed)Files:
- Extend
/lib/etl/executor.ts
Acceptance:
- Bulk insert approved new records
- Create user accounts for new students
- Maintain referential integrity
Estimate: 20 minutes User Story:
GIVEN approved updates
WHEN import executes
THEN existing records are updated
AND changes are logged in audit trailFiles:
- Extend
/lib/etl/executor.ts
Acceptance:
- Bulk update approved records
- Audit log entries created
- Only changed fields updated
Estimate: 20 minutes User Story:
GIVEN an import execution fails
WHEN errors occur
THEN all errors are logged with row number and details
AND user is notifiedFiles:
- Use
import_errorstable
Acceptance:
- Log all errors to database
- Include row number, field, error message
- Return error summary to UI
Estimate: 20 minutes User Story:
GIVEN import execution encounters critical error
WHEN rollback is triggered
THEN all changes are undone
AND database returns to pre-import stateFiles:
- Ensure transactional execution in executor
Acceptance:
- Transaction rollback on error
- No partial imports
- Error status recorded
Estimate: 25 minutes User Story:
GIVEN I visit import history
WHEN the page loads
THEN I see all past imports with filename, status, date, user
AND I can view details of each importFiles:
/app/admin/data/imports/page.tsx- Create
ImportHistoryList.tsx
Acceptance:
- List import jobs
- Status badges
- Click to view detail
- Filter by status/date
Estimate: 20 minutes User Story:
GIVEN I click on a past import
WHEN the detail page loads
THEN I see full report: rows processed, errors, changes made
AND I can download error reportFiles:
/app/admin/data/imports/[jobId]/page.tsx
Acceptance:
- Display job metadata
- Summary statistics
- Error details
- Download error CSV
Estimate: 25 minutes User Story:
GIVEN I want to import students
WHEN I click "Download Template"
THEN I get an Excel file with correct column headers
AND example rows are includedFiles:
/api/admin/imports/templates/[type]/route.ts- Use
exceljsto generate templates
Acceptance:
- Generate template for students
- Generate template for classes
- Generate template for enrollments
- Include headers + example rows
- Include validation notes sheet
Goal: Improve existing teacher features and add missing functionality Estimated Duration: 3-4 weeks Priority: Medium - Builds on existing solid foundation
Estimate: 20 minutes User Story:
GIVEN I'm marking a student as Absent or Late
WHEN I add a note
THEN the note is saved with the attendance record
AND I can view notes in attendance historyFiles:
- Update
AttendanceRegister.tsx - Ensure
notesfield is saved
Acceptance:
- Note text area appears on A/L status
- Note saved to database
- Note displayed in admin view
Estimate: 25 minutes User Story:
GIVEN I made an attendance error yesterday
WHEN I request a correction
THEN a correction request is submitted to admin
AND I'm notified when it's approved/rejectedFiles:
- Create
RequestCorrectionForm.tsx /api/teacher/attendance/corrections/route.ts
Acceptance:
- Correction request form
- Admin notified
- Teacher sees request status
Estimate: 15 minutes User Story:
GIVEN multiple students arrived late
WHEN I click "Mark All Late"
THEN all students are marked Late
AND I can override individualsFiles:
- Update
AttendanceRegister.tsx
Acceptance:
- "Mark All Late" button
- Bulk update function
- Individual overrides work
Estimate: 25 minutes User Story:
GIVEN I've generated lesson plans
WHEN I view my lesson plan history
THEN I see all past plans organized by date/class
AND I can reuse or duplicate plansFiles:
- Create
LessonPlanHistory.tsx /teacher/lesson-planner/history/page.tsx
Acceptance:
- List all plans created by teacher
- Filter by class/date
- "Duplicate" button
- View plan details
Estimate: 30 minutes User Story:
GIVEN I generated a lesson plan
WHEN I click "Edit"
THEN I can modify objectives, activities, timings
AND changes are saved as new versionFiles:
- Create
EditLessonPlan.tsx
Acceptance:
- Edit form pre-populated with plan
- Save as new version (preserve original)
- Update session link
Estimate: 30 minutes User Story:
GIVEN there are common lesson types
WHEN I select a template
THEN a plan is pre-filled with that structure
AND I can customize before savingFiles:
- Create templates table or config
- Add template selector to
LessonPlannerForm.tsx
Acceptance:
- Template selector dropdown
- Templates loaded from database
- Plan pre-filled with template structure
Estimate: 30 minutes User Story:
GIVEN I want to attach materials to a lesson
WHEN I upload files
THEN files are stored in Supabase Storage
AND linked to lesson plan or sessionFiles:
- Create
MaterialsUploader.tsx /api/teacher/materials/route.ts
Acceptance:
- File upload component
- Multiple file support
- Upload to Supabase Storage
- Link to lesson/session
Estimate: 25 minutes User Story:
GIVEN I have uploaded materials
WHEN I view my materials library
THEN I see all materials organized by type/class
AND I can search and reuse materialsFiles:
- Create
MaterialsLibrary.tsx /teacher/materials/page.tsx
Acceptance:
- List all materials
- Filter by type/class
- Search functionality
- Attach to new lesson button
Estimate: 20 minutes User Story:
GIVEN I'm assigned to classes
WHEN I view /teacher/classes
THEN I see all my assigned classes
AND I can click to view class detailsFiles:
- Create
/teacher/classes/page.tsx - Create
MyClassesList.tsx
Acceptance:
- List assigned classes
- Display class info (name, level, schedule)
- Link to class detail
Estimate: 25 minutes User Story:
GIVEN I click on a class
WHEN the detail page loads
THEN I see students, upcoming sessions, materials
AND I can navigate to attendance or lesson planningFiles:
- Create
/teacher/classes/[id]/page.tsx
Acceptance:
- Display class info
- List enrolled students
- Upcoming sessions
- Quick actions (attendance, plan lesson)
Estimate: 25 minutes User Story:
GIVEN I've assigned homework
WHEN I view assignments
THEN I see all assignments with submission status
AND I can click to grade submissionsFiles:
- Create
/teacher/assignments/page.tsx - Create
AssignmentsList.tsx
Acceptance:
- List assignments
- Show submission count
- Filter by class/date
- Link to grading page
Estimate: 30 minutes User Story:
GIVEN students have submitted assignments
WHEN I grade submissions
THEN I can enter scores, feedback, CEFR level
AND grades are saved to databaseFiles:
- Create
/teacher/assignments/[id]/grade/page.tsx - Create
GradingInterface.tsx
Acceptance:
- List submissions
- Input score field
- Feedback text area
- CEFR level selector
- Save grades to
gradestable
Estimate: 25 minutes User Story:
GIVEN I want to see a student's progress
WHEN I view their progress page
THEN I see CEFR descriptors mastered, attendance %, grades
AND I can add progress notesFiles:
- Create
/teacher/students/[id]/progress/page.tsx
Acceptance:
- Display CEFR progress
- Attendance summary
- Grades overview
- Add note functionality
Goal: Build complete student-facing interface Estimated Duration: 4-5 weeks Priority: Medium-High - Completes the application
Estimate: 30 minutes User Story:
GIVEN I'm a logged-in student
WHEN I visit /student/dashboard
THEN I see my upcoming sessions, recent assignments, progress summary
AND I can navigate to all student featuresFiles:
- Create
/student/dashboard/page.tsx - Create
StudentDashboard.tsx
Acceptance:
- Upcoming sessions widget
- Assignments due widget
- Progress summary card
- Quick links to features
Estimate: 25 minutes User Story:
GIVEN I want to see my schedule
WHEN I visit /student/timetable
THEN I see my enrolled classes in weekly view
AND I can see session times and roomsFiles:
- Create
/student/timetable/page.tsx - Reuse
TimetableWeekView.tsxwith student filter
Acceptance:
- Week view calendar
- Show only enrolled classes
- Display time, room, teacher
- Link to session materials
Estimate: 25 minutes User Story:
GIVEN I'm enrolled in classes
WHEN I visit /student/classes
THEN I see all my classes
AND I can view class details and materialsFiles:
- Create
/student/classes/page.tsx - Create
StudentClassesList.tsx
Acceptance:
- List enrolled classes
- Show class info
- Link to materials
Estimate: 25 minutes User Story:
GIVEN I click on a class
WHEN I view class materials
THEN I see all available materials (PDFs, links, etc.)
AND I can download via signed URLsFiles:
- Create
/student/classes/[id]/materials/page.tsx
Acceptance:
- List materials for class
- Signed URLs for download
- Organized by lesson/date
Estimate: 25 minutes User Story:
GIVEN I have assignments
WHEN I visit /student/assignments
THEN I see all assignments with due dates and status
AND I can filter by class or status (todo, submitted, graded)Files:
- Create
/student/assignments/page.tsx - Create
StudentAssignmentsList.tsx
Acceptance:
- List assignments
- Show due dates
- Status badges (todo, submitted, graded)
- Filter controls
Estimate: 30 minutes User Story:
GIVEN I click on an assignment
WHEN I view the detail page
THEN I see assignment instructions and submission form
AND I can upload files or enter text
AND I can submitFiles:
- Create
/student/assignments/[id]/page.tsx - Create
AssignmentSubmissionForm.tsx
Acceptance:
- Display assignment details
- File upload or text editor
- Submit button
- Save to
submissionstable
Estimate: 15 minutes User Story:
GIVEN I submit an assignment
WHEN submission is successful
THEN I see confirmation message
AND assignment status updates to "submitted"Files:
- Update
AssignmentSubmissionForm.tsx
Acceptance:
- Success notification
- Status update
- Submission timestamp displayed
Estimate: 30 minutes User Story:
GIVEN I want to see my learning progress
WHEN I visit /student/progress
THEN I see CEFR level, descriptors mastered, attendance %, grades
AND I see progress visualizationsFiles:
- Create
/student/progress/page.tsx - Create
StudentProgressDashboard.tsx
Acceptance:
- Current CEFR level badge
- Progress chart/visualization
- Descriptors completed list
- Attendance percentage
- Average grade
Estimate: 25 minutes User Story:
GIVEN I want to see CEFR progress detail
WHEN I view descriptors
THEN I see all descriptors for my level
AND completed descriptors are marked
AND I can see evidence (lessons, assessments)Files:
- Create
CEFRDescriptorProgress.tsx
Acceptance:
- List descriptors by domain (Listening, Reading, Writing, Speaking)
- Checkmarks for completed
- Link to evidence (assignments, grades)
Estimate: 20 minutes User Story:
GIVEN I want to see my attendance
WHEN I visit /student/attendance
THEN I see all sessions with my attendance status
AND I see attendance percentageFiles:
- Create
/student/attendance/page.tsx - Query
attendancetable for student
Acceptance:
- List sessions with status (P/A/L)
- Attendance % calculation
- Filter by date range or class
Estimate: 25 minutes User Story:
GIVEN I want to view/update my profile
WHEN I visit /student/profile
THEN I see my personal info
AND I can update email, phone (with verification)Files:
- Create
/student/profile/page.tsx - Create
StudentProfileForm.tsx
Acceptance:
- Display name, email, phone, DOB (read-only)
- Edit email/phone with verification
- Change password link (if applicable)
Estimate: 30 minutes User Story:
GIVEN I update my email
WHEN I save
THEN a verification code is sent
AND I must verify before change is savedFiles:
- Implement verification flow
- Use Supabase Auth or custom OTP
Acceptance:
- Send verification code
- OTP input field
- Verify and update on success
- 1.1 Student Registry (10 tasks)
- 1.2 Classes Management (5 tasks)
- 1.3 Enrollments Management (6 tasks)
- 1.4 Attendance Tracking (4 tasks)
- 1.5 Finance Management (6 tasks)
- 1.6 Compliance & Visa (3 tasks)
- 1.7 Programmes & Courses (4 tasks)
- 1.8 Rooms Management (3 tasks)
- 1.9 Communications (2 tasks)
- 1.10 Enquiries (2 tasks)
- 1.11 Data Management (3 tasks)
- 1.12 Timetable (1 task)
- 1.13 Teachers Management (2 tasks)
- 1.14 Search (1 task)
- 1.15 Settings (3 tasks)
- 1.16 Audit Log (2 tasks)
- 1.17 Progress (1 task)
- 1.18 Bookings (1 task)
- 1.19 Help (1 task)
Total Phase 1 Tasks: 60
- 2.1 ETL Architecture (2 tasks)
- 2.2 Excel Parser (2 tasks)
- 2.3 Data Validation (3 tasks)
- 2.4 Change Detection (2 tasks)
- 2.5 User Confirmation (3 tasks)
- 2.6 Database Execution (3 tasks)
- 2.7 Error Handling (2 tasks)
- 2.8 Import History (2 tasks)
- 2.9 Template Generation (1 task)
Total Phase 2 Tasks: 20
- 3.1 Attendance Enhancements (3 tasks)
- 3.2 Lesson Planner Enhancements (3 tasks)
- 3.3 Materials Management (2 tasks)
- 3.4 Class Management (2 tasks)
- 3.5 Grading & Submissions (2 tasks)
- 3.6 Progress Tracking (1 task)
Total Phase 3 Tasks: 13
- 4.1 Dashboard (1 task)
- 4.2 Timetable (1 task)
- 4.3 Classes & Materials (2 tasks)
- 4.4 Assignments (3 tasks)
- 4.5 Progress (2 tasks)
- 4.6 Attendance (1 task)
- 4.7 Profile (2 tasks)
Total Phase 4 Tasks: 12
Estimated Completion Time:
- Phase 1: 25-30 hours (60 tasks × 25 min avg)
- Phase 2: 8-10 hours (20 tasks × 25 min avg)
- Phase 3: 5-7 hours (13 tasks × 25 min avg)
- Phase 4: 5-6 hours (12 tasks × 25 min avg)
Total: 43-53 hours of focused development
When you run the /MyCastle skill, I will:
- Check the roadmap - Read this file and identify the next uncompleted task
- Review recent commits - Use
git logto see what was last completed - Check specifications - Read REQ.md, DESIGN.md, TASKS.md for context
- Suggest next step - Propose the specific task to work on with:
- Clear user story
- Files to modify
- Acceptance criteria
- Estimated time
This ensures every MyCastle session is:
- ✅ Focused - One clear task at a time
- ✅ Contextual - Aware of project state
- ✅ Efficient - Minimal context/token usage
- ✅ Progressive - Systematic completion
- TypeScript strict mode - All files must pass type checking
- Zod validation - All forms and API inputs validated
- Error boundaries - All pages wrapped in error boundaries
- Loading states - Skeleton loaders for all async operations
- Accessibility - WCAG 2.2 AA compliance
- RLS enforcement - All database queries respect RLS policies
- Unit tests - For utilities and validation logic
- Integration tests - For API routes
- E2E tests - For critical flows (optional for initial implementation)
- Manual testing - Required for all UI components
- Clear labels - No technical jargon (use "Class" not "Entity")
- Helpful errors - User-friendly error messages
- Confirmation dialogs - For destructive actions
- Success feedback - Clear notifications for all actions
- Progressive disclosure - Advanced options hidden by default
- Consistent patterns - Same interactions across all pages
Status: ✅ Active Roadmap Maintained By: Claude Code + Eoin Malone Last Updated: 2025-12-31