sync: migrate secure-online-shop to Gitea (2026-08-10)

This commit is contained in:
konturai-ops
2026-08-10 15:26:59 +00:00
commit 2022c8890d
44 changed files with 3196 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
from app.models.base import Base
from app.models.order import Order, OrderStatusEnum
from app.models.order_item import OrderItem
from app.models.product import Product
from app.models.user import RoleEnum, User
__all__ = [
"Base",
"Order",
"OrderItem",
"OrderStatusEnum",
"Product",
"RoleEnum",
"User",
]
+5
View File
@@ -0,0 +1,5 @@
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
pass
+45
View File
@@ -0,0 +1,45 @@
from __future__ import annotations
from datetime import datetime, timezone
from decimal import Decimal
from enum import Enum
from sqlalchemy import CheckConstraint, DateTime, Enum as SqlEnum, ForeignKey, Numeric
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.models.base import Base
class OrderStatusEnum(str, Enum):
pending = "pending"
paid = "paid"
class Order(Base):
__tablename__ = "orders"
__table_args__ = (
CheckConstraint("total_amount >= 0", name="ck_orders_total_amount_non_negative"),
)
id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False, index=True)
total_amount: Mapped[Decimal] = mapped_column(Numeric(10, 2), nullable=False)
status: Mapped[OrderStatusEnum] = mapped_column(
SqlEnum(OrderStatusEnum, native_enum=False),
default=OrderStatusEnum.pending,
nullable=False,
)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
nullable=False,
)
paid_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
user = relationship("User", back_populates="orders")
items = relationship(
"OrderItem",
back_populates="order",
cascade="all, delete-orphan",
lazy="selectin",
)
+31
View File
@@ -0,0 +1,31 @@
from __future__ import annotations
from decimal import Decimal
from sqlalchemy import CheckConstraint, ForeignKey, Numeric
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.models.base import Base
class OrderItem(Base):
__tablename__ = "order_items"
__table_args__ = (
CheckConstraint("quantity > 0", name="ck_order_items_quantity_positive"),
CheckConstraint("unit_price > 0", name="ck_order_items_unit_price_positive"),
CheckConstraint("subtotal >= 0", name="ck_order_items_subtotal_non_negative"),
)
id: Mapped[int] = mapped_column(primary_key=True)
order_id: Mapped[int] = mapped_column(ForeignKey("orders.id"), nullable=False, index=True)
product_id: Mapped[int] = mapped_column(ForeignKey("products.id"), nullable=False, index=True)
quantity: Mapped[int] = mapped_column(nullable=False)
unit_price: Mapped[Decimal] = mapped_column(Numeric(10, 2), nullable=False)
subtotal: Mapped[Decimal] = mapped_column(Numeric(10, 2), nullable=False)
order = relationship("Order", back_populates="items")
product = relationship("Product", lazy="joined")
@property
def product_name(self) -> str:
return self.product.name
+29
View File
@@ -0,0 +1,29 @@
from __future__ import annotations
from datetime import datetime, timezone
from decimal import Decimal
from sqlalchemy import Boolean, CheckConstraint, DateTime, Numeric, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from app.models.base import Base
class Product(Base):
__tablename__ = "products"
__table_args__ = (
CheckConstraint("price > 0", name="ck_products_price_positive"),
CheckConstraint("stock >= 0", name="ck_products_stock_non_negative"),
)
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(120), nullable=False, index=True)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
price: Mapped[Decimal] = mapped_column(Numeric(10, 2), nullable=False)
stock: Mapped[int] = mapped_column(nullable=False, default=0)
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
nullable=False,
)
+35
View File
@@ -0,0 +1,35 @@
from __future__ import annotations
from datetime import datetime, timezone
from enum import Enum
from sqlalchemy import Boolean, DateTime, Enum as SqlEnum, String
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.models.base import Base
class RoleEnum(str, Enum):
client = "client"
shop = "shop"
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
username: Mapped[str] = mapped_column(String(50), unique=True, nullable=False, index=True)
password_hash: Mapped[str] = mapped_column(String(255), nullable=False)
role: Mapped[RoleEnum] = mapped_column(
SqlEnum(RoleEnum, native_enum=False),
nullable=False,
default=RoleEnum.client,
)
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
nullable=False,
)
orders = relationship("Order", back_populates="user", lazy="selectin")