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
11 KiB
Executable File
Critical APIs to Build - Priority List
Phase 3: API Implementation (Ready for Your Team)
All endpoints follow the standardized middleware pattern defined in src/lib/route-middleware.ts and src/lib/api-response.ts.
Priority 1: CRITICAL (Must Have for MVP)
1. Notifications Hub APIs
POST /api/v1/notifications/send
Purpose: Create and send notification to user(s)
// Request
{
schoolId: string;
userId?: string; // Single user
userIds?: string[]; // Multiple users
category: 'assessment' | 'behavior' | 'communication' | 'wellness' | 'system' | 'announcement';
priority: 'low' | 'normal' | 'high' | 'critical';
title: string;
message: string;
actionUrl?: string;
actionLabel?: string;
sourceType?: string;
sourceId?: string;
expiresAt?: Date;
}
// Response
{
success: true;
data: {
id: string;
createdAt: Date;
sentTo: number;
}
}
Logic:
- Validate user/school relationship
- Create notification_hub entries
- Trigger real-time update via WebSocket
- Log via audit system
- Check user notification preferences before sending
Location: /src/app/api/v1/notifications/send/route.ts
GET /api/v1/notifications/hub?limit=20&offset=0
Purpose: Get user's notifications
// Response
{
success: true;
data: {
notifications: [
{
id: string;
category: string;
priority: string;
title: string;
message: string;
isRead: boolean;
isDismissed: boolean;
createdAt: Date;
actionUrl?: string;
}
];
unreadCount: number;
total: number;
}
}
Location: /src/app/api/v1/notifications/hub/route.ts
PUT /api/v1/notifications/{id}/read
Purpose: Mark notification as read
// Response
{
success: true;
data: {
id: string;
isRead: true;
readAt: Date;
}
}
Location: /src/app/api/v1/notifications/[id]/read/route.ts
2. Dashboard Widget APIs
POST /api/v1/dashboard/widgets
Purpose: Create widget
// Request
{
schoolId: string;
userId: string;
widgetType: string;
size: 'small' | 'medium' | 'large' | 'full_width';
config?: Record<string, any>;
refreshInterval?: number;
}
// Response
{
success: true;
data: {
id: string;
position: number;
widgetType: string;
createdAt: Date;
}
}
Logic:
- Find next available position
- Use getDefaultConfig(widgetType) if config not provided
- Validate widget type exists
- Create dashboard_widget record
Location: /src/app/api/v1/dashboard/widgets/route.ts
GET /api/v1/dashboard/widgets
Purpose: Get user's widgets
// Response
{
success: true;
data: [
{
id: string;
widgetType: string;
title: string;
position: number;
size: string;
config: Record<string, any>;
cacheData?: any;
lastRefresh?: Date;
}
];
}
Location: /src/app/api/v1/dashboard/widgets/route.ts
PUT /api/v1/dashboard/widgets/{id}
Purpose: Update widget (position, config, size)
// Request
{
position?: number;
size?: string;
config?: Record<string, any>;
title?: string;
}
// Response
{
success: true;
data: { /* updated widget */ }
}
Location: /src/app/api/v1/dashboard/widgets/[id]/route.ts
DELETE /api/v1/dashboard/widgets/{id}
Purpose: Remove widget from dashboard
// Response
{
success: true;
data: { id: string }
}
Location: /src/app/api/v1/dashboard/widgets/[id]/route.ts
3. Signage APIs
POST /api/v1/signage/messages
Purpose: Create emergency message
// Request
{
schoolId: string;
signageId?: string; // Broadcast to specific device or all
title: string;
content: string;
messageType: 'emergency' | 'notification' | 'schedule' | 'announcement' | 'alert';
priority: 'low' | 'normal' | 'high' | 'critical';
displayDuration?: number; // seconds
soundAlert?: boolean;
soundFile?: string;
startTime?: Date;
endTime?: Date;
}
// Response
{
success: true;
data: {
id: string;
messageId: string;
broadcastTo: number; // devices affected
priority: string;
}
}
Logic:
- Create signage_message record
- If signageId: send to that device
- Else: broadcast to all active signages via WebSocket
- Log via audit system
- Create signage_audit_log entry
Location: /src/app/api/v1/signage/messages/route.ts
GET /api/v1/signage/devices
Purpose: Get school's signage devices
// Response
{
success: true;
data: [
{
id: string;
displayName: string;
location: string;
isActive: boolean;
signageType: string;
lastHeartbeat?: Date;
currentMessage?: {
id: string;
title: string;
priority: string;
};
}
];
}
Location: /src/app/api/v1/signage/devices/route.ts
POST /api/v1/signage/devices
Purpose: Register new signage device
// Request
{
schoolId: string;
displayName: string;
location: string;
signageType: string;
resolution: string;
ipAddress?: string;
}
// Response
{
success: true;
data: { id: string; apiToken: string }
}
Location: /src/app/api/v1/signage/devices/route.ts
4. Exam Session APIs
POST /api/v1/exam-sessions/start
Purpose: Begin exam session for student
// Request
{
schoolId: string;
assessmentId: string;
studentId: string;
lockdownEnabled?: boolean;
cameraMonitor?: boolean;
screenShare?: boolean;
}
// Response
{
success: true;
data: {
sessionId: string;
startTime: Date;
endTime: Date;
timeAllowed: number; // minutes
token: string; // JWT for session verification
lockdownToken?: string; // For kiosk mode
}
}
Logic:
- Validate student is enrolled in course
- Create exam_session record
- Generate JWT with session data + exp
- If lockdownEnabled: generate kiosk token (restricted permissions)
- Start real-time monitoring via WebSocket
- Log audit trail
Location: /src/app/api/v1/exam-sessions/start/route.ts
GET /api/v1/exam-sessions/{sessionId}/events
Purpose: Stream exam monitoring events
// Query Params
?limit=50&type=all|warning|critical
// Response (streamed)
{
success: true;
data: {
events: [
{
id: string;
eventType: 'tab_switch' | 'copy_paste' | 'window_blur' | 'camera_detected_none' | 'suspicious_movement' | 'time_warning';
severity: 'info' | 'warning' | 'critical';
timestamp: Date;
description?: string;
}
];
securityRisk: 0-100; // Computed score
warnings: Exam
Warning[];
}
}
Logic:
- Retrieve exam_events for session
- Filter by type if provided
- Compute security risk score:
- tab_switch: +15
- copy_paste: +25
- window_blur: +10
- suspicious_movement: +35
- Max capped at 100
- Include active exam_warnings
Location: /src/app/api/v1/exam-sessions/[sessionId]/events/route.ts
POST /api/v1/exam-sessions/{sessionId}/submit
Purpose: Submit exam for grading
// Request
{
studentId: string;
answers: [
{ questionId: string; answer: string }
]
}
// Response
{
success: true;
data: {
sessionId: string;
submittedAt: Date;
status: 'submitted';
securityFlags: number;
}
}
Location: /src/app/api/v1/exam-sessions/[sessionId]/submit/route.ts
Priority 2: IMPORTANT (Build in Week 2)
5. Dashboard Layout API
POST /api/v1/dashboard/layouts
GET /api/v1/dashboard/layouts/{id}
PUT /api/v1/dashboard/layouts/{id}
DELETE /api/v1/dashboard/layouts/{id}
6. Signage Scheduling
POST /api/v1/signage/schedules
GET /api/v1/signage/schedules
PUT /api/v1/signage/schedules/{id}
DELETE /api/v1/signage/schedules/{id}
7. Exam Proctoring (Teacher)
GET /api/v1/exam-proctoring/sessions?classId=xxx
POST /api/v1/exam-proctoring/{sessionId}/pause
POST /api/v1/exam-proctoring/{sessionId}/resume
POST /api/v1/exam-proctoring/{sessionId}/flag-warning
8. Notification Preferences
GET /api/v1/notifications/preferences
PUT /api/v1/notifications/preferences
Implementation Template
Use this template for each API (follows middleware pattern):
// /src/app/api/v1/[module]/[action]/route.ts
import { NextRequest } from 'next/server';
import { withAuth, withAudit, withRateLimit } from '@/lib/route-middleware';
import { apiResponse, apiError } from '@/lib/api-response';
import { db } from '@/lib/db';
import { logComplianceAudit } from '@/lib/audit';
export async function POST(request: NextRequest) {
return withAuth(async (user) => {
return withAudit(async () => {
try {
const body = await request.json();
// Validate input
if (!body.schoolId) {
return apiError('School ID required', 400);
}
// Verify user access to school
const school = await db.school.findUnique({
where: { id: body.schoolId },
});
if (!school) {
return apiError('School not found', 404);
}
// Business logic
const result = await db.yourModel.create({
data: { /* ... */ },
});
// Audit log
await logComplianceAudit({
userId: user.id,
schoolId: body.schoolId,
action: 'YOUR_ACTION',
entityType: 'YourModel',
entityId: result.id,
});
return apiResponse({
success: true,
data: result,
});
} catch (error) {
console.error('[v0] API error:', error);
return apiError('Operation failed', 500);
}
}, request);
}, request);
}
WebSocket Events (Real-Time)
For real-time notifications, exams, and signage updates:
// Server sends:
{
type: 'notification.created' | 'exam.event' | 'signage.updated';
data: { /* event data */ };
timestamp: Date;
}
// Client subscribes:
const ws = new WebSocket('wss://api.domain/ws');
ws.send(JSON.stringify({
action: 'subscribe',
channels: ['notifications', 'exam:sessionId', 'signage:schoolId']
}));
Testing Checklist
For each API:
- ✅ Valid request succeeds with 200
- ✅ Invalid input returns 400
- ✅ Unauthorized returns 401
- ✅ Forbidden returns 403
- ✅ Not found returns 404
- ✅ Audit log created
- ✅ Real-time updates triggered
- ✅ Performance <200ms
Estimated Effort
Priority 1: 3-4 days (10 endpoints)
Priority 2: 3-4 days (8+ endpoints)
Total: 6-8 days for complete API layer
All infrastructure is ready. Just implement the business logic following the templates above.