Files
vpn-control-panel/app/repositories/base.py
smolkik-code 7c7c88621d Initial commit: VPN Control Panel
- FastAPI REST API with JWT auth
- aiogram 3 Telegram bot with admin middleware
- APScheduler daily tasks (expiry, reminders, revoke, sync)
- SQLAlchemy 2 async ORM with Alembic migrations
- Jinja2 admin panel (Dashboard, Users, Payments, Servers, Tariffs)
- VPN provider abstraction with MockProvider
- Stats service with revenue/subscription analytics
- Docker Compose (PostgreSQL + Redis + app)
- Healthcheck endpoint
2026-07-05 17:50:11 +07:00

72 lines
2.2 KiB
Python

from typing import Any, Generic, TypeVar
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import Base
ModelType = TypeVar("ModelType", bound=Base)
class BaseRepository(Generic[ModelType]):
def __init__(self, session: AsyncSession, model: type[ModelType]):
self.session = session
self.model = model
async def create(self, **kwargs: Any) -> ModelType:
instance = self.model(**kwargs)
self.session.add(instance)
await self.session.flush()
return instance
async def get(self, id: int) -> ModelType | None:
return await self.session.get(self.model, id)
async def get_all(
self,
*,
skip: int = 0,
limit: int = 100,
**filters: Any,
) -> list[ModelType]:
stmt = select(self.model)
for field_name, value in filters.items():
if value is not None:
column = getattr(self.model, field_name, None)
if column is not None:
stmt = stmt.where(column == value)
stmt = stmt.offset(skip).limit(limit)
result = await self.session.execute(stmt)
return list(result.scalars().all())
async def update(self, id: int, **kwargs: Any) -> ModelType | None:
instance = await self.get(id)
if instance is None:
return None
for field, value in kwargs.items():
setattr(instance, field, value)
await self.session.flush()
return instance
async def delete(self, id: int) -> bool:
instance = await self.get(id)
if instance is None:
return False
await self.session.delete(instance)
await self.session.flush()
return True
async def count(self, **filters: Any) -> int:
stmt = select(func.count(self.model.id))
for field_name, value in filters.items():
if value is not None:
column = getattr(self.model, field_name, None)
if column is not None:
stmt = stmt.where(column == value)
result = await self.session.execute(stmt)
return result.scalar_one()