Files
breakpilot-core/bpmn-processes/klausur-korrektur.bpmn
Benjamin Boenisch ad111d5e69 Initial commit: breakpilot-core - Shared Infrastructure
Docker Compose with 24+ services:
- PostgreSQL (PostGIS), Valkey, MinIO, Qdrant
- Vault (PKI/TLS), Nginx (Reverse Proxy)
- Backend Core API, Consent Service, Billing Service
- RAG Service, Embedding Service
- Gitea, Woodpecker CI/CD
- Night Scheduler, Health Aggregator
- Jitsi (Web/XMPP/JVB/Jicofo), Mailpit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:13 +01:00

216 lines
11 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
id="Definitions_Klausur"
targetNamespace="http://breakpilot.de/bpmn/klausur">
<bpmn:process id="KlausurKorrekturProcess" name="Klausurkorrektur Workflow" isExecutable="true">
<!-- Start Event -->
<bpmn:startEvent id="start" name="Klausuren hochgeladen">
<bpmn:outgoing>flow_to_ocr</bpmn:outgoing>
</bpmn:startEvent>
<!-- Service Task: OCR Verarbeitung -->
<bpmn:serviceTask id="ocr_processing" name="OCR Verarbeitung" camunda:delegateExpression="${ocrProcessingDelegate}">
<bpmn:incoming>flow_to_ocr</bpmn:incoming>
<bpmn:outgoing>flow_to_quality_check</bpmn:outgoing>
</bpmn:serviceTask>
<!-- Service Task: Qualitaets-Check -->
<bpmn:serviceTask id="quality_check" name="OCR Qualitaets-Check" camunda:delegateExpression="${ocrQualityCheckDelegate}">
<bpmn:incoming>flow_to_quality_check</bpmn:incoming>
<bpmn:outgoing>flow_to_quality_gateway</bpmn:outgoing>
</bpmn:serviceTask>
<!-- Gateway: OCR Qualitaet ausreichend? -->
<bpmn:exclusiveGateway id="quality_gateway" name="OCR Qualitaet OK?">
<bpmn:incoming>flow_to_quality_gateway</bpmn:incoming>
<bpmn:outgoing>flow_quality_ok</bpmn:outgoing>
<bpmn:outgoing>flow_quality_bad</bpmn:outgoing>
</bpmn:exclusiveGateway>
<!-- User Task: Manuelle Nachbearbeitung -->
<bpmn:userTask id="manual_ocr_fix" name="Manuelle OCR-Korrektur" camunda:assignee="${teacherId}">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="correctedText" label="Korrigierter Text" type="string" />
</camunda:formData>
</bpmn:extensionElements>
<bpmn:incoming>flow_quality_bad</bpmn:incoming>
<bpmn:outgoing>flow_from_manual_fix</bpmn:outgoing>
</bpmn:userTask>
<!-- User Task: Erwartungshorizont definieren -->
<bpmn:userTask id="define_expectations" name="Erwartungshorizont" camunda:assignee="${teacherId}">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="criteria" label="Bewertungskriterien" type="string" />
<camunda:formField id="maxPoints" label="Maximale Punktzahl" type="long" />
<camunda:formField id="useTemplate" label="Template verwenden" type="boolean" />
</camunda:formData>
</bpmn:extensionElements>
<bpmn:incoming>flow_quality_ok</bpmn:incoming>
<bpmn:incoming>flow_from_manual_fix</bpmn:incoming>
<bpmn:outgoing>flow_to_ai_grading</bpmn:outgoing>
</bpmn:userTask>
<!-- Service Task: AI Bewertung -->
<bpmn:serviceTask id="ai_grading" name="AI-Bewertung (Claude)" camunda:delegateExpression="${aiGradingDelegate}">
<bpmn:incoming>flow_to_ai_grading</bpmn:incoming>
<bpmn:outgoing>flow_to_teacher_review</bpmn:outgoing>
</bpmn:serviceTask>
<!-- User Task: Lehrer-Review -->
<bpmn:userTask id="teacher_review" name="Lehrer-Review" camunda:assignee="${teacherId}">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="adjustedGrade" label="Angepasste Bewertung" type="long" />
<camunda:formField id="comments" label="Kommentare" type="string" />
<camunda:formField id="approved" label="Bewertung final" type="boolean" />
</camunda:formData>
</bpmn:extensionElements>
<bpmn:incoming>flow_to_teacher_review</bpmn:incoming>
<bpmn:outgoing>flow_to_review_gateway</bpmn:outgoing>
</bpmn:userTask>
<!-- Gateway: Review abgeschlossen? -->
<bpmn:exclusiveGateway id="review_gateway" name="Review OK?">
<bpmn:incoming>flow_to_review_gateway</bpmn:incoming>
<bpmn:outgoing>flow_review_ok</bpmn:outgoing>
<bpmn:outgoing>flow_review_adjust</bpmn:outgoing>
</bpmn:exclusiveGateway>
<!-- Service Task: Noten berechnen -->
<bpmn:serviceTask id="calculate_grades" name="Noten berechnen" camunda:delegateExpression="${calculateGradesDelegate}">
<bpmn:incoming>flow_review_ok</bpmn:incoming>
<bpmn:outgoing>flow_to_gradebook</bpmn:outgoing>
</bpmn:serviceTask>
<!-- Service Task: In Notenbuch uebertragen -->
<bpmn:serviceTask id="update_gradebook" name="Notenbuch aktualisieren" camunda:delegateExpression="${updateGradebookDelegate}">
<bpmn:incoming>flow_to_gradebook</bpmn:incoming>
<bpmn:outgoing>flow_to_export</bpmn:outgoing>
</bpmn:serviceTask>
<!-- Service Task: Export generieren -->
<bpmn:serviceTask id="generate_export" name="Export generieren" camunda:delegateExpression="${generateExportDelegate}">
<bpmn:incoming>flow_to_export</bpmn:incoming>
<bpmn:outgoing>flow_to_notify_gateway</bpmn:outgoing>
</bpmn:serviceTask>
<!-- Gateway: Eltern benachrichtigen? -->
<bpmn:exclusiveGateway id="notify_gateway" name="Eltern benachrichtigen?">
<bpmn:incoming>flow_to_notify_gateway</bpmn:incoming>
<bpmn:outgoing>flow_notify_yes</bpmn:outgoing>
<bpmn:outgoing>flow_notify_no</bpmn:outgoing>
</bpmn:exclusiveGateway>
<!-- Service Task: Eltern benachrichtigen -->
<bpmn:serviceTask id="notify_parents" name="Eltern benachrichtigen" camunda:delegateExpression="${notifyParentsDelegate}">
<bpmn:incoming>flow_notify_yes</bpmn:incoming>
<bpmn:outgoing>flow_from_notify</bpmn:outgoing>
</bpmn:serviceTask>
<!-- Service Task: Archivieren -->
<bpmn:serviceTask id="archive_exam" name="Klausur archivieren" camunda:delegateExpression="${archiveExamDelegate}">
<bpmn:incoming>flow_notify_no</bpmn:incoming>
<bpmn:incoming>flow_from_notify</bpmn:incoming>
<bpmn:outgoing>flow_to_end</bpmn:outgoing>
</bpmn:serviceTask>
<!-- End Event -->
<bpmn:endEvent id="end" name="Korrektur abgeschlossen">
<bpmn:incoming>flow_to_end</bpmn:incoming>
</bpmn:endEvent>
<!-- Boundary Timer: Korrektur-Deadline -->
<bpmn:boundaryEvent id="correction_deadline" attachedToRef="teacher_review" cancelActivity="false">
<bpmn:timerEventDefinition>
<bpmn:timeDuration>P${correctionDeadlineDays}D</bpmn:timeDuration>
</bpmn:timerEventDefinition>
<bpmn:outgoing>flow_deadline_warning</bpmn:outgoing>
</bpmn:boundaryEvent>
<!-- Service Task: Deadline-Warnung -->
<bpmn:serviceTask id="deadline_warning" name="Deadline-Warnung" camunda:delegateExpression="${deadlineWarningDelegate}">
<bpmn:incoming>flow_deadline_warning</bpmn:incoming>
</bpmn:serviceTask>
<!-- Sequence Flows -->
<bpmn:sequenceFlow id="flow_to_ocr" sourceRef="start" targetRef="ocr_processing" />
<bpmn:sequenceFlow id="flow_to_quality_check" sourceRef="ocr_processing" targetRef="quality_check" />
<bpmn:sequenceFlow id="flow_to_quality_gateway" sourceRef="quality_check" targetRef="quality_gateway" />
<bpmn:sequenceFlow id="flow_quality_ok" sourceRef="quality_gateway" targetRef="define_expectations">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${ocrConfidence >= 0.85}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="flow_quality_bad" sourceRef="quality_gateway" targetRef="manual_ocr_fix">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${ocrConfidence &lt; 0.85}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="flow_from_manual_fix" sourceRef="manual_ocr_fix" targetRef="define_expectations" />
<bpmn:sequenceFlow id="flow_to_ai_grading" sourceRef="define_expectations" targetRef="ai_grading" />
<bpmn:sequenceFlow id="flow_to_teacher_review" sourceRef="ai_grading" targetRef="teacher_review" />
<bpmn:sequenceFlow id="flow_to_review_gateway" sourceRef="teacher_review" targetRef="review_gateway" />
<bpmn:sequenceFlow id="flow_review_ok" sourceRef="review_gateway" targetRef="calculate_grades">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${approved == true}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="flow_review_adjust" sourceRef="review_gateway" targetRef="ai_grading">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${approved == false}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="flow_to_gradebook" sourceRef="calculate_grades" targetRef="update_gradebook" />
<bpmn:sequenceFlow id="flow_to_export" sourceRef="update_gradebook" targetRef="generate_export" />
<bpmn:sequenceFlow id="flow_to_notify_gateway" sourceRef="generate_export" targetRef="notify_gateway" />
<bpmn:sequenceFlow id="flow_notify_yes" sourceRef="notify_gateway" targetRef="notify_parents">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${notifyParents == true}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="flow_notify_no" sourceRef="notify_gateway" targetRef="archive_exam">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${notifyParents == false}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="flow_from_notify" sourceRef="notify_parents" targetRef="archive_exam" />
<bpmn:sequenceFlow id="flow_to_end" sourceRef="archive_exam" targetRef="end" />
<bpmn:sequenceFlow id="flow_deadline_warning" sourceRef="correction_deadline" targetRef="deadline_warning" />
</bpmn:process>
<!-- BPMN Diagram -->
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="KlausurKorrekturProcess">
<bpmndi:BPMNShape id="start_di" bpmnElement="start">
<dc:Bounds x="152" y="102" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ocr_processing_di" bpmnElement="ocr_processing">
<dc:Bounds x="240" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="quality_check_di" bpmnElement="quality_check">
<dc:Bounds x="390" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="quality_gateway_di" bpmnElement="quality_gateway" isMarkerVisible="true">
<dc:Bounds x="545" y="95" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="manual_ocr_fix_di" bpmnElement="manual_ocr_fix">
<dc:Bounds x="520" y="200" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="define_expectations_di" bpmnElement="define_expectations">
<dc:Bounds x="650" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ai_grading_di" bpmnElement="ai_grading">
<dc:Bounds x="800" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="teacher_review_di" bpmnElement="teacher_review">
<dc:Bounds x="950" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="calculate_grades_di" bpmnElement="calculate_grades">
<dc:Bounds x="1100" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_di" bpmnElement="end">
<dc:Bounds x="1702" y="102" width="36" height="36" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>