Project Documentation
Queuei Handbook
A self-hosted intelligence platform. It ingests YouTube playlists, distils each video into structured intelligence with Gemini, stores everything in a searchable vector store, and surfaces it through a terminal-style dashboard — plus a generic scheduled-LLM feed engine you can point at anything.
Overview
Queuei turns a stream of long-form video into a queryable knowledge base. Every video in a monitored playlist flows through a pipeline that fetches a transcript, runs a configurable Gemini prompt, generates a 3072-dimension embedding, and writes one document to MongoDB. The dashboard reads those documents back as browsable Stacks, powers semantic Intel Chat, and renders relationship graphs.
Beyond video, the same machinery is generalised: define a prompt, attach a schedule, and Queuei runs it every morning and paints the result as its own dashboard tab. That is how the built-in NASDAQ stock analysis and any custom Dashboard Feed work.
Dual database
Postgres for config & auth, MongoDB for content & vectors.
LLM-native
Gemini for summarisation, embeddings, and transcript fallback.
Schedule anything
Cron-driven pipelines & feeds, editable from the UI.
Architecture
Two Django apps sit on top of two databases.
Two apps
records— the user-facing frontend: auth, dashboard, Intel Chat, Nexus graph, Command Center, Settings, Cron manager, and this documentation portal.tasks— the ingestion & scheduling backend: the YouTube pipeline, stock & feed pipelines, the APScheduler runtime, and utility endpoints.
Two databases
| Store | Access | Holds |
|---|---|---|
| PostgreSQL (Neon) | Django ORM | Users & groups, TaskConfiguration, GlobalSetting, CronJob, DashboardFeed, TranscriptCache. |
| MongoDB (Atlas) | pymongo (no ORM) | All content records, transcripts, LLM outputs, entity annotations, and embedding vectors for search. |
MongoDB connections are raw pymongo. get_db_collection() in
records/views.py opens a fresh connection per request; the pipeline shares a module-level
client from tasks/config.py. There is deliberately no ORM over Mongo.
The Pipeline
Every video runs through YouTubeLLMPipeline (tasks/script_custom/youtube_llm_pipeline.py). One document out per video in.
-
1
Discover
yt-dlp lists recent videos from every playlist in YOUTUBE_PLAYLIST_IDS, up to PLAYLIST_FETCH_LIMIT each. Already-processed IDs are skipped.
-
2
Transcript
Tries the local cache, then the source chain (see Transcript Sources). Successful pulls are written to TranscriptCache so retries never re-fetch.
-
3
LLM action
The task's prompt_template is formatted with {transcript} and sent to Gemini. The response is the intelligence body.
-
4
Embed
The LLM output is embedded with gemini-embedding-001 into a 3072-dim vector.
-
5
Persist
A document — metadata + LLM result + embedding + any EXTRA_DOCUMENT_ARGS — is inserted into the task's target collection in MongoDB.
Concurrency is bounded by EXECUTOR_WORKERS with an INBETWEEN_TASK_SLEEP pause
between batches — the throttle that keeps Gemini rate limits happy. Trigger a run with
POST /tasks/queuei/<task_key>/.
Transcript Sources
Transcripts are fetched through a fallback chain — the first source that returns text wins, and the result is cached.
youtube_transcript_api
Fast and free. Blocked on datacenter IPs (Render, cloud hosts) — often fails in production.
Gemini (server-side fetch)
Gemini reads the YouTube URL from Google's own infrastructure, bypassing datacenter-IP blocks. The reliable cloud path. Public videos only.
RapidAPI
Third-party transcript API. Paid, quota-limited.
Supadata
Second paid fallback.
On cloud hosts the library step almost always fails; Gemini is the workhorse. Because video ingestion is token-heavy, large backfills can hit Gemini rate limits — throttle via EXECUTOR_WORKERS / INBETWEEN_TASK_SLEEP.
Dashboard Features
Stacks
Video intelligence grouped by playlist. Drill into a stack to browse per-video reports; transcripts are excluded from the list query for speed.
Stocks
NASDAQ-100 analysis refreshed every morning by a scheduled pipeline, stored in the stock_results collection and rendered as its own tab.
Feeds
Generic scheduled-LLM tabs. Each run is appended as a new sub-tab (history), so a feed reads like a Stack of daily editions.
Intel Chat
RAG over your corpus: your question is embedded, a $vectorSearch on vector_index pulls the top-5 documents, and Gemini answers grounded in them.
Nexus Graph
A force-directed graph built from entity annotations on documents — people, orgs, and tickers linked across the corpus.
Command Center
Supervisor CRUD over TaskConfiguration — create tasks and edit their prompts and target collections inline.
Configuration Layers
Runtime behaviour lives in PostgreSQL, editable from the UI — no redeploy to change how the pipeline runs.
Defines what a task does: its prompt_template (with {transcript}) and target_collection. Adding a row makes /tasks/queuei/<task_key>/ live immediately.
Defines how the pipeline runs: playlist IDs, fetch limit, AI model, workers, sleep, extra document fields. Seeded from env vars on first visit, then the DB value wins. Read fresh on every run.
Schedules a pipeline or an internal endpoint on a 5-part cron expression. APScheduler hot-reloads on change.
A scheduled-LLM feed: a prompt, a render type (markdown or table), an optional model, and an icon. A CronJob hitting /tasks/feed/<key>/ refreshes it.
Scheduling
A single APScheduler BackgroundScheduler (UTC) reads CronJob rows and fires them.
Two job types:
pipeline— invokes a Python pipeline class directly (e.g. the YouTube or stock pipeline).endpoint— dispatches an internal request to a relative URL with the task secret header (used by feeds).
Timezone note
The scheduler runs in UTC. 9:00 AM IST is
30 3 * * *. Convert your local time to UTC before entering a cron expression.
Data Models (Postgres)
TaskConfiguration
task_key · display_name · prompt_template · target_collection · is_active
GlobalSetting
key · value · description
CronJob
name · job_type · task_key · endpoint_url · cron_expression · is_active · last_run_at · created_at
DashboardFeed
key · title · icon · prompt · render_type · ai_model · is_active · created_at
TranscriptCache
video_id · transcript · cached_at
MongoDB documents are schemaless; a record typically carries video metadata, the LLM result, entity annotations, and a 3072-dim embedding.
Endpoint Reference
| Method | Path | Purpose |
|---|---|---|
| GET | / | Dashboard (Analyst/Supervisor) |
| GET | /intel-chat/ | RAG chat over the corpus |
| GET | /nexus-data/ | Entity force-graph JSON |
| GET | /stocks-data/ | Latest stock analysis JSON |
| ALL | /command-center/ | TaskConfiguration CRUD (Supervisor) |
| ALL | /settings/ | GlobalSetting editor (superuser) |
| ALL | /cron/ | CronJob manager (superuser) |
| GET | /doc/ | This documentation portal |
| POST | /tasks/queuei/<task_key>/ | Run the YouTube pipeline for a task |
| POST | /tasks/feed/<feed_key>/ | Refresh a Dashboard Feed |
| POST | /tasks/stocks_refresh/ | Refresh NASDAQ analysis |
| POST | /tasks/alert/ | Send a Slack webhook alert |
| POST | /tasks/backfill_entities/ | Backfill entity annotations |
Environment Variables
Secrets and infrastructure config live in .env, never in the database.
Pipeline-behaviour vars (playlist IDs, fetch limit, AI model, workers, sleep, extra args) are only seeds — once the Settings page runs, the DB value takes over.
Access Control
New signups are is_active=False until a supervisor approves them. Authorisation is by Django group plus the superuser flag.
| Area | Who |
|---|---|
| Dashboard, Chat, Docs | Analyst or Supervisor |
| Command Center | Supervisor or superuser |
| Settings, Cron | Superuser only |
Unauthorised authenticated users see access_denied.html rather than a redirect.
Deployment
Local development:
# run the app python manage.py migrate python manage.py runserver # after model changes python manage.py makemigrations # build & run the container (connects to production DBs) ./build.sh
The container entrypoint runs migrate then gunicorn on port 8000 with --env-file .env. The scheduler boots inside the web process and hot-loads cron jobs from the DB.