Source: 12b-changelog-data.js

/**
 * @file 12b-changelog-data.js
 * Embedded dev-changelog data, split out of 12a-changelog.js: the wl_dev_log
 * storage key (STORE_DEV_LOG), the test-area name lookup table
 * (TEST_AREA_NAMES), and the hardcoded DEV_CHANGES entry array. New changelog
 * entries are appended to DEV_CHANGES here.
 *
 * A leaf ES module (see `LEAF_MODULES` in build-config.js) — pure literal
 * data with zero references to shared app state or to functions defined in
 * other src/js files, imported at the top of the built bundle ahead of the
 * concatenated block. That import-first placement is also what satisfies
 * 12c-startup.js's startup block, which calls mergeDevLog() (defined in
 * 12a-changelog.js) — which in turn dereferences STORE_DEV_LOG and
 * DEV_CHANGES — at top level: both are already in scope by the time any
 * concatenated file runs.
 */

export const STORE_DEV_LOG = 'wl_dev_log';
export const TEST_AREA_NAMES = {
  1: 'Page load',
  2: 'roundToNearest30',
  3: 'localStorage round-trip',
  4: 'Timer display',
  5: 'Timer persistence',
  6: 'completedAt',
  7: 'Auto-carry',
  8: 'Sort order',
  9: 'Plan count header',
  10: 'Week number',
  11: 'Billable tracking',
  12: 'Export format',
  13: 'Timeline rendering',
  14: 'Work location',
  15: 'Session timing',
};

// Updated each session by Claude — id format: YYYYMMDD-NNN
export const DEV_CHANGES = [
  {
    id: '20260506-001',
    date: '2026-05-06',
    desc: 'Two-box header layout with week/moon/nameday',
    areas: [1],
  },
  { id: '20260506-002', date: '2026-05-06', desc: 'Week number (ISO) in header', areas: [10] },
  {
    id: '20260506-003',
    date: '2026-05-06',
    desc: 'Sunrise/sunset/day length from Open-Meteo',
    areas: [1, 3],
  },
  {
    id: '20260506-004',
    date: '2026-05-06',
    desc: 'Moon phase calculation and zodiac sign',
    areas: [1],
  },
  {
    id: '20260506-005',
    date: '2026-05-06',
    desc: 'Finnish nameday from nimipaivat.fi',
    areas: [1],
  },
  {
    id: '20260506-006',
    date: '2026-05-06',
    desc: 'Completed tasks section with 14-day rolling window',
    areas: [6, 9],
  },
  {
    id: '20260506-007',
    date: '2026-05-06',
    desc: 'Child task auto-promotes parent to In Progress',
    areas: [7, 8],
  },
  {
    id: '20260506-008',
    date: '2026-05-06',
    desc: 'Plan count header format: X to do · X in progress · X done',
    areas: [9],
  },
  {
    id: '20260506-009',
    date: '2026-05-06',
    desc: 'Critical fix: load() restored to startup sequence',
    areas: [1, 3, 4, 5, 7],
  },
  {
    id: '20260506-010',
    date: '2026-05-06',
    desc: 'save() guard against overwriting data with empty arrays',
    areas: [3],
  },
  {
    id: '20260506-011',
    date: '2026-05-06',
    desc: 'Timer restoration protected against load failures',
    areas: [5],
  },
  {
    id: '20260506-012',
    date: '2026-05-06',
    desc: 'completedAt uses roundToNearest30; 23:59 shown as date-only',
    areas: [6],
  },
  {
    id: '20260506-013',
    date: '2026-05-06',
    desc: 'Rain forecast starts from next hour (no past times)',
    areas: [1],
  },
  { id: '20260506-014', date: '2026-05-06', desc: 'Pomodoro ring empties clockwise', areas: [1] },
  { id: '20260506-015', date: '2026-05-06', desc: 'Pomodoro session log added', areas: [1] },
  { id: '20260506-016', date: '2026-05-06', desc: 'Smoke test suite (38 tests) added', areas: [] },
  {
    id: '20260506-017',
    date: '2026-05-06',
    desc: 'End-of-day modal with dev changelog',
    areas: [],
  },
  {
    id: '20260508-001',
    date: '2026-05-08',
    desc: 'Focus mode: Pomodoro now visible alongside emergency task',
    areas: [1],
  },
  {
    id: '20260508-002',
    date: '2026-05-08',
    desc: 'safeRoundedStart() prevents rounded entry times overlapping previous tsEnd',
    areas: [2, 3, 4, 5],
  },
  {
    id: '20260508-003',
    date: '2026-05-08',
    desc: 'statToday counts unique task names, not raw entry count',
    areas: [9],
  },
  {
    id: '20260508-004',
    date: '2026-05-08',
    desc: 'Timeblock expanded to 07:00–21:00 with one-time slot migration',
    areas: [1],
  },
  {
    id: '20260508-005',
    date: '2026-05-08',
    desc: 'Plan task statuses: Pending and Blocked added',
    areas: [7, 8, 9],
  },
  {
    id: '20260508-006',
    date: '2026-05-08',
    desc: 'Pending/Blocked tasks show editable comment with timestamp history',
    areas: [7, 8],
  },
  {
    id: '20260508-007',
    date: '2026-05-08',
    desc: 'Auto-complete parent task when all children marked done',
    areas: [7, 8],
  },
  {
    id: '20260508-008',
    date: '2026-05-08',
    desc: 'Auto-stop timer when active task is marked done in task list',
    areas: [4, 5, 7],
  },
  {
    id: '20260508-009',
    date: '2026-05-08',
    desc: 'Export .txt includes day started, ended, and total workday length',
    areas: [1],
  },
  {
    id: '20260508-010',
    date: '2026-05-08',
    desc: 'File System Access API: exports saved to timesheets/ and JSON backups/ subfolders',
    areas: [1],
  },
  {
    id: '20260513-001',
    date: '2026-05-13',
    desc: 'Quick pick: remove button to hide tasks from recent list',
    areas: [],
  },
  {
    id: '20260513-002',
    date: '2026-05-13',
    desc: 'Quick pick: restore hidden items button; hidden list persists in localStorage',
    areas: [],
  },
  {
    id: '20260513-003',
    date: '2026-05-13',
    desc: 'Inline entry editing: click entry text to edit in place',
    areas: [3],
  },
  {
    id: '20260513-004',
    date: '2026-05-13',
    desc: 'Timelog header added above entry list',
    areas: [],
  },
  {
    id: '20260513-005',
    date: '2026-05-13',
    desc: 'Chart label column widened from 120px to 200px',
    areas: [],
  },
  {
    id: '20260515-001',
    date: '2026-05-15',
    desc: 'Restore "Today\'s name day:" prefix in nameday display (API and fallback)',
    areas: [1],
  },
  {
    id: '20260515-002',
    date: '2026-05-15',
    desc: 'Restore SVG Finnish flag + "Next flag day:" prefix in calendar event display',
    areas: [1],
  },
  {
    id: '20260515-003',
    date: '2026-05-15',
    desc: 'Use full month name (e.g. June 4) in next flag day display',
    areas: [1],
  },
  {
    id: '20260515-004',
    date: '2026-05-15',
    desc: 'Fix streakDays sub-stat to start from yesterday (consistent with calcStreak)',
    areas: [],
  },
  {
    id: '20260515-005',
    date: '2026-05-15',
    desc: 'Add nimipaivarajapinta.fi to CSP connect-src',
    areas: [1],
  },
  {
    id: '20260515-006',
    date: '2026-05-15',
    desc: 'Calendar events: SVG Finnish flag for flag days, 📅 for holidays/notable days, no text prefix',
    areas: [1],
  },
  {
    id: '20260515-007',
    date: '2026-05-15',
    desc: 'Nameday: Finnish names plain, Swedish names smaller/dimmed with sv: label',
    areas: [1],
  },
  {
    id: '20260515-008',
    date: '2026-05-15',
    desc: 'Calendar events: add "Upcoming:" prefix for non-today events',
    areas: [1],
  },
  {
    id: '20260515-009',
    date: '2026-05-15',
    desc: 'Re-add parked thoughts feature (💭 in timer bar, park section, → task / ✓ dismiss)',
    areas: [],
  },
  {
    id: '20260515-010',
    date: '2026-05-15',
    desc: 'Re-add IDKW 🎲 button in plan header — picks random todo task',
    areas: [],
  },
  {
    id: '20260515-011',
    date: '2026-05-15',
    desc: 'Add ⊕ split button on tasks — creates child subtasks with parentId',
    areas: [],
  },
  {
    id: '20260515-012',
    date: '2026-05-15',
    desc: 'Child tasks render indented under parent, sorted grouped',
    areas: [],
  },
  {
    id: '20260515-013',
    date: '2026-05-15',
    desc: 'Park capture auto-closes when timer stops',
    areas: [],
  },
  {
    id: '20260515-014',
    date: '2026-05-15',
    desc: 'Jira ticket links: PROJ-XXXXX prefix becomes clickable link to the configured Jira instance',
    areas: [],
  },
  {
    id: '20260515-015',
    date: '2026-05-15',
    desc: "M365 calendar: ICS feed shows today's meetings in header strip with time, duration, Teams join link",
    areas: [],
  },
  {
    id: '20260518-001',
    date: '2026-05-18',
    desc: 'Calendar: read from all Outlook accounts (GetDefaultFolder + folder tree walk)',
    areas: [],
  },
  {
    id: '20260518-002',
    date: '2026-05-18',
    desc: "Calendar: TODAY'S MEETINGS section header, collapsible, matches plan-section style",
    areas: [],
  },
  {
    id: '20260518-003',
    date: '2026-05-18',
    desc: 'Calendar: past meetings grey/italic, ongoing meeting pulses blue, stops when meeting ends',
    areas: [],
  },
  {
    id: '20260518-004',
    date: '2026-05-18',
    desc: 'Calendar: configurable account labels shown per meeting (see CAL_ACCOUNT_LABELS in 00-config.js)',
    areas: [],
  },
  {
    id: '20260518-005',
    date: '2026-05-18',
    desc: "Calendar: ▶ start button adds meeting to today's plan and starts timer",
    areas: [],
  },
  {
    id: '20260518-006',
    date: '2026-05-18',
    desc: "Calendar section moved above today's tasks",
    areas: [],
  },
  {
    id: '20260518-007',
    date: '2026-05-18',
    desc: 'Nameday: Swedish flag SVG replaces emoji (reliable on all Windows fonts)',
    areas: [1],
  },
  {
    id: '20260518-008',
    date: '2026-05-18',
    desc: "Flag days: add Kaatuneitten muistopäivä (3rd Sun May), Eino Leino, Miina Sillanpää, Swedish Heritage Day, Children's Rights Day, Finnish Nature Day",
    areas: [1],
  },
  {
    id: '20260518-009',
    date: '2026-05-18',
    desc: 'Nameday + calendar API proxied through local server to bypass CORS (works on any port)',
    areas: [],
  },
  {
    id: '20260518-010',
    date: '2026-05-18',
    desc: 'CSP: allow any localhost port and 127.0.0.1 for server flexibility',
    areas: [],
  },
  {
    id: '20260518-011',
    date: '2026-05-18',
    desc: 'Timesheets folder removed from git tracking, added to .gitignore (stays local only)',
    areas: [],
  },
  {
    id: '20260518-012',
    date: '2026-05-18',
    desc: "Fix carry-over: pending/blocked status from most recent past version propagates to today's copy",
    areas: [],
  },
  {
    id: '20260518-013',
    date: '2026-05-18',
    desc: 'Re-implement upcoming status and 🔜 Upcoming Tasks section (lost in force push)',
    areas: [],
  },
  {
    id: '20260518-014',
    date: '2026-05-18',
    desc: 'Calendar: ✕ delete button on each meeting hides it for the day (persists in localStorage)',
    areas: [],
  },
  {
    id: '20260518-015',
    date: '2026-05-18',
    desc: 'Fix: timer input fields now have bright white text on dark background for readability',
    areas: [1],
  },
  {
    id: '20260518-016',
    date: '2026-05-18',
    desc: 'EOD modal: notes-for-tomorrow section with per-task handoff inputs; note shown inline in plan rows next morning',
    areas: [],
  },
  {
    id: '20260519-001',
    date: '2026-05-19',
    desc: 'Task checkpoints: inline step list with progress bar, tick-off, delete, drag-to-reorder; carried forward (reset) on day rollover',
    areas: [],
  },
  {
    id: '20260519-008',
    date: '2026-05-19',
    desc: 'Focus mode: checkpoints shown for active task, pomodoro fixed top-right, tagRow/timeline/calSection hidden',
    areas: [],
  },
  {
    id: '20260520-005',
    date: '2026-05-20',
    desc: 'Billable emoji shown in time log entries; clickable to toggle matching plan task',
    areas: [3, 11],
  },
  {
    id: '20260520-001',
    date: '2026-05-20',
    desc: 'Billable/non-billable: 💰/💸 toggle on all task rows + category default; retroactive update on category change; new tasks default billable',
    areas: [3, 11],
  },
  {
    id: '20260520-002',
    date: '2026-05-20',
    desc: 'Export: billable/non-billable totals in header; pasteable summary line grouped by category at end of .txt',
    areas: [11, 12],
  },
  {
    id: '20260520-003',
    date: '2026-05-20',
    desc: 'Quick-pick: tasks past iteration boundary hidden automatically',
    areas: [3],
  },
  {
    id: '20260520-004',
    date: '2026-05-20',
    desc: 'Timeline + export: consecutive same-task blocks with <30min gap merged into single block',
    areas: [4, 8, 12, 13],
  },
  {
    id: '20260521-001',
    date: '2026-05-21',
    desc: 'Notion integration: 📋 button on each task — sends to Notion second brain as child page under matching project (auto-matched by epic). Uses Claude API + Notion MCP via server-side proxy.',
    areas: [3],
  },
  {
    id: '20260521-002',
    date: '2026-05-21',
    desc: 'Fix: scheduled smoke tests not running (require() broke when package.json got "type":"module"); renamed smoke-tests.js → .cjs',
    areas: [],
  },
  {
    id: '20260521-003',
    date: '2026-05-21',
    desc: 'Fix: paused timers were silently discarded on reload (validTimer rejected startTs:null); now accepts paused timers with accumulatedMs',
    areas: [3, 5],
  },
  {
    id: '20260521-004',
    date: '2026-05-21',
    desc: 'Fix: export "Ended:" line ignored active timer; now factors in running/paused timer\'s effective end',
    areas: [12],
  },
  {
    id: '20260521-005',
    date: '2026-05-21',
    desc: 'Fix: completed section left stale .completed-item DOM nodes when filtered empty (caused phantom items on date change)',
    areas: [6],
  },
  {
    id: '20260521-006',
    date: '2026-05-21',
    desc: 'Focus mode: checkpoints for active task auto-expand after exit',
    areas: [],
  },
  {
    id: '20260521-007',
    date: '2026-05-21',
    desc: "Calendar: tasks started from today's meetings always default to the meeting category (not the currently-selected tag)",
    areas: [],
  },
  {
    id: '20260521-008',
    date: '2026-05-21',
    desc: 'EOD: clicking 🌙 end-the-day auto-deploys the portable build (rebuilds + copies to the saved destination) via PS server /api/portable-deploy. Fire-and-forget — never blocks the modal',
    areas: [],
  },
  {
    id: '20260521-009',
    date: '2026-05-21',
    desc: 'Time-by-task chart: active timer\'s row updates live — synthetic tsEnd treats running timer as ending "now" (paused: ts+accumulated). Auto-refreshes every 15 min while a timer runs. Live row has pulsing dot + bar',
    areas: [4, 13],
  },
  {
    id: '20260521-010',
    date: '2026-05-21',
    desc: 'Task row: billable 💰/💸 button moved from end of line to between status dropdown and task name (more discoverable, less visual clutter at the action-button cluster)',
    areas: [11],
  },
  {
    id: '20260521-011',
    date: '2026-05-21',
    desc: 'EOD: portable deploy moved from modal-open to "Done — close" button so JSON + .txt have time to flush to OneDrive before the build script reads them. Status shown via top-right toast',
    areas: [],
  },
  {
    id: '20260519-011',
    date: '2026-05-19',
    desc: 'Calendar meetings sorted by start time (not by calendar source)',
    areas: [],
  },
  {
    id: '20260519-010',
    date: '2026-05-19',
    desc: "Moved parked thoughts section between today's meetings and today's tasks",
    areas: [],
  },
  {
    id: '20260519-009',
    date: '2026-05-19',
    desc: 'EOD handoff notes: only show tasks actually worked on today',
    areas: [],
  },
  {
    id: '20260519-007',
    date: '2026-05-19',
    desc: 'Checkpoint steps: double-click label to edit inline; Enter/blur saves, Escape cancels',
    areas: [],
  },
  {
    id: '20260519-006',
    date: '2026-05-19',
    desc: 'Fix: checkpoint badge status color only applied when checkpoints exist (0/N); + steps badge stays gray',
    areas: [],
  },
  {
    id: '20260519-005',
    date: '2026-05-19',
    desc: 'Fix: checkpoint badge color mirrors task status (amber for in-progress, purple for pending, red for blocked) until progress begins',
    areas: [],
  },
  {
    id: '20260519-004',
    date: '2026-05-19',
    desc: 'Iteration expiry dates moved to localStorage (wl_expiry_dates); seeded from EXPIRY_SEED on first load; editable via 📅 iterations button',
    areas: [6],
  },
  {
    id: '20260519-003',
    date: '2026-05-19',
    desc: 'Completed tasks expire at iteration boundaries instead of a 14-day rolling window',
    areas: [6],
  },
  {
    id: '20260519-002',
    date: '2026-05-19',
    desc: 'Smoke tests: fix test 24 streak assertion, fix test 25 cal-delete-btn via renderCalStrip injection, add tests 32–34 (checkpoints, handoff notes, parked thoughts)',
    areas: [],
  },
  {
    id: '20260513-006',
    date: '2026-05-13',
    desc: 'Jira CSV importer: drag and drop Jira export to load issues',
    areas: [],
  },
  {
    id: '20260513-007',
    date: '2026-05-13',
    desc: 'Jira CSV importer: category mapping, select/deselect tasks, duplicate detection',
    areas: [7, 9],
  },
  {
    id: '20260513-008',
    date: '2026-05-13',
    desc: 'Plan section headers restyled: smaller, uppercase, icon prefixes',
    areas: [],
  },
  {
    id: '20260513-009',
    date: '2026-05-13',
    desc: 'Pending/Blocked: dedicated tinted section with amber/red accent',
    areas: [7, 8],
  },
  {
    id: '20260513-010',
    date: '2026-05-13',
    desc: 'Pending/Blocked: status comment history with timestamps and expand toggle',
    areas: [7, 8],
  },
  {
    id: '20260513-011',
    date: '2026-05-13',
    desc: 'Timeblock: emoji picker added to slots',
    areas: [],
  },
  {
    id: '20260513-012',
    date: '2026-05-13',
    desc: 'Timeblock: meeting form removed, block editing simplified',
    areas: [],
  },
  {
    id: '20260513-013',
    date: '2026-05-13',
    desc: 'Day start and end times tracked and shown in exports',
    areas: [1],
  },
  {
    id: '20260513-014',
    date: '2026-05-13',
    desc: 'Fix: streak counter now shows correct days at start of day',
    areas: [1],
  },
  {
    id: '20260513-015',
    date: '2026-05-13',
    desc: 'Nameday API: switch from HTML scraping to official Nimipäivärajapinta API',
    areas: [1],
  },
  {
    id: '20260513-016',
    date: '2026-05-13',
    desc: 'Calendar integration: flag days, notable days, and holidays via official API',
    areas: [1],
  },
  {
    id: '20260603-001',
    date: '2026-06-03',
    desc: 'Date-nav week number replaced by a per-day Remote/Office location toggle',
    areas: [14],
  },
  {
    id: '20260603-002',
    date: '2026-06-03',
    desc: 'Session chip and end-the-day button now show the in-view day’s start/end times',
    areas: [15],
  },
];