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
# 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
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:
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
Demo accounts (local dev only)
Instructions
- Read the current state of any file before editing it.
- Backend uses string literals for all statuses/priorities (no Prisma enum imports).
- Always run
npx tsc --noEmit in the frontend dir after changes to catch type errors.
- The Admin Edit panel (amber background) appears at the top of Task Detail and Project Detail pages for admin users only.
- When editing shared components (AppLayout, Sidebar, Header), mirror the change in both
frontend/ and frontend-astro/.
- WORKATHON logo has a white background — always wrap it in
bg-white rounded container when placing on dark backgrounds.
- React Query v5: use
isPending (not isLoading) for initial load guards to avoid blank pages.
- Worker routes must wrap all successful responses in
data: {} — e.g. { success: true, data: { user } }.
- After editing Worker routes, redeploy with
npx wrangler deploy from backend-worker/ (needs CLOUDFLARE_EMAIL + CLOUDFLARE_API_KEY env vars).
- Worker does NOT support file uploads or email sending — those return 501/success-no-op respectively.
- Ask the user what they'd like to work on, then proceed.
1---2name: video-pipeline3description: Load full context for the WORKATHON internal production management app and resume work on it4---56## Project: WORKATHON78Internal web app for managing a video production team workflow. Branded as **WORKATHON** (all caps).910**Locations**11- Backend (local dev): `/Users/prawalbhuyan/video-pipeline/backend`12- Backend (Cloudflare Worker): `/Users/prawalbhuyan/video-pipeline/backend-worker`13- Frontend (Vite/React): `/Users/prawalbhuyan/video-pipeline/frontend` — runs on port 517314- Frontend (Astro): `/Users/prawalbhuyan/video-pipeline/frontend-astro` — runs on port 43211516**Live deployment**17- Frontend: `https://workathon.pages.dev` (Cloudflare Pages)18- Backend: `https://workathon.prawal-bhuyan.workers.dev` (Cloudflare Workers)19- Database: Cloudflare D1 — database name `workathon-db`, ID `947f0078-4573-4d59-a7b8-42418e3fe7ec`20- Admin account: `prawal.bhuyan@vantagecircle.com` / `Admin@2026`21- `PUBLIC_API_URL=https://workathon.prawal-bhuyan.workers.dev` must be set in Cloudflare Pages env vars2223**Stack**24- Frontend (Vite): React 18 + TypeScript + Vite + TailwindCSS + React Query v5 + React Router v625- Frontend (Astro): Astro 4 + React 18 + TypeScript + TailwindCSS + React Query v5 + React Router v6 (client:only="react" SPA pattern)26- Backend (local): Node.js + Express + TypeScript + Prisma ORM + SQLite27- Backend (production/Worker): Hono + Drizzle ORM + Cloudflare D1 + jose (JWT) + bcryptjs28- Auth: JWT (access token in localStorage), bcrypt passwords29- Email: Not implemented in Worker (returns success without sending)30- File uploads: Not implemented in Worker (returns 501)3132**How to run locally**33```bash34# Backend (port 4000, hot reload)35cd /Users/prawalbhuyan/video-pipeline/backend && npm run dev3637# Frontend Vite (port 5173, proxies /api → :4000)38cd /Users/prawalbhuyan/video-pipeline/frontend && npm run dev3940# Frontend Astro (port 4321, proxies /api → :4000)41cd /Users/prawalbhuyan/video-pipeline/frontend-astro && npm run dev42```4344**How to deploy Worker**45```bash46export CLOUDFLARE_EMAIL="prawal.bhuyan@vantagecircle.com"47export CLOUDFLARE_API_KEY="<global-api-key>"48cd /Users/prawalbhuyan/video-pipeline/backend-worker && npx wrangler deploy49```5051**If Worker stops working after a GitHub push** — redeploy and re-set secrets:52```bash53export CLOUDFLARE_EMAIL="prawal.bhuyan@vantagecircle.com" && export CLOUDFLARE_API_KEY="<global-api-key>"54cd /Users/prawalbhuyan/video-pipeline/backend-worker && npx wrangler deploy55npx wrangler secret put JWT_SECRET # value: workathon-secret-202656npx wrangler secret put ADMIN_EMAIL # value: prawal.bhuyan@vantagecircle.com57npx wrangler secret put ADMIN_PASSWORD # value: Admin@202658```5960**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.6162**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.6364**Key backend-worker files**65- `src/index.ts` — Hono app, CORS, admin seed on first request, all route mounts66- `src/routes/auth.ts` — login, register, me, update, password change, forgot/reset, admin user CRUD67- `src/routes/projects.ts` — project CRUD, auto-creates 4 pipeline tasks on create68- `src/routes/tasks.ts` — task CRUD, status transitions, dependency unlocking, project status sync69- `src/routes/dashboard.ts` — user and admin dashboards70- `src/routes/notifications.ts` — list, mark read, mark all read71- `src/routes/reports.ts` — admin team report by year/month72- `src/routes/public.ts` — public overview and member work detail (no auth)73- `src/db/schema.ts` — Drizzle schema (mirrors Prisma schema, dates as ISO strings)74- `src/middleware/auth.ts` — JWT sign/verify with jose, authenticate middleware75- `wrangler.toml` — D1 binding, CLIENT_URL, NODE_ENV76- `drizzle/0000_initial.sql` — DB migration SQL7778**Key local backend files**79- `src/controllers/auth.controller.ts` — login, register, forgotPassword, resetPassword, changePassword, createUserByAdmin, updateUser80- `src/controllers/task.controller.ts` — task CRUD, status transitions, dependency unlocking81- `src/controllers/project.controller.ts` — project CRUD, auto-generates 4 pipeline tasks on create82- `src/controllers/public.controller.ts` — no-auth overview, member work detail83- `src/controllers/report.controller.ts` — admin-only team reports by year/month84- `prisma/schema.prisma` — all enums are String fields (SQLite has no enum support)8586**Worker response format**87All Worker routes return `{ success: true, data: { ... } }` — frontend reads `res.data.data.*`8889**Key frontend files (Vite — src/)**90- `src/pages/` — Login, Register, ForgotPassword, ResetPassword, Dashboard, Projects, ProjectDetail, TaskDetail, KanbanBoard, Team, Reports, PublicOverview91- `src/contexts/AuthContext.tsx` — user state, login/logout, isAdmin flag, `updateCurrentUser` for syncing email changes92- `src/services/api.ts` — all Axios calls (authApi, projectApi, taskApi, fileApi, notificationApi, dashboardApi, publicApi, reportApi)93- `src/components/Layout/Sidebar.tsx` — WORKATHON logo (workathon-logo.png in white container), nav links, logout94- `src/components/Layout/AppLayout.tsx` — four product logos banner at top, then Header + Outlet95- `src/components/Layout/Header.tsx` — page title + notifications bell9697**Key frontend files (Astro — src/)**98- `src/pages/index.astro` — single shell page rendering `<App client:only="react" />` (SPA entry point)99- `src/views/` — all React page components (renamed from pages/ to avoid Astro routing conflict)100- `src/App.tsx` — imports from `./views/` instead of `./pages/`101- `src/styles/global.css` — Tailwind directives102- `docs/` — ARCHITECTURE.md, PAGES.md, API.md103104**Public assets (both frontends)**105- `public/workathon-logo.png` — app logo (dark on white, wrap in `bg-white rounded` on dark backgrounds)106- `public/vantagerecognition-logo.png` — Vantage Recognition107- `public/vantagefit-logo.png` — Vantage Fit108- `public/vantagepulse-logo.png` — Vantage Pulse109- `public/vantageperks-logo.png` — Vantage Perks110111**Logo banner**112- Public overview (`PublicOverview.tsx`): white banner at top with all 4 product logos — `justify-between`, `h-14`113- Authenticated pages (`AppLayout.tsx`): same 4 logos in white banner above the Header — `justify-between`, `h-10`114- Sidebar / auth page logos: WORKATHON logo wrapped in `bg-white rounded-lg px-3 py-1.5` (dark background)115116**Roles**117- `ADMIN` — full access, can edit everything, delete tasks/projects, add members, view reports118- `EDITOR`, `SCRIPT_WRITER`, `SOUND_ENGINEER` — limited to their own tasks119- Self-registration is open (no Admin option in signup form)120121**Auth flows**122- `/` is the public overview (no login required) — Login button in header123- After logout → redirects to `/` (public overview), not `/login`124- Register → auto-login → dashboard125- Forgot password → email with 1-hour reset link (Ethereal in dev: check backend console for preview URL)126- Reset password → redirects to login on success127- 401 response → Axios interceptor clears token, redirects to `/`128129**Pipeline**1304 tasks auto-created per project: SCRIPT_WRITING → VIDEO_EDITING → SOUND_DESIGN → FINAL_REVIEW131Each unlocks the next when completed/approved. Dependency blocking enforced.132Admin can delete tasks — dependents are unblocked (dependsOnId set to null) before deletion.133134**Public overview features**135- No login required — visible to anyone with the URL136- Four product logos banner at top137- WORKATHON header with Login/Dashboard/Logout buttons138- Team member cards: expand to see active tasks, "View Work" button opens modal139- MemberWorkModal: 4 tabs — Current, Upcoming, Monthly (last 12 months), Daily (last 30 days)140- Project cards with pipeline progress bars141- Auto-refreshes every 60 seconds142- Admins are hidden from public view143144**Team page (admin only)**145- Editable name and email (inline pencil icon)146- Email change syncs to AuthContext if editing own account147- Add Member modal (name, email, role, password)148149**Reports page (admin only)**150- Monthly/yearly work summary per team member151- CSV download152153**Live admin account**154- prawal.bhuyan@vantagecircle.com / Admin@2026 (ADMIN role, ID: admin-001)155156**Demo accounts (local dev only)**157- admin@videopipeline.com / admin123158- editor1@videopipeline.com / editor123159- writer@videopipeline.com / writer123160- sound@videopipeline.com / sound123161162## Instructions1631641. Read the current state of any file before editing it.1652. Backend uses string literals for all statuses/priorities (no Prisma enum imports).1663. Always run `npx tsc --noEmit` in the frontend dir after changes to catch type errors.1674. The Admin Edit panel (amber background) appears at the top of Task Detail and Project Detail pages for admin users only.1685. When editing shared components (AppLayout, Sidebar, Header), mirror the change in both `frontend/` and `frontend-astro/`.1696. WORKATHON logo has a white background — always wrap it in `bg-white rounded` container when placing on dark backgrounds.1707. React Query v5: use `isPending` (not `isLoading`) for initial load guards to avoid blank pages.1718. Worker routes must wrap all successful responses in `data: {}` — e.g. `{ success: true, data: { user } }`.1729. After editing Worker routes, redeploy with `npx wrangler deploy` from `backend-worker/` (needs CLOUDFLARE_EMAIL + CLOUDFLARE_API_KEY env vars).17310. Worker does NOT support file uploads or email sending — those return 501/success-no-op respectively.17411. Ask the user what they'd like to work on, then proceed.