Quellcode des ICON CRM (4)
This commit is contained in:
@@ -0,0 +1,418 @@
|
||||
-- ============================================================================
|
||||
-- ICON CRM - Datenbankschema (MariaDB, Datenbank icon_CRM)
|
||||
--
|
||||
-- Idempotent: die Datei laeuft bei jedem Backend-Start durch. Jedes Statement
|
||||
-- muss deshalb ein IF NOT EXISTS tragen oder sonst wiederholbar sein.
|
||||
-- Spaltenaenderungen an bestehenden Tabellen gehoeren nicht hierher, sondern in
|
||||
-- die Migrationen in db.js - CREATE TABLE IF NOT EXISTS fasst eine vorhandene
|
||||
-- Tabelle nicht an.
|
||||
--
|
||||
-- Grundgedanke des Modells (aus der Featureliste vom 14.09.2026):
|
||||
-- * "Experten" heissen jetzt Kontakte und umfassen auch die Ansprechpartner
|
||||
-- der Kunden - eine Tabelle, unterschieden ueber `kind`.
|
||||
-- * "Kunden" heissen jetzt Unternehmen. Ein Kunde ist ein Unternehmen mit
|
||||
-- is_customer = 1; der Umschalter in der Oberflaeche filtert nur darauf.
|
||||
-- * Jede Aenderung landet in icon_history. Wer wann was getan hat, steht
|
||||
-- damit an genau einer Stelle - je Kontakt, je Unternehmen und global.
|
||||
-- ============================================================================
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Benutzer
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_users (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(60) NOT NULL,
|
||||
email VARCHAR(190) NULL,
|
||||
name VARCHAR(190) NOT NULL,
|
||||
role ENUM('admin','user') NOT NULL DEFAULT 'user',
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
-- Persoenliche Farbe: traegt Initialen-Avatare, Historie und Netzwerkknoten.
|
||||
color VARCHAR(9) NULL,
|
||||
-- Foto als Data-URL, im Browser auf 256 px vorkomprimiert.
|
||||
avatar MEDIUMTEXT NULL,
|
||||
theme VARCHAR(40) NULL,
|
||||
theme_mode ENUM('light','dark') NULL,
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uq_icon_users_username (username),
|
||||
UNIQUE KEY uq_icon_users_email (email)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Unternehmen (fruehere "Kunden")
|
||||
--
|
||||
-- `is_customer` unterscheidet unsere Kunden von allen uebrigen bekannten
|
||||
-- Unternehmen; `customer_state` trennt darin aktiv von alumni. Ein Unternehmen
|
||||
-- ohne Kundenhaken ist trotzdem vollwertig - dort haengen Werdegaenge, Leads
|
||||
-- und die Unternehmenskarte dran.
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_companies (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(190) NOT NULL,
|
||||
-- Dachgesellschaft, z. B. "Finanz Informatik" ueber FI Hamburg/Frankfurt.
|
||||
group_name VARCHAR(190) NULL,
|
||||
industry VARCHAR(190) NULL,
|
||||
employees INT UNSIGNED NULL,
|
||||
website VARCHAR(300) NULL,
|
||||
address TEXT NULL,
|
||||
logo MEDIUMTEXT NULL,
|
||||
-- 0 = nicht bewertet, 1..5 Sterne: wie interessant ist das Unternehmen.
|
||||
rating TINYINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
is_customer TINYINT(1) NOT NULL DEFAULT 0,
|
||||
customer_state ENUM('aktiv','alumni') NOT NULL DEFAULT 'aktiv',
|
||||
freelancers ENUM('unbekannt','ja','nein') NOT NULL DEFAULT 'unbekannt',
|
||||
notes MEDIUMTEXT NULL,
|
||||
created_by INT UNSIGNED NULL,
|
||||
owner_id INT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
KEY idx_icon_companies_name (name),
|
||||
KEY idx_icon_companies_group (group_name),
|
||||
KEY idx_icon_companies_customer (is_customer, customer_state),
|
||||
CONSTRAINT fk_icon_companies_creator FOREIGN KEY (created_by)
|
||||
REFERENCES icon_users (id) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_icon_companies_owner FOREIGN KEY (owner_id)
|
||||
REFERENCES icon_users (id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Kontakte (fruehere "Experten" plus Ansprechpartner der Unternehmen)
|
||||
--
|
||||
-- Der Verfuegbarkeitsstatus ist bewusst entfallen (Featureliste 14.09.2026).
|
||||
-- `status` beschreibt nur noch den Stand der Zusammenarbeit.
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_contacts (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
first_name VARCHAR(120) NULL,
|
||||
last_name VARCHAR(120) NOT NULL,
|
||||
position VARCHAR(190) NULL,
|
||||
email VARCHAR(190) NULL,
|
||||
phone VARCHAR(80) NULL,
|
||||
linkedin VARCHAR(300) NULL,
|
||||
avatar MEDIUMTEXT NULL,
|
||||
-- Aktueller Arbeitgeber. Die Historie der frueheren steht in
|
||||
-- icon_employments - daraus speist sich der Zweig "Verlassen".
|
||||
company_id INT UNSIGNED NULL,
|
||||
kind ENUM('Experte','Ansprechpartner','Lead') NOT NULL DEFAULT 'Experte',
|
||||
status ENUM('Interessiert','Interview','Gebucht','Inaktiv') NOT NULL DEFAULT 'Interessiert',
|
||||
-- Woher kommt der Kontakt (LinkedIn, Empfehlung, Portal, ...).
|
||||
lead_source VARCHAR(190) NULL,
|
||||
-- Featureliste: "persoenlicher Kontakt" oder "noch kein Kontakt gehabt".
|
||||
contact_state ENUM('unbekannt','persoenlich','kein Kontakt') NOT NULL DEFAULT 'unbekannt',
|
||||
freelancers ENUM('unbekannt','ja','nein') NOT NULL DEFAULT 'unbekannt',
|
||||
bio MEDIUMTEXT NULL,
|
||||
-- Kommagetrennte Schlagworte; die Oberflaeche zerlegt sie in Chips.
|
||||
tags VARCHAR(1000) NULL,
|
||||
rate_onsite DECIMAL(8,2) NULL,
|
||||
rate_remote DECIMAL(8,2) NULL,
|
||||
cv_url VARCHAR(500) NULL,
|
||||
cv_file VARCHAR(255) NULL,
|
||||
created_by INT UNSIGNED NULL,
|
||||
owner_id INT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
KEY idx_icon_contacts_name (last_name, first_name),
|
||||
KEY idx_icon_contacts_company (company_id),
|
||||
KEY idx_icon_contacts_kind (kind),
|
||||
KEY idx_icon_contacts_status (status),
|
||||
CONSTRAINT fk_icon_contacts_company FOREIGN KEY (company_id)
|
||||
REFERENCES icon_companies (id) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_icon_contacts_creator FOREIGN KEY (created_by)
|
||||
REFERENCES icon_users (id) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_icon_contacts_owner FOREIGN KEY (owner_id)
|
||||
REFERENCES icon_users (id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Werdegang: welcher Kontakt war wann bei welchem Unternehmen
|
||||
--
|
||||
-- Traegt zwei Dinge aus der Featureliste: die automatische Liste "letzter
|
||||
-- Arbeitgeber (Branche & Unternehmen)" und den Zweig "Verlassen" im Stammbaum
|
||||
-- eines Unternehmens (is_current = 0).
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_employments (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
contact_id INT UNSIGNED NOT NULL,
|
||||
company_id INT UNSIGNED NOT NULL,
|
||||
position VARCHAR(190) NULL,
|
||||
started_on DATE NULL,
|
||||
ended_on DATE NULL,
|
||||
is_current TINYINT(1) NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
KEY idx_icon_employments_contact (contact_id),
|
||||
KEY idx_icon_employments_company (company_id, is_current),
|
||||
CONSTRAINT fk_icon_employments_contact FOREIGN KEY (contact_id)
|
||||
REFERENCES icon_contacts (id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_icon_employments_company FOREIGN KEY (company_id)
|
||||
REFERENCES icon_companies (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Interviews: "Hatten wir schon einmal ein Interview, und falls ja - wann,
|
||||
-- mit wem?" Eigene Tabelle statt Freitext, damit danach gefiltert werden kann.
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_interviews (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
contact_id INT UNSIGNED NULL,
|
||||
company_id INT UNSIGNED NULL,
|
||||
-- Wer von uns das Gespraech gefuehrt hat.
|
||||
user_id INT UNSIGNED NULL,
|
||||
held_on DATE NOT NULL,
|
||||
notes MEDIUMTEXT NULL,
|
||||
created_by INT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
KEY idx_icon_interviews_contact (contact_id, held_on),
|
||||
KEY idx_icon_interviews_company (company_id, held_on),
|
||||
CONSTRAINT fk_icon_interviews_contact FOREIGN KEY (contact_id)
|
||||
REFERENCES icon_contacts (id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_icon_interviews_company FOREIGN KEY (company_id)
|
||||
REFERENCES icon_companies (id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_icon_interviews_user FOREIGN KEY (user_id)
|
||||
REFERENCES icon_users (id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Historie / Aktivitaetsprotokoll
|
||||
--
|
||||
-- Eine Tabelle fuer alles: Systemereignisse (angelegt, geaendert, geloescht)
|
||||
-- und von Hand erfasste Notizen. `entity_type`/`entity_id` sagen, an welcher
|
||||
-- Karte der Eintrag haengt; `user_id` immer, wer es war.
|
||||
--
|
||||
-- Absichtlich keine Fremdschluessel auf die Ziel-Tabellen: die Historie soll
|
||||
-- einen geloeschten Kontakt ueberleben. Deshalb steht mit `entity_label` auch
|
||||
-- der Name zum Zeitpunkt des Eintrags mit drin.
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_history (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
entity_type ENUM('contact','company','tender','project','lead','user','system') NOT NULL,
|
||||
entity_id INT UNSIGNED NULL,
|
||||
entity_label VARCHAR(300) NULL,
|
||||
-- created | updated | deleted | note | mention | interview | stage | ...
|
||||
action VARCHAR(40) NOT NULL DEFAULT 'note',
|
||||
-- Anzeigetext, darf Mention-Token @[Name](contact:12) enthalten.
|
||||
text MEDIUMTEXT NULL,
|
||||
-- Feldaenderungen als JSON: { feld: [vorher, nachher], ... }
|
||||
changes MEDIUMTEXT NULL,
|
||||
user_id INT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
KEY idx_icon_history_entity (entity_type, entity_id, created_at),
|
||||
KEY idx_icon_history_created (created_at),
|
||||
CONSTRAINT fk_icon_history_user FOREIGN KEY (user_id)
|
||||
REFERENCES icon_users (id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Erwaehnungen (@-Mentions)
|
||||
--
|
||||
-- Der Token steht im Text; diese Tabelle ist der Index dazu. Damit beantwortet
|
||||
-- eine Abfrage "wo wurde dieses Unternehmen ueberall genannt?", ohne jeden
|
||||
-- Freitext der Datenbank durchsuchen zu muessen.
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_mentions (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
-- Wo die Erwaehnung steht.
|
||||
source_type ENUM('history','contact','company','tender','project','lead') NOT NULL,
|
||||
source_id BIGINT UNSIGNED NOT NULL,
|
||||
-- Wer bzw. was erwaehnt wurde.
|
||||
target_type ENUM('contact','company','user') NOT NULL,
|
||||
target_id INT UNSIGNED NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uq_icon_mentions (source_type, source_id, target_type, target_id),
|
||||
KEY idx_icon_mentions_target (target_type, target_id, created_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Netzwerk: wer kennt wen
|
||||
--
|
||||
-- Das Paar wird aufsteigend gespeichert (a < b), der Unique-Key verhindert
|
||||
-- damit Duplikate in beide Richtungen.
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_connections (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
contact_a INT UNSIGNED NOT NULL,
|
||||
contact_b INT UNSIGNED NOT NULL,
|
||||
kind VARCHAR(60) NOT NULL DEFAULT 'Kontakt',
|
||||
strength TINYINT UNSIGNED NOT NULL DEFAULT 1,
|
||||
created_by INT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uq_icon_connections (contact_a, contact_b),
|
||||
CONSTRAINT fk_icon_connections_a FOREIGN KEY (contact_a)
|
||||
REFERENCES icon_contacts (id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_icon_connections_b FOREIGN KEY (contact_b)
|
||||
REFERENCES icon_contacts (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Ausschreibungen
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_tenders (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(300) NOT NULL,
|
||||
source VARCHAR(190) NULL,
|
||||
link VARCHAR(600) NULL,
|
||||
company_id INT UNSIGNED NULL,
|
||||
status ENUM('Aktiv','Inaktiv','Ausgelaufen','Archiviert') NOT NULL DEFAULT 'Aktiv',
|
||||
stage ENUM('Ausschreibung','Kontakte sichten','Interview','Kunden Interview',
|
||||
'Vertragsgestaltung','Abschluss','Geschlossen') NOT NULL DEFAULT 'Ausschreibung',
|
||||
online TINYINT(1) NOT NULL DEFAULT 1,
|
||||
details MEDIUMTEXT NULL,
|
||||
notes MEDIUMTEXT NULL,
|
||||
deadline DATE NULL,
|
||||
created_by INT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
KEY idx_icon_tenders_stage (stage),
|
||||
KEY idx_icon_tenders_status (status),
|
||||
CONSTRAINT fk_icon_tenders_company FOREIGN KEY (company_id)
|
||||
REFERENCES icon_companies (id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS icon_tender_contacts (
|
||||
tender_id INT UNSIGNED NOT NULL,
|
||||
contact_id INT UNSIGNED NOT NULL,
|
||||
role VARCHAR(120) NULL,
|
||||
PRIMARY KEY (tender_id, contact_id),
|
||||
CONSTRAINT fk_icon_tc_tender FOREIGN KEY (tender_id)
|
||||
REFERENCES icon_tenders (id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_icon_tc_contact FOREIGN KEY (contact_id)
|
||||
REFERENCES icon_contacts (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Laufende Projekte
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_projects (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(300) NOT NULL,
|
||||
company_id INT UNSIGNED NULL,
|
||||
contact_id INT UNSIGNED NULL,
|
||||
started_on DATE NULL,
|
||||
ended_on DATE NULL,
|
||||
status ENUM('Aktiv','Nicht aktiv','Abgeschlossen') NOT NULL DEFAULT 'Aktiv',
|
||||
rate DECIMAL(8,2) NULL,
|
||||
notes MEDIUMTEXT NULL,
|
||||
created_by INT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
KEY idx_icon_projects_status (status),
|
||||
CONSTRAINT fk_icon_projects_company FOREIGN KEY (company_id)
|
||||
REFERENCES icon_companies (id) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_icon_projects_contact FOREIGN KEY (contact_id)
|
||||
REFERENCES icon_contacts (id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Lead-Pipeline (Kanban)
|
||||
--
|
||||
-- Schema steht schon; die Oberflaeche dazu kommt in der zweiten Ausbaustufe.
|
||||
-- `remind_at` traegt die Erinnerungsfunktion, `reminder_days` das Intervall.
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_leads (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(300) NOT NULL,
|
||||
company_id INT UNSIGNED NULL,
|
||||
contact_id INT UNSIGNED NULL,
|
||||
stage ENUM('Fuer Spaeter','Neuer Lead','Erstkontakt','1. Gespraech',
|
||||
'Followup geplant','Followup Gespraech','Closed','Absage')
|
||||
NOT NULL DEFAULT 'Neuer Lead',
|
||||
contact_state ENUM('unbekannt','persoenlich','kein Kontakt') NOT NULL DEFAULT 'unbekannt',
|
||||
archived TINYINT(1) NOT NULL DEFAULT 0,
|
||||
position INT NOT NULL DEFAULT 0,
|
||||
notes MEDIUMTEXT NULL,
|
||||
-- Zeitpunkt der naechsten Erinnerung; NULL = keine.
|
||||
remind_at DATETIME NULL,
|
||||
reminder_days INT UNSIGNED NULL,
|
||||
last_contact_at DATETIME NULL,
|
||||
owner_id INT UNSIGNED NULL,
|
||||
created_by INT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
KEY idx_icon_leads_stage (stage, archived, position),
|
||||
KEY idx_icon_leads_remind (remind_at),
|
||||
CONSTRAINT fk_icon_leads_company FOREIGN KEY (company_id)
|
||||
REFERENCES icon_companies (id) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_icon_leads_contact FOREIGN KEY (contact_id)
|
||||
REFERENCES icon_contacts (id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS icon_lead_todos (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
lead_id INT UNSIGNED NOT NULL,
|
||||
text VARCHAR(500) NOT NULL,
|
||||
done TINYINT(1) NOT NULL DEFAULT 0,
|
||||
due_on DATE NULL,
|
||||
position INT NOT NULL DEFAULT 0,
|
||||
created_by INT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
KEY idx_icon_lead_todos_lead (lead_id, position),
|
||||
CONSTRAINT fk_icon_lead_todos_lead FOREIGN KEY (lead_id)
|
||||
REFERENCES icon_leads (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- CV-Import
|
||||
--
|
||||
-- Der Ablauf aus der Featureliste als drei Ordner in einer Tabelle:
|
||||
-- eingang hochgeladen, noch nicht ausgelesen
|
||||
-- screening von der KI ausgelesen, wartet auf Ja oder Nein
|
||||
-- auswahl uebernommen - der Kontakt ist angelegt, der CV haengt dran
|
||||
-- verworfen abgelehnt; die Datei bleibt, bis sie jemand loescht
|
||||
--
|
||||
-- `extracted` haelt die Ausgabe des Modells als JSON. Sie bleibt auch nach der
|
||||
-- Uebernahme stehen: so laesst sich spaeter nachvollziehen, was die KI gelesen
|
||||
-- hat und was ein Mensch daran geaendert hat.
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_cv_imports (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
original_name VARCHAR(255) NOT NULL,
|
||||
mime VARCHAR(120) NULL,
|
||||
size_bytes INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
status ENUM('eingang','screening','auswahl','verworfen') NOT NULL DEFAULT 'eingang',
|
||||
extracted MEDIUMTEXT NULL,
|
||||
-- Das im Lebenslauf gefundene Portrait, unveraendert als Data-URL. Es steht
|
||||
-- hier nur zwischen Auslesen und Uebernehmen; beim Anlegen des Kontakts geht
|
||||
-- es verkleinert an icon_contacts.avatar und wird hier geleert.
|
||||
photo MEDIUMTEXT NULL,
|
||||
error VARCHAR(500) NULL,
|
||||
contact_id INT UNSIGNED NULL,
|
||||
uploaded_by INT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
processed_at TIMESTAMP NULL DEFAULT NULL,
|
||||
KEY idx_icon_cv_status (status, created_at),
|
||||
CONSTRAINT fk_icon_cv_contact FOREIGN KEY (contact_id)
|
||||
REFERENCES icon_contacts (id) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_icon_cv_user FOREIGN KEY (uploaded_by)
|
||||
REFERENCES icon_users (id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Stammdaten: gepflegte Auswahllisten
|
||||
--
|
||||
-- Branche und Kontaktart waren Freitext bzw. ein festes ENUM. Beides wird in
|
||||
-- der Praxis erweitert - eine neue Branche, eine neue Art von Kontakt - und
|
||||
-- beides soll ohne Codeaenderung gehen. Die Werte stehen deshalb hier und
|
||||
-- speisen die Auswahlfelder der Oberflaeche.
|
||||
--
|
||||
-- `field` ist bewusst kein ENUM: eine weitere Liste soll keine Migration
|
||||
-- kosten.
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_options (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
field VARCHAR(40) NOT NULL,
|
||||
value VARCHAR(190) NOT NULL,
|
||||
position INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uq_icon_options (field, value),
|
||||
KEY idx_icon_options_field (field, position)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Einstellungen (Schluessel/Wert) - auch fuer einmalige Migrationsmerker
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS icon_settings (
|
||||
key_name VARCHAR(100) NOT NULL PRIMARY KEY,
|
||||
value MEDIUMTEXT NULL,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
Reference in New Issue
Block a user