[split-required] Split final batch of monoliths >1000 LOC

Python (6 files in klausur-service):
- rbac.py (1,132 → 4), admin_api.py (1,012 → 4)
- routes/eh.py (1,111 → 4), ocr_pipeline_geometry.py (1,105 → 5)

Python (2 files in backend-lehrer):
- unit_api.py (1,226 → 6), game_api.py (1,129 → 5)

Website (6 page files):
- 4x klausur-korrektur pages (1,249-1,328 LOC each) → shared components
  in website/components/klausur-korrektur/ (17 shared files)
- companion (1,057 → 10), magic-help (1,017 → 8)

All re-export barrels preserve backward compatibility.
Zero import errors verified.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-24 23:17:30 +02:00
parent b2a0126f14
commit 6811264756
67 changed files with 12270 additions and 13651 deletions

View File

@@ -0,0 +1,97 @@
'use client'
import { useState, useEffect } from 'react'
import type { Feature, TeacherFeedback } from './types'
import { initialFeatures, initialFeedback, roadmapPhases } from './data'
// Data version - increment when adding new features/feedback to force refresh
const DATA_VERSION = '8.2.0' // Phase 8e: Frontend UI-Komponenten (ContextBar, Sidebar, PathPanel)
export function useCompanionDev() {
const [features, setFeatures] = useState<Feature[]>(initialFeatures)
const [feedback, setFeedback] = useState<TeacherFeedback[]>(initialFeedback)
const [activeTab, setActiveTab] = useState<'roadmap' | 'features' | 'feedback' | 'backlog'>('roadmap')
const [selectedPhase, setSelectedPhase] = useState<string | null>(null)
const [feedbackFilter, setFeedbackFilter] = useState<string>('all')
// Load from localStorage with version check
useEffect(() => {
const savedVersion = localStorage.getItem('companion-dev-version')
const savedFeatures = localStorage.getItem('companion-dev-features')
const savedFeedback = localStorage.getItem('companion-dev-feedback')
// If version mismatch or no version, use initial data and save new version
if (savedVersion !== DATA_VERSION) {
console.log(`Companion Dev: Data version updated from ${savedVersion} to ${DATA_VERSION}`)
localStorage.setItem('companion-dev-version', DATA_VERSION)
localStorage.setItem('companion-dev-features', JSON.stringify(initialFeatures))
localStorage.setItem('companion-dev-feedback', JSON.stringify(initialFeedback))
// State already initialized with initialFeatures/initialFeedback, no need to setFeatures
return
}
// Load saved data if version matches
if (savedFeatures) setFeatures(JSON.parse(savedFeatures))
if (savedFeedback) setFeedback(JSON.parse(savedFeedback))
}, [])
// Save to localStorage
useEffect(() => {
localStorage.setItem('companion-dev-features', JSON.stringify(features))
}, [features])
useEffect(() => {
localStorage.setItem('companion-dev-feedback', JSON.stringify(feedback))
}, [feedback])
const getPhaseStats = () => {
const total = roadmapPhases.length
const completed = roadmapPhases.filter(p => p.status === 'completed').length
const inProgress = roadmapPhases.filter(p => p.status === 'in_progress').length
return { total, completed, inProgress }
}
const getFeatureStats = () => {
const total = features.length
const done = features.filter(f => f.status === 'done').length
const inProgress = features.filter(f => f.status === 'in_progress').length
return { total, done, inProgress, percentage: Math.round((done / total) * 100) }
}
const getFeedbackStats = () => {
const total = feedback.length
const newCount = feedback.filter(f => f.status === 'new').length
const bugs = feedback.filter(f => f.type === 'bug').length
const requests = feedback.filter(f => f.type === 'feature_request').length
return { total, newCount, bugs, requests }
}
const updateFeatureStatus = (id: string, status: Feature['status']) => {
setFeatures(features.map(f => f.id === id ? { ...f, status } : f))
}
const updateFeedbackStatus = (id: string, status: TeacherFeedback['status']) => {
setFeedback(feedback.map(f => f.id === id ? { ...f, status } : f))
}
const filteredFeedback = feedbackFilter === 'all'
? feedback
: feedback.filter(f => f.type === feedbackFilter || f.status === feedbackFilter)
return {
features,
feedback,
activeTab,
setActiveTab,
selectedPhase,
setSelectedPhase,
feedbackFilter,
setFeedbackFilter,
phaseStats: getPhaseStats(),
featureStats: getFeatureStats(),
feedbackStats: getFeedbackStats(),
updateFeatureStatus,
updateFeedbackStatus,
filteredFeedback,
}
}