Files
PocketVeto/backend/app/main.py
Jack Levy 9e5ac9b33d feat: collections, watchlists, and shareable links (v0.9.0)
Phase 3 completion — Personal Workflow feature set is now complete.

Collections / Watchlists:
- New tables: collections (UUID share_token, slug, public/private) and
  collection_bills (unique bill-per-collection constraint)
- Full CRUD API at /api/collections with bill add/remove endpoints
- Public share endpoint /api/collections/share/{token} (no auth)
- /collections list page with inline create form and delete
- /collections/[id] detail page: inline rename, public toggle,
  copy-share-link, bill search/add/remove
- CollectionPicker bookmark-icon popover on bill detail pages
- Collections nav link in sidebar (auth-required)

Shareable Brief Links:
- share_token UUID column on bill_briefs (backfilled on migration)
- Unified public share router at /api/share (brief + collection)
- /share/brief/[token] — minimal layout, full AIBriefCard, CTAs
- /share/collection/[token] — minimal layout, bill list, CTA
- Share2 button in BriefPanel header row, "Link copied!" flash

AuthGuard: /collections → AUTH_REQUIRED; /share prefix → NO_SHELL_PATHS

Authored-By: Jack Levy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 23:23:45 -05:00

34 lines
1.6 KiB
Python

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.api import bills, members, follows, dashboard, search, settings, admin, health, auth, notifications, notes, collections, share
from app.config import settings as config
app = FastAPI(
title="PocketVeto",
description="Monitor US Congressional activity with AI-powered bill summaries.",
version="1.0.0",
)
app.add_middleware(
CORSMiddleware,
allow_origins=[o for o in [config.LOCAL_URL, config.PUBLIC_URL] if o],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
app.include_router(bills.router, prefix="/api/bills", tags=["bills"])
app.include_router(members.router, prefix="/api/members", tags=["members"])
app.include_router(follows.router, prefix="/api/follows", tags=["follows"])
app.include_router(dashboard.router, prefix="/api/dashboard", tags=["dashboard"])
app.include_router(search.router, prefix="/api/search", tags=["search"])
app.include_router(settings.router, prefix="/api/settings", tags=["settings"])
app.include_router(admin.router, prefix="/api/admin", tags=["admin"])
app.include_router(health.router, prefix="/api/health", tags=["health"])
app.include_router(notifications.router, prefix="/api/notifications", tags=["notifications"])
app.include_router(notes.router, prefix="/api/notes", tags=["notes"])
app.include_router(collections.router, prefix="/api/collections", tags=["collections"])
app.include_router(share.router, prefix="/api/share", tags=["share"])