Initial commit: VoIdeaAI - voice-first AI idea assistant
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
"""Base classes for VoIdea models and services."""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Generic, TypeVar
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from sqlalchemy import DateTime, func
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class SQLBase(DeclarativeBase):
|
||||
"""Base class for all SQLAlchemy models."""
|
||||
|
||||
type_annotation_map = {
|
||||
datetime: DateTime(timezone=True),
|
||||
}
|
||||
|
||||
|
||||
class CoreModel(BaseModel):
|
||||
"""Base Pydantic model with common fields."""
|
||||
|
||||
model_config = ConfigDict(
|
||||
from_attributes=True,
|
||||
populate_by_name=True,
|
||||
)
|
||||
|
||||
|
||||
class TimestampMixin:
|
||||
"""Mixin for timestamp fields."""
|
||||
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
server_default=func.now(),
|
||||
)
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
server_default=func.now(),
|
||||
onupdate=func.now(),
|
||||
)
|
||||
|
||||
|
||||
class UUIDMixin:
|
||||
"""Mixin for UUID primary key."""
|
||||
|
||||
id: Mapped[UUID] = mapped_column(primary_key=True, default=uuid4)
|
||||
|
||||
|
||||
class BaseRepository(Generic[T]):
|
||||
"""Base repository for data access."""
|
||||
|
||||
model: type[T]
|
||||
|
||||
def __init__(self, session: Any):
|
||||
self.session = session
|
||||
|
||||
async def get_by_id(self, id: UUID) -> T | None:
|
||||
"""Get entity by ID."""
|
||||
return await self.session.get(self.model, id)
|
||||
|
||||
async def get_all(self, limit: int = 100, offset: int = 0) -> list[T]:
|
||||
"""Get all entities with pagination."""
|
||||
result = await self.session.execute(
|
||||
select(self.model).limit(limit).offset(offset)
|
||||
)
|
||||
return list(result.scalars().all())
|
||||
|
||||
async def create(self, **kwargs: Any) -> T:
|
||||
"""Create new entity."""
|
||||
entity = self.model(**kwargs)
|
||||
self.session.add(entity)
|
||||
await self.session.commit()
|
||||
await self.session.refresh(entity)
|
||||
return entity
|
||||
|
||||
async def update(self, entity: T, **kwargs: Any) -> T:
|
||||
"""Update entity."""
|
||||
for key, value in kwargs.items():
|
||||
setattr(entity, key, value)
|
||||
await self.session.commit()
|
||||
await self.session.refresh(entity)
|
||||
return entity
|
||||
|
||||
async def delete(self, entity: T) -> None:
|
||||
"""Delete entity."""
|
||||
await self.session.delete(entity)
|
||||
await self.session.commit()
|
||||
|
||||
|
||||
class BaseService:
|
||||
"""Base service class."""
|
||||
|
||||
def __init__(self, repository: BaseRepository):
|
||||
self.repository = repository
|
||||
Reference in New Issue
Block a user