lusa-back-planner/CLAUDE.md
Vadym Samoilenko 78582ed381 Fix documented server redirect URI to match Azure AD registration
Update CLAUDE.md to use correct mixed-case URL without trailing slash
(lusa-Back-Planner) to match what is registered in Azure AD.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 12:01:35 +00:00

4.7 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

npm run dev          # Dev server at localhost:3000
npm run build        # Production build → dist/
npm run build:dev    # Development build
npm run preview      # Preview production build
npm run lint         # ESLint
npm run test         # Vitest (single run)
npm run test:watch   # Vitest (watch mode)
npm run test -- src/test/example.test.ts   # Run a single test file

Architecture

Client-side React SPA (no backend) for generating production timelines for L'Oréal USA brand teams. Users set a deadline, pick a production lane, and get a workback timeline with milestones.

Key source paths

  • src/pages/Index.tsx — Main page; owns form state (lane, date, revisions) and orchestrates child components
  • src/lib/templates.ts — Lane definitions (Rush/Express/Production/Specialist) and timeline generation logic (generateTimeline)
  • src/lib/workdays.ts — Business day math: federal holiday set, subtractWorkdays, countWorkdays, weekend/holiday detection
  • src/lib/parse-brief.ts — Extracts due date, brand, project name from uploaded PDF briefs using pdfjs-dist; uses keyword proximity scoring and multi-regex date detection
  • src/lib/parse-timeline-pdf.ts — Parses existing timeline PDFs for the change request workflow
  • src/lib/sla-data.ts — SLA durations for 90+ asset types
  • src/lib/brands.ts — 38 L'Oréal brand definitions
  • src/components/TimelineView.tsx — Timeline display, inline editing, PDF export (jsPDF + html2canvas)
  • src/components/ChangeRequestTab.tsx — Upload existing timeline, add update reason, re-export
  • src/components/AuthGuard.tsx — Wraps the app; shows a login page with SSO button for unauthenticated users, handles MSAL redirect flow
  • src/components/ui/ — shadcn/ui primitives (do not manually edit; use npx shadcn-ui@latest add <component> to add new ones)

Data flow

  1. User lands on app → AuthGuard checks MSAL session; unauthenticated users see a login page with "Sign in with Microsoft" button
  2. After SSO, user uploads a PDF brief → parse-brief.ts extracts date/brand/lane suggestion
  3. User confirms lane + deadline → templates.ts:generateTimeline() creates milestones by subtracting workdays from the deadline
  4. TimelineView renders milestones and handles PDF export
  5. Change requests: upload existing timeline PDF → parser extracts milestones → user selects update reason → new PDF exported

Component tree

main.tsx renders AuthGuardMsalProviderAppBrowserRouter → Routes. Auth wraps outside the router, so all routes require authentication. New routes go in App.tsx above the catch-all * route.

Authentication (MSAL / Azure AD SSO)

  • src/lib/msal-config.ts exports msalInstance and loginRequest; all config is read from env vars at module load time
  • AuthGuard calls instance.initialize() then handleRedirectPromise() before rendering; does not auto-redirect — it renders a login page and the user clicks to initiate the redirect
  • Required .env variables (must use VITE_ prefix):
    • VITE_AZURE_TENANT_ID
    • VITE_AZURE_CLIENT_ID
    • VITE_AZURE_REDIRECT_URI
  • Cache strategy: sessionStorage; login scope: User.Read
  • Two environments (see .env.example for full values):
    • Local: VITE_AZURE_CLIENT_ID=15c0c4e2-..., redirect http://localhost:3000/
    • Server: VITE_AZURE_CLIENT_ID=9079054c-..., redirect https://ai-sandbox.oliver.solutions/lusa-Back-Planner
  • Base path in vite.config.ts is /lusa-Back-Planner/ in production, / in dev — the redirect URI registered in Azure AD must match exactly

Deployment

Static site deployed to Apache on Ubuntu. Production build outputs to dist/. Hosted at https://ai-sandbox.oliver.solutions/lusa-Back-Planner as a subdirectory with FallbackResource for SPA routing. See README.md for full Apache config.

Conventions

  • Path alias: @/* maps to src/*
  • Styling: Tailwind CSS with custom theme (purple primary HSL 258 60% 55%, Montserrat font)
  • UI components: shadcn/ui (Radix UI + Tailwind); config in components.json
  • Forms: react-hook-form + zod
  • Date handling: date-fns (not native Date methods)
  • All processing is client-side — no API calls, no server state
  • Test environment: Vitest with jsdom; globals enabled (no need to import describe/it/expect); setup file at src/test/setup.ts
  • TypeScript strict mode is disabledstrict, strictNullChecks, noImplicitAny are all off
  • templates.ts builds stages dynamically via buildStages() based on revision count before calling generateTimeline()