SliceSeeker

Architecture

Phases, containers, and how data moves through the system

SliceSeeker is a pnpm monorepo. Application code lives in workspace packages; production runs those packages as containers plus shared infrastructure.

Phase model

┌─────────────────────────────────────────────┐
│  Phase 1: Indexing                          │
│  admin-ui → indexer-api → Valkey queues     │
│                 ↓                           │
│           indexer-worker                    │
│                 ↓                           │
│         Postgres + S3                       │
└─────────────────────────────────────────────┘

                      ▼  shared schema
┌─────────────────────────────────────────────┐
│  Phase 2: Search                            │
│  search-api  ←→  Postgres                   │
│  (embeds the query, reads vectors only)     │
└─────────────────────────────────────────────┘

Phases do not call each other over HTTP. Phase 2 only needs a populated Postgres instance and an embedding provider for query vectors.

Application containers

ContainerSourceRole
indexer-apiserver/Phase 1 HTTP API: uploads/hooks, collections, modality pipelines, search + costs used by the admin UI. Exposes /health and /ready.
indexer-workerworker/BullMQ consumers. Includes ffmpeg. Runs prep jobs (chunk / extract / sample) and API jobs (embed / ASR). Exits on startup if AI_GATEWAY_API_KEY is missing.
admin-uiclient/Operator UI. Proxies API and tusd.
search-apisearch/Phase 2 read-only search: multimodal, transcript, frame, and hybrid RRF endpoints. /ready checks gateway key + schema.
db-pushpackages/db/One-shot: enable vector extension and push Drizzle schema.

Infrastructure containers

ServiceTypical imageRole
dbpgvector/pgvectorPostgres + vectors
valkeyValkey / Redis-compatibleBullMQ job state. Must use maxmemory-policy noeviction.
rustfs (self-contained layout)S3-compatibleObject storage for source video, audio extracts, frames
tusdtusproject/tusdResumable uploads to S3; HTTP hooks notify indexer-api

Shared packages

PackagePurpose
dbDrizzle schema and access layer (uploads, collections, chunks, transcripts, frames, costs)
queueJob names, payloads, Valkey connection, concurrency helpers
search-clientTyped SDK for search-api

Queues

Phase 1 splits work across two BullMQ queues so ffmpeg-heavy prep can scale separately from embedding / Whisper load:

QueueKind of workConcurrency env
Prep (demo-prep-jobs)chunk-video, extract-audio, sample-frames, …PREP_WORKER_CONCURRENCY
API (demo-api-jobs)embed-chunk, transcribe-part, embed-transcript, embed-frame, …API_WORKER_CONCURRENCY

See Operations for pool sizing, retries, and readiness checks.

Data flow (one modality)

  1. Browser uploads via tusd → object lands in S3.
  2. tusd hook → indexer-api records the upload.
  3. Operator starts a pipeline → API enqueues a parent task.
  4. indexer-worker runs prep then embed/ASR jobs.
  5. Vectors and metadata land in Postgres.
  6. search-api (or indexer-api from the admin UI) embeds the query and runs cosine similarity.

On this page