Add TicketDTO, user_tickets/user_bookings to CalendarService protocol and SqlCalendarService implementation, plus nav links and panel templates for the auth account sub-pages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
130 lines
3.4 KiB
Python
130 lines
3.4 KiB
Python
"""Frozen dataclasses for cross-domain data transfer.
|
|
|
|
These are the *only* shapes that cross domain boundaries. Consumers never
|
|
see ORM model instances from another domain — only these DTOs.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Blog domain
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class PostDTO:
|
|
id: int
|
|
slug: str
|
|
title: str
|
|
status: str
|
|
visibility: str
|
|
is_page: bool = False
|
|
feature_image: str | None = None
|
|
html: str | None = None
|
|
excerpt: str | None = None
|
|
custom_excerpt: str | None = None
|
|
published_at: datetime | None = None
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Calendar / Events domain
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class CalendarDTO:
|
|
id: int
|
|
container_type: str
|
|
container_id: int
|
|
name: str
|
|
slug: str
|
|
description: str | None = None
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class TicketDTO:
|
|
id: int
|
|
code: str
|
|
state: str
|
|
entry_name: str
|
|
entry_start_at: datetime
|
|
entry_end_at: datetime | None = None
|
|
ticket_type_name: str | None = None
|
|
calendar_name: str | None = None
|
|
created_at: datetime | None = None
|
|
checked_in_at: datetime | None = None
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class CalendarEntryDTO:
|
|
id: int
|
|
calendar_id: int
|
|
name: str
|
|
start_at: datetime
|
|
state: str
|
|
cost: Decimal
|
|
end_at: datetime | None = None
|
|
user_id: int | None = None
|
|
session_id: str | None = None
|
|
order_id: int | None = None
|
|
slot_id: int | None = None
|
|
ticket_price: Decimal | None = None
|
|
ticket_count: int | None = None
|
|
calendar_name: str | None = None
|
|
calendar_slug: str | None = None
|
|
calendar_container_id: int | None = None
|
|
calendar_container_type: str | None = None
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Market domain
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class MarketPlaceDTO:
|
|
id: int
|
|
container_type: str
|
|
container_id: int
|
|
name: str
|
|
slug: str
|
|
description: str | None = None
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class ProductDTO:
|
|
id: int
|
|
slug: str
|
|
title: str | None = None
|
|
image: str | None = None
|
|
description_short: str | None = None
|
|
rrp: Decimal | None = None
|
|
regular_price: Decimal | None = None
|
|
special_price: Decimal | None = None
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Cart domain
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class CartItemDTO:
|
|
id: int
|
|
product_id: int
|
|
quantity: int
|
|
product_title: str | None = None
|
|
product_slug: str | None = None
|
|
product_image: str | None = None
|
|
unit_price: Decimal | None = None
|
|
market_place_id: int | None = None
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class CartSummaryDTO:
|
|
count: int = 0
|
|
total: Decimal = Decimal("0")
|
|
calendar_count: int = 0
|
|
calendar_total: Decimal = Decimal("0")
|
|
items: list[CartItemDTO] = field(default_factory=list)
|