A unified video indexing and publishing pipeline that discovers recordings on Zoom, Fireflies, Loom, YouTube, and Kaltura, lets curators review and approve them, and publishes approved content to YouTube and/or Kaltura with provenance preserved end-to-end.
Live: https://video-sync.agentics.org — gated by Google Cloud IAP. Operators authenticated via Google Workspace receive a role (Admin / Publisher / Viewer) based on group membership.
The project is built as a Next.js 15 app with a Rust/WASM domain model, runs on Google Cloud Run, and persists state to a GCS-FUSE-mounted bucket plus a Google Workspace Shared Drive (for human-readable artifacts).
- Import video metadata from Zoom (S2S OAuth), Fireflies (API key), Loom (oEmbed + Apollo-state scrape for createdAt / transcript / owner / language / chapters), YouTube uploads + live broadcasts, Kaltura entries (including live broadcasts captured via streaming software), direct URLs, or manual entry
- Triage with a rules engine (day of week, duration, title patterns, participants, tags) — scope / auto-approve / auto-skip
- Review via a catalog dashboard with processing-rule previews, transcripts, notes, per-video event logs, and a unified search across title / source / date / catalog id / tags / participants
- Publish to YouTube (per-operator brand-account OAuth so YouTube records the actual operator identity) and/or Kaltura (org-shared admin credential). Single-shot resumable uploads, title/description/tag templating, quota-aware backfill orchestration over 18-month backlogs
- Recover videos whose upload SSE dropped or that were uploaded out-of-band, via auto-lookup against the authorised YouTube channel + sibling-match dedupe across platforms
- Store artifacts (transcripts, generated descriptions, long summaries, in-meeting chat) in a Workspace Shared Drive folder per meeting (
<year>/<month>/<meeting>/{transcript,description,summary,chat}.md) - Audit every API request with
audit: "access"|"mutation"+ actor email/role; surfaced both to Cloud Logging and to the in-app EventLog via an 8-second poll - Track provenance across platforms (origin / intermediate / destination) with same-event sibling detection across sources
- Generate shorts via Opus Clip from published YouTube videos
src/ Rust domain model (compiled to WASM via wasm-pack)
catalog/ VideoRecord aggregate, value objects, events, WASM bindings
web/ Next.js 15 app
src/app/ App Router pages + API routes
src/components/ React components (VideoCard, BackfillPanel, ConnectionsPanel, …)
src/lib/ Client + server libraries (store, processingRules, sharedCredentials,
driveArtifactStore, siblingMatcher, …)
pkg/ Built WASM artifacts (generated by wasm-pack; gitignored)
docs/ User-facing and architectural documentation
adr/ Architecture Decision Records (ADR-001 … ADR-044)
notes/ External-facing notes (e.g. questions for IT)
.github/
ISSUE_TEMPLATE/ Structured forms for feedback / bug / feature requests
scripts/ Utility scripts (deploy preflight, ADR index generator,
transcript migration, FUSE bucket setup, …)
deploy.sh Manual deploy to Cloud Run (Docker build + push + deploy)
Start here if you're a user:
docs/mission-and-vision.md— what the app is for and why it existsdocs/user-guide.md— comprehensive feature walkthrough (connections, import, review, publish, backfill, recovery)docs/user-flows.md— step-by-step diagrams of common workflowsdocs/stakeholders.md— roles (Curator, Content Owner, Platform Admin, DevOps, Compliance)docs/capabilities.md— capability matrix (status + ADR refs per row) for side-by-side comparison with other tools- In-app Help button (top-right) → project wiki on GitHub
Start here if you're a developer:
CLAUDE.md— project conventions for AI-assisted developmentdocs/adr/— all architectural decisions. The current-state shortlist:- ADR-002 Unified video metadata schema
- ADR-008 DDD bounded contexts
- ADR-035 Persistence topology — the single source of truth for what lives where (Levels 1 + 2 active)
- ADR-036 Google Workspace authentication + role-based access (IAP-fronted, Cloud Identity Groups)
- ADR-039 Drive-based artifact storage (transcripts / descriptions / summaries / chat)
- ADR-040 Broaden source imports — Kaltura, YouTube Live, multi-origin per date
- ADR-041 App-level audit log of access + mutation attempts
- ADR-042 Server-side credentials with operator override (Secret Manager hybrid)
- ADR-043 Share backfill profiles, queue, exclusions across operators
- ADR-044 Always show Kaltura presence alongside YouTube (Proposed)
- ADR-045 Wider IAP gate + app-level redirect for unauthorized users
- ADR-046 Prompt-driven video summaries on Drive
- ADR-047 Automated Catch-Up action
- ADR-048 Date-distance gates in matchers
- ADR-049 Live-stream provenance — Zoom-to-YouTube broadcasts
- ADR-050 Fireflies as downstream of the meeting source
- ADR-051 YouTube source rows from publish-trail ingest land at Published
- ADR-052 Catch-Up Summary Badge Backfill (Proposed)
- ADR-053 Transcript provenance lookup — borrow from related records (Proposed)
docs/guide.md— legacy short-form overview; preferdocs/user-guide.md
# Build the WASM domain model
wasm-pack build --target web --release --out-dir pkg
# Run the Next.js dev server
cd web && npm install && npm run dev
# Type-check and build for production
NODE_OPTIONS="--max-old-space-size=6144" npx tsc --noEmit
npm run buildTests for the Rust domain live under src/ (cargo test). The Next.js side has Vitest configured but only thin coverage today; see ADR-041 / ADR-042 review notes for the prioritised gap list.
Local Docker builds OOM in low-memory devcontainers during static page generation, so deploy via Cloud Build:
SHA=$(git rev-parse --short HEAD)
gcloud builds submit \
--tag "us-central1-docker.pkg.dev/agentics-487016/video-sync/app:$SHA" \
--project=agentics-487016 \
--timeout=20m
gcloud run services update video-sync \
--region=us-central1 \
--image="us-central1-docker.pkg.dev/agentics-487016/video-sync/app:$SHA" \
--update-env-vars=IAP_AUDIENCE=/projects/667037737667/locations/us-central1/services/video-syncA ./deploy.sh wrapper exists for end-to-end local builds when host memory is generous.
Before the first deploy on a new machine:
gcloud auth login
gcloud auth configure-docker us-central1-docker.pkg.dev
gcloud config set project agentics-487016gcloud run services update-traffic video-sync \
--region=us-central1 --to-revisions=<PREV_REVISION>=100Cloud Run retains every revision — roll back via the console or the command above.
- In-app Feedback button (top-right) drops you on a structured GitHub issue template pre-filled with the build SHA
- Bug reports / feature requests / general feedback templates live under
.github/ISSUE_TEMPLATE/— also available via the standard "New issue" picker on GitHub
- Catalog, transcripts, rules, backfill profiles + queue, exclusions all live on the server (FUSE-mounted GCS or Drive); two browsers on the same URL see the same state
- Credentials are hybrid: shared defaults in Google Secret Manager managed by Admins; operator overrides in localStorage; YouTube is per-operator only (brand-account attribution per ADR-042)
- Audit log captures every API request with actor identity and
audit: "access"|"mutation"classification; surfaced both to Cloud Logging and to the in-app EventLog - IAP gates the door; Cloud Identity Groups drive Admin / Publisher / Viewer roles
- YouTube API quota: 10,000 units/day default. An upload costs 1,600 units (~6/day). Reads are 1 unit each. See ADR-012 and ADR-016 for how the backfill orchestrator works within this.
- Per-instance audit ring buffer: the in-app EventLog audit feed (ADR-041) is per-Cloud-Run-instance. Cloud Logging is the cross-instance source of truth.
- Multi-instance credential cache lag: shared-secret rotation propagates within 5 minutes per-instance (ADR-042 §risks). An admin flush-cache endpoint is in ADR-042 Phase 3.
- Cloud Run 1-hour request timeout: large Loom uploads to YouTube can approach this for multi-hour videos. The publish route uses yt-dlp + resumable upload but has no checkpointing.
Not yet licensed — this is an internal project. Discuss with the maintainer before using externally.