diff --git a/DEPLOY.md b/DEPLOY.md new file mode 100644 index 0000000..e1afc13 --- /dev/null +++ b/DEPLOY.md @@ -0,0 +1,206 @@ +# Deploying dow-prod-tracker + +Target: **`https://optical-dev.oliver.solutions/dow-prod-tracker`**, hosted on the +shared Oliver Agency dev box alongside `hp-prod-tracker`. + +Run the deploy script from the repo root on the server: + +```bash +cd /srv/dow-prod-tracker # or wherever you cloned it +./deploy.sh +``` + +The first run will install Docker, Compose, Apache and UFW if missing, prompt +you to fill in `.env` from `.env.example`, then bring everything up. Subsequent +runs are idempotent — safe to re-run for updates. + +--- + +## Why this deploy is different from the rest + +The shared server runs multiple apps from sibling deploy directories. **Two +things must hold or those apps will silently corrupt each other** (this has +bitten us before — see CLAUDE.md): + +1. **`docker-compose.yml` MUST pin a top-level `name:` field.** + We pin `name: dow-prod-tracker`. Without this, Compose defaults the project + name to the parent directory name. If two apps both live under `deploy/`, + they collapse onto the same project and fight over containers + (`deploy-db-1`) and volumes (`deploy_pgdata`). Deploying one would silently + evict the other and destroy its data. + +2. **Every `docker compose` invocation in `deploy.sh` passes `-p + dow-prod-tracker` as belt-and-braces.** + This is redundant with `name:` today, but if anyone moves the `name:` line + out of the compose file, or runs commands by hand from a different cwd, + the `-p` flag is the safety net. + +The deploy script also enforces: + +| Concern | Value | Where | +|---|---|---| +| Compose project name | `dow-prod-tracker` | `name:` in `docker-compose.yml` + `-p` in `deploy.sh` | +| App port (host) | `3002` | `docker-compose.yml` ports + `deploy.sh` `APP_PORT` + `apache/dow-prod-tracker.conf` | +| DB port (host) | `5492` | `docker-compose.yml` ports | +| DB name | `dow_prod_tracker` | `docker-compose.yml` env + `.env` `DATABASE_URL` | +| App URL path | `/dow-prod-tracker` | `next.config.ts` `basePath` | +| Apache reverse proxy | `→ 127.0.0.1:3002/dow-prod-tracker` | `apache/dow-prod-tracker.conf` | + +If you change any of these, change them in **all** the listed locations or +the deploy will silently fail (or, worse, route Dow traffic to HP's app). + +`hp-prod-tracker` runs on **port 3001**. Don't reuse it. + +--- + +## .env.production checklist + +Required env vars on the server: + +``` +DATABASE_URL=postgresql://postgres:@db:5432/dow_prod_tracker?schema=public +DB_PASSWORD= +AUTH_SECRET= + +# Auth — local credentials in MVP. Flip to true post-MVP once Entra is wired. +NEXT_PUBLIC_AUTH_ENTRA_ENABLED=false + +# Entra (only required when NEXT_PUBLIC_AUTH_ENTRA_ENABLED=true) +AZURE_CLIENT_ID= +AZURE_TENANT_ID= +AZURE_REDIRECT_URI=https://optical-dev.oliver.solutions/dow-prod-tracker/login + +# OMG webhook receiver +OMG_WEBHOOK_SECRET= # share with Shashank +OMG_WEBHOOK_ALLOW_INSECURE=false + +# AI chat (optional — chat features degrade gracefully if absent) +ANTHROPIC_API_KEY= +OLLAMA_HOST=http://10.24.42.219:11434 +OLLAMA_CHAT_MODEL=gemma4:latest +OLLAMA_EMBED_MODEL=nomic-embed-text + +# Cron + API key (used for scheduled tasks + machine-to-machine API access) +CRON_SECRET= +API_KEY= + +# Initial admin (optional — overrides the default admin@dowjones.com / random pw) +DOW_ADMIN_EMAIL=admin@dowjones.com +DOW_ADMIN_PASSWORD= # leave blank → seed prints a random one +``` + +--- + +## First-time setup on a fresh server + +```bash +# 1. Clone +sudo mkdir -p /srv && sudo chown $USER:$USER /srv +cd /srv +git clone git@bitbucket.org:zlalani/dow-prod-tracker.git +cd dow-prod-tracker + +# 2. Configure +cp .env.example .env +$EDITOR .env # fill in real secrets + +# 3. Deploy (installs deps, builds, runs migrations, configures Apache + UFW) +./deploy.sh + +# 4. Seed the Dow tenant + initial admin (one-time) +docker compose -p dow-prod-tracker exec app npm run db:seed +# → save the printed admin email + temp password +``` + +--- + +## Updating an existing deployment + +```bash +cd /srv/dow-prod-tracker +./deploy.sh # pulls, rebuilds, restarts +``` + +The Prisma migration in `prisma/migrations/20260420000000_init/` runs on +container startup (via the standalone Next.js entrypoint). New migrations land +automatically. + +--- + +## Verification — must pass before declaring deploy done + +1. **Volume isolation** — both apps' volumes must be distinct: + ```bash + docker volume ls | grep -E "hp-prod-tracker|dow-prod-tracker" + ``` + Expect to see `hp-prod-tracker_pgdata`, `hp-prod-tracker_uploads_data`, + `dow-prod-tracker_pgdata`, `dow-prod-tracker_uploads_data` — four distinct + volumes. + +2. **HP unaffected** — hit HP's URL in a browser and confirm it loads. If it + fails, the new deploy collided with it (don't continue — fix first). + +3. **Health check** — `curl https://optical-dev.oliver.solutions/dow-prod-tracker/api/health` + should return 200. + +4. **Login** — open the URL in a browser, sign in with the seed admin + credentials, get redirected to `/change-password?first=1`, set a real + password, land on `/dashboard`. + +5. **XLSX ingest** — upload `Dow Jones_Studio Tracker_Example_*.xlsx` via + `POST /api/projects/bulk-import?commit=false` (curl or via the UI button). + Expect a preview JSON with normalized rows + any row errors. Then commit + with `?commit=true` and spot-check a project in psql: + ```bash + docker compose -p dow-prod-tracker exec db \ + psql -U postgres -d dow_prod_tracker \ + -c "select \"omgJobNumber\", name, status, \"clientTeamId\" from projects limit 5;" + ``` + +6. **OMG webhook** — when Shashank confirms the payload shape, share + `OMG_WEBHOOK_SECRET` and have OMG POST to + `https://optical-dev.oliver.solutions/dow-prod-tracker/api/webhooks/omg` + with header `X-OMG-Signature: sha256=`. + +7. **Per-team visibility** — invite a test user as `CLIENT_VIEWER`, assign + them to one client team only (Settings → Client Teams), accept the invite + link, sign in, confirm they only see that team's projects. + +--- + +## Rollback + +If a deploy goes wrong: + +```bash +cd /srv/dow-prod-tracker +git log --oneline -5 # find previous good commit +git checkout +./deploy.sh --skip-pull # rebuild from that commit +``` + +If the database itself is in a bad state (rare — Prisma migrations are +forward-only), restore from the latest postgres dump in `/srv/backups/` +(set up your own cron for these — not yet automated). + +--- + +## Common issues + +**"port is already allocated"** — something else is on 3002 or 5492. Check +with `sudo ss -tlnp | grep -E '3002|5492'`. If it's a stale dow-prod-tracker +container from a botched deploy, `docker compose -p dow-prod-tracker down` +will release it. + +**Apache returns 502** — the app container isn't running or its health check +is failing. `docker compose -p dow-prod-tracker logs app --tail 50`. + +**"Project with that OMG number already exists in a different organization"** +— a previous import landed projects under a different org (e.g. dev seed). +Either delete those projects, or recreate the org with the canonical +`dowjones.com` domain (the seed and webhook both look up the org by domain). + +**`/api/webhooks/omg` returns 401** — signature mismatch. Verify both ends +share the exact `OMG_WEBHOOK_SECRET` and that OMG sends the header as +`X-OMG-Signature: sha256=`. For local stub testing only, set +`OMG_WEBHOOK_ALLOW_INSECURE=true` in `.env` and restart. diff --git a/README.md b/README.md index fd0a2c4..7a9ad83 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,17 @@ # Dow Jones Studio Tracker -A purpose-built production tracking tool for the HP CG department — replacing the fragmented workflow of Workfront, Excel spreadsheets, and the OMG platform with a single, unified web application. +A production tracking tool for the Dow Jones studio team at Oliver Agency — +replacing Excel/Planner with a single web app: per-team-scoped project visibility, +the 11-stage Dow pipeline (Pipeline → New → Copywriter → Client Review → In +Progress Creative → Internal Review → Client Feedback → Final Approval → +Completed + On Hold + Canceled), and ingest from both the OMG webhook and the +Studio Tracker XLSX. -Built for producers and CG artists who need real-time visibility into where every deliverable stands across every stage of the pipeline. +Forked from `hp-prod-tracker`, customized for Dow Jones. See [DEPLOY.md](./DEPLOY.md) +for deployment to `optical-dev.oliver.solutions/dow-prod-tracker`. + +Built for producers and creative team members who need real-time visibility into +where every deliverable stands across every stage of the pipeline. --- diff --git a/src/components/layout/sidebar.tsx b/src/components/layout/sidebar.tsx index 97ebe2c..4be062e 100644 --- a/src/components/layout/sidebar.tsx +++ b/src/components/layout/sidebar.tsx @@ -1,6 +1,7 @@ "use client"; import Link from "next/link"; +import Image from "next/image"; import { usePathname } from "next/navigation"; import { LayoutDashboard, @@ -175,14 +176,16 @@ export function Sidebar() { isCollapsed ? "justify-center px-2" : "px-4" )}> {!isCollapsed && ( -
- - Dow Jones Studio - - - by Oliver Agency - -
+ + Dow Jones Studio Tracker + )}