Initial kitchen scaffold — Phase 1 kitchen port (build-verified 2026-07-11)

FastAPI backend (Python 3.11, MSSQL ODBC for SambaPOS, Azure DI OCR),
kitchen_db on central PG. React/TS/Vite frontend with navy sidebar layout.

Backend: auth.py (APP_SLUG=kitchen, SimpleNamespace — archive routes use
.kitchen_id/.is_admin without modification), main.py (51 migrations, scheduler,
internal router for KDS bookings feed), api/internal.py, full archive API
(31 routers: invoices, recipes, menus, sambapos, resos, newbook, disputes,
purchase_orders, etc.), models, migrations, OCR pipeline.
kitchen_id pinned to 1 (B1 — single hotel).

Frontend: AuthGate (app=kitchen, token shim for archive compat — B5b pending),
Layout (navy sidebar, 6 sections, Lucide icons, teal --app-primary),
App.tsx (Outlet pattern, UploadApp outside Layout), index.css (full :root block).
strict: false — archive components have type issues; build clean.

Note: 45 archive components call fetch('/api/...') without /kitchen/ prefix
(B5b). Runtime 404s; deferred until after initial testing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-12 12:15:39 +00:00
commit 8d688b459d
10003 changed files with 1928395 additions and 0 deletions

View file

@ -0,0 +1,50 @@
"""
AcknowledgedPrice model for tracking user-acknowledged price changes.
When a price change is detected and flagged, users can acknowledge it
to prevent it from being repeatedly flagged.
"""
from datetime import datetime
from decimal import Decimal
from sqlalchemy import ForeignKey, String, Text, Numeric, DateTime, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from database import Base
class AcknowledgedPrice(Base):
"""Tracks acknowledged price changes for line items."""
__tablename__ = "acknowledged_prices"
id: Mapped[int] = mapped_column(primary_key=True)
kitchen_id: Mapped[int] = mapped_column(ForeignKey("kitchens.id"))
supplier_id: Mapped[int] = mapped_column(ForeignKey("suppliers.id"))
# Product identification (same logic as line item consolidation)
product_code: Mapped[str | None] = mapped_column(String(100), nullable=True)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
# The acknowledged price point
acknowledged_price: Mapped[Decimal] = mapped_column(Numeric(10, 2))
acknowledged_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
acknowledged_by_user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
# Which invoice triggered this acknowledgement
source_invoice_id: Mapped[int | None] = mapped_column(ForeignKey("invoices.id"), nullable=True)
source_line_item_id: Mapped[int | None] = mapped_column(ForeignKey("line_items.id"), nullable=True)
# Relationships
kitchen = relationship("Kitchen", backref="acknowledged_prices")
supplier = relationship("Supplier", backref="acknowledged_prices")
acknowledged_by_user = relationship("User", backref="acknowledged_prices")
source_invoice = relationship("Invoice", backref="acknowledged_prices")
# Unique constraint: one acknowledged price per product per supplier per kitchen
__table_args__ = (
UniqueConstraint(
'kitchen_id', 'supplier_id', 'product_code', 'description',
name='uix_acknowledged_price'
),
)
def __repr__(self):
return f"<AcknowledgedPrice {self.id}: {self.product_code or self.description} @ {self.acknowledged_price}>"