Add Qualifications module - DB schema, roadmap
This commit is contained in:
251
MODULES_ROADMAP.md
Normal file
251
MODULES_ROADMAP.md
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
# SeCu Module Roadmap
|
||||||
|
|
||||||
|
## Modulares Preismodell
|
||||||
|
|
||||||
|
### 🆓 Basis (kostenlos/Grundpreis)
|
||||||
|
- Mitarbeiterverwaltung
|
||||||
|
- Benutzerverwaltung (Chef, Disponent, Mitarbeiter)
|
||||||
|
- Einstellungen & Profil
|
||||||
|
- Hilfe-System
|
||||||
|
|
||||||
|
### 💰 Premium-Module (Aufpreis)
|
||||||
|
|
||||||
|
| Modul | Priorität | Beschreibung |
|
||||||
|
|-------|-----------|--------------|
|
||||||
|
| **Aufträge** | ⭐⭐⭐ | Auftragsverwaltung, Zuweisung |
|
||||||
|
| **Stundenzettel** | ⭐⭐⭐ | Zeiterfassung, Foto-Upload, Genehmigung |
|
||||||
|
| **Verfügbarkeiten** | ⭐⭐⭐ | Einsatzplanung, Kalender |
|
||||||
|
| **Qualifikationen** | ⭐⭐⭐ | Zertifikate, §34a, Ablauf-Tracking |
|
||||||
|
| **Objektverwaltung** | ⭐⭐⭐ | Wachobjekte, Standorte, Kontakte |
|
||||||
|
| **Schichtplanung** | ⭐⭐ | Dienstpläne, Wochenpläne, Vertretungen |
|
||||||
|
| **Wächterkontrolle** | ⭐⭐ | QR/NFC-Checkpoints, Rundgänge, GPS |
|
||||||
|
| **Vorfallberichte** | ⭐⭐ | Incidents, Fotos, Kategorien |
|
||||||
|
| **Fahrzeuge** | ⭐ | Firmenwagen, Kilometer, Wartung |
|
||||||
|
| **Dokumente** | ⭐ | Verträge, Policies, Uploads |
|
||||||
|
| **Kunden/CRM** | ⭐ | Kundenverwaltung, Kontakte |
|
||||||
|
| **Abrechnung** | ⭐ | Rechnungen, Export |
|
||||||
|
| **Partnerschaften** | ⭐ | Subunternehmer, Stundenzettel-Austausch |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Modul-Details
|
||||||
|
|
||||||
|
### 1. Qualifikationen & Zertifikate ⭐⭐⭐
|
||||||
|
**Status:** 🔨 In Entwicklung
|
||||||
|
|
||||||
|
**Datenmodell:**
|
||||||
|
- `qualifications` - Verfügbare Qualifikationstypen
|
||||||
|
- `employee_qualifications` - Zuordnung MA ↔ Qualifikation
|
||||||
|
|
||||||
|
**Qualifikationstypen:**
|
||||||
|
- §34a Sachkundenachweis (Pflicht!)
|
||||||
|
- §34a Unterrichtungsnachweis
|
||||||
|
- Waffensachkunde
|
||||||
|
- Waffenschein (grün/gelb)
|
||||||
|
- Erste-Hilfe-Zertifikat
|
||||||
|
- Brandschutzhelfer
|
||||||
|
- Evakuierungshelfer
|
||||||
|
- Führerschein Klasse B/C/D
|
||||||
|
- Personenschutz-Ausbildung
|
||||||
|
- Hundeführerschein
|
||||||
|
- Sprachen (Englisch, etc.)
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Ablaufdatum-Tracking
|
||||||
|
- Automatische Erinnerungen (E-Mail/Push)
|
||||||
|
- Dokument-Upload (Scan des Zertifikats)
|
||||||
|
- Qualifikations-Matrix (wer hat was)
|
||||||
|
- Bei Auftragszuweisung: Prüfung ob MA qualifiziert
|
||||||
|
- Ablaufende Qualifikationen im Dashboard
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Objektverwaltung ⭐⭐⭐
|
||||||
|
**Status:** 📋 Geplant
|
||||||
|
|
||||||
|
**Datenmodell:**
|
||||||
|
- `objects` - Wachobjekte/Standorte
|
||||||
|
- `object_contacts` - Ansprechpartner pro Objekt
|
||||||
|
- `object_instructions` - Dienstanweisungen
|
||||||
|
- `object_documents` - Lagepläne, Schlüssellisten
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Objektdetails (Adresse, Typ, Größe)
|
||||||
|
- Mehrere Ansprechpartner
|
||||||
|
- Dienstanweisungen (PDF/Text)
|
||||||
|
- Schlüsselverwaltung
|
||||||
|
- Zugangsregeln
|
||||||
|
- Notfallpläne
|
||||||
|
- Objekt-spezifische Checklisten
|
||||||
|
- Verknüpfung mit Aufträgen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Schichtplanung ⭐⭐
|
||||||
|
**Status:** 📋 Geplant
|
||||||
|
|
||||||
|
**Datenmodell:**
|
||||||
|
- `shifts` - Schichtdefinitionen
|
||||||
|
- `shift_assignments` - Wer arbeitet wann
|
||||||
|
- `shift_templates` - Wiederkehrende Muster
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Wochenansicht / Monatsansicht
|
||||||
|
- Drag & Drop Planung
|
||||||
|
- Verfügbarkeits-Check
|
||||||
|
- Qualifikations-Check
|
||||||
|
- Vertretungsanfragen
|
||||||
|
- Push-Benachrichtigung bei Änderungen
|
||||||
|
- Export (PDF, iCal)
|
||||||
|
- Arbeitszeitkonto
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Wächterkontrollsystem ⭐⭐
|
||||||
|
**Status:** 📋 Geplant
|
||||||
|
|
||||||
|
**Datenmodell:**
|
||||||
|
- `checkpoints` - QR/NFC Kontrollpunkte
|
||||||
|
- `patrol_routes` - Rundgang-Routen
|
||||||
|
- `patrol_logs` - Erfasste Rundgänge
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- QR-Code Generator für Checkpoints
|
||||||
|
- NFC-Tag Unterstützung
|
||||||
|
- GPS-Koordinaten bei Scan
|
||||||
|
- Pflicht-Reihenfolge definierbar
|
||||||
|
- Zeitfenster für Rundgänge
|
||||||
|
- Abweichungs-Alarme
|
||||||
|
- Rundgang-Historie
|
||||||
|
- Berichte für Kunden
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Vorfallberichte ⭐⭐
|
||||||
|
**Status:** 📋 Geplant
|
||||||
|
|
||||||
|
**Datenmodell:**
|
||||||
|
- `incidents` - Vorfälle
|
||||||
|
- `incident_categories` - Kategorien
|
||||||
|
- `incident_attachments` - Fotos, Dokumente
|
||||||
|
|
||||||
|
**Kategorien:**
|
||||||
|
- Einbruch/Einbruchsversuch
|
||||||
|
- Vandalismus
|
||||||
|
- Hausfriedensbruch
|
||||||
|
- Technische Störung
|
||||||
|
- Brand/Brandgefahr
|
||||||
|
- Unfall
|
||||||
|
- Sonstiges
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Schnell-Erfassung (Mobile-optimiert)
|
||||||
|
- Foto-Upload (vor Ort)
|
||||||
|
- Kategorisierung
|
||||||
|
- Schweregrad
|
||||||
|
- Beteiligte Personen
|
||||||
|
- Maßnahmen dokumentieren
|
||||||
|
- PDF-Export für Kunden
|
||||||
|
- Eskalations-Workflow
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. Fahrzeugverwaltung ⭐
|
||||||
|
**Status:** 📋 Geplant
|
||||||
|
|
||||||
|
**Datenmodell:**
|
||||||
|
- `vehicles` - Fahrzeuge
|
||||||
|
- `vehicle_bookings` - Buchungen
|
||||||
|
- `vehicle_logs` - Fahrten, Tanken
|
||||||
|
- `vehicle_maintenance` - Wartungen
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Fahrzeugpool
|
||||||
|
- Buchungssystem
|
||||||
|
- Kilometerstand-Tracking
|
||||||
|
- Tankbelege
|
||||||
|
- Wartungserinnerungen (TÜV, Inspektion)
|
||||||
|
- Schadensmeldungen
|
||||||
|
- Führerschein-Kontrolle
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7. Dokumentenverwaltung ⭐
|
||||||
|
**Status:** 📋 Geplant
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Arbeitsverträge
|
||||||
|
- Datenschutzerklärungen
|
||||||
|
- Dienstanweisungen
|
||||||
|
- Schulungsunterlagen
|
||||||
|
- Versionierung
|
||||||
|
- Lesebestätigung durch MA
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 8. Kunden/CRM ⭐
|
||||||
|
**Status:** 📋 Geplant
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Kundenstammdaten
|
||||||
|
- Ansprechpartner
|
||||||
|
- Vertragsübersicht
|
||||||
|
- Kommunikationshistorie
|
||||||
|
- Umsatz pro Kunde
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 9. Abrechnung ⭐
|
||||||
|
**Status:** 📋 Geplant
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Stundensätze pro Kunde/Objekt
|
||||||
|
- Automatische Rechnungserstellung
|
||||||
|
- PDF-Export
|
||||||
|
- DATEV-Export
|
||||||
|
- Mahnwesen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entwicklungsreihenfolge
|
||||||
|
|
||||||
|
1. ✅ Basis (Benutzer, Auth, Dashboard)
|
||||||
|
2. ✅ Aufträge
|
||||||
|
3. ✅ Stundenzettel
|
||||||
|
4. ✅ Verfügbarkeiten
|
||||||
|
5. ✅ Hilfe-System
|
||||||
|
6. 🔨 **Qualifikationen** ← AKTUELL
|
||||||
|
7. 📋 Objektverwaltung
|
||||||
|
8. 📋 Schichtplanung
|
||||||
|
9. 📋 Wächterkontrolle
|
||||||
|
10. 📋 Vorfallberichte
|
||||||
|
11. 📋 Fahrzeuge
|
||||||
|
12. 📋 Dokumente
|
||||||
|
13. 📋 CRM
|
||||||
|
14. 📋 Abrechnung
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Technische Umsetzung
|
||||||
|
|
||||||
|
### Modul-System (Backend)
|
||||||
|
```typescript
|
||||||
|
// modules Tabelle erweitern
|
||||||
|
{
|
||||||
|
key: 'qualifications',
|
||||||
|
name: 'Qualifikationen',
|
||||||
|
description: 'Zertifikate & Nachweise verwalten',
|
||||||
|
icon: '🎓',
|
||||||
|
price_monthly: 29.00,
|
||||||
|
price_yearly: 290.00,
|
||||||
|
is_premium: true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Feature-Flags (Frontend)
|
||||||
|
```typescript
|
||||||
|
// Modul-Check vor Anzeige
|
||||||
|
if (orgStore.hasModule('qualifications')) {
|
||||||
|
// Zeige Menüpunkt
|
||||||
|
}
|
||||||
|
```
|
||||||
182
db/migrations/003_qualifications.sql
Normal file
182
db/migrations/003_qualifications.sql
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
-- Migration: 003_qualifications.sql
|
||||||
|
-- Qualifikationen & Zertifikate Modul
|
||||||
|
|
||||||
|
-- Verfügbare Qualifikationstypen (System-weit)
|
||||||
|
CREATE TABLE IF NOT EXISTS qualification_types (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
key VARCHAR(50) UNIQUE NOT NULL,
|
||||||
|
name VARCHAR(100) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
category VARCHAR(50) NOT NULL DEFAULT 'general',
|
||||||
|
has_expiry BOOLEAN DEFAULT true,
|
||||||
|
validity_months INTEGER, -- Standard-Gültigkeit in Monaten
|
||||||
|
is_required BOOLEAN DEFAULT false, -- Pflicht für alle MA?
|
||||||
|
icon VARCHAR(10) DEFAULT '📜',
|
||||||
|
sort_order INTEGER DEFAULT 0,
|
||||||
|
is_system BOOLEAN DEFAULT true, -- System-vorgegeben oder custom
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Standard-Qualifikationstypen einfügen
|
||||||
|
INSERT INTO qualification_types (key, name, description, category, has_expiry, validity_months, is_required, icon, sort_order, is_system) VALUES
|
||||||
|
-- Gesetzliche Pflicht
|
||||||
|
('sachkunde_34a', '§34a Sachkundenachweis', 'Sachkundeprüfung nach §34a GewO - Pflicht für Bewachungsgewerbe', 'legal', false, NULL, true, '📋', 1, true),
|
||||||
|
('unterrichtung_34a', '§34a Unterrichtungsnachweis', '40-Stunden Unterrichtung nach §34a GewO', 'legal', false, NULL, false, '📋', 2, true),
|
||||||
|
|
||||||
|
-- Waffen
|
||||||
|
('waffensachkunde', 'Waffensachkunde', 'Sachkundenachweis für Waffenbesitz', 'weapons', false, NULL, false, '🔫', 10, true),
|
||||||
|
('waffenschein_gruen', 'Waffenschein (grün)', 'Waffenschein für Schusswaffen', 'weapons', true, 36, false, '🟢', 11, true),
|
||||||
|
('waffenschein_gelb', 'Waffenschein (gelb)', 'Kleiner Waffenschein', 'weapons', true, 36, false, '🟡', 12, true),
|
||||||
|
|
||||||
|
-- Erste Hilfe & Sicherheit
|
||||||
|
('erste_hilfe', 'Erste-Hilfe-Kurs', 'Erste-Hilfe-Ausbildung (9 UE)', 'safety', true, 24, false, '🏥', 20, true),
|
||||||
|
('brandschutzhelfer', 'Brandschutzhelfer', 'Ausbildung zum Brandschutzhelfer', 'safety', true, 36, false, '🔥', 21, true),
|
||||||
|
('evakuierungshelfer', 'Evakuierungshelfer', 'Ausbildung zum Evakuierungshelfer', 'safety', true, 24, false, '🚪', 22, true),
|
||||||
|
('defibrillator', 'AED/Defibrillator', 'Einweisung Automatisierter Externer Defibrillator', 'safety', true, 24, false, '💓', 23, true),
|
||||||
|
|
||||||
|
-- Führerscheine
|
||||||
|
('fuehrerschein_b', 'Führerschein Klasse B', 'PKW Führerschein', 'driving', true, NULL, false, '🚗', 30, true),
|
||||||
|
('fuehrerschein_c', 'Führerschein Klasse C', 'LKW Führerschein', 'driving', true, 60, false, '🚛', 31, true),
|
||||||
|
('fuehrerschein_d', 'Führerschein Klasse D', 'Bus Führerschein', 'driving', true, 60, false, '🚌', 32, true),
|
||||||
|
|
||||||
|
-- Spezial-Ausbildungen
|
||||||
|
('personenschutz', 'Personenschutz', 'Ausbildung zum Personenschützer', 'special', false, NULL, false, '🛡️', 40, true),
|
||||||
|
('hundefuehrer', 'Diensthundeführer', 'Ausbildung zum Diensthundeführer', 'special', true, 12, false, '🐕', 41, true),
|
||||||
|
('intervention', 'Interventionskraft', 'Ausbildung zur Interventionskraft (IK)', 'special', false, NULL, false, '⚡', 42, true),
|
||||||
|
('nsk', 'NSK (Notruf-Service-Kraft)', 'Notruf- und Service-Leitstelle', 'special', false, NULL, false, '📞', 43, true),
|
||||||
|
|
||||||
|
-- Sprachen
|
||||||
|
('sprache_englisch', 'Englisch', 'Englischkenntnisse', 'language', false, NULL, false, '🇬🇧', 50, true),
|
||||||
|
('sprache_franzoesisch', 'Französisch', 'Französischkenntnisse', 'language', false, NULL, false, '🇫🇷', 51, true),
|
||||||
|
('sprache_russisch', 'Russisch', 'Russischkenntnisse', 'language', false, NULL, false, '🇷🇺', 52, true),
|
||||||
|
('sprache_tuerkisch', 'Türkisch', 'Türkischkenntnisse', 'language', false, NULL, false, '🇹🇷', 53, true),
|
||||||
|
('sprache_arabisch', 'Arabisch', 'Arabischkenntnisse', 'language', false, NULL, false, '🇸🇦', 54, true)
|
||||||
|
|
||||||
|
ON CONFLICT (key) DO NOTHING;
|
||||||
|
|
||||||
|
-- Custom Qualifikationstypen pro Organisation
|
||||||
|
CREATE TABLE IF NOT EXISTS org_qualification_types (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
||||||
|
key VARCHAR(50) NOT NULL,
|
||||||
|
name VARCHAR(100) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
category VARCHAR(50) DEFAULT 'custom',
|
||||||
|
has_expiry BOOLEAN DEFAULT true,
|
||||||
|
validity_months INTEGER,
|
||||||
|
icon VARCHAR(10) DEFAULT '📜',
|
||||||
|
sort_order INTEGER DEFAULT 100,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
UNIQUE(org_id, key)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Mitarbeiter-Qualifikationen
|
||||||
|
CREATE TABLE IF NOT EXISTS employee_qualifications (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
||||||
|
|
||||||
|
-- Entweder System-Typ oder Custom-Typ
|
||||||
|
qualification_type_id UUID REFERENCES qualification_types(id),
|
||||||
|
org_qualification_type_id UUID REFERENCES org_qualification_types(id),
|
||||||
|
|
||||||
|
-- Daten
|
||||||
|
issued_date DATE, -- Ausstellungsdatum
|
||||||
|
expiry_date DATE, -- Ablaufdatum (falls zutreffend)
|
||||||
|
issuer VARCHAR(255), -- Ausstellende Stelle
|
||||||
|
certificate_number VARCHAR(100), -- Zertifikatsnummer
|
||||||
|
|
||||||
|
-- Level/Stufe (optional)
|
||||||
|
level VARCHAR(50), -- z.B. "A1", "B2" für Sprachen
|
||||||
|
|
||||||
|
-- Dokument
|
||||||
|
document_url TEXT, -- Scan des Zertifikats
|
||||||
|
document_name VARCHAR(255),
|
||||||
|
|
||||||
|
-- Status
|
||||||
|
status VARCHAR(20) DEFAULT 'active', -- active, expired, revoked, pending
|
||||||
|
verified_by UUID REFERENCES users(id), -- Wer hat verifiziert
|
||||||
|
verified_at TIMESTAMPTZ,
|
||||||
|
|
||||||
|
-- Notizen
|
||||||
|
notes TEXT,
|
||||||
|
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
|
||||||
|
-- Constraint: Entweder System-Typ oder Custom-Typ
|
||||||
|
CONSTRAINT chk_qualification_type CHECK (
|
||||||
|
(qualification_type_id IS NOT NULL AND org_qualification_type_id IS NULL) OR
|
||||||
|
(qualification_type_id IS NULL AND org_qualification_type_id IS NOT NULL)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Index für schnelle Abfragen
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_emp_qual_user ON employee_qualifications(user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_emp_qual_org ON employee_qualifications(org_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_emp_qual_expiry ON employee_qualifications(expiry_date);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_emp_qual_status ON employee_qualifications(status);
|
||||||
|
|
||||||
|
-- Erinnerungen für ablaufende Qualifikationen
|
||||||
|
CREATE TABLE IF NOT EXISTS qualification_reminders (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
employee_qualification_id UUID NOT NULL REFERENCES employee_qualifications(id) ON DELETE CASCADE,
|
||||||
|
reminder_date DATE NOT NULL,
|
||||||
|
days_before INTEGER NOT NULL, -- 30, 14, 7, 1
|
||||||
|
sent BOOLEAN DEFAULT false,
|
||||||
|
sent_at TIMESTAMPTZ,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_qual_reminder_date ON qualification_reminders(reminder_date, sent);
|
||||||
|
|
||||||
|
-- View: Qualifikationen mit Details
|
||||||
|
CREATE OR REPLACE VIEW v_employee_qualifications AS
|
||||||
|
SELECT
|
||||||
|
eq.id,
|
||||||
|
eq.user_id,
|
||||||
|
eq.org_id,
|
||||||
|
u.first_name,
|
||||||
|
u.last_name,
|
||||||
|
u.email,
|
||||||
|
COALESCE(qt.key, oqt.key) as qualification_key,
|
||||||
|
COALESCE(qt.name, oqt.name) as qualification_name,
|
||||||
|
COALESCE(qt.category, oqt.category) as category,
|
||||||
|
COALESCE(qt.icon, oqt.icon) as icon,
|
||||||
|
COALESCE(qt.has_expiry, oqt.has_expiry) as has_expiry,
|
||||||
|
eq.issued_date,
|
||||||
|
eq.expiry_date,
|
||||||
|
eq.issuer,
|
||||||
|
eq.certificate_number,
|
||||||
|
eq.level,
|
||||||
|
eq.document_url,
|
||||||
|
eq.status,
|
||||||
|
eq.verified_by,
|
||||||
|
eq.verified_at,
|
||||||
|
eq.notes,
|
||||||
|
eq.created_at,
|
||||||
|
-- Berechnete Felder
|
||||||
|
CASE
|
||||||
|
WHEN eq.expiry_date IS NULL THEN 'no_expiry'
|
||||||
|
WHEN eq.expiry_date < CURRENT_DATE THEN 'expired'
|
||||||
|
WHEN eq.expiry_date < CURRENT_DATE + INTERVAL '30 days' THEN 'expiring_soon'
|
||||||
|
ELSE 'valid'
|
||||||
|
END as expiry_status,
|
||||||
|
CASE
|
||||||
|
WHEN eq.expiry_date IS NOT NULL
|
||||||
|
THEN eq.expiry_date - CURRENT_DATE
|
||||||
|
ELSE NULL
|
||||||
|
END as days_until_expiry
|
||||||
|
FROM employee_qualifications eq
|
||||||
|
JOIN users u ON eq.user_id = u.id
|
||||||
|
LEFT JOIN qualification_types qt ON eq.qualification_type_id = qt.id
|
||||||
|
LEFT JOIN org_qualification_types oqt ON eq.org_qualification_type_id = oqt.id;
|
||||||
|
|
||||||
|
-- Modul in modules Tabelle einfügen
|
||||||
|
INSERT INTO modules (key, name, description, icon, is_premium, price_monthly, price_yearly, sort_order) VALUES
|
||||||
|
('qualifications', 'Qualifikationen', 'Zertifikate, Nachweise & Ablauf-Tracking', '🎓', true, 29.00, 290.00, 10)
|
||||||
|
ON CONFLICT (key) DO UPDATE SET
|
||||||
|
name = EXCLUDED.name,
|
||||||
|
description = EXCLUDED.description,
|
||||||
|
price_monthly = EXCLUDED.price_monthly,
|
||||||
|
price_yearly = EXCLUDED.price_yearly;
|
||||||
Reference in New Issue
Block a user