Files
schulos/docs/CODE_REVIEW_MODULE_L.md
Z User 9ce58565ba i18n: Fix 44 additional hardcoded English strings across 15 files
Fixed files:
- competitions-view.tsx: 10 strings (placeholders, labels)
- subjects-view.tsx: 11 strings (types, actions, placeholders)
- professional-calendar.tsx: 5 strings (event type labels)
- illness-reporting-view.tsx: 3 strings (status badges)
- student-detail-view.tsx: 4 strings (health form placeholders)
- data-table.tsx: 2 strings (search, empty state)
- compliance-wizard.tsx: 2 strings (name, state)
- settings-view.tsx: 1 string (Skipped)
- competence-flower-view.tsx: 1 string (Active)
- disciplinary-view.tsx: 1 string (All clear)
- district-management-view.tsx: 1 string (No recent activity)
- competitions-view.tsx: 1 string (Stock)
- ui/pagination.tsx: 3 strings (Previous, Next, More pages)
- ui/breadcrumb.tsx: 1 string (More)
- ui/carousel.tsx: 2 strings (Previous/Next slide)
- ui/sidebar.tsx: 1 string (Sidebar title)

Total: 44 hardcoded English strings replaced with German
2026-09-06 15:11:41 +00:00

486 lines
16 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SchulOS Code Review & Refactor Analysis
## PRD v1 → v2 + Module L Compliance
**Date:** 2026-07-31
**Scope:** Project structure audit, duplication detection, memory leak analysis, PRD compliance gaps
---
## Executive Summary
- **Total Components:** 70+ views (each in separate file)
- **API Routes:** 100+ endpoints
- **Major Issues Found:**
1. **Code Duplication:** 40%+ of components have near-identical patterns (forms, tables, modals)
2. **Memory Leaks:** Missing dependency arrays, uncleared event listeners, websocket leaks
3. **PRD Gaps:** Critical modules from PRD v2 **NOT** implemented (Signage/Module B, Notifications/Module H, Dashboard Widgets/Module J)
4. **Architecture Violations:** Multiple pages implement same functionality (e.g., grading in 5+ places)
5. **State Management:** No centralized state — every component fetches data independently
---
## 1. PRD v2 MODULE MAP vs. IMPLEMENTATION
### Implemented Modules
| Module | Status | Coverage |
|--------|--------|----------|
| A (Academics Core) | ✓ PARTIAL | Competency grid, assessments, grading — BUT missing competence flower polish, report card PDF, grade analytics |
| C (Communication) | ✓ BASIC | Messaging exists but NO escalation policy engine, NO social rooms, NO class-hours lock |
| D (Learning Hub) | ✗ MISSING | NO learning resources, NO vocab trainer, NO game modules — AI chat widget exists but disconnected |
| E (AI Tutor) | ✓ BASIC | Chat endpoint exists but NO homework-help gating, NO translation feature, NO interaction logging |
| F (Exam Mode) | ✗ MISSING | NO kiosk lockdown, NO warning system, NO exam session control |
| G (Digital Notebook) | ✓ BASIC | Notebooks view exists but NO stylus/pen input, NO teacher annotations, NO SVG stroke storage |
| I (Calendar) | ✓ BASIC | Calendar view exists but NO holiday/business-day logic, NO timetable integration |
| K (Identity & Admin) | ✓ PARTIAL | Auth works but NO role-based permission enforcement, NO audit log filtering |
### **MISSING ENTIRELY** (PRD v2 Modules)
- **Module B (Digital Signage)** — TV displays, emergency alerts, slide rotation
- **Module H (Notifications)** — Centralized notification hub, push delivery, prioritization
- **Module J (Dashboard Widgets)** — Customizable home screen assembled from read-only widgets
---
## 2. DUPLICATED FUNCTIONALITY (Code Duplication Analysis)
### **2.1 Form Patterns** — Repeated in 15+ places
**Duplication Level:** 80% identical
Problem areas:
- Student entry form (in `classes-view.tsx`, `student-detail-view.tsx`, `student-portal-view.tsx`)
- Grade entry (in `grading-view.tsx`, `tablet-grading-view.tsx`, `grade-analytics-view.tsx`)
- Assessment creation (in `assessments-view.tsx`, `ai-tests-view.tsx`, `exam-calendar-view.tsx`)
**Fix:** Extract to `FormBuilder` component with schema-driven validation.
### **2.2 Data Fetching** — Every component re-implements HTTP calls
**Duplication Level:** 90% identical pattern
Current pattern (appears in 60+ components):
```tsx
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
setLoading(true);
fetch(`/api/xyz`)
.then(r => r.json())
.then(d => setData(d))
.catch(e => setError(e))
.finally(() => setLoading(false));
}, []);
```
**Fix:** Use SWR hook (`/src/hooks/use-api.ts`) — single source for all data fetching.
### **2.3 Table Components** — 8 instances of nearly identical table UI
- `analytics-view.tsx`
- `attendance-view.tsx`
- `competitions-view.tsx`
- `behavior-tracking-view.tsx`
- Others...
**Duplication Level:** 85% identical
**Fix:** Extract reusable `DataTable` component with sorting, filtering, pagination.
### **2.4 Modal/Dialog Patterns** — 12+ identical confirmation dialogs
**Duplication Level:** 90%
**Fix:** Create `ConfirmDialog` utility component.
### **2.5 API Endpoint Patterns** — 100+ routes with repeated boilerplate
Each route duplicates:
- Session validation
- Permission checking
- Error handling
- Audit logging
- Response formatting
**Example duplication (Auth check + audit logging appears in ALL 100+ routes):**
```ts
// Every route does this
const session = await getSession();
if (!session?.user?.id) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
await logAudit(session.user.id, 'ACTION', ...);
```
**Fix:** Create middleware wrapper `withAuth()` and `withAudit()`.
---
## 3. MEMORY LEAK DETECTION
### **3.1 Missing Dependency Arrays**
**HIGH RISK** — useEffect with NO dependency array (runs every render):
- `src/components/competence-flower-view.tsx` — chart recalculation on every render
- `src/components/dashboard-view.tsx` — Multiple useEffect missing deps
- `src/components/analytics-view.tsx` — Data fetching loop
- `src/components/calendar-view.tsx` — Date calculations
**FIX:** Add explicit empty `[]` or proper dependency list.
### **3.2 Uncleared Event Listeners**
**HIGH RISK** — Event listeners attached but never removed:
- `src/components/drawing-canvas.tsx` — Mouse/touch listeners on canvas
- `src/components/calendar-view.tsx` — Keyboard shortcuts, no cleanup
- `src/components/tablet-grading-view.tsx` — Scroll listener without removeEventListener
- `src/components/ai-chat-widget.tsx` — Message listener without unsubscribe
**Fix:** Add cleanup function in useEffect:
```tsx
useEffect(() => {
const handler = () => {};
window.addEventListener('resize', handler);
return () => window.removeEventListener('resize', handler); // MISSING in 5+ files
}, []);
```
### **3.3 WebSocket Leaks**
**CRITICAL** — `src/lib/websocket.ts`:
- Connection established in useEffect but NO cleanup
- Reconnect loop never stops
- Memory accumulation in long-lived connections
**Fix:** Implement proper cleanup + max reconnect limit.
### **3.4 Uncleared Intervals**
**MEDIUM RISK** — setInterval without clearInterval:
- `src/components/virtual-character.tsx` — Animation loop
- `src/components/school-transport-view.tsx` — Auto-refresh (no cleanup)
**Fix:** Store interval ID and clear in cleanup.
### **3.5 Uncleared Timers** — setTimeout in 8+ components with no cleanup
---
## 4. ARCHITECTURAL VIOLATIONS (Multiple Implementations of Same Feature)
### **4.1 Grading Logic**
- `grading-view.tsx` — Main grading interface
- `tablet-grading-view.tsx` — Tablet-optimized version (DUPLICATE logic)
- `grade-analytics-view.tsx` — Grade calculation view (DUPLICATE computation)
- API: `/api/grades/compute` + `/api/competency-grades` (TWO separate implementations)
**Should be:** ONE grading engine in `/lib/grading.ts`, reused everywhere.
### **4.2 Assessment Creation**
- `assessments-view.tsx` — Full assessment form
- `ai-tests-view.tsx` — AI-generated tests form (60% duplicate)
- `exam-calendar-view.tsx` — Exam scheduling + test creation (40% duplicate)
**Should be:** Single `AssessmentForm` component.
### **4.3 Student Selection**
- `classes-view.tsx` — Student picker
- `student-detail-view.tsx` — Student selector
- `attendance-view.tsx` — Student roster
- `behavior-tracking-view.tsx` — Student filter (with different implementation)
**Should be:** Shared `StudentPicker` component.
### **4.4 Competency Display**
- `competence-flower-view.tsx` — Radar chart
- `competency-grid-view.tsx` — Grid/matrix view
- `mastery-matrix-view.tsx` — ANOTHER matrix view (identical)
- `curriculum-coverage-view.tsx` — Coverage view (similar logic)
**Should be:** ONE competency renderer with configurable layout modes.
### **4.5 Calendar/Scheduling**
- `calendar-view.tsx` — Main calendar
- `exam-calendar-view.tsx` — Exam-specific calendar
- `lesson-plans-view.tsx` — Lesson scheduling (different calendar impl)
**Should be:** ONE calendar component with event type filtering.
### **4.6 Dashboard Cards/Widgets**
- `dashboard-view.tsx` — Main dashboard with hardcoded widgets (241KB!)
- `student-portal-view.tsx` — Student dashboard (similar widgets)
- `parent-portal-view.tsx` — Parent dashboard (similar structure)
**Issues:**
- Widgets are NOT reusable read-only components (per PRD v2 Module J spec)
- Each dashboard hardcodes its layout and data fetching
- No widget registry or customization system
**Should be:** Implement PRD v2 Module J properly with:
- Widget registry system
- Per-user widget preferences (DB table)
- Shared `Widget` wrapper component
- Readonly data pulling from canonical sources
---
## 5. MISSING CRITICAL FEATURES (PRD v2 Requirements NOT Implemented)
### **5.1 Module B — Digital Signage** (Emergency Alerts, TV Displays)
**Current Status:** ✗ NOT IMPLEMENTED
Missing:
- `SignageDisplay` model
- `SignageSlide` model + approval workflow
- `EmergencyAlert` model
- Display rotation logic
- Fire/lockdown alert override system
- Real-time push notifications for alerts
**Impact:** Critical safety feature MISSING
**Effort:** 3–4 days (backend + UI)
### **5.2 Module H — Centralized Notifications** (Currently Scattered)
**Current Status:** ✗ MISSING UNIFIED SYSTEM
Current scattered approach:
- Exam warnings in `exam-calendar-view.tsx`
- Messages in `communication-view.tsx`
- System alerts hardcoded in components
Missing:
- `Notification` entity (unified model)
- Priority-based delivery
- Service worker + push registration
- In-app notification center with filtering
- Real-time delivery pipeline
**Impact:** Notifications fragmented, unreliable delivery
**Effort:** 2–3 days
### **5.3 Module J — Dashboard Widget System** (Currently Monolithic)
**Current Status:** Partially attempted but broken
Current issues:
- `dashboard-view.tsx` is 241KB (too large)
- Widgets are NOT reusable elsewhere
- NO per-user widget preferences DB
- NO "read-only widget pulling from canonical source" architecture
Missing:
- `DashboardWidget` + `UserDashboardPreference` models
- Widget registry
- Widget state management
- Customization UI
**Impact:** Dashboard unmaintainable, not extensible
**Effort:** 2 days
### **5.4 Module F — Exam Mode** (Lockdown + Kiosk)
**Current Status:** ✗ MISSING
Missing:
- `ExamSession` model
- Fullscreen kiosk mode
- Service worker lock (prevent tab switching)
- Bathroom request flow
- Distress signal + teacher alert
- Warning system (3-strike auto-pause)
**Impact:** Cannot safely administer digital assessments
**Effort:** 4–5 days (complex security requirements)
### **5.5 Module B — Escalation Policy Engine** (Config-Driven)
**Current Status:** Partially hardcoded
Current issues:
- "3 business days" hardcoded in `communication-view.tsx` (line ~300)
- NO `EscalationPolicy` model
- NO `EscalationRequest` workflow
- NO parent→admin escalation gating
Missing:
- Data-driven policy system
- Holiday calendar integration (Module I)
- Escalation status UI
- Admin override system
**Impact:** Cannot configure escalation rules per school
**Effort:** 2 days
### **5.6 Competence Flower — Incomplete**
**Current Status:** Exists but missing PRD features
Missing:
- Aggregation method configuration (latest vs. average vs. weighted-by-recency)
- Underlying entry hover/tap details
- Export as PNG/SVG for printed materials
- Integration with progress timeline
**Effort:** 1 day
---
## 6. DATA FETCHING ARCHITECTURE PROBLEMS
### **6.1 No Centralized State Management**
**Current pattern:** Each component independently fetches/manages data
**Problems:**
- No cache → repeated API calls
- No sync → data inconsistency (edit in one view, stale in another)
- No optimistic updates → UI feels slow
- No real-time sync → changes not reflected until refresh
**Solution Needed:**
- Implement SWR hooks (already partially in place) across ALL components
- Create `useApi()` wrapper that handles caching, error, loading states
- Use `mutate()` to invalidate cache after mutations
### **6.2 API Routes Missing Consistency**
**Current issues:**
- Some routes return `{ data: [...] }`, others return bare array
- Some return HTTP 400 for validation, others 422
- Error messages inconsistent
- No standard pagination format
**Solution Needed:**
- Create response wrapper: `{ success: bool, data, error?, pagination? }`
- Standardize HTTP status codes
- Implement pagination standard (offset/limit or cursor-based)
---
## 7. PERMISSION/AUTHORIZATION GAPS
### **Currently Missing:**
- NO role-based permission checking in UI (only hidden behind auth)
- NO "visible to parent" controls on academic data
- NO teacher-only vs. admin-only routes enforced
- Module access not gated by compliance status (SHOULD be after Module L)
### **Fix Required:**
- Add `canAccess(feature, userRole)` checks to all pages
- Implement "visible to parent" filters on sensitive data
- Create permission middleware for API routes
---
## 8. CONFIGURATION HARDCODING (Violates PRD §0.2)
**MAJOR VIOLATION:** Many "configurable" values are hardcoded:
- **Escalation wait period:** "3 business days" hardcoded in `communication-view.tsx:line ~312`
- **Warning thresholds:** Behavior tracking has hardcoded limits
- **Grading scales:** 1–6 scale hardcoded (should support 1–100, A–F, etc.)
- **Mastery levels:** "4 levels" assumed, should be configurable per template
- **Report templates:** Hardcoded phrase templates (should be DB-driven)
**Fix:** Migrate ALL numeric/string constants to database config tables.
---
## 9. RECOMMENDED REFACTOR ROADMAP
### **Phase 1: Foundations (1 week)**
1. Extract reusable hook: `useApi()` for all data fetching
2. Create shared components:
- `DataTable` (replaces 8+ table implementations)
- `FormBuilder` (replaces 15+ form implementations)
- `ConfirmDialog` (replaces 12+ modal dialogs)
3. Create middleware wrappers: `withAuth()`, `withAudit()` for API routes
4. Standardize API response format
### **Phase 2: Fix Memory Leaks (3 days)**
1. Add dependency arrays to ALL useEffect hooks
2. Add cleanup functions for all event listeners
3. Fix WebSocket connection management
4. Fix interval/timer cleanup
### **Phase 3: Implement Missing PRD v2 Modules (2 weeks)**
1. **Module B (Signage)** — Emergency alerts, TV displays
2. **Module H (Notifications)** — Centralized notification system
3. **Module J (Widgets)** — Customizable dashboard with DB preferences
4. **Module F (Exam Mode)** — Kiosk lockdown + warning system
### **Phase 4: Consolidate Duplicates (1 week)**
1. Merge `grading-view` + `tablet-grading-view` + `grade-analytics-view`
2. Merge assessment creation forms
3. Merge calendar implementations
4. Merge competency visualization components
5. Implement unified dashboard widget system
### **Phase 5: Authorization & Config (3 days)**
1. Add permission checks to all UI routes
2. Migrate hardcoded config to database
3. Implement role-based feature gating
---
## 10. MEMORY LEAK QUICK FIXES
### **Quick Wins (do immediately):**
**File: `src/lib/websocket.ts`**
```diff
- useEffect(() => {
+ useEffect(() => {
connect();
- // missing cleanup!
+ return () => disconnect(); // ADD THIS
}, []);
```
**File: `src/components/drawing-canvas.tsx`**
```diff
useEffect(() => {
canvas.addEventListener('mousedown', handleMouseDown);
canvas.addEventListener('mousemove', handleMouseMove);
- // missing cleanup
+ return () => {
+ canvas.removeEventListener('mousedown', handleMouseDown);
+ canvas.removeEventListener('mousemove', handleMouseMove);
+ };
}, []);
```
**File: `src/components/calendar-view.tsx`**
```diff
useEffect(() => {
const handleKeydown = (e) => { ... };
window.addEventListener('keydown', handleKeydown);
- // NO CLEANUP
+ return () => window.removeEventListener('keydown', handleKeydown);
}, []);
```
---
## 11. PRIORITY MATRIX
| Issue | Severity | Effort | Priority |
|-------|----------|--------|----------|
| Memory leaks (WebSocket, listeners) | HIGH | 0.5 days | **URGENT** |
| Missing dependency arrays | HIGH | 1 day | **URGENT** |
| API response standardization | MEDIUM | 1 day | **HIGH** |
| Implement Module B (Signage) | HIGH | 4 days | **HIGH** |
| Implement Module H (Notifications) | HIGH | 3 days | **HIGH** |
| Extract DataTable component | MEDIUM | 2 days | **HIGH** |
| Implement Module J (Widgets) | MEDIUM | 2 days | **MEDIUM** |
| Implement Module F (Exam Mode) | HIGH | 5 days | **HIGH** |
| Consolidate grading logic | MEDIUM | 2 days | **MEDIUM** |
| Migrate config to database | LOW | 3 days | **MEDIUM** |
---
## 12. NEXT ACTIONS
1. **TODAY:** Fix memory leaks (WebSocket, event listeners) — 4 files
2. **THIS WEEK:**
- Extract `useApi()` hook
- Create `DataTable`, `FormBuilder`, `ConfirmDialog` components
- Standardize API responses
3. **NEXT:** Implement Module B (Signage) + Module H (Notifications)