Skip to content

Code Quality Audit

Last updated: 2026-03-05


Domain Critical High Medium Low
Backend — Soft-Delete Guards 3 ✅ 5 ✅ 0 0
Frontend — React & UI 0 1 ✅ 3 ✅ 1 ✅
DB Schema 0 0 Notes Notes
Total 3 ✅ 6 ✅ 3 ✅ 1 ✅

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.

ID File Method Missing Guard Severity Status
BE-1 session-service.ts:120 bookSession() notDeleted(services) in cross-service eligibility Critical ✅ Fixed
BE-2 session-service.ts:273 bookMultipleSessions() notDeleted(services) in cross-service eligibility Critical ✅ Fixed
BE-3 lesson-template-service.ts:90 delete() notDeleted(lessonTemplates) — allowed re-deleting already deleted templates Critical ✅ Fixed
BE-4 slot-engine.ts:264 getAvailableSlotsForService() notDeleted(services) — deleted services could generate booking slots High ✅ Fixed
BE-5 lesson-template-service.ts:12 create() notDeleted(materialFolders) — could create templates in deleted folders High ✅ Fixed
BE-6 lesson-template-service.ts:48 update() notDeleted(lessonTemplates) — could update deleted templates High ✅ Fixed
BE-7 resource-service.ts:49 create() notDeleted(materialFolders) — could create resources in deleted folders High ✅ Fixed
BE-8 resource-service.ts:249 linkToTemplate() notDeleted(lessonTemplates) — could link resources to deleted templates High ✅ Fixed

ID File Issue Severity Status
FE-1 week-calendar-grid.tsx:381 useEffect dependency availDrag.type !== 'idle' creates new boolean each render — should be availDrag.type High ✅ Fixed
FE-2 calendar.lazy.tsx:525 useShortcut “complete selected” missing completeMutation in dependency array — stale closure Medium ✅ Fixed
FE-3 dashboard.lazy.tsx:223 KPI reorder mutation missing onError handler — no user feedback on failure Medium ✅ Fixed
FE-4 dashboard.lazy.tsx:214 Unsafe as KpiMetricKey[] cast without runtime validation — replaced with Array.isArray() check Medium ✅ Fixed
FE-5 week-calendar-grid.tsx:997 Preview slots using index-based key — replaced with stable date-startTime key Low ✅ 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)