feat: 4-tier role concept, personal balance & cash register system, left off-canvas drawer navigation

This commit is contained in:
2026-09-22 09:05:14 +02:00
parent 0bdcbe7976
commit 896f1d7d08
8 changed files with 1350 additions and 257 deletions
+25 -3
View File
@@ -1,4 +1,4 @@
from sqlalchemy import Column, Integer, String, Boolean, DateTime, Date, Numeric, ForeignKey, func
from sqlalchemy import Column, Integer, String, Boolean, DateTime, Date, Numeric, ForeignKey, func, desc
from sqlalchemy.orm import relationship
from .database import Base
@@ -30,12 +30,33 @@ class User(Base):
password_hash = Column(String(255), default="")
first_name = Column(String(100), nullable=False)
last_name = Column(String(100), nullable=False)
role = Column(String(20), default="user") # 'admin', 'user', 'guest'
role = Column(String(20), default="user") # 'admin', 'organizer', 'user', 'guest'
balance = Column(Numeric(10, 2), default=0.00, nullable=False)
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, default=func.now())
tenant = relationship("Tenant", back_populates="users")
orders = relationship("Order", back_populates="user")
transactions = relationship("BalanceTransaction", foreign_keys="BalanceTransaction.user_id", back_populates="user", order_by="desc(BalanceTransaction.created_at)")
class BalanceTransaction(Base):
__tablename__ = "balance_transactions"
id = Column(Integer, primary_key=True, index=True)
tenant_id = Column(Integer, ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False)
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
order_id = Column(Integer, ForeignKey("orders.id", ondelete="SET NULL"), nullable=True)
amount = Column(Numeric(10, 2), nullable=False)
transaction_type = Column(String(30), nullable=False) # 'deposit', 'order_charge', 'adjustment', 'refund'
description = Column(String(255), nullable=True)
created_by_id = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
created_at = Column(DateTime, default=func.now())
tenant = relationship("Tenant")
user = relationship("User", foreign_keys=[user_id], back_populates="transactions")
order = relationship("Order")
created_by = relationship("User", foreign_keys=[created_by_id])
class Invitation(Base):
@@ -45,7 +66,7 @@ class Invitation(Base):
tenant_id = Column(Integer, ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False)
token = Column(String(64), unique=True, index=True, nullable=False)
email = Column(String(191), nullable=True)
role = Column(String(20), default="user", nullable=False)
role = Column(String(20), default="user", nullable=False) # 'admin', 'organizer', 'user', 'guest'
created_by = Column(Integer, nullable=True)
expires_at = Column(DateTime, nullable=True)
used_at = Column(DateTime, nullable=True)
@@ -100,6 +121,7 @@ class Order(Base):
guest_display_name = Column(String(150), nullable=True)
total_price = Column(Numeric(10, 2), nullable=False, default=0.00)
is_paid = Column(Boolean, default=False)
payment_method = Column(String(30), default="cash") # 'cash', 'balance', 'sponsored'
created_at = Column(DateTime, default=func.now())
tenant = relationship("Tenant", back_populates="orders")