Four phases shipped together. Each is a logical deploy unit on its own;
keeping the diff atomic so the rename runbook + migrations stay aligned.
Phase 1 — restore HP's formal review workflow
- Prisma: FeedbackItem, ReviewSession, ReviewSessionItem + enums
- New ApprovalType (NONE | SIMPLE | FORMAL) on PipelineStageDefinition
and PipelineStageTemplate. Stage row UI branches per type.
- feedback-service + review-session-service ported from HP (no ColorProbe)
- annotation-service auto-creates a FeedbackItem; revision-service
carries forward unresolved action items into the new revision.
- API: /api/reviews/*, /api/stages/[id]/feedback, /api/feedback/[id]
- Hooks: use-feedback, use-review-sessions
- UI: feedback-checklist, feedback-item-card, feedback-progress-bar,
create-session-dialog, session-builder, session-presenter,
session-summary, plus a new stage-review-panel
- Pages: /reviews list + detail, deliverable annotation review page
- Pipeline editor gets the approvalType select; sidebar gets Reviews
Phase 2 — full Dow Jones → L'Oréal rebrand + slug rename
- URL slug /dow-prod-tracker → /loreal-prod-tracker (next.config,
base path, redirects)
- docker-compose name + DB → loreal_prod_tracker; server path
/opt/loreal-prod-tracker; apache template renamed
- All visible strings → L'Oréal; sidebar bg #002B5C → black
- docs/RENAME_RUNBOOK.md describes the one-shot server migration
- Internal modules dow-excel-service/dow-import + OMG webhook domain
dowjones.com deliberately preserved (orthogonal to the rebrand)
Phase 3 — external /api/v1 for projects + deliverables
- API-key auth already in middleware; finished idempotency support
via new IdempotencyRecord model + src/lib/api/idempotency.ts
- Default-pipeline fallback in createProject when no template id given
- POST/GET /api/v1/projects + POST /api/v1/projects/[id]/deliverables
- docs/EXTERNAL_API.md with curl examples
Phase 4 — Box bidirectional integration
- JWT app-auth via jose (no extra deps). Config mounted as a docker
compose secret; deploy.sh stubs an empty {} so compose can start
before the operator drops the real JSON.
- Outbound: pushDeliverableToBox auto-fires on !APPROVED → APPROVED
in deliverable-status-service; "Send to client (Box)" manual button
on the approval stage row. Folder naming
{omgJobNumber}_{slug}_v{round}. 3-attempt exp backoff. BoxPushLog
audit.
- Inbound: /api/webhooks/box receives Box's signed events, matches by
OMG # + slug, creates a new Revision, routes to assignee or notifies
project owner. BoxInboundLog audit + two new NotificationType
values (BOX_UNMATCHED_FILE, NEW_FILE_AWAITING_REVIEWER).
- Naming-convention logic isolated in external-delivery-service so an
OMG-API transport can swap in later without touching matchers.
- Admin /settings/box page surfaces config status + recent activity.
Three Prisma migrations to apply on next deploy:
20260512000000_restore_review_workflow
20260512100000_idempotency_records
20260512200000_box_integration
URL rename is a one-shot — see docs/RENAME_RUNBOOK.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.9 KiB
Dow Jones Studio Tracker — Development Setup
Cross-platform setup guide for macOS and Windows 11.
Prerequisites
| Tool | Version | macOS | Windows |
|---|---|---|---|
| Node.js | 22.x | nvm install 22 |
nvm install 22 (nvm-windows) |
| npm | bundled with Node | Included | Included |
| PostgreSQL | 17.x | brew install postgresql@17 |
Installer or winget install PostgreSQL.PostgreSQL.17 |
| Git | any recent | Included with Xcode CLT | git-scm.com |
Node Version Manager
macOS — nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
Windows — nvm-windows: Download the latest installer from the releases page and run it.
After installing nvm, the .nvmrc file in the project root specifies Node 22:
nvm install # reads .nvmrc automatically (macOS)
nvm use # switch to the project's Node version
On nvm-windows, specify the version explicitly:
nvm install 22
nvm use 22
1. Clone the Repository
git clone <repo-url> loreal_prod_tracker
cd loreal_prod_tracker
2. Install Dependencies
npm install
This also runs prisma generate automatically via the postinstall hook, creating
the generated Prisma client at src/generated/prisma/.
If the generated client is missing for any reason:
npx prisma generate
3. Set Up PostgreSQL
macOS (Homebrew)
brew install postgresql@17
brew services start postgresql@17
createdb loreal_prod_tracker
The default Homebrew PostgreSQL setup uses your system username with no password.
Windows
- Install PostgreSQL 17 via the official installer or winget:
winget install PostgreSQL.PostgreSQL.17 - During installation, note the password you set for the
postgresuser. - Open pgAdmin or psql and create the database:
CREATE DATABASE loreal_prod_tracker; - Optionally create a dedicated user:
CREATE USER leivur WITH PASSWORD 'your_password'; GRANT ALL PRIVILEGES ON DATABASE loreal_prod_tracker TO leivur;
Verify Connection
psql -h localhost -U leivur -d loreal_prod_tracker
# or on Windows if using postgres user:
psql -h localhost -U postgres -d loreal_prod_tracker
4. Configure Environment Variables
Create a .env file in the project root (this file is gitignored):
# ─── Database ────────────────────────────────────────────
# macOS (Homebrew, no password):
DATABASE_URL="postgresql://leivur@localhost:5432/loreal_prod_tracker?schema=public"
# Windows (with password):
# DATABASE_URL="postgresql://leivur:your_password@localhost:5432/loreal_prod_tracker?schema=public"
# ─── Auth (Dev Bypass) ──────────────────────────────────
# Skips SSO and uses a seeded dev user. Set to "false" or remove for production SSO.
DEV_BYPASS_AUTH="true"
DEV_USER_ID="dev-user-001"
# ─── Auth (Production SSO — optional for local dev) ─────
# AUTH_GOOGLE_ID=""
# AUTH_GOOGLE_SECRET=""
# AUTH_MICROSOFT_ENTRA_ID_ID=""
# AUTH_MICROSOFT_ENTRA_ID_SECRET=""
# AUTH_MICROSOFT_ENTRA_ID_TENANT_ID=""
# ─── NextAuth ───────────────────────────────────────────
NEXTAUTH_SECRET="any-random-string-change-in-production"
NEXTAUTH_URL="http://localhost:3000"
5. Initialize the Database
Apply migrations and run the seed script:
npx prisma migrate dev
npx prisma db seed
migrate dev applies pending migrations and creates new ones from schema changes.
db seed populates:
- 10 pipeline stage templates with dependency rules
- Dev organization (id:
dev-org-001) - Dev admin user (id:
dev-user-001, email:dev@localhost)
To inspect the database visually:
npx prisma studio
6. Start the Dev Server
npm run dev
Open http://localhost:3000. With DEV_BYPASS_AUTH="true", you'll
be logged in automatically as the dev admin user.
Available Scripts
| Script | Command | Description |
|---|---|---|
| Dev server | npm run dev |
Start Next.js with Turbopack |
| Build | npm run build |
Production build |
| Start | npm start |
Run production build |
| Lint | npm run lint |
ESLint check |
| Format | npm run format |
Prettier format all files |
| Format check | npm run format:check |
Prettier check (no write) |
| Generate client | npm run db:generate |
Regenerate Prisma client |
| Migrate | npm run db:migrate |
Apply/create migrations |
| Seed | npm run db:seed |
Run seed script |
| Studio | npm run db:studio |
Open Prisma Studio GUI |
Platform-Specific Notes
macOS
-
nvm: Must be sourced in each shell session. If
nodeisn't found, run:export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"This is typically added to
~/.zshrcautomatically by the nvm installer. -
PostgreSQL service: Start/stop with Homebrew:
brew services start postgresql@17 brew services stop postgresql@17
Windows
-
nvm-windows: Requires an elevated (admin) terminal for
nvm installandnvm use. -
PostgreSQL service: Runs as a Windows service by default. Manage via Services app or:
net start postgresql-x64-17 net stop postgresql-x64-17 -
Line endings: Git should handle CRLF/LF conversion automatically. If you see formatting issues, verify your Git config:
git config --global core.autocrlf true -
Terminal: PowerShell, Windows Terminal, or Git Bash all work. The npm scripts are cross-platform.
Switching Between Machines
The workflow for moving between macOS and Windows:
-
Commit and push from the current machine:
git add -A && git commit -m "WIP" && git push -
Pull on the other machine:
git pull npm install # in case dependencies changed npx prisma migrate dev # apply any new migrations npm run dev
The .env file is gitignored, so each machine maintains its own database connection
string and auth settings. The database content is local to each machine — use
npx prisma db seed to reset to baseline data on a fresh setup.
Troubleshooting
prisma generate fails
Ensure Node 22 is active (node -v) and npm install completed successfully.
The generated client at src/generated/prisma/ is gitignored and must be generated
locally.
Database connection refused
- Verify PostgreSQL is running (
brew services liston macOS,services.mscon Windows) - Check
DATABASE_URLin.envmatches your local PostgreSQL user/password/port
Port 3000 already in use
# macOS
lsof -ti:3000 | xargs kill
# Windows
netstat -ano | findstr :3000
taskkill /PID <pid> /F
Schema out of sync after git pull
npx prisma migrate dev # applies pending migrations, creates new ones if schema changed
npx prisma generate # regenerates the client types
nvm: command not found (macOS)
Add to ~/.zshrc:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Tech Stack Quick Reference
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, Turbopack) |
| Language | TypeScript 5.x |
| Styling | Tailwind CSS 4 |
| Components | shadcn/ui (Radix + Tailwind) |
| Database | PostgreSQL 17 + Prisma 7 |
| Auth | Auth.js v5 (Google + Microsoft SSO) |
| State | TanStack Query v5 + Zustand |
| Forms | React Hook Form + Zod v4 |
| Charts | Recharts |
| Icons | Lucide React |