feat(scouts): add cloud scout CRUD routes + serializer
This commit is contained in:
@@ -42,6 +42,9 @@ from app.db import get_session
|
||||
from app.integrations import encrypt_token
|
||||
from app.models import CloudScoutConfig, ScoutRunLog, LocalScoutConfig
|
||||
from app.schemas import (
|
||||
CloudScoutCreateRequest,
|
||||
CloudScoutResponse,
|
||||
CloudScoutUpdateRequest,
|
||||
ScoutCatalogItem,
|
||||
ScoutCreationCheckRequest,
|
||||
ScoutCreationCheckResponse,
|
||||
@@ -269,6 +272,109 @@ async def summarize_note(
|
||||
return NoteSummarizeResponse(summary=summary)
|
||||
|
||||
|
||||
# ── Cloud scout CRUD ──────────────────────────────────────────────────────────
|
||||
|
||||
_DEFAULT_CLOUD_SCHEDULE = "0 */6 * * *"
|
||||
|
||||
|
||||
def _to_cloud_response(scout: CloudScoutConfig) -> dict:
|
||||
return {
|
||||
"id": scout.id,
|
||||
"user_id": scout.user_id,
|
||||
"provider": scout.provider,
|
||||
"name": scout.name,
|
||||
"data_types": scout.data_types or [],
|
||||
"prompt_template": scout.prompt_template or "",
|
||||
"schedule_cron": scout.schedule_cron,
|
||||
"filter_config": scout.filter_config,
|
||||
"auto_trash_spam": scout.auto_trash_spam,
|
||||
"enabled": scout.enabled,
|
||||
"last_run_at": _dt_ms_opt(scout.last_run_at),
|
||||
"gmail_address": scout.gmail_address,
|
||||
"oauth_connected": scout.oauth_token_encrypted is not None,
|
||||
"created_at": _dt_ms(scout.created_at),
|
||||
"updated_at": _dt_ms(scout.updated_at),
|
||||
}
|
||||
|
||||
|
||||
@router.get("/cloud", response_model=list[CloudScoutResponse])
|
||||
async def list_cloud_scouts(
|
||||
db: AsyncSession = Depends(get_session),
|
||||
current_user: UserProfile = Depends(get_current_user),
|
||||
):
|
||||
rows = (await db.execute(
|
||||
select(CloudScoutConfig).where(CloudScoutConfig.user_id == current_user.id)
|
||||
)).scalars().all()
|
||||
return [_to_cloud_response(s) for s in rows]
|
||||
|
||||
|
||||
@router.post("/cloud", response_model=CloudScoutResponse, status_code=status.HTTP_201_CREATED)
|
||||
async def create_cloud_scout(
|
||||
body: CloudScoutCreateRequest,
|
||||
db: AsyncSession = Depends(get_session),
|
||||
current_user: UserProfile = Depends(get_current_user),
|
||||
):
|
||||
scout = CloudScoutConfig(
|
||||
id=str(uuid.uuid4()),
|
||||
user_id=current_user.id,
|
||||
provider=body.provider,
|
||||
name=body.name,
|
||||
data_types=body.data_types,
|
||||
prompt_template=body.prompt_template,
|
||||
filter_config=body.filter_config,
|
||||
schedule_cron=body.schedule_cron or _DEFAULT_CLOUD_SCHEDULE,
|
||||
auto_trash_spam=body.auto_trash_spam,
|
||||
enabled=True,
|
||||
)
|
||||
db.add(scout)
|
||||
await db.commit()
|
||||
await db.refresh(scout)
|
||||
return _to_cloud_response(scout)
|
||||
|
||||
|
||||
@router.put("/cloud/{scout_id}", response_model=CloudScoutResponse)
|
||||
async def update_cloud_scout(
|
||||
scout_id: str,
|
||||
body: CloudScoutUpdateRequest,
|
||||
db: AsyncSession = Depends(get_session),
|
||||
current_user: UserProfile = Depends(get_current_user),
|
||||
):
|
||||
scout = await db.get(CloudScoutConfig, scout_id)
|
||||
if scout is None or scout.user_id != current_user.id:
|
||||
raise HTTPException(status.HTTP_404_NOT_FOUND, "Scout not found")
|
||||
if body.name is not None:
|
||||
scout.name = body.name
|
||||
if body.data_types is not None:
|
||||
scout.data_types = body.data_types
|
||||
if body.prompt_template is not None:
|
||||
scout.prompt_template = body.prompt_template
|
||||
if body.schedule_cron is not None:
|
||||
scout.schedule_cron = body.schedule_cron
|
||||
if body.filter_config is not None:
|
||||
scout.filter_config = body.filter_config
|
||||
if body.auto_trash_spam is not None:
|
||||
scout.auto_trash_spam = body.auto_trash_spam
|
||||
if body.enabled is not None:
|
||||
scout.enabled = body.enabled
|
||||
await db.commit()
|
||||
await db.refresh(scout)
|
||||
return _to_cloud_response(scout)
|
||||
|
||||
|
||||
@router.delete("/cloud/{scout_id}")
|
||||
async def delete_cloud_scout(
|
||||
scout_id: str,
|
||||
db: AsyncSession = Depends(get_session),
|
||||
current_user: UserProfile = Depends(get_current_user),
|
||||
):
|
||||
scout = await db.get(CloudScoutConfig, scout_id)
|
||||
if scout is None or scout.user_id != current_user.id:
|
||||
raise HTTPException(status.HTTP_404_NOT_FOUND, "Scout not found")
|
||||
await db.delete(scout)
|
||||
await db.commit()
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
# ── Gmail OAuth setup (scout-specific) ───────────────────────────────────────
|
||||
|
||||
# Scopes required for Gmail scout connectivity.
|
||||
|
||||
Reference in New Issue
Block a user