feat(local_backend): reservations, print analytics, workday summary, zone-PIN management
- New reservations module: model, schema, router (CRUD + status updates + upcoming alerts) and background task for auto-expiring stale reservations - Reports: print_products, print_categories, print_tables analytics endpoints plus meta_products and business_day_summary for workday close/view flow - printer_service: configurable font sizes/weights, donut/bar chart print layout helpers, analytics print blocks per printer - tables/schemas: surfaced color, zone, and other new fields on Table, Product, User, Printer - demo_seed.py for quick dev DB population; wipe_database.py utility Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,7 @@ 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
|
||||
import models.reservation # noqa: F401
|
||||
|
||||
from routers import auth, tables, products, orders, waiters, reports, system, setup as setup_router
|
||||
from routers import business_day as business_day_router
|
||||
@@ -29,6 +30,7 @@ from routers import messages as messages_router
|
||||
from routers import sse as sse_router
|
||||
from routers import data_transfer as data_transfer_router
|
||||
from routers import connect_orders as connect_orders_router
|
||||
from routers import reservations as reservations_router
|
||||
|
||||
|
||||
def _run_migrations():
|
||||
@@ -237,6 +239,29 @@ def _run_migrations():
|
||||
"ALTER TABLE products ADD COLUMN digital_price REAL",
|
||||
"ALTER TABLE products ADD COLUMN digital_discount REAL NOT NULL DEFAULT 0.0",
|
||||
"ALTER TABLE products ADD COLUMN digital_image_url VARCHAR",
|
||||
# Per-printer line width (chars per line) — default 48 for 80mm Jolimark
|
||||
"ALTER TABLE printers ADD COLUMN line_width INTEGER NOT NULL DEFAULT 48",
|
||||
# Product description (plain-text, for menu display)
|
||||
"ALTER TABLE products ADD COLUMN description TEXT",
|
||||
# Staff note (internal memo on a waiter's profile)
|
||||
"ALTER TABLE users ADD COLUMN note VARCHAR",
|
||||
# Reservations table
|
||||
"""CREATE TABLE IF NOT EXISTS reservations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
guest_name VARCHAR NOT NULL,
|
||||
party_size INTEGER NOT NULL,
|
||||
phone VARCHAR,
|
||||
email VARCHAR,
|
||||
note TEXT,
|
||||
reserved_for DATETIME NOT NULL,
|
||||
table_id INTEGER REFERENCES tables(id),
|
||||
status VARCHAR NOT NULL DEFAULT 'pending',
|
||||
source VARCHAR NOT NULL DEFAULT 'manager_app',
|
||||
created_by_user_id INTEGER REFERENCES users(id),
|
||||
online_customer_id VARCHAR,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)""",
|
||||
]
|
||||
for sql in migrations:
|
||||
try:
|
||||
@@ -251,12 +276,15 @@ def _run_migrations():
|
||||
async def lifespan(app: FastAPI):
|
||||
import asyncio
|
||||
from services.sse_bus import init_loop
|
||||
from services.reservation_tasks import start_reservation_tasks
|
||||
init_loop(asyncio.get_running_loop())
|
||||
Base.metadata.create_all(bind=engine)
|
||||
_run_migrations()
|
||||
sync_task = await start_cloud_sync()
|
||||
reservation_task = await start_reservation_tasks()
|
||||
yield
|
||||
sync_task.cancel()
|
||||
reservation_task.cancel()
|
||||
|
||||
|
||||
app = FastAPI(title="POS Local Backend", lifespan=lifespan)
|
||||
@@ -295,3 +323,4 @@ app.include_router(messages_router.router, prefix="/api/messages", tag
|
||||
app.include_router(sse_router.router, prefix="/api/sse", tags=["sse"])
|
||||
app.include_router(data_transfer_router.router, prefix="/api/data-transfer", tags=["data-transfer"])
|
||||
app.include_router(connect_orders_router.router, prefix="/api/connect", tags=["connect"])
|
||||
app.include_router(reservations_router.router, prefix="/api/reservations", tags=["reservations"])
|
||||
|
||||
Reference in New Issue
Block a user