|
| 1 | +# Release v0.6.x - FamilySearch Normalization & Architecture Refinement |
| 2 | + |
| 3 | +Released: YYYY-MM-DD |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +This release normalizes FamilySearch as a downstream provider (equal to Ancestry, WikiTree, etc.) and establishes SparseTree SQLite as the canonical source of truth. Major architectural cleanup removes all legacy fallback code in favor of migration scripts. |
| 8 | + |
| 9 | +## New Features |
| 10 | + |
| 11 | +### Ancestry Update Automation Page (v0.6.x) |
| 12 | +- New database-scoped page at `/db/:dbId/ancestry-update` for bulk Ancestry synchronization |
| 13 | +- BFS traversal of direct-ancestor sparse tree from selected root person |
| 14 | +- Configurable generation depth (1-4 or full tree) |
| 15 | +- Per-person pipeline: check Ancestry link, process free hints, download/scrape provider data |
| 16 | +- Real-time SSE progress with emoji-prefixed execution log |
| 17 | +- Test mode (dry run) for previewing what would happen |
| 18 | +- Adds "Ancestry Update" link to database sidebar |
| 19 | +- API endpoints: GET `/api/ancestry-update/status`, GET `/:dbId/events` (SSE), POST `/:dbId/cancel`, GET `/:dbId/validate/:personId` |
| 20 | + |
| 21 | +### Ancestry Free Hints Automation (v0.6.x) |
| 22 | +- New "Hints" button on Ancestry row in Provider Data table to process free record hints |
| 23 | +- Playwright automation navigates to hints page, reviews each hint, accepts and saves to tree |
| 24 | +- Supports checkbox selection for adding related people from hints |
| 25 | +- Includes consecutive failure safeguard (stops after 3 failures) and remaining hints re-check |
| 26 | +- SSE-based progress events for real-time UI updates |
| 27 | +- API endpoints: POST/GET `/api/ancestry-hints/:dbId/:personId`, cancel, status |
| 28 | + |
| 29 | +### Ancestry Vital Info Upload (v0.6.x) |
| 30 | +- Extended Ancestry upload to support birth date, birth place, death date, death place, and name (not just photos) |
| 31 | +- Upload dialog now shows field-by-field comparison between local SparseTree data and cached Ancestry data |
| 32 | +- Browser automation uses Ancestry's Quick Edit sidebar to update person facts |
| 33 | +- Automatically handles Living/Deceased status toggle when setting death information |
| 34 | +- Pre-selects all differing fields for upload convenience |
| 35 | + |
| 36 | +### FamilySearch Normalization (v0.6.5) |
| 37 | +- FamilySearch now treated as equal downstream provider (no special priority) |
| 38 | +- Photos use `-familysearch` suffix like other providers: `{personId}-familysearch.jpg` |
| 39 | +- Added `linkFamilySearch()` and `getFamilySearchPhotoPath()` to augmentation service |
| 40 | +- ID resolution uses alphabetical order (no FamilySearch priority) |
| 41 | + |
| 42 | +### Architecture: Source of Truth Principle (v0.6.x) |
| 43 | +- SparseTree SQLite is now the canonical source of truth |
| 44 | +- Provider cache (`data/provider-cache/`) is for comparison only, not a fallback data source |
| 45 | +- All data reads come from SQLite; provider cache shows what providers have vs what SparseTree has |
| 46 | + |
| 47 | +## Bug Fixes |
| 48 | + |
| 49 | +### SQLite Vital Event Row ID Preservation (v0.6.x) |
| 50 | +- Changed vital_event INSERT from `INSERT OR REPLACE` to `ON CONFLICT DO UPDATE` |
| 51 | +- Preserves row IDs which are critical for local_override references |
| 52 | +- INSERT OR REPLACE was deleting and re-inserting rows, orphaning override references |
| 53 | + |
| 54 | +### Improved Vital Event Date Parsing (v0.6.x) |
| 55 | +- Now uses actual `birth.date` and `death.date` objects instead of parsing lifespan string |
| 56 | +- Captures full dates (e.g., "1979-07-31") rather than just years from lifespan ("1979-2020") |
| 57 | +- Added `parseYearFromDate()` function to handle various date formats including BC notation |
| 58 | + |
| 59 | +### Ancestry Update Log Memory Fix (v0.6.x) |
| 60 | +- Limited execution log entries to 500 to prevent browser memory issues on large trees |
| 61 | +- Shows notice when older entries are truncated |
| 62 | + |
| 63 | +### FamilySearch Upload Improvements (v0.6.x) |
| 64 | +- Auto-refresh FamilySearch cache after successful upload so UI shows updated data |
| 65 | +- Improved photo comparison to detect already-uploaded photos via symlink matching |
| 66 | +- Fixed Google login button selector for updated FamilySearch login page |
| 67 | +- Improved vitals page editing: handles conclusion dialogs and edit buttons |
| 68 | +- Added autocomplete handling for date/place fields (clicks first suggestion) |
| 69 | + |
| 70 | +### Scraper Auto-Login (v0.6.x) |
| 71 | +- Scraper now attempts auto-login via Google OAuth when landing on FamilySearch login page |
| 72 | +- Added `handleLoginIfNeeded()` function to detect login pages and complete OAuth flow |
| 73 | +- Navigates directly to target URL after successful login |
| 74 | + |
| 75 | +### Provider Comparison Not Using Local Overrides (v0.6.x) |
| 76 | +- Fixed comparison service using original database values instead of user-applied overrides |
| 77 | +- Added `applyLocalOverrides()` to fetch and apply vital_event overrides before comparison |
| 78 | +- FamilySearch/Ancestry now correctly show "match" when user has applied their values |
| 79 | + |
| 80 | +### Date Format Differences Showing as Different (v0.6.x) |
| 81 | +- Added date normalization to expand month abbreviations (e.g., "AUG" → "august") |
| 82 | +- "29 AUG 1933" now correctly matches "29 August 1933" |
| 83 | +- Reduces false positives in provider comparison diff counts |
| 84 | + |
| 85 | +### Unicode Escape in View Mode Selector (v0.6.x) |
| 86 | +- Fixed checkmark showing as literal `\u2713` text instead of ✓ in tree view mode dropdown |
| 87 | +- JSX text content requires actual Unicode characters, not escape sequences |
| 88 | + |
| 89 | +### Fan Chart Ancestor Count (v0.6.x) |
| 90 | +- Fixed footer showing incorrect count like "109 of 62 ancestors shown" |
| 91 | +- Now correctly counts only ancestors within the visible generation range |
| 92 | + |
| 93 | +### Stale Browser Connection Detection (v0.6.x) |
| 94 | +- Added `verifyAndReconnect()` to browser service that checks both Playwright state and actual browser process |
| 95 | +- Augmentation service now detects and recovers from stale connections before scraping |
| 96 | +- Fixes silent failures when browser was closed but connection state was still "connected" |
| 97 | + |
| 98 | +### Auto-Login on Sync (v0.6.x) |
| 99 | +- FamilySearch sync now attempts automatic login when auth token is missing |
| 100 | +- Uses `providerService.ensureAuthenticated()` to try Google SSO or stored credentials |
| 101 | +- Eliminates need for manual browser login before sync operations |
| 102 | +- Applies to both `refreshPerson()` and `fetchPersonDisplayName()` methods |
| 103 | + |
| 104 | +### FamilySearch Scraper Not Extracting Data (v0.6.x) |
| 105 | +- Updated scraper selectors to match current FamilySearch DOM structure |
| 106 | +- Name now extracted using `[data-testid="fullName"]` |
| 107 | +- Birth/death dates now extracted from `[data-testid="conclusionDisplay:BIRTH"]` and `[data-testid="conclusionDisplay:DEATH"]` containers |
| 108 | +- Added handling for collapsed Vitals section (auto-expands before extracting) |
| 109 | +- Photo extraction uses avatar container near `[data-testid="update-portrait-button"]` |
| 110 | +- Fixed TypeScript `__name` decorator issue causing `page.evaluate` to fail in browser context |
| 111 | +- Added detailed debug logging for photo extraction troubleshooting |
| 112 | +- Improved UI feedback: loading toast during scrape, success toast shows extracted fields |
| 113 | + |
| 114 | +### "Use" Button Not Updating SparseTree Row (v0.6.x) |
| 115 | +- Fixed clicking "Use" on provider field values not updating the SparseTree row display |
| 116 | +- Root causes fixed: |
| 117 | + - Client: `onFieldChanged` callback now refetches person data after applying override |
| 118 | + - Server: `getPerson()` now applies local overrides to returned person data |
| 119 | +- Added `applyLocalOverridesToPerson()` to database service for consistent override application |
| 120 | +- Birth/death date/place values from providers now properly display after clicking "Use" |
| 121 | + |
| 122 | +### "Set as Primary" Photo Not Updating (v0.6.x) |
| 123 | +- Fixed photo not updating after clicking "Set as Primary" on provider photos |
| 124 | +- Root causes fixed: |
| 125 | + - `getPhotoPath()` now checks for primary photo (`{personId}.jpg`) before provider-suffixed photos |
| 126 | + - Photo priority in PersonDetail header and SparseTree row now shows primary photo first |
| 127 | + - Added `Cache-Control: no-cache` headers to all photo "exists" endpoints to prevent stale responses |
| 128 | +- Added FamilySearch-specific photo endpoint: `GET /augment/:personId/familysearch-photo` |
| 129 | +- Added client API methods: `getFsPhotoUrl()`, `hasFsPhotoProvider()` |
| 130 | +- Added `photoVersion` state for cache-busting photo URLs after changes |
| 131 | + |
| 132 | +### HMR Context Resilience (v0.6.x) |
| 133 | +- Fixed "useSidebar must be used within a SidebarProvider" error during HMR transitions |
| 134 | +- `useSidebar()` and `useTheme()` hooks now return safe defaults during dev hot reloads |
| 135 | +- Prevents crashes when React context identity changes during development |
| 136 | + |
| 137 | +## Improvements |
| 138 | + |
| 139 | +### FamilySearch Upload Performance (v0.6.x) |
| 140 | +- Eliminated redundant post-login delays in FamilySearch upload automation |
| 141 | +- After Google OAuth redirect, now checks if already on target page before re-navigating |
| 142 | +- Replaced fixed `waitForTimeout` delays with element-based `waitForSelector` for responsiveness |
| 143 | +- Added PM2 timestamps to server logs for better debugging (`time: true` in ecosystem config) |
| 144 | + |
| 145 | +### Page-Level Padding Control (v0.6.x) |
| 146 | +- Moved `p-6` padding from Layout to individual pages for flexibility |
| 147 | +- Full-height pages (tree views, PersonDetail, SparseTreePage) control their own layout |
| 148 | +- Standard content pages receive consistent padding via their root element |
| 149 | +- Fixed missing padding on SparseTreePage and PersonDetail |
| 150 | +- Removed double padding from AIProviders page (external component handles its own padding) |
| 151 | + |
| 152 | +### Tree Visualization Parity with Ancestry.com (v0.6.x) |
| 153 | +- Added 5 tree view modes matching Ancestry.com functionality |
| 154 | +- **Fan Chart** (default): Radial pedigree with lineage-colored wedges (paternal=blue/teal, maternal=red/coral) |
| 155 | +- **Horizontal Pedigree**: Root left, ancestors right with expandable nodes |
| 156 | +- **Vertical Family**: Ancestors top, root middle with generation labels |
| 157 | +- **Columns** and **Focus**: Existing views retained |
| 158 | +- URL-based routing: `/tree/:dbId/:personId/:viewMode` |
| 159 | +- New shared components: TreeCanvas (D3 zoom/pan), TreeControls, AncestorNode |
| 160 | +- New utilities: lineageColors, treeLayout, arcGenerator |
| 161 | +- Fixed classic view bugs: dynamic centering, ResizeObserver instead of setTimeout |
| 162 | + |
| 163 | +### Vertical Family View Improvements (v0.6.x) |
| 164 | +- Refactored layout to use multi-pass collision resolution algorithm |
| 165 | +- Parents properly avoid overlapping when multiple branches are expanded |
| 166 | +- Added horizontal coupling bars between parent pairs (matching Ancestry.com style) |
| 167 | +- Fixed expand button centering on cards |
| 168 | +- Expansion now maintains current zoom level and pans to center on expanded node |
| 169 | +- No longer zooms out and shifts to bottom-right when expanding ancestors |
| 170 | +- Fixed expand/collapse button positioning to overlap card tops consistently |
| 171 | +- Moved spouse connection line from middle of card to name/date area |
| 172 | + |
| 173 | +### Avatar Placeholders (v0.6.x) |
| 174 | +- Replaced emoji-based avatar placeholders with proper SVG components throughout tree views |
| 175 | +- New `AvatarPlaceholder` component renders gender-aware silhouettes (male/female/unknown profiles) |
| 176 | +- Updated PersonCard, FocusNavigatorView, GenerationalColumnsView, PedigreeChartView, and SparseTreePage |
| 177 | +- Softened gender color palette for better visual harmony (less saturated blue/pink) |
| 178 | + |
| 179 | +### Legacy Code Removal (v0.6.x) |
| 180 | +- Removed all legacy fallback code from services (no more dual-path lookups) |
| 181 | +- Services updated: `familysearch-refresh`, `multi-platform-comparison`, `augmentation`, `scraper`, `person.routes` |
| 182 | +- Architecture policy: use migration scripts instead of maintaining legacy paths |
| 183 | + |
| 184 | +## Migration Scripts |
| 185 | + |
| 186 | +### Photo Migration |
| 187 | +- `scripts/migrate-fs-photos.ts` - Renames FamilySearch photos from `{personId}.jpg` to `{personId}-familysearch.jpg` |
| 188 | + |
| 189 | +### Cache Migration |
| 190 | +- `scripts/migrate-legacy-cache.ts` - Moves JSON files from `data/person/` to `data/provider-cache/familysearch/` |
| 191 | + |
| 192 | +## Technical Details |
| 193 | + |
| 194 | +### Source of Truth Architecture |
| 195 | +``` |
| 196 | +┌─────────────────────────────────────────────────────────────────┐ |
| 197 | +│ Layer 3: Local Overrides │ |
| 198 | +│ User edits that take precedence and survive provider re-sync │ |
| 199 | +├─────────────────────────────────────────────────────────────────┤ |
| 200 | +│ Layer 2: Normalized Data (SQLite) │ |
| 201 | +│ CANONICAL SOURCE OF TRUTH - all reads come from here │ |
| 202 | +├─────────────────────────────────────────────────────────────────┤ |
| 203 | +│ Layer 1: Raw Provider Cache │ |
| 204 | +│ For comparison only - shows what providers have │ |
| 205 | +└─────────────────────────────────────────────────────────────────┘ |
| 206 | +``` |
| 207 | + |
| 208 | +### Key Principles |
| 209 | +1. **Initial Seeding**: When indexing, data writes to both SQLite (as record) AND provider-cache (for comparison) |
| 210 | +2. **No Fallback Code**: Migration scripts upgrade data in place; no dual-path lookups |
| 211 | +3. **Explicit Apply**: Downloaded provider data is cached but never auto-applied; users click "Use" buttons |
| 212 | +4. **Provider Equality**: All providers treated equally as downstream data sources |
| 213 | + |
| 214 | +## Full Changelog |
| 215 | + |
| 216 | +**Full Diff**: https://github.com/atomantic/SparseTree/compare/v0.5.4...v0.6.x |
0 commit comments