[dyad] Kalan branding alt başlığını kaldır
This commit is contained in:
1 parent
71b9ca0eb4
commit
b9e4ed4dfc
42 files changed
+168
-37
No files matched your search
@@ -0,0 +1,431 @@
|
||||
# SchulOS Refactor Action Plan
|
||||
## PRD v1 → v2 → Production Ready
|
||||
|
||||
**Current State Analysis:**
|
||||
- 70+ view components
|
||||
- 100+ API routes
|
||||
- Estimated 40% code duplication
|
||||
- 4 major PRD v2 modules not implemented
|
||||
- Multiple memory leak patterns (detected but mostly fixed)
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Quick Wins (Week 1)
|
||||
|
||||
### 1.1 Implement Centralized API Fetching Hook
|
||||
**File:** `src/hooks/use-api.ts`
|
||||
|
||||
Replace the 60+ identical fetch patterns with SWR:
|
||||
|
||||
```tsx
|
||||
// Before: Repeated in every component
|
||||
const [data, setData] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
useEffect(() => {
|
||||
fetch(`/api/xyz`)
|
||||
.then(r => r.json())
|
||||
.then(d => setData(d))
|
||||
.catch(e => setError(e))
|
||||
.finally(() => setLoading(false));
|
||||
}, []);
|
||||
|
||||
// After: Single hook in 60+ places
|
||||
const { data, isLoading, error, mutate } = useApi('/api/xyz');
|
||||
```
|
||||
|
||||
**Impact:** Reduces component code by 30%, fixes data sync issues, enables optimistic updates.
|
||||
|
||||
**Affected Files:** 60+ components
|
||||
|
||||
---
|
||||
|
||||
### 1.2 Extract Reusable UI Components
|
||||
|
||||
#### `src/components/ui/data-table.tsx`
|
||||
Used in: analytics, attendance, competitions, behavior-tracking, grade-analytics
|
||||
- Sorting, filtering, pagination
|
||||
- Configurable columns
|
||||
- Batch actions
|
||||
|
||||
#### `src/components/forms/form-builder.tsx`
|
||||
Used in: student entry, grade entry, assessment creation, subject management
|
||||
- Schema-driven validation
|
||||
- Reusable field types
|
||||
- Error handling
|
||||
|
||||
#### `src/components/dialogs/confirm-dialog.tsx`
|
||||
Used in: 12+ places (delete confirmations, cancel actions)
|
||||
- Consistent styling
|
||||
- Accessibility
|
||||
- Custom actions
|
||||
|
||||
**Impact:** Eliminates 25+ duplicate component implementations.
|
||||
|
||||
---
|
||||
|
||||
### 1.3 Standardize API Response Format
|
||||
|
||||
**Current inconsistency:** Some routes return `{ data: [...] }`, others return bare array
|
||||
|
||||
**Standard format:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [...],
|
||||
"error": null,
|
||||
"pagination": {
|
||||
"total": 100,
|
||||
"limit": 20,
|
||||
"offset": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Create middleware:** `src/lib/api-response.ts`
|
||||
|
||||
**Impact:** Simplifies error handling, enables consistent pagination, better client-side caching.
|
||||
|
||||
---
|
||||
|
||||
### 1.4 Create API Route Middleware
|
||||
|
||||
**Problem:** Every route duplicates:
|
||||
```ts
|
||||
const session = await getSession();
|
||||
if (!session?.user?.id) return unauthorized();
|
||||
await logAudit(session.user.id, action);
|
||||
```
|
||||
|
||||
**Solution:** Higher-order middleware wrapper
|
||||
|
||||
```ts
|
||||
// Before
|
||||
export async function GET(req: Request) {
|
||||
const session = await getSession();
|
||||
if (!session?.user?.id) return unauthorized();
|
||||
// 50+ lines of actual logic
|
||||
await logAudit(...);
|
||||
}
|
||||
|
||||
// After
|
||||
export const GET = withAuth(withAudit(async (req, context) => {
|
||||
// Just the business logic
|
||||
const data = await db.xyz.findMany();
|
||||
return apiResponse(data);
|
||||
}));
|
||||
```
|
||||
|
||||
**Affected:** All 100+ API routes
|
||||
|
||||
**Impact:** Reduces average route size by 40%, eliminates repeated auth/audit code.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Fix Architectural Issues (Weeks 2-3)
|
||||
|
||||
### 2.1 Consolidate Grading Logic
|
||||
|
||||
**Current duplication:** 3 implementations
|
||||
- `src/components/grading-view.tsx` — Main grading UI
|
||||
- `src/components/tablet-grading-view.tsx` — Tablet variant
|
||||
- `src/components/grade-analytics-view.tsx` — Analytics view
|
||||
|
||||
**Problem:** Logic inconsistencies, hard to maintain
|
||||
|
||||
**Solution:**
|
||||
1. Extract grading engine → `src/lib/grading-engine.ts`
|
||||
- Pure functions for grade computation
|
||||
- Unit tested
|
||||
- Reusable everywhere
|
||||
|
||||
2. Create UI layer → `src/components/grading/`
|
||||
- `GradingForm.tsx` — Input component (reusable)
|
||||
- `GradingView.tsx` — Desktop view (uses GradingForm)
|
||||
- `TabletGradingView.tsx` — Tablet view (uses GradingForm + responsive)
|
||||
- `GradeAnalytics.tsx` — Analytics (uses grading-engine)
|
||||
|
||||
**Impact:** Single source of truth for grading logic, easier to test, consistent across UI.
|
||||
|
||||
---
|
||||
|
||||
### 2.2 Unify Assessment Creation
|
||||
|
||||
**Current duplication:** 3 implementations
|
||||
- `assessments-view.tsx` — Standard assessments
|
||||
- `ai-tests-view.tsx` — AI-generated tests
|
||||
- `exam-calendar-view.tsx` — Exam scheduling + creation
|
||||
|
||||
**Solution:**
|
||||
1. Create `AssessmentForm.tsx` — Reusable form component
|
||||
2. Create `AssessmentType.tsx` — Form variant selector (standard/AI-generated/exam)
|
||||
3. Refactor views to use form component
|
||||
|
||||
---
|
||||
|
||||
### 2.3 Implement Single Competency Renderer
|
||||
|
||||
**Current duplication:** 4 implementations
|
||||
- `competence-flower-view.tsx` — Radar chart
|
||||
- `competency-grid-view.tsx` — Grid view
|
||||
- `mastery-matrix-view.tsx` — Matrix view (duplicate of above)
|
||||
- `curriculum-coverage-view.tsx` — Coverage view
|
||||
|
||||
**Solution:**
|
||||
```tsx
|
||||
// New component with configurable layout
|
||||
<CompetencyViewer
|
||||
layout="flower" // or "grid" or "matrix" or "coverage"
|
||||
competencies={competencies}
|
||||
config={config}
|
||||
/>
|
||||
```
|
||||
|
||||
**Impact:** Single source of truth for competency data rendering.
|
||||
|
||||
---
|
||||
|
||||
### 2.4 Unify Calendar Implementations
|
||||
|
||||
**Current:** 3 separate calendar components
|
||||
- `calendar-view.tsx` — General calendar
|
||||
- `exam-calendar-view.tsx` — Exam-specific calendar
|
||||
- `lesson-plans-view.tsx` — Lesson scheduling calendar
|
||||
|
||||
**Solution:** Single calendar with event type filtering
|
||||
```tsx
|
||||
<Calendar
|
||||
events={allEvents}
|
||||
eventTypeFilters={['lesson', 'exam', 'deadline']}
|
||||
config={config}
|
||||
/>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Implement Missing PRD v2 Modules (Weeks 4-6)
|
||||
|
||||
### 3.1 Module B — Digital Signage (Emergency Alerts, TV Displays)
|
||||
|
||||
**Required tables:**
|
||||
- `SignageDisplay` — Physical displays
|
||||
- `SignageSlide` — Content slides
|
||||
- `SignagePlaylist` — Rotation config
|
||||
- `EmergencyAlert` — Alert system
|
||||
|
||||
**Implementation:**
|
||||
1. Create admin interface: `/admin/signage/displays`, `/admin/signage/slides`
|
||||
2. Create display client: `/signage/display/[displayId]` (fullscreen kiosk)
|
||||
3. Create push notifications for emergency alerts (integrate with Module H)
|
||||
4. Add approval workflow for teacher-submitted slides
|
||||
|
||||
**Safety requirement:** Emergency alerts must override all displays immediately with push notification to staff.
|
||||
|
||||
**Effort:** 4–5 days
|
||||
|
||||
**Files to create:**
|
||||
- `src/app/admin/signage/` — Admin pages
|
||||
- `src/app/signage/display/` — Display client
|
||||
- `src/components/signage/` — Reusable components
|
||||
- `src/lib/signage-engine.ts` — Rotation logic
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Module H — Centralized Notifications
|
||||
|
||||
**Required tables:**
|
||||
- `Notification` — Unified notification model
|
||||
- `NotificationPreference` — Per-user settings
|
||||
- `NotificationSubscription` — Service worker subscriptions
|
||||
|
||||
**Implementation:**
|
||||
1. Create `Notification` model unified for all alert types
|
||||
2. Implement service worker + Web Push API
|
||||
3. Create notification center UI: `/notifications`
|
||||
4. Add real-time delivery via WebSocket
|
||||
5. Refactor all modules to emit into this system instead of creating own alerts
|
||||
|
||||
**Current alerts to consolidate:**
|
||||
- Exam warnings (from exam-calendar-view)
|
||||
- Messages (from communication-view)
|
||||
- System alerts (scattered)
|
||||
- Signage emergencies (new from Module B)
|
||||
|
||||
**Effort:** 3–4 days
|
||||
|
||||
**Files to create:**
|
||||
- `src/app/api/notifications/` — Notification API
|
||||
- `src/app/api/push-subscriptions/` — Web Push setup
|
||||
- `src/components/notification-center.tsx`
|
||||
- `src/lib/notification-engine.ts`
|
||||
- `src/lib/push-service-worker.ts`
|
||||
|
||||
---
|
||||
|
||||
### 3.3 Module J — Dashboard Widget System (Customizable Home)
|
||||
|
||||
**Current issue:** Dashboard monolithic (241KB), not reusable per spec
|
||||
|
||||
**Required tables:**
|
||||
- `DashboardWidget` — Widget definitions
|
||||
- `UserDashboardPreference` — Per-user layout
|
||||
- `WidgetData` — Cached widget data (optional)
|
||||
|
||||
**Implementation:**
|
||||
1. Create widget registry system
|
||||
2. Create `Widget` wrapper component (read-only data consumer)
|
||||
3. Create customization UI: `/dashboard/customize`
|
||||
4. Refactor `dashboard-view.tsx` to use widget system
|
||||
5. Make dashboard widgets available elsewhere (student portal, parent portal)
|
||||
|
||||
**Widgets to create (examples):**
|
||||
- `AttendanceWidget` — Pulls from canonical attendance data
|
||||
- `UpcomingExamsWidget` — Pulls from calendar
|
||||
- `GradeWidget` — Pulls from grading system
|
||||
- `RecentActivitiesWidget` — Pulls from audit log
|
||||
- `WeatherWidget` — Optional external data
|
||||
|
||||
**Each widget must:**
|
||||
- Fetch from single canonical source (no duplication)
|
||||
- Be read-only in dashboard context
|
||||
- Have configurable options (hidden by user preference)
|
||||
- Load independently with skeleton state
|
||||
|
||||
**Effort:** 2–3 days
|
||||
|
||||
**Files to create:**
|
||||
- `src/components/dashboard-widgets/` — Widget implementations
|
||||
- `src/app/dashboard/customize/` — Customization page
|
||||
- `src/lib/widget-registry.ts` — Widget system
|
||||
|
||||
---
|
||||
|
||||
### 3.4 Module F — Exam Mode (Kiosk Lockdown + Proctoring)
|
||||
|
||||
**Required tables:**
|
||||
- `ExamSession` — Active exam session
|
||||
- `ExamWarning` — Warning log
|
||||
- `ExamIncidentEvent` — Incident tracking
|
||||
|
||||
**Implementation:**
|
||||
1. Create `ExamSession` model + lifecycle (started → paused → resumed → ended)
|
||||
2. Implement fullscreen kiosk UI: `/exam/[sessionId]`
|
||||
3. Add browser-level lockdown:
|
||||
- Service worker intercepts navigation
|
||||
- Fullscreen API lock
|
||||
- Tab/window switching detection
|
||||
4. Create teacher control panel: `/exam/monitor`
|
||||
5. Implement warning system (3-strike auto-pause)
|
||||
6. Add bathroom request flow + distress signal
|
||||
7. Create incident logging + parent visibility
|
||||
|
||||
**Safety requirements:**
|
||||
- Bathroom requests pause only that student's session
|
||||
- Distress signal triggers immediate teacher alert
|
||||
- 3rd warning auto-pauses (not teacher-initiated)
|
||||
- All incidents logged for audit trail
|
||||
|
||||
**Effort:** 5–6 days (complex client-side security)
|
||||
|
||||
**Files to create:**
|
||||
- `src/app/exam/[sessionId]/` — Kiosk page
|
||||
- `src/app/exam/monitor/` — Teacher control panel
|
||||
- `src/components/exam-mode/` — Exam UI components
|
||||
- `src/lib/exam-lockdown.ts` — Kiosk logic
|
||||
- `src/lib/service-worker-exam.ts` — Browser lockdown
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Consolidate Duplicates (Weeks 7-8)
|
||||
|
||||
After Phases 1-3, apply architectural changes:
|
||||
|
||||
1. **Merge grading implementations** → Single engine + UI variants
|
||||
2. **Merge assessment creation** → Unified form component
|
||||
3. **Merge competency renderers** → Configurable component
|
||||
4. **Merge calendar implementations** → Single calendar with filters
|
||||
5. **Delete 12+ duplicate utility functions** → Use shared lib
|
||||
|
||||
**Result:** Code reduction 30-40%.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Configuration & Compliance (Week 9)
|
||||
|
||||
### 5.1 Database Configuration System
|
||||
|
||||
Migrate hardcoded values to database:
|
||||
|
||||
**Create `SystemConfig` table:**
|
||||
```ts
|
||||
{
|
||||
key: string (PK),
|
||||
value: string | number | boolean | JSON,
|
||||
description: string,
|
||||
editable: boolean,
|
||||
schoolId: string? (null = system-wide)
|
||||
}
|
||||
```
|
||||
|
||||
**Migrate:**
|
||||
- Escalation wait period: "3 business days" → `Config["escalation.wait_days"]`
|
||||
- Grading scales: hardcoded 1–6 → configurable per school
|
||||
- Mastery levels: hardcoded 4 levels → configurable
|
||||
- Report templates: hardcoded phrases → DB-driven
|
||||
|
||||
**Effort:** 2 days
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Role-Based Permission UI
|
||||
|
||||
Implement UI-level permission checks:
|
||||
|
||||
```tsx
|
||||
// Before: Just hidden, not prevented
|
||||
{userRole === 'ADMIN' && <AdminButton />}
|
||||
|
||||
// After: Proper permission check
|
||||
<ProtectedFeature feature="admin.grading" fallback={<LockedIcon />}>
|
||||
<AdminButton />
|
||||
</ProtectedFeature>
|
||||
```
|
||||
|
||||
**Effort:** 1 day
|
||||
|
||||
---
|
||||
|
||||
## Timeline Summary
|
||||
|
||||
| Phase | Duration | Completion |
|
||||
|-------|----------|------------|
|
||||
| Phase 1 (Quick Wins) | 1 week | Reduce duplication by 30% |
|
||||
| Phase 2 (Architecture) | 2 weeks | Consolidate major duplicates |
|
||||
| Phase 3 (Missing Modules) | 3 weeks | Implement B, H, J, F |
|
||||
| Phase 4 (Consolidation) | 1 week | Final cleanup |
|
||||
| Phase 5 (Config) | 1 week | Database config system |
|
||||
| **Total** | **~9 weeks** | **Production ready** |
|
||||
|
||||
---
|
||||
|
||||
## Immediate Next Steps
|
||||
|
||||
1. **Create `use-api.ts` hook** — Replace 60+ fetch patterns
|
||||
2. **Extract `DataTable`, `FormBuilder`, `ConfirmDialog`** — Eliminate 25+ duplicates
|
||||
3. **Standardize API responses** — Middleware wrapper
|
||||
4. **Start Module B (Signage)** — Critical safety feature
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- [ ] Codebase reduced by 30% (duplication eliminated)
|
||||
- [ ] All 11 PRD v2 modules implemented
|
||||
- [ ] Zero memory leaks (verified with Chrome DevTools)
|
||||
- [ ] All API responses standardized
|
||||
- [ ] Role-based permissions enforced UI + backend
|
||||
- [ ] Configuration system working
|
||||
- [ ] Dashboard customization working
|
||||
- [ ] Emergency alert system tested
|
||||
- [ ] Exam mode kiosk tested
|
||||
- [ ] Full test coverage for critical paths (>80%)
|
||||
|
||||
Reference in new issue
Block a user