Files
MABEA/backend/alembic/versions/0022_wartung.py
T
patrickandClaude Sonnet 5 2a4d391711
CI / backend-tests (push) Failing after 2m4s
CI / frontend-build (push) Successful in 18s
feat(maintenance): MAINT-Epic (Wartungspläne/-aufträge, Werkstatt) + Akte-Redesign
Neues Wartungskonzept: Wartungsplan+Position+Intervall (zeit/km/
Betriebsstunden, kombinierbar - fällig sobald ein Kriterium erreicht
ist), Wartungsauftrag mit intern/externer Werkstatt, Status offen/
in_arbeit/erledigt, Kosten, Historie, Dokument-Anhang. Ad-hoc-Aufträge
ohne Plan möglich (z.B. kleinere Reparatur). Admin-Tab "Wartungspläne".

Objektakte-Redesign (Epic 21, Nutzer-Feedback "wirkt nicht modern"):
CSS-Grid statt Karten-Stapel, einspaltig mobil, zweispaltig ab 900px;
Fahrzeug-Objekte zeigen Wartung/Fahrzeugdaten prominent, Geräte/
Rucksäcke die Beladung. Dabei gefundene Lücke: Beladung (Soll/Ist je
Position) fehlte in der Akte komplett, nur über eine laufende
Kontrolle sichtbar - jetzt eigene Karte.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-06 23:17:39 +02:00

83 lines
2.7 KiB
Python

"""MAINT-001..006: Wartungsplaene, Intervalle, Wartungsauftraege.
Revision ID: 0022_wartung
Revises: 0021_ausgabe
Create Date: 2026-09-06
"""
from typing import Sequence, Union
from alembic import op
revision: str = "0022_wartung"
down_revision: Union[str, None] = "0021_ausgabe"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.execute("CREATE TYPE intervall_typ AS ENUM ('zeit', 'km', 'betriebsstunden')")
op.execute("CREATE TYPE wartungsauftrag_status AS ENUM ('offen', 'in_arbeit', 'erledigt')")
op.execute(
"""
CREATE TABLE wartungsplan (
id SERIAL PRIMARY KEY,
objekttyp_id INTEGER NOT NULL REFERENCES objekttyp(id),
name TEXT NOT NULL
)
"""
)
op.execute(
"""
CREATE TABLE wartungsplan_position (
id SERIAL PRIMARY KEY,
wartungsplan_id INTEGER NOT NULL REFERENCES wartungsplan(id),
wartungsart TEXT NOT NULL,
beschreibung TEXT
)
"""
)
op.execute(
"""
CREATE TABLE wartungsintervall (
id SERIAL PRIMARY KEY,
wartungsplan_position_id INTEGER NOT NULL REFERENCES wartungsplan_position(id),
typ intervall_typ NOT NULL,
wert INTEGER NOT NULL
)
"""
)
op.execute(
"""
CREATE TABLE wartungsauftrag (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
objekt_id INTEGER NOT NULL REFERENCES objekt(id),
geraet_instanz_id UUID REFERENCES geraet_instanz(id),
wartungsplan_position_id INTEGER REFERENCES wartungsplan_position(id),
wartungsart TEXT NOT NULL,
beschreibung TEXT,
status wartungsauftrag_status NOT NULL DEFAULT 'offen',
werkstatt_intern BOOLEAN NOT NULL DEFAULT TRUE,
werkstatt_name TEXT,
faelligkeit_am DATE,
erstellt_am TIMESTAMPTZ NOT NULL,
erledigt_am TIMESTAMPTZ,
durchgefuehrt_von INTEGER REFERENCES benutzer(id),
kosten NUMERIC,
kilometerstand_bei_erledigung INTEGER,
betriebsstunden_bei_erledigung NUMERIC
)
"""
)
op.execute("CREATE INDEX idx_wartungsauftrag_objekt ON wartungsauftrag (objekt_id)")
op.execute("CREATE INDEX idx_wartungsauftrag_status ON wartungsauftrag (status)")
def downgrade() -> None:
op.execute("DROP TABLE wartungsauftrag")
op.execute("DROP TABLE wartungsintervall")
op.execute("DROP TABLE wartungsplan_position")
op.execute("DROP TABLE wartungsplan")
op.execute("DROP TYPE wartungsauftrag_status")
op.execute("DROP TYPE intervall_typ")