Skip to content

Code Quality Audit

Last updated: 2026-03-05


DomainCriticalHighMediumLow
Backend — Soft-Delete Guards3 ✅5 ✅00
Frontend — React & UI01 ✅3 ✅1 ✅
DB Schema00NotesNotes
Total3631

1. Backend — Missing notDeleted() Guards

Section titled “1. Backend — Missing notDeleted() Guards”

PinTeach uses soft-delete (deletedAt column) on 7 tables: services, students, lesson_templates, teacher_resources, material_folders, class_categories, tags. All queries must include notDeleted(table) in WHERE clauses.

IDFileMethodMissing GuardSeverityStatus
BE-1session-service.ts:120bookSession()notDeleted(services) in cross-service eligibilityCritical✅ Fixed
BE-2session-service.ts:273bookMultipleSessions()notDeleted(services) in cross-service eligibilityCritical✅ Fixed
BE-3lesson-template-service.ts:90delete()notDeleted(lessonTemplates) — allowed re-deleting already deleted templatesCritical✅ Fixed
BE-4slot-engine.ts:264getAvailableSlotsForService()notDeleted(services) — deleted services could generate booking slotsHigh✅ Fixed
BE-5lesson-template-service.ts:12create()notDeleted(materialFolders) — could create templates in deleted foldersHigh✅ Fixed
BE-6lesson-template-service.ts:48update()notDeleted(lessonTemplates) — could update deleted templatesHigh✅ Fixed
BE-7resource-service.ts:49create()notDeleted(materialFolders) — could create resources in deleted foldersHigh✅ Fixed
BE-8resource-service.ts:249linkToTemplate()notDeleted(lessonTemplates) — could link resources to deleted templatesHigh✅ Fixed

IDFileIssueSeverityStatus
FE-1week-calendar-grid.tsx:381useEffect dependency availDrag.type !== 'idle' creates new boolean each render — should be availDrag.typeHigh✅ Fixed
FE-2calendar.lazy.tsx:525useShortcut “complete selected” missing completeMutation in dependency array — stale closureMedium✅ Fixed
FE-3dashboard.lazy.tsx:223KPI reorder mutation missing onError handler — no user feedback on failureMedium✅ Fixed
FE-4dashboard.lazy.tsx:214Unsafe as KpiMetricKey[] cast without runtime validation — replaced with Array.isArray() checkMedium✅ Fixed
FE-5week-calendar-grid.tsx:997Preview slots using index-based key — replaced with stable date-startTime keyLow✅ Fixed

These are not bugs but improvement opportunities for future migrations:

Several foreign keys lack explicit onDelete behavior. Not urgent because the app uses soft-delete and never hard-deletes teachers/services via SQL:

  • class_sessions: enrollmentId, serviceId, teacherId, studentId, scheduleItemId
  • enrollments: serviceId, teacherId
  • class_categories, tags: teacherId

Some foreign keys would benefit from indexes for query performance:

  • contact_log: teacherId, studentId
  • teacher_notifications: teacherId
  • availability_rules: teacherId, scheduleId
  • legal_document_acceptances: studentId
  • Color field length: services.color is varchar(7) while tags, class_categories, material_folders use varchar(20). Not a bug — services only store hex colors (#RRGGBB).
  • Availability tables: availability_schedules, availability_rules, availability_overrides don’t have deletedAt for soft-delete. Intentional — these are managed via CRUD without need for recovery.

All fixes verified with:

  1. bun run typecheck — all 6 packages pass
  2. Manual review of each notDeleted() addition
  3. Confirmed no other soft-delete table queries are missing guards (class-category, tag, material-folder, student-management, enrollment, waitlist services all have proper guards)