Add v0.2 pillars: chaos inbox, identity center, command palette

This commit is contained in:
Alexa Amundson
2025-11-16 18:12:33 -06:00
parent d8c5b073be
commit 785f5f6dd3
30 changed files with 1425 additions and 40 deletions

View File

@@ -0,0 +1,88 @@
"""Unified search endpoints"""
from typing import List
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from pydantic import BaseModel
from app.auth import get_current_active_user
from app.database import get_db
from app.models.capture import CaptureItem
from app.models.identity_profile import UserProfile
from app.models.creator import CreativeProject
from app.models.user import User
router = APIRouter(prefix="/api/search", tags=["Search"])
class SearchResult(BaseModel):
app_id: str
type: str
title: str
snippet: str | None = None
ref_id: str | None = None
@router.get("", response_model=List[SearchResult])
async def unified_search(
q: str,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
results: List[SearchResult] = []
# Capture items search
capture_result = await db.execute(
select(CaptureItem).where(CaptureItem.raw_content.ilike(f"%{q}%"))
)
for item in capture_result.scalars().all():
results.append(
SearchResult(
app_id="chaos-inbox",
type=item.type,
title=item.raw_content[:60] if item.raw_content else item.type,
snippet=item.status,
ref_id=str(item.id)
)
)
# Creative projects
project_result = await db.execute(
select(CreativeProject).where(CreativeProject.title.ilike(f"%{q}%"))
)
for project in project_result.scalars().all():
results.append(
SearchResult(
app_id="creator-studio",
type=project.type,
title=project.title,
snippet=project.description[:80] if project.description else None,
ref_id=str(project.id)
)
)
# Identity profile
profile_result = await db.execute(select(UserProfile).where(UserProfile.user_id == current_user.id))
profile = profile_result.scalar_one_or_none()
if profile and q.lower() in (profile.name or "").lower():
results.append(
SearchResult(
app_id="identity-center",
type="profile",
title=profile.name or "Profile",
snippet=profile.email,
ref_id=str(profile.id)
)
)
# App discovery (front-end uses registry; include sample results)
if "identity" in q.lower():
results.append(SearchResult(app_id="identity-center", type="app", title="Identity Center"))
if "chaos" in q.lower() or "note" in q.lower():
results.append(SearchResult(app_id="chaos-inbox", type="app", title="Chaos Inbox"))
if "creator" in q.lower():
results.append(SearchResult(app_id="creator-studio", type="app", title="Creator Studio"))
if "compliance" in q.lower():
results.append(SearchResult(app_id="compliance-ops", type="app", title="Compliance & Ops"))
return results