Backend overhaul: new models, routers, schemas for shifts, business day, flags, messages, settings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,13 +9,23 @@ from middleware.license_check import LicenseCheckMiddleware
|
||||
from services.cloud_sync import start_cloud_sync
|
||||
|
||||
# Import all models so SQLAlchemy can create their tables
|
||||
import models.user # noqa: F401 — also registers WaiterZone
|
||||
import models.table # noqa: F401
|
||||
import models.printer # noqa: F401
|
||||
import models.product # noqa: F401
|
||||
import models.order # noqa: F401 — also registers OrderAuditLog, OrderDiscount
|
||||
import models.user # noqa: F401 — also registers WaiterZone
|
||||
import models.table # noqa: F401
|
||||
import models.printer # noqa: F401
|
||||
import models.product # noqa: F401
|
||||
import models.order # noqa: F401 — also registers OrderAuditLog, OrderDiscount
|
||||
import models.business_day # noqa: F401
|
||||
import models.shift # noqa: F401 — registers WaiterShift, ShiftBreak
|
||||
import models.settings # noqa: F401
|
||||
import models.flag # noqa: F401 — registers TableFlagDef, TableFlagAssignment
|
||||
import models.message # noqa: F401 — registers StaffMessage, StaffMessageAck, QuickMessageTemplate
|
||||
|
||||
from routers import auth, tables, products, orders, waiters, reports, system
|
||||
from routers import business_day as business_day_router
|
||||
from routers import shifts as shifts_router
|
||||
from routers import settings as settings_router
|
||||
from routers import flags as flags_router
|
||||
from routers import messages as messages_router
|
||||
|
||||
|
||||
def _run_migrations():
|
||||
@@ -64,6 +74,17 @@ def _run_migrations():
|
||||
"ALTER TABLE users ADD COLUMN nickname VARCHAR",
|
||||
"ALTER TABLE users ADD COLUMN mobile_phone VARCHAR",
|
||||
"ALTER TABLE users ADD COLUMN avatar_url VARCHAR",
|
||||
# Quick options (flat, allow_multiple)
|
||||
"""CREATE TABLE IF NOT EXISTS product_quick_options (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
product_id INTEGER NOT NULL REFERENCES products(id),
|
||||
name VARCHAR NOT NULL,
|
||||
price REAL NOT NULL DEFAULT 0.0,
|
||||
allow_multiple INTEGER NOT NULL DEFAULT 0,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0
|
||||
)""",
|
||||
# allow_multiple flag on extras (product_options)
|
||||
"ALTER TABLE product_options ADD COLUMN allow_multiple INTEGER NOT NULL DEFAULT 0",
|
||||
# Discounts table (future-proofed, schema ready now)
|
||||
"""CREATE TABLE IF NOT EXISTS order_discounts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -75,6 +96,87 @@ def _run_migrations():
|
||||
applied_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
reason TEXT
|
||||
)""",
|
||||
# Business day scoping on orders
|
||||
"ALTER TABLE orders ADD COLUMN business_day_id INTEGER REFERENCES business_days(id)",
|
||||
# Shift attribution on paid items
|
||||
"ALTER TABLE order_items ADD COLUMN paid_in_shift_id INTEGER REFERENCES waiter_shifts(id)",
|
||||
# Seed default POS settings (INSERT OR IGNORE = no-op if already exists)
|
||||
"INSERT OR IGNORE INTO pos_settings (key, value, updated_at) VALUES ('shifts.waiter_self_start', 'true', CURRENT_TIMESTAMP)",
|
||||
"INSERT OR IGNORE INTO pos_settings (key, value, updated_at) VALUES ('shifts.waiter_self_end', 'true', CURRENT_TIMESTAMP)",
|
||||
"INSERT OR IGNORE INTO pos_settings (key, value, updated_at) VALUES ('business_day.force_close_allowed', 'true', CURRENT_TIMESTAMP)",
|
||||
"INSERT OR IGNORE INTO pos_settings (key, value, updated_at) VALUES ('flags.display_mode', 'both', CURRENT_TIMESTAMP)",
|
||||
# Table flags
|
||||
"""CREATE TABLE IF NOT EXISTS table_flag_defs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name VARCHAR NOT NULL,
|
||||
emoji VARCHAR,
|
||||
color VARCHAR DEFAULT '#6b7280',
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)""",
|
||||
"""CREATE TABLE IF NOT EXISTS table_flag_assignments (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
table_id INTEGER NOT NULL REFERENCES tables(id),
|
||||
flag_id INTEGER NOT NULL REFERENCES table_flag_defs(id),
|
||||
assigned_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
assigned_by INTEGER REFERENCES users(id)
|
||||
)""",
|
||||
# Staff messaging
|
||||
"""CREATE TABLE IF NOT EXISTS quick_message_templates (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
body VARCHAR NOT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)""",
|
||||
"""CREATE TABLE IF NOT EXISTS staff_messages (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sender_id INTEGER NOT NULL REFERENCES users(id),
|
||||
body TEXT NOT NULL,
|
||||
target_waiter_ids TEXT NOT NULL DEFAULT '[]',
|
||||
table_ids TEXT NOT NULL DEFAULT '[]',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)""",
|
||||
"""CREATE TABLE IF NOT EXISTS staff_message_acks (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
message_id INTEGER NOT NULL REFERENCES staff_messages(id),
|
||||
waiter_id INTEGER NOT NULL REFERENCES users(id),
|
||||
acked_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)""",
|
||||
# Seed default flag definitions
|
||||
"INSERT OR IGNORE INTO table_flag_defs (id, name, emoji, color, sort_order) VALUES (1, 'Χρειάζεται καθάρισμα', '🧹', '#ef4444', 1)",
|
||||
"INSERT OR IGNORE INTO table_flag_defs (id, name, emoji, color, sort_order) VALUES (2, 'Χρειάζεται Βοήθεια', '🆘', '#f97316', 2)",
|
||||
"INSERT OR IGNORE INTO table_flag_defs (id, name, emoji, color, sort_order) VALUES (3, 'Χρειάζεται Σερβιτόρο', '🔔', '#eab308', 3)",
|
||||
"INSERT OR IGNORE INTO table_flag_defs (id, name, emoji, color, sort_order) VALUES (4, 'Περιμένει να πληρώσει', '💳', '#3b82f6', 4)",
|
||||
"INSERT OR IGNORE INTO table_flag_defs (id, name, emoji, color, sort_order) VALUES (5, 'VIP', '⭐', '#8b5cf6', 5)",
|
||||
"INSERT OR IGNORE INTO table_flag_defs (id, name, emoji, color, sort_order) VALUES (6, 'Ευγενικός Πελάτης', '😊', '#22c55e', 6)",
|
||||
"INSERT OR IGNORE INTO table_flag_defs (id, name, emoji, color, sort_order) VALUES (7, 'Αγενής Πελάτης', '😤', '#dc2626', 7)",
|
||||
"INSERT OR IGNORE INTO table_flag_defs (id, name, emoji, color, sort_order) VALUES (8, 'Αλλεργίες', '⚠️', '#f59e0b', 8)",
|
||||
"INSERT OR IGNORE INTO table_flag_defs (id, name, emoji, color, sort_order) VALUES (9, 'Παιδιά στο τραπέζι', '👶', '#06b6d4', 9)",
|
||||
"INSERT OR IGNORE INTO table_flag_defs (id, name, emoji, color, sort_order) VALUES (10, 'Επέτειος / Γενέθλια', '🎂', '#ec4899', 10)",
|
||||
# Seed default quick message templates
|
||||
"INSERT OR IGNORE INTO quick_message_templates (id, body, sort_order) VALUES (1, 'Σε χρειάζομαι τώρα', 1)",
|
||||
"INSERT OR IGNORE INTO quick_message_templates (id, body, sort_order) VALUES (2, 'Πάρε διάλειμμα', 2)",
|
||||
"INSERT OR IGNORE INTO quick_message_templates (id, body, sort_order) VALUES (3, 'Ετοιμάσου για κλείσιμο', 3)",
|
||||
"INSERT OR IGNORE INTO quick_message_templates (id, body, sort_order) VALUES (4, 'Ήρθε νέος πελάτης', 4)",
|
||||
"INSERT OR IGNORE INTO quick_message_templates (id, body, sort_order) VALUES (5, 'Ο πελάτης περιμένει να πληρώσει', 5)",
|
||||
# Product lifecycle status (active / archived)
|
||||
"ALTER TABLE products ADD COLUMN lifecycle_status VARCHAR NOT NULL DEFAULT 'active'",
|
||||
# Favorite flags + ordering on all product sub-item types
|
||||
"ALTER TABLE product_quick_options ADD COLUMN is_favorite INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE product_quick_options ADD COLUMN favorite_sort_order INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE product_options ADD COLUMN is_favorite INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE product_options ADD COLUMN favorite_sort_order INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE product_ingredients ADD COLUMN is_favorite INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE product_ingredients ADD COLUMN favorite_sort_order INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE product_preference_sets ADD COLUMN is_favorite INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE product_preference_sets ADD COLUMN favorite_sort_order INTEGER NOT NULL DEFAULT 0",
|
||||
# Sub-category support
|
||||
"ALTER TABLE categories ADD COLUMN parent_id INTEGER REFERENCES categories(id)",
|
||||
"ALTER TABLE categories ADD COLUMN general_sort_order INTEGER NOT NULL DEFAULT 0",
|
||||
# Auto-expand flag for sub-categories on the PWA accordion
|
||||
"ALTER TABLE categories ADD COLUMN auto_expanded INTEGER NOT NULL DEFAULT 0",
|
||||
]
|
||||
for sql in migrations:
|
||||
try:
|
||||
@@ -114,10 +216,15 @@ AVATAR_DIR = "/app/data/avatars"
|
||||
os.makedirs(AVATAR_DIR, exist_ok=True)
|
||||
app.mount("/static/avatars", StaticFiles(directory=AVATAR_DIR), name="avatars")
|
||||
|
||||
app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
|
||||
app.include_router(tables.router, prefix="/api/tables", tags=["tables"])
|
||||
app.include_router(products.router, prefix="/api/products", tags=["products"])
|
||||
app.include_router(orders.router, prefix="/api/orders", tags=["orders"])
|
||||
app.include_router(waiters.router, prefix="/api/waiters", tags=["waiters"])
|
||||
app.include_router(reports.router, prefix="/api/reports", tags=["reports"])
|
||||
app.include_router(system.router, prefix="/api/system", tags=["system"])
|
||||
app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
|
||||
app.include_router(tables.router, prefix="/api/tables", tags=["tables"])
|
||||
app.include_router(products.router, prefix="/api/products", tags=["products"])
|
||||
app.include_router(orders.router, prefix="/api/orders", tags=["orders"])
|
||||
app.include_router(waiters.router, prefix="/api/waiters", tags=["waiters"])
|
||||
app.include_router(reports.router, prefix="/api/reports", tags=["reports"])
|
||||
app.include_router(system.router, prefix="/api/system", tags=["system"])
|
||||
app.include_router(business_day_router.router, prefix="/api/business-day", tags=["business-day"])
|
||||
app.include_router(shifts_router.router, prefix="/api/shifts", tags=["shifts"])
|
||||
app.include_router(settings_router.router, prefix="/api/settings", tags=["settings"])
|
||||
app.include_router(flags_router.router, prefix="/api/flags", tags=["flags"])
|
||||
app.include_router(messages_router.router, prefix="/api/messages", tags=["messages"])
|
||||
|
||||
Reference in New Issue
Block a user