Initial commit: CI Agent competitive-intelligence monitoring app
FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring, source collection, LLM-based change analysis, enrichment, and account security (Turnstile, escalating lockout, email verification).
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.db.base import ensure_aware_utc
|
||||
from app.models.unban_request import UnbanRequest
|
||||
|
||||
|
||||
class UnbanRequestRepository:
|
||||
def __init__(self, db: AsyncSession) -> None:
|
||||
self.db = db
|
||||
|
||||
async def get(self, request_id: uuid.UUID) -> UnbanRequest | None:
|
||||
result = await self.db.execute(select(UnbanRequest).where(UnbanRequest.id == request_id))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
async def delete(self, request_id: uuid.UUID) -> None:
|
||||
request = await self.get(request_id)
|
||||
if request is not None:
|
||||
await self.db.delete(request)
|
||||
await self.db.flush()
|
||||
|
||||
async def most_recent_for_ip(self, ip_address: str) -> UnbanRequest | None:
|
||||
result = await self.db.execute(
|
||||
select(UnbanRequest)
|
||||
.where(UnbanRequest.ip_address == ip_address)
|
||||
.order_by(UnbanRequest.created_at.desc())
|
||||
.limit(1)
|
||||
)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
async def within_cooldown(self, ip_address: str, cooldown_hours: int = 24) -> bool:
|
||||
latest = await self.most_recent_for_ip(ip_address)
|
||||
if latest is None:
|
||||
return False
|
||||
cutoff = datetime.now(UTC) - timedelta(hours=cooldown_hours)
|
||||
return ensure_aware_utc(latest.created_at) > cutoff
|
||||
|
||||
async def create(self, ip_address: str, message: str | None) -> UnbanRequest:
|
||||
record = UnbanRequest(ip_address=ip_address, message=message)
|
||||
self.db.add(record)
|
||||
await self.db.flush()
|
||||
return record
|
||||
|
||||
async def list_all(self, limit: int = 100) -> list[UnbanRequest]:
|
||||
result = await self.db.execute(
|
||||
select(UnbanRequest).order_by(UnbanRequest.created_at.desc()).limit(limit)
|
||||
)
|
||||
return list(result.scalars().all())
|
||||
Reference in New Issue
Block a user