feat: add embed-status endpoint for per-video embedding/Qdrant detail
GET /admin/pipeline/embed-status/{video_id} returns technique pages
linked to the video, Qdrant vector count, and last stage 6 event —
provides data for the currently non-functional Embed tab in admin UI.
This commit is contained in:
parent
7d4168c048
commit
c3e5a8fe86
1 changed files with 72 additions and 0 deletions
|
|
@ -1306,6 +1306,78 @@ async def reindex_all(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ── Admin: Embedding status ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
@router.get("/admin/pipeline/embed-status/{video_id}")
|
||||||
|
async def get_embed_status(
|
||||||
|
video_id: str,
|
||||||
|
db: AsyncSession = Depends(get_session),
|
||||||
|
):
|
||||||
|
"""Get embedding/indexing status for a video's technique pages.
|
||||||
|
|
||||||
|
Returns which technique pages have been embedded, vector counts from
|
||||||
|
Qdrant, and the last stage 6 event timestamp.
|
||||||
|
"""
|
||||||
|
from models import KeyMoment
|
||||||
|
|
||||||
|
# Get technique pages linked to this video's key moments
|
||||||
|
moments = (await db.execute(
|
||||||
|
select(KeyMoment.technique_page_id)
|
||||||
|
.where(KeyMoment.source_video_id == video_id)
|
||||||
|
.where(KeyMoment.technique_page_id.isnot(None))
|
||||||
|
.distinct()
|
||||||
|
)).scalars().all()
|
||||||
|
|
||||||
|
page_ids = set(moments)
|
||||||
|
pages_info = []
|
||||||
|
if page_ids:
|
||||||
|
rows = (await db.execute(
|
||||||
|
select(TechniquePage.id, TechniquePage.title, TechniquePage.slug)
|
||||||
|
.where(TechniquePage.id.in_(page_ids))
|
||||||
|
)).all()
|
||||||
|
pages_info = [{"id": str(r.id), "title": r.title, "slug": r.slug} for r in rows]
|
||||||
|
|
||||||
|
# Get last stage 6 event for this video
|
||||||
|
last_embed_event = (await db.execute(
|
||||||
|
select(PipelineEvent.created_at, PipelineEvent.event_type)
|
||||||
|
.where(PipelineEvent.video_id == video_id)
|
||||||
|
.where(PipelineEvent.stage == "stage6_embed_and_index")
|
||||||
|
.order_by(PipelineEvent.created_at.desc())
|
||||||
|
.limit(1)
|
||||||
|
)).first()
|
||||||
|
|
||||||
|
# Try to get Qdrant vector count for this video
|
||||||
|
qdrant_count = None
|
||||||
|
try:
|
||||||
|
from config import get_settings
|
||||||
|
from pipeline.qdrant_client import QdrantManager
|
||||||
|
from qdrant_client.models import Filter, FieldCondition, MatchValue
|
||||||
|
|
||||||
|
settings = get_settings()
|
||||||
|
qdrant = QdrantManager(settings)
|
||||||
|
result = qdrant._client.count(
|
||||||
|
collection_name=qdrant._collection,
|
||||||
|
count_filter=Filter(
|
||||||
|
must=[FieldCondition(key="source_video_id", match=MatchValue(value=video_id))]
|
||||||
|
),
|
||||||
|
exact=True,
|
||||||
|
)
|
||||||
|
qdrant_count = result.count
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {
|
||||||
|
"video_id": video_id,
|
||||||
|
"technique_pages": pages_info,
|
||||||
|
"technique_page_count": len(pages_info),
|
||||||
|
"qdrant_vector_count": qdrant_count,
|
||||||
|
"last_embed_event": {
|
||||||
|
"created_at": last_embed_event.created_at.isoformat(),
|
||||||
|
"event_type": last_embed_event.event_type,
|
||||||
|
} if last_embed_event else None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# ── Admin: Creator profile editing ───────────────────────────────────────────
|
# ── Admin: Creator profile editing ───────────────────────────────────────────
|
||||||
|
|
||||||
@router.put("/admin/pipeline/creators/{creator_id}")
|
@router.put("/admin/pipeline/creators/{creator_id}")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue