backend/db.js gelöscht
This commit is contained in:
204
backend/db.js
204
backend/db.js
@@ -1,204 +0,0 @@
|
|||||||
const Database = require('better-sqlite3');
|
|
||||||
const bcrypt = require('bcryptjs');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const db = new Database(process.env.DB_PATH || '/data/dickendock.db');
|
|
||||||
db.pragma('journal_mode = WAL');
|
|
||||||
db.pragma('foreign_keys = ON');
|
|
||||||
|
|
||||||
db.exec(`
|
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
username TEXT UNIQUE NOT NULL,
|
|
||||||
password_hash TEXT NOT NULL,
|
|
||||||
role TEXT NOT NULL DEFAULT 'user',
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Dashboard-Widgets
|
|
||||||
CREATE TABLE IF NOT EXISTS quick_links (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
title TEXT NOT NULL,
|
|
||||||
url TEXT NOT NULL,
|
|
||||||
icon TEXT NOT NULL DEFAULT '🔗',
|
|
||||||
sort_order INTEGER DEFAULT 0
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS todos (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
text TEXT NOT NULL,
|
|
||||||
done INTEGER NOT NULL DEFAULT 0,
|
|
||||||
sort_order INTEGER DEFAULT 0,
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS notes (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
user_id INTEGER NOT NULL UNIQUE REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
content TEXT NOT NULL DEFAULT '',
|
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Tool: 3D-Kalkulator
|
|
||||||
CREATE TABLE IF NOT EXISTS calendar_feeds (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
url TEXT NOT NULL,
|
|
||||||
color TEXT NOT NULL DEFAULT '#4ecdc4',
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS folders (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
parent_id INTEGER REFERENCES folders(id) ON DELETE CASCADE,
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS folder_shares (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
folder_id INTEGER NOT NULL REFERENCES folders(id) ON DELETE CASCADE,
|
|
||||||
shared_by INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
shared_with INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
UNIQUE(folder_id, shared_with)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS files (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
filename TEXT NOT NULL,
|
|
||||||
originalname TEXT NOT NULL,
|
|
||||||
mimetype TEXT NOT NULL DEFAULT 'application/octet-stream',
|
|
||||||
size INTEGER NOT NULL,
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS file_shares (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
||||||
shared_by INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
shared_with INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
UNIQUE(file_id, shared_with)
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS user_keys (
|
|
||||||
user_id INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
public_key TEXT NOT NULL,
|
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS push_subscriptions (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
endpoint TEXT NOT NULL UNIQUE,
|
|
||||||
p256dh TEXT NOT NULL,
|
|
||||||
auth TEXT NOT NULL,
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS messages (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
sender_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
recipient_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
encrypted_content TEXT NOT NULL,
|
|
||||||
iv TEXT NOT NULL,
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
deleted_by_sender INTEGER NOT NULL DEFAULT 0,
|
|
||||||
deleted_by_recipient INTEGER NOT NULL DEFAULT 0
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS admin_settings (
|
|
||||||
key TEXT PRIMARY KEY,
|
|
||||||
value TEXT NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS orders (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
bemerkung TEXT NOT NULL DEFAULT '',
|
|
||||||
status TEXT NOT NULL DEFAULT 'warteliste',
|
|
||||||
custom_price REAL,
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS order_items (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
order_id INTEGER NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
|
|
||||||
calculation_id INTEGER REFERENCES calculations(id) ON DELETE SET NULL,
|
|
||||||
calc_name TEXT NOT NULL,
|
|
||||||
preis_freundschaft REAL NOT NULL,
|
|
||||||
preis_normal REAL NOT NULL,
|
|
||||||
preis_auftrag REAL NOT NULL,
|
|
||||||
stueckzahl INTEGER NOT NULL DEFAULT 1
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS calculations (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
gramm REAL NOT NULL,
|
|
||||||
stunden REAL NOT NULL,
|
|
||||||
farben INTEGER NOT NULL DEFAULT 1,
|
|
||||||
materialpreis_pro_gramm REAL NOT NULL DEFAULT 0.01,
|
|
||||||
stromverbrauch_kw REAL NOT NULL DEFAULT 0.15,
|
|
||||||
strompreis_pro_kwh REAL NOT NULL DEFAULT 0.38,
|
|
||||||
druckerpreis REAL NOT NULL DEFAULT 550,
|
|
||||||
gesamtdruckstunden REAL NOT NULL DEFAULT 5000,
|
|
||||||
verschleiss_pro_stunde REAL NOT NULL DEFAULT 0.06,
|
|
||||||
preis_freundschaft REAL NOT NULL,
|
|
||||||
preis_normal REAL NOT NULL,
|
|
||||||
preis_auftrag REAL NOT NULL,
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
`);
|
|
||||||
|
|
||||||
// Standard-Admin beim ersten Start anlegen
|
|
||||||
// Default admin settings
|
|
||||||
const settingDefaults = [
|
|
||||||
['file_max_size_mb', '50'],
|
|
||||||
['file_max_count', '20'],
|
|
||||||
['file_allowed_ext', '.pdf,.jpg,.jpeg,.png,.gif,.zip,.txt,.docx,.xlsx,.mp4,.stl,.3mf'],
|
|
||||||
];
|
|
||||||
for (const [key, value] of settingDefaults) {
|
|
||||||
if (!db.prepare('SELECT key FROM admin_settings WHERE key=?').get(key))
|
|
||||||
db.prepare('INSERT INTO admin_settings (key,value) VALUES (?,?)').run(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (db.prepare('SELECT COUNT(*) c FROM users').get().c === 0) {
|
|
||||||
db.prepare('INSERT INTO users (username, password_hash, role) VALUES (?, ?, ?)')
|
|
||||||
.run('admin', bcrypt.hashSync('admin123', 12), 'admin');
|
|
||||||
console.log('✅ Erster Start: Admin angelegt: admin / admin123 → Bitte Passwort sofort ändern!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Migrationen (werden bei jedem Start geprüft) ─────────────────────────────
|
|
||||||
const cols = db.prepare("PRAGMA table_info(calculations)").all().map(r => r.name);
|
|
||||||
if (!cols.includes('image')) db.exec("ALTER TABLE calculations ADD COLUMN image TEXT");
|
|
||||||
if (!cols.includes('bemerkung')) db.exec("ALTER TABLE calculations ADD COLUMN bemerkung TEXT NOT NULL DEFAULT ''");
|
|
||||||
|
|
||||||
// Migrationen orders
|
|
||||||
const ordCols = db.prepare("PRAGMA table_info(orders)").all().map(r => r.name);
|
|
||||||
if (!ordCols.includes('bezahlt')) db.exec("ALTER TABLE orders ADD COLUMN bezahlt INTEGER NOT NULL DEFAULT 0");
|
|
||||||
if (!ordCols.includes('bezahlt_am')) db.exec("ALTER TABLE orders ADD COLUMN bezahlt_am DATETIME");
|
|
||||||
|
|
||||||
// Migrationen order_items
|
|
||||||
// files migrations
|
|
||||||
const fileCols = db.prepare("PRAGMA table_info(files)").all().map(r => r.name);
|
|
||||||
if (!fileCols.includes('folder_id')) db.exec("ALTER TABLE files ADD COLUMN folder_id INTEGER REFERENCES folders(id) ON DELETE SET NULL");
|
|
||||||
|
|
||||||
// folder_shares migrations (only if table exists)
|
|
||||||
const fsTableExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='folder_shares'").get();
|
|
||||||
if (fsTableExists) {
|
|
||||||
const fsCols = db.prepare("PRAGMA table_info(folder_shares)").all().map(r => r.name);
|
|
||||||
if (!fsCols.includes('created_at')) db.exec("ALTER TABLE folder_shares ADD COLUMN created_at DATETIME DEFAULT NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
const oiCols = db.prepare("PRAGMA table_info(order_items)").all().map(r => r.name);
|
|
||||||
if (!oiCols.includes('stunden')) db.exec("ALTER TABLE order_items ADD COLUMN stunden REAL NOT NULL DEFAULT 0");
|
|
||||||
if (!oiCols.includes('custom_price')) db.exec("ALTER TABLE order_items ADD COLUMN custom_price REAL");
|
|
||||||
if (!oiCols.includes('status')) db.exec("ALTER TABLE order_items ADD COLUMN status TEXT NOT NULL DEFAULT 'warteliste'");
|
|
||||||
if (!oiCols.includes('qty_warteliste')) db.exec("ALTER TABLE order_items ADD COLUMN qty_warteliste INTEGER NOT NULL DEFAULT 0");
|
|
||||||
if (!oiCols.includes('qty_in_arbeit')) db.exec("ALTER TABLE order_items ADD COLUMN qty_in_arbeit INTEGER NOT NULL DEFAULT 0");
|
|
||||||
if (!oiCols.includes('qty_fertig')) db.exec("ALTER TABLE order_items ADD COLUMN qty_fertig INTEGER NOT NULL DEFAULT 0");
|
|
||||||
// Bestehende Einträge: alle Stücke auf Warteliste setzen falls noch keine Qtys gesetzt
|
|
||||||
db.exec("UPDATE order_items SET qty_warteliste=stueckzahl WHERE qty_warteliste=0 AND qty_in_arbeit=0 AND qty_fertig=0");
|
|
||||||
module.exports = db;
|
|
||||||
Reference in New Issue
Block a user