UI-Redesign: AegisSight Design, Filter-Popover, Header-Umbau

- Session-Timeout auf 60 Minuten erhöht (ACCESS_TOKEN_EXPIRY + SESSION_TIMEOUT)
- AegisSight Light Theme: Gold-Akzent (#C8A851) statt Indigo
- Navigation-Tabs in eigene Zeile unter Header verschoben (HTML-Struktur)
- Filter-Bar durch kompaktes Popover mit Checkboxen ersetzt (Mehrfachauswahl)
- Archiv-Funktion repariert (lädt jetzt per API statt leerem Store)
- Filter-Bugs behoben: Reset-Button ID, Default-Werte, Ohne-Datum-Filter
- Mehrspalten-Layout Feature entfernt
- Online-Status vom Header an User-Avatar verschoben (grüner Punkt)
- Lupen-Icon entfernt
- CLAUDE.md: Docker-Deploy und CSS-Tricks Regeln aktualisiert

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
Server Deploy
2026-03-19 18:49:38 +01:00
Ursprung 99a6b7437b
Commit 4bd57d653f
36 geänderte Dateien mit 5027 neuen und 2897 gelöschten Zeilen

Datei anzeigen

@@ -113,7 +113,7 @@ function createTables() {
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL,
column_id INTEGER NOT NULL,
column_id INTEGER,
title TEXT NOT NULL,
description TEXT,
priority TEXT DEFAULT 'medium',
@@ -128,7 +128,7 @@ function createTables() {
created_by INTEGER,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
FOREIGN KEY (column_id) REFERENCES columns(id) ON DELETE CASCADE,
FOREIGN KEY (column_id) REFERENCES columns(id) ON DELETE SET NULL,
FOREIGN KEY (assigned_to) REFERENCES users(id),
FOREIGN KEY (depends_on) REFERENCES tasks(id) ON DELETE SET NULL,
FOREIGN KEY (created_by) REFERENCES users(id)
@@ -613,31 +613,109 @@ function createTables() {
)
`);
// Kontakte
// Neues optimiertes Kontakt-Schema
db.exec(`
CREATE TABLE IF NOT EXISTS contacts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
type TEXT NOT NULL CHECK(type IN ('person', 'company')),
-- Gemeinsame Felder
display_name TEXT NOT NULL,
status TEXT DEFAULT 'active' CHECK(status IN ('active', 'inactive', 'archived')),
tags TEXT,
notes TEXT,
avatar_url TEXT,
-- Person-spezifische Felder
salutation TEXT,
first_name TEXT,
last_name TEXT,
company TEXT,
position TEXT,
email TEXT,
phone TEXT,
mobile TEXT,
address TEXT,
postal_code TEXT,
city TEXT,
country TEXT,
department TEXT,
parent_company_id INTEGER,
-- Firma-spezifische Felder
company_name TEXT,
company_type TEXT,
industry TEXT,
website TEXT,
notes TEXT,
tags TEXT,
-- Meta
project_id INTEGER NOT NULL,
created_by INTEGER NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
created_by INTEGER,
FOREIGN KEY (parent_company_id) REFERENCES contacts(id) ON DELETE SET NULL,
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
FOREIGN KEY (created_by) REFERENCES users(id)
)
`);
// Kontaktdetails (E-Mails, Telefone, Adressen)
db.exec(`
CREATE TABLE IF NOT EXISTS contact_details (
id INTEGER PRIMARY KEY AUTOINCREMENT,
contact_id INTEGER NOT NULL,
type TEXT NOT NULL CHECK(type IN ('email', 'phone', 'mobile', 'fax', 'address', 'social')),
label TEXT DEFAULT 'Arbeit',
value TEXT NOT NULL,
is_primary BOOLEAN DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE
)
`);
// Kontakt-Kategorien
db.exec(`
CREATE TABLE IF NOT EXISTS contact_categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
color TEXT DEFAULT '#6B7280',
icon TEXT,
project_id INTEGER,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
)
`);
// Kontakt-Kategorie Zuordnungen
db.exec(`
CREATE TABLE IF NOT EXISTS contact_to_categories (
contact_id INTEGER NOT NULL,
category_id INTEGER NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (contact_id, category_id),
FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE,
FOREIGN KEY (category_id) REFERENCES contact_categories(id) ON DELETE CASCADE
)
`);
// Interaktionen/Historie
db.exec(`
CREATE TABLE IF NOT EXISTS contact_interactions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
contact_id INTEGER NOT NULL,
type TEXT NOT NULL CHECK(type IN ('call', 'email', 'meeting', 'note', 'task')),
subject TEXT,
content TEXT,
interaction_date DATETIME DEFAULT CURRENT_TIMESTAMP,
created_by INTEGER NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE,
FOREIGN KEY (created_by) REFERENCES users(id)
)
`);
// Trigger für updated_at auf Kontakte-Tabelle
db.exec(`
CREATE TRIGGER IF NOT EXISTS update_contacts_timestamp
AFTER UPDATE ON contacts
BEGIN
UPDATE contacts SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END
`);
// Indizes für Performance
db.exec(`
CREATE INDEX IF NOT EXISTS idx_tasks_project ON tasks(project_id);
@@ -660,8 +738,16 @@ function createTables() {
CREATE INDEX IF NOT EXISTS idx_coding_directories_position ON coding_directories(position);
CREATE INDEX IF NOT EXISTS idx_coding_usage_directory ON coding_usage(directory_id);
CREATE INDEX IF NOT EXISTS idx_coding_usage_timestamp ON coding_usage(timestamp);
CREATE INDEX IF NOT EXISTS idx_contacts_company ON contacts(company);
CREATE INDEX IF NOT EXISTS idx_contacts_tags ON contacts(tags);
-- Kontakt-Indizes für Performance
CREATE INDEX IF NOT EXISTS idx_contacts_type ON contacts(type);
CREATE INDEX IF NOT EXISTS idx_contacts_status ON contacts(status);
CREATE INDEX IF NOT EXISTS idx_contacts_project ON contacts(project_id);
CREATE INDEX IF NOT EXISTS idx_contacts_parent ON contacts(parent_company_id);
CREATE INDEX IF NOT EXISTS idx_contacts_display_name ON contacts(display_name);
CREATE INDEX IF NOT EXISTS idx_details_contact ON contact_details(contact_id);
CREATE INDEX IF NOT EXISTS idx_details_type ON contact_details(type);
CREATE INDEX IF NOT EXISTS idx_interactions_contact ON contact_interactions(contact_id);
CREATE INDEX IF NOT EXISTS idx_interactions_date ON contact_interactions(interaction_date);
`);
logger.info('Datenbank-Tabellen erstellt');