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
83 lines
2.7 KiB
Python
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")
|