# Video Pipeline

> Load full context for the WORKATHON internal production management app and resume work on it

- Skill: `prawal-bhuyan/video-pipeline` (Agent Skill)
- Install (CLI): `npx skillmds@latest add prawal-bhuyan/video-pipeline`
- Raw SKILL.md: https://api.skillmd.com/api/skills/prawal-bhuyan/video-pipeline/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: Prawal-Bhuyan (https://skillmd.com/u/prawal-bhuyan)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/prawal-bhuyan/video-pipeline

---


## Project: WORKATHON

Internal web app for managing a video production team workflow. Branded as **WORKATHON** (all caps).

**Locations**
- Backend (local dev): `/Users/prawalbhuyan/video-pipeline/backend`
- Backend (Cloudflare Worker): `/Users/prawalbhuyan/video-pipeline/backend-worker`
- Frontend (Vite/React): `/Users/prawalbhuyan/video-pipeline/frontend` — runs on port 5173
- Frontend (Astro): `/Users/prawalbhuyan/video-pipeline/frontend-astro` — runs on port 4321

**Live deployment**
- Frontend: `https://workathon.pages.dev` (Cloudflare Pages)
- Backend: `https://workathon.prawal-bhuyan.workers.dev` (Cloudflare Workers)
- Database: Cloudflare D1 — database name `workathon-db`, ID `947f0078-4573-4d59-a7b8-42418e3fe7ec`
- Admin account: `prawal.bhuyan@vantagecircle.com` / `Admin@2026`
- `PUBLIC_API_URL=https://workathon.prawal-bhuyan.workers.dev` must be set in Cloudflare Pages env vars

**Stack**
- Frontend (Vite): React 18 + TypeScript + Vite + TailwindCSS + React Query v5 + React Router v6
- Frontend (Astro): Astro 4 + React 18 + TypeScript + TailwindCSS + React Query v5 + React Router v6 (client:only="react" SPA pattern)
- Backend (local): Node.js + Express + TypeScript + Prisma ORM + SQLite
- Backend (production/Worker): Hono + Drizzle ORM + Cloudflare D1 + jose (JWT) + bcryptjs
- Auth: JWT (access token in localStorage), bcrypt passwords
- Email: Not implemented in Worker (returns success without sending)
- File uploads: Not implemented in Worker (returns 501)

**How to run locally**
```bash
# Backend (port 4000, hot reload)
cd /Users/prawalbhuyan/video-pipeline/backend && npm run dev

# Frontend Vite (port 5173, proxies /api → :4000)
cd /Users/prawalbhuyan/video-pipeline/frontend && npm run dev

# Frontend Astro (port 4321, proxies /api → :4000)
cd /Users/prawalbhuyan/video-pipeline/frontend-astro && npm run dev
```

**How to deploy Worker**
```bash
export CLOUDFLARE_EMAIL="prawal.bhuyan@vantagecircle.com"
export CLOUDFLARE_API_KEY="<global-api-key>"
cd /Users/prawalbhuyan/video-pipeline/backend-worker && npx wrangler deploy
```

**If Worker stops working after a GitHub push** — redeploy and re-set secrets:
```bash
export CLOUDFLARE_EMAIL="prawal.bhuyan@vantagecircle.com" && export CLOUDFLARE_API_KEY="<global-api-key>"
cd /Users/prawalbhuyan/video-pipeline/backend-worker && npx wrangler deploy
npx wrangler secret put JWT_SECRET        # value: workathon-secret-2026
npx wrangler secret put ADMIN_EMAIL       # value: prawal.bhuyan@vantagecircle.com
npx wrangler secret put ADMIN_PASSWORD    # value: Admin@2026
```

**IMPORTANT:** The Worker GitHub auto-deploy has been disconnected — only deploy manually via wrangler. Never reconnect GitHub to the Worker or it will overwrite the secrets.

**Worker URL is hardcoded** in `frontend-astro/src/services/api.ts` as fallback — `PUBLIC_API_URL` env var is no longer required in Cloudflare Pages. Login is stable.

**Key backend-worker files**
- `src/index.ts` — Hono app, CORS, admin seed on first request, all route mounts
- `src/routes/auth.ts` — login, register, me, update, password change, forgot/reset, admin user CRUD
- `src/routes/projects.ts` — project CRUD, auto-creates 4 pipeline tasks on create
- `src/routes/tasks.ts` — task CRUD, status transitions, dependency unlocking, project status sync
- `src/routes/dashboard.ts` — user and admin dashboards
- `src/routes/notifications.ts` — list, mark read, mark all read
- `src/routes/reports.ts` — admin team report by year/month
- `src/routes/public.ts` — public overview and member work detail (no auth)
- `src/db/schema.ts` — Drizzle schema (mirrors Prisma schema, dates as ISO strings)
- `src/middleware/auth.ts` — JWT sign/verify with jose, authenticate middleware
- `wrangler.toml` — D1 binding, CLIENT_URL, NODE_ENV
- `drizzle/0000_initial.sql` — DB migration SQL

**Key local backend files**
- `src/controllers/auth.controller.ts` — login, register, forgotPassword, resetPassword, changePassword, createUserByAdmin, updateUser
- `src/controllers/task.controller.ts` — task CRUD, status transitions, dependency unlocking
- `src/controllers/project.controller.ts` — project CRUD, auto-generates 4 pipeline tasks on create
- `src/controllers/public.controller.ts` — no-auth overview, member work detail
- `src/controllers/report.controller.ts` — admin-only team reports by year/month
- `prisma/schema.prisma` — all enums are String fields (SQLite has no enum support)

**Worker response format**
All Worker routes return `{ success: true, data: { ... } }` — frontend reads `res.data.data.*`

**Key frontend files (Vite — src/)**
- `src/pages/` — Login, Register, ForgotPassword, ResetPassword, Dashboard, Projects, ProjectDetail, TaskDetail, KanbanBoard, Team, Reports, PublicOverview
- `src/contexts/AuthContext.tsx` — user state, login/logout, isAdmin flag, `updateCurrentUser` for syncing email changes
- `src/services/api.ts` — all Axios calls (authApi, projectApi, taskApi, fileApi, notificationApi, dashboardApi, publicApi, reportApi)
- `src/components/Layout/Sidebar.tsx` — WORKATHON logo (workathon-logo.png in white container), nav links, logout
- `src/components/Layout/AppLayout.tsx` — four product logos banner at top, then Header + Outlet
- `src/components/Layout/Header.tsx` — page title + notifications bell

**Key frontend files (Astro — src/)**
- `src/pages/index.astro` — single shell page rendering `<App client:only="react" />` (SPA entry point)
- `src/views/` — all React page components (renamed from pages/ to avoid Astro routing conflict)
- `src/App.tsx` — imports from `./views/` instead of `./pages/`
- `src/styles/global.css` — Tailwind directives
- `docs/` — ARCHITECTURE.md, PAGES.md, API.md

**Public assets (both frontends)**
- `public/workathon-logo.png` — app logo (dark on white, wrap in `bg-white rounded` on dark backgrounds)
- `public/vantagerecognition-logo.png` — Vantage Recognition
- `public/vantagefit-logo.png` — Vantage Fit
- `public/vantagepulse-logo.png` — Vantage Pulse
- `public/vantageperks-logo.png` — Vantage Perks

**Logo banner**
- Public overview (`PublicOverview.tsx`): white banner at top with all 4 product logos — `justify-between`, `h-14`
- Authenticated pages (`AppLayout.tsx`): same 4 logos in white banner above the Header — `justify-between`, `h-10`
- Sidebar / auth page logos: WORKATHON logo wrapped in `bg-white rounded-lg px-3 py-1.5` (dark background)

**Roles**
- `ADMIN` — full access, can edit everything, delete tasks/projects, add members, view reports
- `EDITOR`, `SCRIPT_WRITER`, `SOUND_ENGINEER` — limited to their own tasks
- Self-registration is open (no Admin option in signup form)

**Auth flows**
- `/` is the public overview (no login required) — Login button in header
- After logout → redirects to `/` (public overview), not `/login`
- Register → auto-login → dashboard
- Forgot password → email with 1-hour reset link (Ethereal in dev: check backend console for preview URL)
- Reset password → redirects to login on success
- 401 response → Axios interceptor clears token, redirects to `/`

**Pipeline**
4 tasks auto-created per project: SCRIPT_WRITING → VIDEO_EDITING → SOUND_DESIGN → FINAL_REVIEW
Each unlocks the next when completed/approved. Dependency blocking enforced.
Admin can delete tasks — dependents are unblocked (dependsOnId set to null) before deletion.

**Public overview features**
- No login required — visible to anyone with the URL
- Four product logos banner at top
- WORKATHON header with Login/Dashboard/Logout buttons
- Team member cards: expand to see active tasks, "View Work" button opens modal
- MemberWorkModal: 4 tabs — Current, Upcoming, Monthly (last 12 months), Daily (last 30 days)
- Project cards with pipeline progress bars
- Auto-refreshes every 60 seconds
- Admins are hidden from public view

**Team page (admin only)**
- Editable name and email (inline pencil icon)
- Email change syncs to AuthContext if editing own account
- Add Member modal (name, email, role, password)

**Reports page (admin only)**
- Monthly/yearly work summary per team member
- CSV download

**Live admin account**
- prawal.bhuyan@vantagecircle.com / Admin@2026 (ADMIN role, ID: admin-001)

**Demo accounts (local dev only)**
- admin@videopipeline.com / admin123
- editor1@videopipeline.com / editor123
- writer@videopipeline.com / writer123
- sound@videopipeline.com / sound123

## Instructions

1. Read the current state of any file before editing it.
2. Backend uses string literals for all statuses/priorities (no Prisma enum imports).
3. Always run `npx tsc --noEmit` in the frontend dir after changes to catch type errors.
4. The Admin Edit panel (amber background) appears at the top of Task Detail and Project Detail pages for admin users only.
5. When editing shared components (AppLayout, Sidebar, Header), mirror the change in both `frontend/` and `frontend-astro/`.
6. WORKATHON logo has a white background — always wrap it in `bg-white rounded` container when placing on dark backgrounds.
7. React Query v5: use `isPending` (not `isLoading`) for initial load guards to avoid blank pages.
8. Worker routes must wrap all successful responses in `data: {}` — e.g. `{ success: true, data: { user } }`.
9. After editing Worker routes, redeploy with `npx wrangler deploy` from `backend-worker/` (needs CLOUDFLARE_EMAIL + CLOUDFLARE_API_KEY env vars).
10. Worker does NOT support file uploads or email sending — those return 501/success-no-op respectively.
11. Ask the user what they'd like to work on, then proceed.

