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
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""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")
|
||||
Reference in New Issue
Block a user