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:
@@ -10,8 +10,16 @@ class Category(Base):
|
||||
name = Column(String, nullable=False)
|
||||
color = Column(String, nullable=True)
|
||||
sort_order = Column(Integer, default=0)
|
||||
# self-referential: null = top-level, non-null = sub-category of parent
|
||||
parent_id = Column(Integer, ForeignKey("categories.id"), nullable=True)
|
||||
# position of the "General" group (direct products) among sub-categories
|
||||
general_sort_order = Column(Integer, default=0, nullable=False)
|
||||
# sub-categories only: if True, the accordion section is expanded by default on the PWA
|
||||
auto_expanded = Column(Boolean, default=False, nullable=False)
|
||||
|
||||
products = relationship("Product", back_populates="category")
|
||||
subcategories = relationship("Category", back_populates="parent", foreign_keys="Category.parent_id")
|
||||
parent = relationship("Category", back_populates="subcategories", remote_side="Category.id", foreign_keys="Category.parent_id")
|
||||
|
||||
|
||||
class Product(Base):
|
||||
@@ -22,12 +30,15 @@ class Product(Base):
|
||||
category_id = Column(Integer, ForeignKey("categories.id"), nullable=True)
|
||||
base_price = Column(Float, nullable=False)
|
||||
is_available = Column(Boolean, default=True, nullable=False)
|
||||
# "active" | "archived" — archived products are kept for order history but hidden from active use
|
||||
lifecycle_status = Column(String, default="active", nullable=False)
|
||||
printer_zone_id = Column(Integer, ForeignKey("printers.id"), nullable=True)
|
||||
image_url = Column(String, nullable=True)
|
||||
sort_order = Column(Integer, default=0, nullable=False)
|
||||
|
||||
category = relationship("Category", back_populates="products")
|
||||
printer_zone = relationship("Printer", back_populates="products")
|
||||
quick_options = relationship("ProductQuickOption", back_populates="product", cascade="all, delete-orphan")
|
||||
options = relationship("ProductOption", back_populates="product", cascade="all, delete-orphan")
|
||||
ingredients = relationship("ProductIngredient", back_populates="product", cascade="all, delete-orphan")
|
||||
preference_sets = relationship("ProductPreferenceSet", back_populates="product", cascade="all, delete-orphan")
|
||||
@@ -41,12 +52,30 @@ class ProductOption(Base):
|
||||
product_id = Column(Integer, ForeignKey("products.id"), nullable=False)
|
||||
name = Column(String, nullable=False)
|
||||
extra_cost = Column(Float, default=0.0)
|
||||
allow_multiple = Column(Boolean, default=False, nullable=False)
|
||||
# JSON array [{name, extra_cost, is_default}] — sub-options shown when this option is checked
|
||||
sub_choices = Column(Text, nullable=True)
|
||||
is_favorite = Column(Boolean, default=False, nullable=False)
|
||||
favorite_sort_order = Column(Integer, default=0, nullable=False)
|
||||
|
||||
product = relationship("Product", back_populates="options")
|
||||
|
||||
|
||||
class ProductQuickOption(Base):
|
||||
__tablename__ = "product_quick_options"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
product_id = Column(Integer, ForeignKey("products.id"), nullable=False)
|
||||
name = Column(String, nullable=False)
|
||||
price = Column(Float, default=0.0, nullable=False)
|
||||
allow_multiple = Column(Boolean, default=False, nullable=False)
|
||||
sort_order = Column(Integer, default=0, nullable=False)
|
||||
is_favorite = Column(Boolean, default=False, nullable=False)
|
||||
favorite_sort_order = Column(Integer, default=0, nullable=False)
|
||||
|
||||
product = relationship("Product", back_populates="quick_options")
|
||||
|
||||
|
||||
class ProductIngredient(Base):
|
||||
__tablename__ = "product_ingredients"
|
||||
|
||||
@@ -54,6 +83,8 @@ class ProductIngredient(Base):
|
||||
product_id = Column(Integer, ForeignKey("products.id"), nullable=False)
|
||||
name = Column(String, nullable=False)
|
||||
extra_cost = Column(Float, default=0.0)
|
||||
is_favorite = Column(Boolean, default=False, nullable=False)
|
||||
favorite_sort_order = Column(Integer, default=0, nullable=False)
|
||||
|
||||
product = relationship("Product", back_populates="ingredients")
|
||||
|
||||
@@ -68,6 +99,8 @@ class ProductPreferenceSet(Base):
|
||||
# JSON: {name, default_choice_index, choices:[{name,extra_cost,is_default}]}
|
||||
# Shared sub-set shown for all choices that don't have disables_subset=True
|
||||
shared_subset = Column(Text, nullable=True)
|
||||
is_favorite = Column(Boolean, default=False, nullable=False)
|
||||
favorite_sort_order = Column(Integer, default=0, nullable=False)
|
||||
|
||||
product = relationship("Product", back_populates="preference_sets")
|
||||
choices = relationship("ProductPreferenceChoice", back_populates="set", cascade="all, delete-orphan")
|
||||
|
||||
Reference in New Issue
Block a user