Commit graph

59 commits

Author SHA1 Message Date
Phil Dore
586cb57155 Simplify Stage 8 syndication and derive Advisor Stage 6 complexity
- Stage 8: replace 3x3 complexity x EAN grid with single syndicationType
  dropdown -- Salsify Prep Only (4d), Syndication PDP (5d), Syndication
  Non-PDP (3d). Advisor maps contentType to PDP/Non-PDP only; Salsify
  Prep Only is not surfaced in the Advisor (team decision).
- Stage 6 (Advisor): derive complexity from staticWorkType / videoWorkType
  / needsHTML toggles via deriveProductionComplexity helper. Precedence
  bespoke > creation > complex > simple, max across enabled toggles.
  HTML-only falls back to complex (placeholder, may revisit).
- Bump config.json cache-bust to 2026050801.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 13:24:02 +01:00
Phil Dore
5e301b68c1 Update production day estimates per v3 amends (06/05/26)
Simple row reduced across all brackets (4/5/7/7/7 → 2/4/6/6/6). Creation reshaped (5/10/11/13/13 → 7/9/11/11/11). Simple default revision rounds 1 → 2. Complex, bespoke and Opera Upload unchanged. Cache-bust bumped to 2026050601 on both scripts so browsers refetch the new config.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 17:37:51 +01:00
Phil Dore
45238e7a9b Bump config.json cache-bust version to 2026050101
Forces browsers to fetch updated config.json with revised production day estimates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 17:00:47 +01:00
Phil Dore
d877dfb559 Update production day estimates per v2 amends (01/05/26)
Simple 100–200 & 200–300: 6→7. Complex 100–200 & 200–300: 7→8. Creation across all brackets reduced (0–50: 6→5, 50–100: 15→10, 100–200: 18→11, 200–300: 20→13, 300–400: 22→13). Bespoke unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 16:45:12 +01:00
Phil Dore
a77efee3fc Remove handover days from SLA Calculator to match Advisor
Mirrors the change from commit d19f7e7 which removed handover from
the Advisor. Sets handover:0 for all stages, removes grey Handover
phase bars from Gantt, removes Handover column from summary table,
CSV export, and email copy. Bumps script version to bust cache.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 12:18:19 +01:00
Phil Dore
1f7153d105 Bump script version strings to bust browser cache
Forces browsers to fetch updated market-script.js and script.js
with the Gantt red line position fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 11:48:54 +01:00
Phil Dore
375ca684a1 Fix Gantt red line offset: add LABEL_W to marker position in both charts
The deadline marker was positioned relative to the outer container but
calculated relative to the timeline column only, placing it LABEL_W px
too far left. Adds LABEL_W offset so EST. COMPLETION (Advisor) and
SUGGESTED LIVE (Calculator) lines land on the correct dates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 11:36:31 +01:00
Phil Dore
d19f7e7864 Brief Advisor: amends from Internal Ops Review + asset bracket expansion
- Rename 'live by' label to 'When do you need Oliver tasks completed by?'
- Remove 2-week syndication buffer from calculation and all caveat text
- Add 'Brief Accepted By' + 'Submit Brief By' (2 days earlier) dual lozenges
- Update caveat to include 'assume suitable working files have been provided'
- Add rounds of amends inputs per content type (Static, Video, HTML, Translation)
- Remove handover days from all stage calculations
- Port Gantt sub-phase view to Brief Advisor (WIP/Feedback/Revision, Download PNG)
- Add hidden SLA one-pager link placeholder (#slaPagerLink)
- Restore 200–300 and 300–400 asset volume brackets in Brief Advisor dropdown

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 12:17:07 +01:00
Phil Dore
7d54c040d5 Update asset volume brackets to 3 tiers and revise production/Opera Upload days
Simplifies asset volume from 6 brackets to 3 (0–50, 50–100, 100–200) per team sign-off.
Updates Production cross-reference table and Opera Upload day map to match new brackets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 12:16:20 +01:00
Phil Dore
3ed76f15b6 Add Gantt sub-phase breakdown with day-grid header and PNG export
- Gantt now shows per-stage phases: WIP 1, Feedback 1, WIP 2... (violet/amber colour coding)
- Replaced month-based % layout with fixed 28px/day grid (horizontally scrollable)
- Two-row header: week-start dates + SMTWTFS day letters
- Weekend columns shaded gray across all stage rows
- Added Download PNG button using html2canvas (2x retina quality)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 12:15:13 +01:00
Phil Dore
3331472994 Add 200–300 and 300–400 asset volume tiers to Production and Opera Upload
Extends the 3-tier bracket structure to 5 tiers per updated SLA reference sheet.
Adds dropdown options, crossReferenceTable entries, and Opera Upload day mappings
for the two new tiers across all four complexity levels.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 12:56:25 +01:00
Phil Dore
2a811ca3a1 Update asset volume brackets to 3 tiers and revise production/Opera Upload days
Simplifies asset volume from 6 brackets to 3 (0–50, 50–100, 100–200) per team sign-off.
Updates Production cross-reference table and Opera Upload day map to match new brackets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 17:58:11 +01:00
Philip Dore
d1d43d603c SLA Brief Advisor: updates from brief docs 1 & 2
- HTML/Rich media default brief type → Creation (was Adaptation)
- Video dropdown now shows all brief types (same as static)
- Static + Video combined: new asset wins over adapting → Creation
- Urgent Brief: hide deadline banner, timeline, and summary cards
- Urgent Brief: add Show/Hide timeline details toggle
- Urgent Brief (eventing, 0-30, static resizing): 6 hrs production + confirmation time
- Video tab: removed (new KV & Visual ID) label, restricted to Adaptation/Creation with video-specific descriptions
- Static feedback days label updated with urgent brief note

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 18:08:58 +00:00
Philip Dore
5f2d888541 Update syndication timings across all complexity/EAN combinations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 11:00:34 +00:00
Vadym Samoilenko
53a73cb9c9 Fix SSO redirect URI: remove trailing slash to match Azure registration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 16:28:11 +00:00
Vadym Samoilenko
598d2879f1 Fix SSO redirect URI to single registered URL, restore page after login
Instead of registering each page as a redirect URI in Azure AD, always
redirect to the registered /loreal-sla-calculator/ URL. Before initiating
the redirect, save the originating page in sessionStorage and navigate
back after the token exchange completes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 16:26:12 +00:00
Vadym Samoilenko
28fc722da6 Remove Analytics nav links — page accessible by direct URL only
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 16:24:49 +00:00
Vadym Samoilenko
96134f3c13 Fix MSAL CDN in analytics.html — use jsdelivr to match index.html
alcdn.msauth.net was failing to expose the msal global, causing
"msal is not defined" on auth init.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 16:17:13 +00:00
Vadym Samoilenko
8843af6402 Add analytics link to page headers, event tracking to calculator, update deploy script
- Add analytics.html to STATIC_FILES in deploy.sh
- Add trackEvent/getVisitorId to script.js with page_view, show_results, copy_email hooks
- Add "Analytics →" nav link to index.html and market.html headers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 16:15:12 +00:00
Alessandro Benedetti Admin
6bedd5c074 Fix SSO redirect URI to work on any page (analytics, index, etc.)
Dynamic redirectUri using window.location instead of hardcoded path.
Note: Vadym must register analytics.html as a redirect URI in Azure AD.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:07:07 +00:00
Alessandro Benedetti Admin
21ec93f966 Add usage analytics: event tracking, API, and dashboard
Track page views, results clicks, copy-to-email on market page.
Track login events with auth method (SSO/email) and L'Oréal domain detection.
New analytics.html dashboard with charts (Chart.js), period/page filters.
Localhost auth bypass for local dev testing.

Post-deploy: run npm run migrate to create usage_events table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 11:41:50 +00:00
Alessandro Benedetti Admin
a1abbbc2a9 Add static work type sub-selector and brief type override dropdown
Form: When Static imagery is toggled ON, shows 3 radio options:
- New Asset (creation) — default
- Adapting existing (adaptation)
- Resizing / Cropping (simple)
This feeds into determineBriefType() for smarter auto-suggestions.

Results: Replace static brief type text with a dropdown populated
from all 9 brief types in config.json (consistent with full calculator).
Changing the dropdown recalculates the entire timeline instantly.
Description shown in blue info box with bullet points.
Notes when brief type was manually changed from suggestion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 17:16:54 +00:00
Alessandro Benedetti Admin
d98dadec8f Fix: Translation/Syndication toggles now override base stage matrix
The base stage matrix for brief types like country_pull_adaptation
includes Translation stages by default. In the Brief Advisor, the
user's toggles should be authoritative — if Translation is OFF, those
stages must be removed regardless of the base matrix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:01:09 +00:00
Alessandro Benedetti Admin
ac9a3f057b Allow decimal feedback days (0.1 step) in Brief Advisor
- Add step="0.1" to all 4 feedback day inputs (static, video, HTML, translation)
- Change parseInt → parseFloat so fractional values like 0.5 or 2.5 are preserved
- Business day arithmetic naturally rounds up fractions to next whole business day

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:12:55 +00:00
Alessandro Benedetti Admin
80d90da95e Market Brief Advisor: copy for email, timeline dates, syndication default, verdict fix
- Add Copy for Email button with rich HTML table (Outlook-compatible)
- Show start → end dates on each timeline stage row
- Syndication toggled ON by default
- Fix translation feedback default to 5 days (matches config.json)
- Restore form validation (disabled button until all fields filled)
- Fix verdict logic in full calculator to include syndication buffer
  in deadline comparison (suggestedGoLive vs goLive)
- Differentiate verdict message: production-over vs syndication-short
- Update README with client estimator docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:00:46 +00:00
Alessandro Benedetti Admin
b261df2387 Rename client→market, add feedback days, earliest go-live, update disclaimer
- Rename client.html → market.html and client-script.js → market-script.js
- Update top disclaimer to match bold amber results banner
- Add collapsible "Days needed for feedback" field on each toggle
  (Static, Video, HTML, Translation); feeds into stage calculations
- Add "Earliest Go-Live" card in results showing the soonest possible
  date if the brief were submitted today
- Update deploy.sh with new filenames

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 11:38:47 +00:00
Alessandro Benedetti Admin
3bb45c217f Add Static imagery toggle to Brief Advisor
Adds a new "Static imagery" toggle option to the client form.
Static-only production maps to Country Pull - Creation brief type,
while Video/HTML continues to map to Country Pull - Adaptation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 11:32:08 +00:00
Alessandro Benedetti Admin
928750689c Add missing client-script.js for Brief Advisor page
The JS engine for client.html was never committed, causing the
date picker and all form logic to fail on the deployed site.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:33:02 +00:00
Alessandro Benedetti Admin
38c7c2a70a Make disclaimer banners more prominent and reposition higher
Move lead-time and reference-only disclaimers from small grey text
at the bottom to bold amber warning banners positioned right after
the verdict/PM instruction (index.html) and deadline banner
(client.html). Uses warning icon, border-2, and font-bold/semibold
for visibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:30:35 +00:00
Alessandro Benedetti Admin
ce50b98e66 Add client.html and client-script.js to deploy static files list
The Brief Advisor page was missing from the Apache deployment,
returning a 404. Added both files to the STATIC_FILES array.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:29:25 +00:00
Alessandro Benedetti Admin
95451fc86c Add syndication lead-time note and disclaimer to results
Adds "Assumes 2-week lead time between syndication and Live Date"
to the Syndication card and results section in both the full SLA
Calculator (index.html) and the Brief Advisor (client.html).
Includes a reference-only disclaimer with BCM confirmation guidance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:21:23 +00:00
Vadym Samoilenko
6900dabfea merge git and server changes 2026-03-13 10:52:07 +00:00
Alessandro Benedetti Admin
cf9075a7e0 Lock Opera Upload stage as always-active and non-deselectable
Opera Upload (stage 7) is now permanently enabled for all brief types.
Toggle is disabled in Step 2, badge is non-clickable in Step 1, and a
"Required" label is shown in both views. Uses config-driven alwaysActive
flag — no hard-coded stage index in JS. Cache-busting bumped to v=2026031302.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:29:48 +00:00
Alessandro Benedetti Admin
878f231574 Add cache-busting version strings to script.js and config.json
Browsers were serving stale cached files after deploy. Added ?v=2026031201
query params to force fresh loads.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:52:49 +00:00
Alessandro Benedetti Admin
6fd89761f0 Update README with changelog and recent feature descriptions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:49:33 +00:00
Alessandro Benedetti Admin
0c85cb4319 Update brief type descriptions, add disclaimer, decimal inputs, extend asset brackets
- Add non-contractual dates disclaimer banner at top of page
- Allow decimal values (0.1 step) in revision and approval fields
- Make Opera Upload mandatory for all brief types
- Remove Speed Up by % slider from Production stage
- Extend asset volume brackets: 100-200, 200-300, 300-400
- Update all 9 brief type descriptions with client scope definitions
- Render brief descriptions as bullet lists for clarity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:44:06 +00:00
Vadym Samoilenko
e8c708f6eb Fix password special characters breaking login via WAF
Base64-encode passwords on the frontend before sending in JSON body,
and decode on the backend before passing to bcrypt. Prevents Nginx WAF
from returning an HTML error page when passwords contain <, >, &, etc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 18:40:46 +00:00
Vadym Samoilenko
0eb2b86bb6 Rebrand transactional emails with L'Oréal-styled HTML templates
Replace bare-bones HTML with a table-based, fully inline-styled email
layout — black header with L'ORÉAL · PARIS wordmark, red accent bar,
clean white body, branded red CTA button, fallback plain-text URL, and
a styled footer. Both password-reset and verification emails share a
single reusable wrapper function.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 10:56:21 +00:00
Vadym Samoilenko
4be7f8742a Remove @loreal.com domain restriction for SSO — Azure AD tenant is the gatekeeper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 20:08:02 +00:00
Vadym Samoilenko
3aef3c4080 Switch MSAL CDN from alcdn.msauth.net to jsdelivr for reliability
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 20:06:25 +00:00
Vadym Samoilenko
7ba7cebf56 Fix API base path: use /loreal-sla-calculator/api prefix for all fetch calls
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 20:05:07 +00:00
Vadym Samoilenko
e54222190b Fix SSL for Docker PostgreSQL — use DB_SSL env var instead of NODE_ENV
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 19:59:22 +00:00
Vadym Samoilenko
720f8c65d3 Fix wait_healthy to use docker inspect instead of python3 JSON parsing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 19:58:25 +00:00
Vadym Samoilenko
86df16fc78 Make MAILGUN vars optional in deploy.sh validation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 19:43:21 +00:00
Vadym Samoilenko
552e37157c Move .env to /opt/loreal-sla-calculator/server/.env
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 19:32:32 +00:00
Vadym Samoilenko
d1af08786c Add Node.js/Express backend, PostgreSQL, email/password auth, and Docker deployment
- Add Express server (server/) with JWT auth, rate limiting, and all /api/auth/* routes
- Add PostgreSQL schema and migration runner (3 migrations)
- Add email/password login, registration, password reset via Mailgun
- Validate MSAL SSO ID token server-side, upsert user into DB
- Rewrite auth.js: 8-panel auth UI (SSO, login, register, forgot, reset, verify)
- Expand index.html auth overlay with full multi-view auth UI
- Add apiFetch() helper in script.js with auto token refresh
- Add Dockerfile, docker-compose.yml, .dockerignore for containerised deployment
- Add idempotent deploy.sh: git pull, docker build, migrate, copy static to /var/www
- Add .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 19:27:44 +00:00
Vadym Samoilenko
7ba4695f19 Add Azure AD SSO authentication using MSAL.js
Gate app access behind Microsoft login so only authenticated L'Oreal
users can use the calculator. Shows spinner overlay during sign-in,
displays user name in header with sign-out button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 20:36:26 +00:00
Alessandro Benedetti Admin
a6135e09bc Add Gantt chart view to results page
- LIST/GANTT toggle buttons switch between table and visual views
- Pure CSS Gantt chart — no external library needed
- Horizontal bars show stage durations with purple gradient colors
- Month markers along the top for timeline context
- Red dashed GO-LIVE deadline marker when visible in range
- Stages 4 & 5 (Translation) shown as parallel bars
- Only active stages displayed in Gantt
- Hover tooltip shows date range and total days per stage
- Legend with stage duration and go-live indicators
- Works in both light and dark modes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:49:35 +00:00
Alessandro Benedetti Admin
9afa90391b Disable weekends and past dates in date pickers
- Flatpickr now greys out Sat/Sun so they cannot be selected
- minDate set to 'today' to prevent picking dates in the past
- Business day calculations already excluded weekends (addBusinessDays)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:41:53 +00:00
Alessandro Benedetti Admin
e23c887b0f Show step 4 (Results) as green checkmark in stepper
Step 4 now shows a green checkmark like completed steps, since reaching
Results means the wizard is complete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:39:40 +00:00