feat(scouts): debug scripts + deliver_pending diagnostic logs

- scripts/trigger_gmail_scout.py: manually fire ScoutEngine.trigger_scout
- scripts/inspect_gmail_scout_token.py: decrypt + show stored OAuth scopes
- scripts/show_gmail_scout_state.py: print scout config + queue/log counts
- scripts/reset_triage_queue_to_queued.py: revert delivered → queued for re-delivery
- engine.py: info logs around deliver_pending (rows found, send_json roundtrip)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Roberto
2026-06-11 00:27:04 +02:00
parent f64ca11888
commit 79a926e4d8
5 changed files with 227 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
"""Print Gmail scout state for debugging.
Usage:
python scripts/show_gmail_scout_state.py
"""
from __future__ import annotations
import asyncio
import sys
from pathlib import Path
_API_ROOT = Path(__file__).resolve().parent.parent
if str(_API_ROOT) not in sys.path:
sys.path.insert(0, str(_API_ROOT))
from sqlalchemy import select, func
from app.db import async_session
from app.models import CloudScoutConfig, ScoutTriageQueue, ScoutRunLog
async def main() -> None:
async with async_session() as session:
scouts = (
await session.execute(
select(CloudScoutConfig).where(CloudScoutConfig.provider == "gmail")
)
).scalars().all()
for scout in scouts:
print(f"\nScout: {scout.name} (id={scout.id})")
print(f" enabled: {scout.enabled}")
print(f" gmail_history_id: {scout.gmail_history_id}")
print(f" gmail_watch_expires_at: {scout.gmail_watch_expires_at}")
print(f" auto_trash_spam: {scout.auto_trash_spam}")
print(f" last_run_at: {scout.last_run_at}")
queued_count = (
await session.execute(
select(func.count())
.select_from(ScoutTriageQueue)
.where(ScoutTriageQueue.scout_id == scout.id)
)
).scalar()
print(f" triage_queue rows: {queued_count}")
run_count = (
await session.execute(
select(func.count())
.select_from(ScoutRunLog)
.where(ScoutRunLog.scout_id == scout.id)
)
).scalar()
print(f" scout_run_logs: {run_count}")
if __name__ == "__main__":
asyncio.run(main())