Spaces:
Running
Running
| """admin/routers/onboarding.py — Author onboarding checklist (R-169).""" | |
| from fastapi import APIRouter, Depends | |
| from sqlalchemy.ext.asyncio import AsyncSession | |
| from app.dependencies import get_db, get_current_author_scoped | |
| from app.repositories.book_repo import BookRepository | |
| from app.repositories.access_repo import AccessRepository | |
| router = APIRouter() | |
| async def onboarding_checklist( | |
| author_slug: str, | |
| current_user=Depends(get_current_author_scoped), | |
| db: AsyncSession = Depends(get_db), | |
| ): | |
| """Return onboarding progress: import, upload, embed.""" | |
| books = await BookRepository(db).list_for_author(current_user.id) | |
| ready = [b for b in books if b.status == "ready"] | |
| access = await AccessRepository(db).get_active_for_author(current_user.id) | |
| has_token = access is not None and not access.is_revoked | |
| steps = [ | |
| { | |
| "id": "import_book", | |
| "label": "Import or add a book", | |
| "done": len(books) > 0, | |
| }, | |
| { | |
| "id": "upload_manuscript", | |
| "label": "Upload PDF/EPUB for full-book chat", | |
| "done": any((b.chunk_count or 0) > 5 for b in ready), | |
| }, | |
| { | |
| "id": "embed_widget", | |
| "label": "Copy embed code and go live", | |
| "done": has_token and len(ready) > 0, | |
| }, | |
| ] | |
| completed = sum(1 for s in steps if s["done"]) | |
| return { | |
| "steps": steps, | |
| "completed": completed, | |
| "total": len(steps), | |
| "percent": round(completed / len(steps) * 100) if steps else 0, | |
| } | |