d582f15681
- Implemented tests for import polling functionality, ensuring correct behavior for active and terminal import statuses. - Created tests for the login page, validating user interactions and error handling. - Added unit tests for money utility functions, covering parsing, formatting, and summation of monetary values. - Developed tests for query keys, ensuring proper scoping and invalidation roots. chore: setup testing environment and configuration - Added setup file for testing with Vitest and Testing Library. - Configured TypeScript and Vite for the frontend project. - Created Docker and Nginx configurations for local development and production environments. - Established a PostgreSQL initialization script for setting up application roles. docs: add README and environment configuration for infra - Included README for the infra directory, detailing local development setup and service descriptions. - Created an example environment configuration file for local development with placeholders for sensitive information.
53 lines
1.5 KiB
Python
53 lines
1.5 KiB
Python
import uuid
|
|
from datetime import UTC, datetime
|
|
from typing import Any
|
|
|
|
from sqlalchemy import DateTime, MetaData, TypeDecorator
|
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
|
|
|
NAMING_CONVENTION = {
|
|
"ix": "ix_%(column_0_label)s",
|
|
"uq": "uq_%(table_name)s_%(column_0_name)s",
|
|
"ck": "ck_%(table_name)s_%(constraint_name)s",
|
|
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
|
"pk": "pk_%(table_name)s",
|
|
}
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
metadata = MetaData(naming_convention=NAMING_CONVENTION)
|
|
|
|
|
|
class UTCDateTime(TypeDecorator):
|
|
"""Datetimes stored as naive UTC in the DB and exposed tz-aware (UTC) in Python."""
|
|
|
|
impl = DateTime
|
|
cache_ok = True
|
|
|
|
def process_bind_param(self, value: Any, dialect: Any) -> Any:
|
|
if value is not None:
|
|
if value.tzinfo is None:
|
|
value = value.replace(tzinfo=UTC)
|
|
value = value.astimezone(UTC).replace(tzinfo=None)
|
|
return value
|
|
|
|
def process_result_value(self, value: Any, dialect: Any) -> Any:
|
|
if value is not None:
|
|
value = value.replace(tzinfo=UTC)
|
|
return value
|
|
|
|
|
|
def utcnow() -> datetime:
|
|
return datetime.now(UTC)
|
|
|
|
|
|
class PkMixin:
|
|
id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4)
|
|
|
|
|
|
class TimestampMixin:
|
|
created_at: Mapped[datetime] = mapped_column(UTCDateTime(), default=utcnow, nullable=False)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
UTCDateTime(), default=utcnow, onupdate=utcnow, nullable=False
|
|
)
|