Include Loyalty/Communication/Sports Center backends and registry updates alongside production nginx and compose wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
104 lines
3.0 KiB
Python
104 lines
3.0 KiB
Python
from uuid import UUID
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from pydantic import BaseModel
|
|
|
|
from app.api.deps import AsyncSession, CurrentUser, get_current_user, get_db, require_tenant
|
|
from app.schemas.common import (
|
|
ContactCreate,
|
|
ContactOut,
|
|
ContactSourceCreate,
|
|
ContactSourceOut,
|
|
)
|
|
from app.services.contact_service import ContactService
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class CSVImportBody(BaseModel):
|
|
csv_text: str
|
|
|
|
|
|
class ResolveBody(BaseModel):
|
|
source_id: UUID | None = None
|
|
query: dict | None = None
|
|
channel: str = "sms"
|
|
|
|
|
|
@router.get("/manual", response_model=list[ContactOut])
|
|
async def list_manual_contacts(
|
|
tenant_id: UUID = Depends(require_tenant),
|
|
session: AsyncSession = Depends(get_db),
|
|
_: CurrentUser = Depends(get_current_user),
|
|
):
|
|
return await ContactService(session).list_manual(tenant_id)
|
|
|
|
|
|
@router.post("/manual", response_model=ContactOut, status_code=201)
|
|
async def create_manual_contact(
|
|
body: ContactCreate,
|
|
tenant_id: UUID = Depends(require_tenant),
|
|
session: AsyncSession = Depends(get_db),
|
|
user: CurrentUser = Depends(get_current_user),
|
|
):
|
|
return await ContactService(session).create_manual(
|
|
tenant_id, body.model_dump(), actor_id=user.user_id
|
|
)
|
|
|
|
|
|
@router.post("/manual/import-csv", response_model=list[ContactOut], status_code=201)
|
|
async def import_csv(
|
|
body: CSVImportBody,
|
|
tenant_id: UUID = Depends(require_tenant),
|
|
session: AsyncSession = Depends(get_db),
|
|
user: CurrentUser = Depends(get_current_user),
|
|
):
|
|
return await ContactService(session).import_csv(
|
|
tenant_id, body.csv_text, actor_id=user.user_id
|
|
)
|
|
|
|
|
|
@router.get("/sources", response_model=list[ContactSourceOut])
|
|
async def list_sources(
|
|
tenant_id: UUID = Depends(require_tenant),
|
|
session: AsyncSession = Depends(get_db),
|
|
_: CurrentUser = Depends(get_current_user),
|
|
):
|
|
return await ContactService(session).list_sources(tenant_id)
|
|
|
|
|
|
@router.post("/sources", response_model=ContactSourceOut, status_code=201)
|
|
async def create_source(
|
|
body: ContactSourceCreate,
|
|
tenant_id: UUID = Depends(require_tenant),
|
|
session: AsyncSession = Depends(get_db),
|
|
user: CurrentUser = Depends(get_current_user),
|
|
):
|
|
return await ContactService(session).create_source(
|
|
tenant_id, body.model_dump(), actor_id=user.user_id
|
|
)
|
|
|
|
|
|
@router.post("/resolve")
|
|
async def resolve_contacts(
|
|
body: ResolveBody,
|
|
tenant_id: UUID = Depends(require_tenant),
|
|
session: AsyncSession = Depends(get_db),
|
|
_: CurrentUser = Depends(get_current_user),
|
|
):
|
|
resolved = await ContactService(session).resolve(
|
|
tenant_id,
|
|
source_id=body.source_id,
|
|
query=body.query,
|
|
channel=body.channel,
|
|
)
|
|
return [
|
|
{
|
|
"address": r.address,
|
|
"display_name": r.display_name,
|
|
"external_ref": r.external_ref,
|
|
"source_type": r.source_type,
|
|
}
|
|
for r in resolved
|
|
]
|