fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
411
docs/architecture/zeugnis-system.md
Normal file
411
docs/architecture/zeugnis-system.md
Normal file
@@ -0,0 +1,411 @@
|
||||
# Zeugnis-System - Architecture Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The Zeugnis (Certificate) System enables schools to generate official school certificates with grades, attendance data, and remarks. It extends the existing School-Service with comprehensive grade management and certificate generation workflows.
|
||||
|
||||
## Architecture Diagram
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Python Backend (Port 8000) │
|
||||
│ backend/frontend/modules/school.py │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ panel-school-certificates │ │
|
||||
│ │ - Klassenauswahl │ │
|
||||
│ │ - Notenspiegel │ │
|
||||
│ │ - Zeugnis-Wizard (5 Steps) │ │
|
||||
│ │ - Workflow-Status │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
└──────────────────┬──────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ School-Service (Go, Port 8084) │
|
||||
├─────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────────────────┐ │
|
||||
│ │ Grade Handlers │ │ Statistics Handlers │ │ Certificate Handlers │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ GetClassGrades │ │ GetClassStatistics │ │ GetCertificateTemplates │ │
|
||||
│ │ GetStudentGrades │ │ GetSubjectStatistics│ │ GetClassCertificates │ │
|
||||
│ │ UpdateOralGrade │ │ GetStudentStatistics│ │ GenerateCertificate │ │
|
||||
│ │ CalculateFinalGrades│ │ GetNotenspiegel │ │ BulkGenerateCertificates │ │
|
||||
│ │ TransferApprovedGrades│ │ │ │ FinalizeCertificate │ │
|
||||
│ │ LockFinalGrade │ │ │ │ GetCertificatePDF │ │
|
||||
│ │ UpdateGradeWeights │ │ │ │ │ │
|
||||
│ └─────────────────────┘ └─────────────────────┘ └─────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────────────┐│
|
||||
│ │ Grade Service Layer ││
|
||||
│ │ ││
|
||||
│ │ - ClassStatistics struct (average, pass_rate, at_risk_count, grade_distribution) ││
|
||||
│ │ - SubjectStatistics struct (class average, best/worst, exam results) ││
|
||||
│ │ - StudentStatistics struct (overall average, subject performance) ││
|
||||
│ │ - Notenspiegel struct (grade 1-6 distribution) ││
|
||||
│ └─────────────────────────────────────────────────────────────────────────────────────┘│
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ PostgreSQL Database │
|
||||
│ │
|
||||
│ Tables: │
|
||||
│ - grade_overview │
|
||||
│ - exam_results │
|
||||
│ - students │
|
||||
│ - classes │
|
||||
│ - subjects │
|
||||
│ - certificates │
|
||||
│ - attendance │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Zeugnis Workflow (Role Chain)
|
||||
|
||||
The certificate workflow follows a strict approval chain from subject teachers to school principal:
|
||||
|
||||
```
|
||||
┌──────────────────┐ ┌──────────────────┐ ┌────────────────────────┐ ┌────────────────────┐ ┌──────────────────┐
|
||||
│ FACHLEHRER │───▶│ KLASSENLEHRER │───▶│ ZEUGNISBEAUFTRAGTER │───▶│ SCHULLEITUNG │───▶│ SEKRETARIAT │
|
||||
│ (Subject │ │ (Class │ │ (Certificate │ │ (Principal) │ │ (Secretary) │
|
||||
│ Teacher) │ │ Teacher) │ │ Coordinator) │ │ │ │ │
|
||||
└──────────────────┘ └──────────────────┘ └────────────────────────┘ └────────────────────┘ └──────────────────┘
|
||||
│ │ │ │ │
|
||||
▼ ▼ ▼ ▼ ▼
|
||||
Grades Entry Approve Quality Check Sign-off & Lock Print & Archive
|
||||
(Oral/Written) Grades & Review
|
||||
```
|
||||
|
||||
### Workflow States
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ DRAFT │────▶│ SUBMITTED │────▶│ REVIEWED │────▶│ SIGNED │────▶│ PRINTED │
|
||||
│ (Entwurf) │ │ (Eingereicht)│ │ (Geprueft) │ │(Unterzeichnet) │ (Gedruckt) │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
||||
│ │ │ │
|
||||
▼ ▼ ▼ ▼
|
||||
Fachlehrer Klassenlehrer Zeugnisbeauftragter Schulleitung
|
||||
```
|
||||
|
||||
## RBAC Integration
|
||||
|
||||
### Certificate-Related Roles
|
||||
|
||||
| Role | German | Description |
|
||||
|------|--------|-------------|
|
||||
| `FACHLEHRER` | Fachlehrer | Subject teacher - enters grades |
|
||||
| `KLASSENLEHRER` | Klassenlehrer | Class teacher - approves class grades |
|
||||
| `ZEUGNISBEAUFTRAGTER` | Zeugnisbeauftragter | Certificate coordinator - quality control |
|
||||
| `SCHULLEITUNG` | Schulleitung | Principal - final sign-off |
|
||||
| `SEKRETARIAT` | Sekretariat | Secretary - printing & archiving |
|
||||
|
||||
### Certificate Resource Types
|
||||
|
||||
| ResourceType | Description |
|
||||
|--------------|-------------|
|
||||
| `ZEUGNIS` | Final certificate document |
|
||||
| `ZEUGNIS_VORLAGE` | Certificate template (per Bundesland) |
|
||||
| `ZEUGNIS_ENTWURF` | Draft certificate (before approval) |
|
||||
| `FACHNOTE` | Subject grade |
|
||||
| `KOPFNOTE` | Head grade (Arbeits-/Sozialverhalten) |
|
||||
| `BEMERKUNG` | Certificate remarks |
|
||||
| `STATISTIK` | Class/subject statistics |
|
||||
| `NOTENSPIEGEL` | Grade distribution chart |
|
||||
|
||||
### Permission Matrix
|
||||
|
||||
| Role | ZEUGNIS | ZEUGNIS_ENTWURF | ZEUGNIS_VORLAGE | FACHNOTE | Actions |
|
||||
|------|---------|-----------------|-----------------|----------|---------|
|
||||
| FACHLEHRER | R | CRUD | R | CRUD | Create/Update grades |
|
||||
| KLASSENLEHRER | CRU | CRUD | R | CRUD | Approve class grades |
|
||||
| ZEUGNISBEAUFTRAGTER | RU | RU | RUU | RU | Quality review |
|
||||
| SCHULLEITUNG | R/SIGN/LOCK | RU | RU | R | Final approval |
|
||||
| SEKRETARIAT | RD | R | R | R | Print & archive |
|
||||
|
||||
Legend: C=Create, R=Read, U=Update, D=Delete, SIGN=Sign-off, LOCK=Lock final
|
||||
|
||||
### VerfahrenType for Certificates
|
||||
|
||||
```python
|
||||
class VerfahrenType(str, Enum):
|
||||
# Exam types
|
||||
ABITUR = "abitur"
|
||||
KLAUSUR = "klausur"
|
||||
...
|
||||
|
||||
# Certificate types
|
||||
HALBJAHRESZEUGNIS = "halbjahreszeugnis" # Mid-year certificate
|
||||
JAHRESZEUGNIS = "jahreszeugnis" # End-of-year certificate
|
||||
ABSCHLUSSZEUGNIS = "abschlusszeugnis" # Graduation certificate
|
||||
ABGANGSZEUGNIS = "abgangszeugnis" # Leaving certificate
|
||||
```
|
||||
|
||||
## Statistics API
|
||||
|
||||
### Endpoints
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/api/v1/school/statistics/:classId` | Class statistics |
|
||||
| GET | `/api/v1/school/statistics/:classId/subject/:subjectId` | Subject statistics |
|
||||
| GET | `/api/v1/school/statistics/student/:studentId` | Student statistics |
|
||||
| GET | `/api/v1/school/statistics/:classId/notenspiegel` | Grade distribution |
|
||||
|
||||
### Response Structures
|
||||
|
||||
**ClassStatistics:**
|
||||
```json
|
||||
{
|
||||
"class_id": "uuid",
|
||||
"class_name": "5a",
|
||||
"semester": 1,
|
||||
"average": 2.4,
|
||||
"pass_rate": 92.8,
|
||||
"at_risk_count": 2,
|
||||
"student_count": 25,
|
||||
"subjects": [
|
||||
{
|
||||
"subject_id": "uuid",
|
||||
"subject_name": "Mathematik",
|
||||
"average": 2.8
|
||||
}
|
||||
],
|
||||
"grade_distribution": {
|
||||
"1": 3,
|
||||
"2": 8,
|
||||
"3": 10,
|
||||
"4": 5,
|
||||
"5": 2,
|
||||
"6": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Notenspiegel:**
|
||||
```json
|
||||
{
|
||||
"class_id": "uuid",
|
||||
"subject_id": "uuid",
|
||||
"exam_id": "uuid",
|
||||
"distribution": {
|
||||
"1": 2,
|
||||
"2": 5,
|
||||
"3": 8,
|
||||
"4": 6,
|
||||
"5": 3,
|
||||
"6": 1
|
||||
},
|
||||
"total_students": 25,
|
||||
"average": 3.1,
|
||||
"median": 3.0
|
||||
}
|
||||
```
|
||||
|
||||
## Frontend Components
|
||||
|
||||
### Certificate Panel (`panel-school-certificates`)
|
||||
|
||||
Located in: `backend/frontend/modules/school.py`
|
||||
|
||||
Features:
|
||||
- **Statistik-Karten**: Overview cards showing class average, pass rate, at-risk students
|
||||
- **Notenspiegel Chart**: Bar chart visualization of grade distribution (1-6)
|
||||
- **Workflow-Status**: Visual display of certificate approval chain
|
||||
- **Student Table**: List of students with grades, attendance, certificate status
|
||||
|
||||
### Zeugnis-Wizard (5 Steps)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Zeugnis-Wizard Modal │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Step 1: Klasse auswaehlen │
|
||||
│ ├── Dropdown: Klasse (5a, 5b, 6a, ...) │
|
||||
│ ├── Dropdown: Halbjahr (1 oder 2) │
|
||||
│ └── Vorschau: Anzahl Schueler, Durchschnitt │
|
||||
│ │
|
||||
│ Step 2: Noten pruefen │
|
||||
│ ├── Tabelle: Schueler | Fach1 | Fach2 | ... | Status │
|
||||
│ ├── Fehlende Noten markiert │
|
||||
│ └── Edit-Moeglichkeit direkt in Tabelle │
|
||||
│ │
|
||||
│ Step 3: Vorlage waehlen │
|
||||
│ ├── Dropdown: Bundesland (Niedersachsen, Bayern, ...) │
|
||||
│ ├── Dropdown: Schulform (Gymnasium, Realschule, ...) │
|
||||
│ └── Vorschau: Template-Preview │
|
||||
│ │
|
||||
│ Step 4: Bemerkungen │
|
||||
│ ├── Textarea pro Schueler │
|
||||
│ ├── Textbausteine / Vorlagen │
|
||||
│ └── KI-generierte Vorschlaege (optional) │
|
||||
│ │
|
||||
│ Step 5: Zusammenfassung & Generieren │
|
||||
│ ├── Uebersicht aller Einstellungen │
|
||||
│ ├── Checkbox: Alle Zeugnisse generieren │
|
||||
│ └── Button: Zeugnisse erstellen (mit Fortschrittsbalken) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Seed Data Generator
|
||||
|
||||
Located in: `school-service/internal/seed/`
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Run seed data generation
|
||||
go run cmd/seed/main.go -teacher-id=<teacher-uuid>
|
||||
|
||||
# Or with default teacher ID
|
||||
go run cmd/seed/main.go
|
||||
```
|
||||
|
||||
### Generated Data
|
||||
|
||||
| Entity | Count | Details |
|
||||
|--------|-------|---------|
|
||||
| School Years | 3 | 2022/23, 2023/24, 2024/25 |
|
||||
| Classes per Year | 6 | 5a, 5b, 6a, 6b, 7a, 7b |
|
||||
| Students per Class | 15-25 | Realistic German names |
|
||||
| Subjects | 10 | Deutsch, Mathe, Englisch, ... |
|
||||
| Exams per Class/Subject | 3-5 | With grade distribution |
|
||||
| Attendance Records | Variable | 0-10 absence days |
|
||||
|
||||
### German Name Generator
|
||||
|
||||
```go
|
||||
var firstNames = []string{
|
||||
"Anna", "Emma", "Mia", "Sophie", "Marie", "Lena", "Lea", "Emily",
|
||||
"Ben", "Paul", "Leon", "Luis", "Max", "Felix", "Noah", "Elias", ...
|
||||
}
|
||||
|
||||
var lastNames = []string{
|
||||
"Mueller", "Schmidt", "Schneider", "Fischer", "Weber", "Meyer",
|
||||
"Wagner", "Becker", "Schulz", "Hoffmann", "Koch", "Richter", ...
|
||||
}
|
||||
```
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
school-service/
|
||||
├── cmd/
|
||||
│ ├── server/
|
||||
│ │ └── main.go # Main server with all routes
|
||||
│ └── seed/
|
||||
│ └── main.go # Seed data CLI
|
||||
├── internal/
|
||||
│ ├── config/
|
||||
│ │ └── config.go
|
||||
│ ├── database/
|
||||
│ │ └── database.go
|
||||
│ ├── handlers/
|
||||
│ │ ├── handlers.go # Base handler
|
||||
│ │ ├── grade_handlers.go # Grade + Statistics endpoints
|
||||
│ │ └── certificate_handlers.go
|
||||
│ ├── services/
|
||||
│ │ └── grade_service.go # Statistics calculations
|
||||
│ ├── models/
|
||||
│ │ └── models.go
|
||||
│ └── seed/
|
||||
│ └── seed_data.go # Fake data generator
|
||||
└── go.mod
|
||||
|
||||
backend/frontend/modules/
|
||||
└── school.py # Zeugnis-UI (panel-school-certificates)
|
||||
|
||||
klausur-service/backend/
|
||||
├── rbac.py # RBAC with certificate roles
|
||||
└── tests/
|
||||
└── test_rbac.py # RBAC unit tests
|
||||
```
|
||||
|
||||
## API Routes (School-Service)
|
||||
|
||||
### Grade Management
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/api/v1/school/grades/:classId` | Get class grades |
|
||||
| GET | `/api/v1/school/grades/student/:studentId` | Get student grades |
|
||||
| PUT | `/api/v1/school/grades/:studentId/:subjectId/oral` | Update oral grade |
|
||||
| POST | `/api/v1/school/grades/calculate` | Calculate final grades |
|
||||
| POST | `/api/v1/school/grades/transfer` | Transfer approved grades |
|
||||
| PUT | `/api/v1/school/grades/:studentId/:subjectId/lock` | Lock final grade |
|
||||
| PUT | `/api/v1/school/grades/:studentId/:subjectId/weights` | Update grade weights |
|
||||
|
||||
### Statistics
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/api/v1/school/statistics/:classId` | Class statistics |
|
||||
| GET | `/api/v1/school/statistics/:classId/subject/:subjectId` | Subject statistics |
|
||||
| GET | `/api/v1/school/statistics/student/:studentId` | Student statistics |
|
||||
| GET | `/api/v1/school/statistics/:classId/notenspiegel` | Grade distribution |
|
||||
|
||||
### Certificates
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/api/v1/school/certificates/templates` | List templates |
|
||||
| GET | `/api/v1/school/certificates/class/:classId` | Class certificates |
|
||||
| POST | `/api/v1/school/certificates/generate` | Generate single |
|
||||
| POST | `/api/v1/school/certificates/generate-bulk` | Generate bulk |
|
||||
| GET | `/api/v1/school/certificates/detail/:id` | Get certificate |
|
||||
| PUT | `/api/v1/school/certificates/detail/:id` | Update certificate |
|
||||
| PUT | `/api/v1/school/certificates/detail/:id/finalize` | Finalize |
|
||||
| GET | `/api/v1/school/certificates/detail/:id/pdf` | Download PDF |
|
||||
| DELETE | `/api/v1/school/certificates/detail/:id` | Delete |
|
||||
| GET | `/api/v1/school/certificates/feedback/:studentId` | AI feedback |
|
||||
|
||||
## German Grading System
|
||||
|
||||
| Grade | Meaning | Points |
|
||||
|-------|---------|--------|
|
||||
| 1 | sehr gut (excellent) | 15-13 |
|
||||
| 2 | gut (good) | 12-10 |
|
||||
| 3 | befriedigend (satisfactory) | 9-7 |
|
||||
| 4 | ausreichend (adequate) | 6-4 |
|
||||
| 5 | mangelhaft (poor) | 3-1 |
|
||||
| 6 | ungenuegend (inadequate) | 0 |
|
||||
|
||||
### Grade Calculation
|
||||
|
||||
```
|
||||
Final Grade = (Written Weight * Written Avg) + (Oral Weight * Oral Avg)
|
||||
|
||||
Default weights:
|
||||
- Written (Klassenarbeiten): 50%
|
||||
- Oral (muendliche Note): 50%
|
||||
|
||||
Customizable per subject/student via UpdateGradeWeights endpoint.
|
||||
```
|
||||
|
||||
## Integration with BYOEH
|
||||
|
||||
The Zeugnis system can optionally integrate with BYOEH for:
|
||||
- AI-generated certificate remarks
|
||||
- Template suggestion based on student performance
|
||||
- Feedback text generation (`/certificates/feedback/:studentId`)
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **RBAC Enforcement**: All certificate operations check user role permissions
|
||||
2. **Tenant Isolation**: Teachers only see their own classes/students
|
||||
3. **Audit Trail**: All grade changes and approvals logged
|
||||
4. **Lock Mechanism**: Finalized certificates cannot be modified
|
||||
5. **Workflow Enforcement**: Cannot skip approval steps
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- [ ] PDF template editor (LaTeX/HTML)
|
||||
- [ ] Bundesland-specific templates (all 16 states)
|
||||
- [ ] Kopfnoten (head grades) support
|
||||
- [ ] Digital signatures for certificates
|
||||
- [ ] Parent portal access to certificates
|
||||
- [ ] Archive/retention policies
|
||||
Reference in New Issue
Block a user