[interface-change] Phase 4: Extract shared types + fix Docker context
Shared types extracted to shared/types/: - companion.ts (33+ types, was 100% duplicated admin-lehrer ↔ studio-v2) - klausur.ts (18+ types, was 95% duplicated across 4 locations) - ocr-labeling.ts (11 types, was 100% duplicated admin-lehrer ↔ website) Original type files replaced with re-exports for backward compat. tsconfig.json paths updated with @shared/* alias in all 3 services. Docker: Changed build context from ./service to . (root) so shared/ is accessible. Dockerfiles updated to COPY service/ + shared/. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,13 +4,14 @@ FROM node:20-alpine AS builder
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package.json package-lock.json* ./
|
||||
COPY website/package.json website/package-lock.json* ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm install
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
# Copy source code + shared types
|
||||
COPY website/ .
|
||||
COPY shared/ /shared/
|
||||
|
||||
# Build arguments for environment variables
|
||||
ARG NEXT_PUBLIC_BILLING_API_URL
|
||||
|
||||
@@ -1,195 +1 @@
|
||||
// TypeScript Interfaces für Klausur-Korrektur
|
||||
|
||||
export interface Klausur {
|
||||
id: string
|
||||
title: string
|
||||
subject: string
|
||||
year: number
|
||||
semester: string
|
||||
modus: 'abitur' | 'vorabitur'
|
||||
eh_id?: string
|
||||
created_at: string
|
||||
student_count?: number
|
||||
completed_count?: number
|
||||
status?: 'draft' | 'in_progress' | 'completed'
|
||||
}
|
||||
|
||||
export interface StudentWork {
|
||||
id: string
|
||||
klausur_id: string
|
||||
anonym_id: string
|
||||
file_path: string
|
||||
file_type: 'pdf' | 'image'
|
||||
ocr_text: string
|
||||
criteria_scores: CriteriaScores
|
||||
gutachten: string
|
||||
status: StudentStatus
|
||||
raw_points: number
|
||||
grade_points: number
|
||||
grade_label?: string
|
||||
created_at: string
|
||||
examiner_id?: string
|
||||
second_examiner_id?: string
|
||||
second_examiner_grade?: number
|
||||
}
|
||||
|
||||
export type StudentStatus =
|
||||
| 'UPLOADED'
|
||||
| 'OCR_PROCESSING'
|
||||
| 'OCR_COMPLETE'
|
||||
| 'ANALYZING'
|
||||
| 'FIRST_EXAMINER'
|
||||
| 'SECOND_EXAMINER'
|
||||
| 'COMPLETED'
|
||||
| 'ERROR'
|
||||
|
||||
export interface CriteriaScores {
|
||||
rechtschreibung?: number
|
||||
grammatik?: number
|
||||
inhalt?: number
|
||||
struktur?: number
|
||||
stil?: number
|
||||
[key: string]: number | undefined
|
||||
}
|
||||
|
||||
export interface Criterion {
|
||||
id: string
|
||||
name: string
|
||||
weight: number
|
||||
description?: string
|
||||
}
|
||||
|
||||
export interface GradeInfo {
|
||||
thresholds: Record<number, number>
|
||||
labels: Record<number, string>
|
||||
criteria: Record<string, Criterion>
|
||||
}
|
||||
|
||||
export interface Annotation {
|
||||
id: string
|
||||
student_work_id: string
|
||||
page: number
|
||||
position: AnnotationPosition
|
||||
type: AnnotationType
|
||||
text: string
|
||||
severity: 'minor' | 'major' | 'critical'
|
||||
suggestion?: string
|
||||
created_by: string
|
||||
created_at: string
|
||||
role: 'first_examiner' | 'second_examiner'
|
||||
linked_criterion?: string
|
||||
}
|
||||
|
||||
export interface AnnotationPosition {
|
||||
x: number // Prozent (0-100)
|
||||
y: number // Prozent (0-100)
|
||||
width: number // Prozent (0-100)
|
||||
height: number // Prozent (0-100)
|
||||
}
|
||||
|
||||
export type AnnotationType =
|
||||
| 'rechtschreibung'
|
||||
| 'grammatik'
|
||||
| 'inhalt'
|
||||
| 'struktur'
|
||||
| 'stil'
|
||||
| 'comment'
|
||||
| 'highlight'
|
||||
|
||||
export interface FairnessAnalysis {
|
||||
klausur_id: string
|
||||
student_count: number
|
||||
average_grade: number
|
||||
std_deviation: number
|
||||
spread: number
|
||||
outliers: OutlierInfo[]
|
||||
criteria_analysis: Record<string, CriteriaStats>
|
||||
fairness_score: number
|
||||
warnings: string[]
|
||||
}
|
||||
|
||||
export interface OutlierInfo {
|
||||
student_id: string
|
||||
anonym_id: string
|
||||
grade_points: number
|
||||
deviation: number
|
||||
reason: string
|
||||
}
|
||||
|
||||
export interface CriteriaStats {
|
||||
min: number
|
||||
max: number
|
||||
average: number
|
||||
std_deviation: number
|
||||
}
|
||||
|
||||
export interface EHSuggestion {
|
||||
criterion: string
|
||||
excerpt: string
|
||||
relevance_score: number
|
||||
source_chunk_id: string
|
||||
}
|
||||
|
||||
export interface GutachtenSection {
|
||||
title: string
|
||||
content: string
|
||||
evidence_links?: string[]
|
||||
}
|
||||
|
||||
export interface Gutachten {
|
||||
einleitung: string
|
||||
hauptteil: string
|
||||
fazit: string
|
||||
staerken: string[]
|
||||
schwaechen: string[]
|
||||
generated_at?: string
|
||||
}
|
||||
|
||||
// API Response Types
|
||||
export interface KlausurenResponse {
|
||||
klausuren: Klausur[]
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface StudentsResponse {
|
||||
students: StudentWork[]
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface AnnotationsResponse {
|
||||
annotations: Annotation[]
|
||||
}
|
||||
|
||||
// Color mapping for annotation types
|
||||
export const ANNOTATION_COLORS: Record<AnnotationType, string> = {
|
||||
rechtschreibung: '#dc2626', // Red
|
||||
grammatik: '#2563eb', // Blue
|
||||
inhalt: '#16a34a', // Green
|
||||
struktur: '#9333ea', // Purple
|
||||
stil: '#ea580c', // Orange
|
||||
comment: '#6b7280', // Gray
|
||||
highlight: '#eab308', // Yellow
|
||||
}
|
||||
|
||||
// Status colors
|
||||
export const STATUS_COLORS: Record<StudentStatus, string> = {
|
||||
UPLOADED: '#6b7280',
|
||||
OCR_PROCESSING: '#eab308',
|
||||
OCR_COMPLETE: '#3b82f6',
|
||||
ANALYZING: '#8b5cf6',
|
||||
FIRST_EXAMINER: '#f97316',
|
||||
SECOND_EXAMINER: '#06b6d4',
|
||||
COMPLETED: '#22c55e',
|
||||
ERROR: '#ef4444',
|
||||
}
|
||||
|
||||
export const STATUS_LABELS: Record<StudentStatus, string> = {
|
||||
UPLOADED: 'Hochgeladen',
|
||||
OCR_PROCESSING: 'OCR läuft',
|
||||
OCR_COMPLETE: 'OCR fertig',
|
||||
ANALYZING: 'Analyse läuft',
|
||||
FIRST_EXAMINER: 'Erstkorrektur',
|
||||
SECOND_EXAMINER: 'Zweitkorrektur',
|
||||
COMPLETED: 'Abgeschlossen',
|
||||
ERROR: 'Fehler',
|
||||
}
|
||||
export * from '../../../../shared/types/klausur'
|
||||
|
||||
@@ -1,123 +1 @@
|
||||
/**
|
||||
* TypeScript types for OCR Labeling UI
|
||||
*/
|
||||
|
||||
/**
|
||||
* Available OCR Models
|
||||
*
|
||||
* - llama3.2-vision:11b: Vision LLM, beste Qualitaet bei Handschrift (Standard)
|
||||
* - trocr: Microsoft TrOCR, schnell bei gedrucktem Text
|
||||
* - paddleocr: PaddleOCR + LLM, 4x schneller durch Hybrid-Ansatz
|
||||
* - donut: Document Understanding Transformer, strukturierte Dokumente
|
||||
*/
|
||||
export type OCRModel = 'llama3.2-vision:11b' | 'trocr' | 'paddleocr' | 'donut'
|
||||
|
||||
export const OCR_MODEL_INFO: Record<OCRModel, { label: string; description: string; speed: string }> = {
|
||||
'llama3.2-vision:11b': {
|
||||
label: 'Vision LLM',
|
||||
description: 'Beste Qualitaet bei Handschrift',
|
||||
speed: 'langsam',
|
||||
},
|
||||
trocr: {
|
||||
label: 'Microsoft TrOCR',
|
||||
description: 'Schnell bei gedrucktem Text',
|
||||
speed: 'schnell',
|
||||
},
|
||||
paddleocr: {
|
||||
label: 'PaddleOCR + LLM',
|
||||
description: 'Hybrid-Ansatz: OCR + Strukturierung',
|
||||
speed: 'sehr schnell',
|
||||
},
|
||||
donut: {
|
||||
label: 'Donut',
|
||||
description: 'Document Understanding fuer Tabellen/Formulare',
|
||||
speed: 'mittel',
|
||||
},
|
||||
}
|
||||
|
||||
export interface OCRSession {
|
||||
id: string
|
||||
name: string
|
||||
source_type: 'klausur' | 'handwriting_sample' | 'scan'
|
||||
description?: string
|
||||
ocr_model?: OCRModel
|
||||
total_items: number
|
||||
labeled_items: number
|
||||
confirmed_items: number
|
||||
corrected_items: number
|
||||
skipped_items: number
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface OCRItem {
|
||||
id: string
|
||||
session_id: string
|
||||
session_name: string
|
||||
image_path: string
|
||||
image_url?: string
|
||||
ocr_text?: string
|
||||
ocr_confidence?: number
|
||||
ground_truth?: string
|
||||
status: 'pending' | 'confirmed' | 'corrected' | 'skipped'
|
||||
metadata?: Record<string, unknown>
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface OCRStats {
|
||||
total_sessions?: number
|
||||
session_id?: string
|
||||
name?: string
|
||||
total_items: number
|
||||
labeled_items: number
|
||||
confirmed_items: number
|
||||
corrected_items: number
|
||||
skipped_items?: number
|
||||
pending_items: number
|
||||
exportable_items?: number
|
||||
accuracy_rate: number
|
||||
avg_label_time_seconds?: number
|
||||
progress_percent?: number
|
||||
}
|
||||
|
||||
export interface TrainingSample {
|
||||
id: string
|
||||
image_path: string
|
||||
ground_truth: string
|
||||
export_format: 'generic' | 'trocr' | 'llama_vision'
|
||||
training_batch: string
|
||||
exported_at?: string
|
||||
}
|
||||
|
||||
export interface CreateSessionRequest {
|
||||
name: string
|
||||
source_type: 'klausur' | 'handwriting_sample' | 'scan'
|
||||
description?: string
|
||||
ocr_model?: OCRModel
|
||||
}
|
||||
|
||||
export interface ConfirmRequest {
|
||||
item_id: string
|
||||
label_time_seconds?: number
|
||||
}
|
||||
|
||||
export interface CorrectRequest {
|
||||
item_id: string
|
||||
ground_truth: string
|
||||
label_time_seconds?: number
|
||||
}
|
||||
|
||||
export interface ExportRequest {
|
||||
export_format: 'generic' | 'trocr' | 'llama_vision'
|
||||
session_id?: string
|
||||
batch_id?: string
|
||||
}
|
||||
|
||||
export interface UploadResult {
|
||||
id: string
|
||||
filename: string
|
||||
image_path: string
|
||||
image_hash: string
|
||||
ocr_text?: string
|
||||
ocr_confidence?: number
|
||||
status: string
|
||||
}
|
||||
export * from '../../../../shared/types/ocr-labeling'
|
||||
|
||||
@@ -1,195 +1 @@
|
||||
// TypeScript Interfaces für Klausur-Korrektur
|
||||
|
||||
export interface Klausur {
|
||||
id: string
|
||||
title: string
|
||||
subject: string
|
||||
year: number
|
||||
semester: string
|
||||
modus: 'abitur' | 'vorabitur'
|
||||
eh_id?: string
|
||||
created_at: string
|
||||
student_count?: number
|
||||
completed_count?: number
|
||||
status?: 'draft' | 'in_progress' | 'completed'
|
||||
}
|
||||
|
||||
export interface StudentWork {
|
||||
id: string
|
||||
klausur_id: string
|
||||
anonym_id: string
|
||||
file_path: string
|
||||
file_type: 'pdf' | 'image'
|
||||
ocr_text: string
|
||||
criteria_scores: CriteriaScores
|
||||
gutachten: string
|
||||
status: StudentStatus
|
||||
raw_points: number
|
||||
grade_points: number
|
||||
grade_label?: string
|
||||
created_at: string
|
||||
examiner_id?: string
|
||||
second_examiner_id?: string
|
||||
second_examiner_grade?: number
|
||||
}
|
||||
|
||||
export type StudentStatus =
|
||||
| 'UPLOADED'
|
||||
| 'OCR_PROCESSING'
|
||||
| 'OCR_COMPLETE'
|
||||
| 'ANALYZING'
|
||||
| 'FIRST_EXAMINER'
|
||||
| 'SECOND_EXAMINER'
|
||||
| 'COMPLETED'
|
||||
| 'ERROR'
|
||||
|
||||
export interface CriteriaScores {
|
||||
rechtschreibung?: number
|
||||
grammatik?: number
|
||||
inhalt?: number
|
||||
struktur?: number
|
||||
stil?: number
|
||||
[key: string]: number | undefined
|
||||
}
|
||||
|
||||
export interface Criterion {
|
||||
id: string
|
||||
name: string
|
||||
weight: number
|
||||
description?: string
|
||||
}
|
||||
|
||||
export interface GradeInfo {
|
||||
thresholds: Record<number, number>
|
||||
labels: Record<number, string>
|
||||
criteria: Record<string, Criterion>
|
||||
}
|
||||
|
||||
export interface Annotation {
|
||||
id: string
|
||||
student_work_id: string
|
||||
page: number
|
||||
position: AnnotationPosition
|
||||
type: AnnotationType
|
||||
text: string
|
||||
severity: 'minor' | 'major' | 'critical'
|
||||
suggestion?: string
|
||||
created_by: string
|
||||
created_at: string
|
||||
role: 'first_examiner' | 'second_examiner'
|
||||
linked_criterion?: string
|
||||
}
|
||||
|
||||
export interface AnnotationPosition {
|
||||
x: number // Prozent (0-100)
|
||||
y: number // Prozent (0-100)
|
||||
width: number // Prozent (0-100)
|
||||
height: number // Prozent (0-100)
|
||||
}
|
||||
|
||||
export type AnnotationType =
|
||||
| 'rechtschreibung'
|
||||
| 'grammatik'
|
||||
| 'inhalt'
|
||||
| 'struktur'
|
||||
| 'stil'
|
||||
| 'comment'
|
||||
| 'highlight'
|
||||
|
||||
export interface FairnessAnalysis {
|
||||
klausur_id: string
|
||||
student_count: number
|
||||
average_grade: number
|
||||
std_deviation: number
|
||||
spread: number
|
||||
outliers: OutlierInfo[]
|
||||
criteria_analysis: Record<string, CriteriaStats>
|
||||
fairness_score: number
|
||||
warnings: string[]
|
||||
}
|
||||
|
||||
export interface OutlierInfo {
|
||||
student_id: string
|
||||
anonym_id: string
|
||||
grade_points: number
|
||||
deviation: number
|
||||
reason: string
|
||||
}
|
||||
|
||||
export interface CriteriaStats {
|
||||
min: number
|
||||
max: number
|
||||
average: number
|
||||
std_deviation: number
|
||||
}
|
||||
|
||||
export interface EHSuggestion {
|
||||
criterion: string
|
||||
excerpt: string
|
||||
relevance_score: number
|
||||
source_chunk_id: string
|
||||
}
|
||||
|
||||
export interface GutachtenSection {
|
||||
title: string
|
||||
content: string
|
||||
evidence_links?: string[]
|
||||
}
|
||||
|
||||
export interface Gutachten {
|
||||
einleitung: string
|
||||
hauptteil: string
|
||||
fazit: string
|
||||
staerken: string[]
|
||||
schwaechen: string[]
|
||||
generated_at?: string
|
||||
}
|
||||
|
||||
// API Response Types
|
||||
export interface KlausurenResponse {
|
||||
klausuren: Klausur[]
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface StudentsResponse {
|
||||
students: StudentWork[]
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface AnnotationsResponse {
|
||||
annotations: Annotation[]
|
||||
}
|
||||
|
||||
// Color mapping for annotation types
|
||||
export const ANNOTATION_COLORS: Record<AnnotationType, string> = {
|
||||
rechtschreibung: '#dc2626', // Red
|
||||
grammatik: '#2563eb', // Blue
|
||||
inhalt: '#16a34a', // Green
|
||||
struktur: '#9333ea', // Purple
|
||||
stil: '#ea580c', // Orange
|
||||
comment: '#6b7280', // Gray
|
||||
highlight: '#eab308', // Yellow
|
||||
}
|
||||
|
||||
// Status colors
|
||||
export const STATUS_COLORS: Record<StudentStatus, string> = {
|
||||
UPLOADED: '#6b7280',
|
||||
OCR_PROCESSING: '#eab308',
|
||||
OCR_COMPLETE: '#3b82f6',
|
||||
ANALYZING: '#8b5cf6',
|
||||
FIRST_EXAMINER: '#f97316',
|
||||
SECOND_EXAMINER: '#06b6d4',
|
||||
COMPLETED: '#22c55e',
|
||||
ERROR: '#ef4444',
|
||||
}
|
||||
|
||||
export const STATUS_LABELS: Record<StudentStatus, string> = {
|
||||
UPLOADED: 'Hochgeladen',
|
||||
OCR_PROCESSING: 'OCR läuft',
|
||||
OCR_COMPLETE: 'OCR fertig',
|
||||
ANALYZING: 'Analyse läuft',
|
||||
FIRST_EXAMINER: 'Erstkorrektur',
|
||||
SECOND_EXAMINER: 'Zweitkorrektur',
|
||||
COMPLETED: 'Abgeschlossen',
|
||||
ERROR: 'Fehler',
|
||||
}
|
||||
export * from '../../../../shared/types/klausur'
|
||||
|
||||
@@ -1,39 +1,17 @@
|
||||
/**
|
||||
* Types and constants for the Klausur-Korrektur list page.
|
||||
* Shared between admin and lehrer routes.
|
||||
*
|
||||
* Domain types are re-exported from the shared module.
|
||||
* Only the API_BASE constant remains local (env-dependent).
|
||||
*/
|
||||
|
||||
export type {
|
||||
TabId,
|
||||
CreateKlausurForm,
|
||||
VorabiturEHForm,
|
||||
EHTemplate,
|
||||
DirektuploadForm,
|
||||
} from '../../../shared/types/klausur'
|
||||
|
||||
export const API_BASE = process.env.NEXT_PUBLIC_KLAUSUR_SERVICE_URL || 'http://localhost:8086'
|
||||
|
||||
export type TabId = 'willkommen' | 'klausuren' | 'erstellen' | 'direktupload' | 'statistiken'
|
||||
|
||||
export interface CreateKlausurForm {
|
||||
title: string
|
||||
subject: string
|
||||
year: number
|
||||
semester: string
|
||||
modus: 'abitur' | 'vorabitur'
|
||||
}
|
||||
|
||||
export interface VorabiturEHForm {
|
||||
aufgabentyp: string
|
||||
titel: string
|
||||
text_titel: string
|
||||
text_autor: string
|
||||
aufgabenstellung: string
|
||||
}
|
||||
|
||||
export interface EHTemplate {
|
||||
aufgabentyp: string
|
||||
name: string
|
||||
description: string
|
||||
category: string
|
||||
}
|
||||
|
||||
export interface DirektuploadForm {
|
||||
files: File[]
|
||||
ehFile: File | null
|
||||
ehText: string
|
||||
aufgabentyp: string
|
||||
klausurTitle: string
|
||||
}
|
||||
|
||||
@@ -1,81 +1,23 @@
|
||||
/**
|
||||
* Types and constants for the Korrektur-Workspace.
|
||||
* Shared between admin and lehrer routes.
|
||||
*
|
||||
* Domain types are re-exported from the shared module.
|
||||
* Only the API_BASE constant remains local (env-dependent).
|
||||
*/
|
||||
|
||||
import type { CriteriaScores } from '../../app/admin/klausur-korrektur/types'
|
||||
export type {
|
||||
ExaminerInfo,
|
||||
ExaminerResult,
|
||||
ExaminerWorkflow,
|
||||
ActiveTab,
|
||||
CriteriaScores,
|
||||
} from '../../../shared/types/klausur'
|
||||
|
||||
// Examiner workflow types
|
||||
export interface ExaminerInfo {
|
||||
id: string
|
||||
assigned_at: string
|
||||
notes?: string
|
||||
}
|
||||
|
||||
export interface ExaminerResult {
|
||||
grade_points: number
|
||||
criteria_scores?: CriteriaScores
|
||||
notes?: string
|
||||
submitted_at: string
|
||||
}
|
||||
|
||||
export interface ExaminerWorkflow {
|
||||
student_id: string
|
||||
workflow_status: string
|
||||
visibility_mode: string
|
||||
user_role: 'ek' | 'zk' | 'dk' | 'viewer'
|
||||
first_examiner?: ExaminerInfo
|
||||
second_examiner?: ExaminerInfo
|
||||
third_examiner?: ExaminerInfo
|
||||
first_result?: ExaminerResult
|
||||
first_result_visible?: boolean
|
||||
second_result?: ExaminerResult
|
||||
third_result?: ExaminerResult
|
||||
grade_difference?: number
|
||||
final_grade?: number
|
||||
consensus_reached?: boolean
|
||||
consensus_type?: string
|
||||
einigung?: {
|
||||
final_grade: number
|
||||
notes: string
|
||||
type: string
|
||||
submitted_by: string
|
||||
submitted_at: string
|
||||
ek_grade: number
|
||||
zk_grade: number
|
||||
}
|
||||
drittkorrektur_reason?: string
|
||||
}
|
||||
|
||||
export type ActiveTab = 'kriterien' | 'gutachten' | 'annotationen' | 'eh-vorschlaege'
|
||||
|
||||
// Workflow status labels
|
||||
export const WORKFLOW_STATUS_LABELS: Record<string, { label: string; color: string }> = {
|
||||
not_started: { label: 'Nicht gestartet', color: 'bg-slate-100 text-slate-700' },
|
||||
ek_in_progress: { label: 'EK in Arbeit', color: 'bg-blue-100 text-blue-700' },
|
||||
ek_completed: { label: 'EK abgeschlossen', color: 'bg-blue-200 text-blue-800' },
|
||||
zk_assigned: { label: 'ZK zugewiesen', color: 'bg-amber-100 text-amber-700' },
|
||||
zk_in_progress: { label: 'ZK in Arbeit', color: 'bg-amber-200 text-amber-800' },
|
||||
zk_completed: { label: 'ZK abgeschlossen', color: 'bg-amber-300 text-amber-900' },
|
||||
einigung_required: { label: 'Einigung erforderlich', color: 'bg-orange-100 text-orange-700' },
|
||||
einigung_completed: { label: 'Einigung abgeschlossen', color: 'bg-green-100 text-green-700' },
|
||||
drittkorrektur_required: { label: 'DK erforderlich', color: 'bg-red-100 text-red-700' },
|
||||
drittkorrektur_assigned: { label: 'DK zugewiesen', color: 'bg-red-200 text-red-800' },
|
||||
drittkorrektur_in_progress: { label: 'DK in Arbeit', color: 'bg-red-300 text-red-900' },
|
||||
completed: { label: 'Abgeschlossen', color: 'bg-green-200 text-green-800' },
|
||||
}
|
||||
|
||||
export const ROLE_LABELS: Record<string, { label: string; color: string }> = {
|
||||
ek: { label: 'Erstkorrektor', color: 'bg-blue-500' },
|
||||
zk: { label: 'Zweitkorrektor', color: 'bg-amber-500' },
|
||||
dk: { label: 'Drittkorrektor', color: 'bg-purple-500' },
|
||||
viewer: { label: 'Betrachter', color: 'bg-slate-500' },
|
||||
}
|
||||
export {
|
||||
WORKFLOW_STATUS_LABELS,
|
||||
ROLE_LABELS,
|
||||
GRADE_LABELS,
|
||||
} from '../../../shared/types/klausur'
|
||||
|
||||
export const API_BASE = process.env.NEXT_PUBLIC_KLAUSUR_SERVICE_URL || 'http://localhost:8086'
|
||||
|
||||
export const GRADE_LABELS: Record<number, string> = {
|
||||
15: '1+', 14: '1', 13: '1-', 12: '2+', 11: '2', 10: '2-',
|
||||
9: '3+', 8: '3', 7: '3-', 6: '4+', 5: '4', 4: '4-',
|
||||
3: '5+', 2: '5', 1: '5-', 0: '6',
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./*"
|
||||
],
|
||||
"@shared/*": [
|
||||
"../shared/*"
|
||||
]
|
||||
},
|
||||
"target": "ES2017"
|
||||
|
||||
Reference in New Issue
Block a user