Skip to content

Commit 434c1a6

Browse files
authored
Merge pull request #7 from atomantic/dev
v0.7.x: Migration Map, AI Discovery Dismiss, Debug Endpoints
2 parents e1148c3 + f2e6fe4 commit 434c1a6

28 files changed

Lines changed: 2328 additions & 123 deletions

.changelog/v0.7.x.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Release v0.7.x - Migration Map, AI Discovery Improvements
2+
3+
Released: Unreleased
4+
5+
## Overview
6+
7+
This release improves the AI Discovery feature with dismiss functionality, debugging capabilities, and better CLI integration.
8+
9+
## New Features
10+
11+
### AI Discovery Dismiss Functionality (v0.7.0)
12+
- Dismiss AI-discovered candidates to exclude them from future discoveries
13+
- Batch dismiss all unselected candidates at once
14+
- View dismissed candidates with original AI reasoning and tags
15+
- Undo dismiss to restore candidates
16+
- Clear all dismissed candidates for a database
17+
- Dismissed candidates stored in SQLite with `discovery_dismissed` table
18+
- API endpoints: POST `/dismiss`, POST `/dismiss-batch`, GET `/dismissed`, DELETE `/dismissed/:personId`, DELETE `/dismissed`
19+
20+
### AI Discovery Debug Endpoints (v0.7.0)
21+
- New debug endpoints for troubleshooting AI run failures
22+
- GET `/api/ai-discovery/debug/runs` - list recent AI runs with metadata
23+
- GET `/api/ai-discovery/debug/runs/:runId` - detailed run info including prompt preview and output
24+
- Error details capture (last 10 lines of stderr/stdout) stored on failed runs
25+
26+
### Migration Map Visualization (v0.7.x)
27+
- New 6th tree view mode: "Migration Map" plots ancestors on an interactive world map
28+
- Leaflet.js map with OpenStreetMap/CartoDB dark tiles
29+
- Lineage-colored markers (paternal=blue, maternal=red) with generation depth variation
30+
- Migration polylines connecting parent birth to child birth locations
31+
- Time range slider for filtering by birth year
32+
- Paternal/Maternal layer toggle checkboxes
33+
- Geocoding via Nominatim with permanent SQLite cache (`place_geocode` table)
34+
- Progressive geocode broadening: strips specific locality parts to resolve historical place names
35+
- User-initiated batch geocoding with SSE progress streaming (EventSource)
36+
- Sparse tree map page at `/favorites/sparse-tree/:dbId/map`
37+
- API: `GET /api/map/:dbId/:personId`, `GET /api/map/:dbId/sparse`, `GET /api/map/geocode/stream`
38+
39+
## Bug Fixes
40+
41+
### CLI Provider Integration (v0.7.0)
42+
- Fixed large prompt handling via stdin piping for CLI providers (codex, claude-code)
43+
- Added `-` flag detection in provider args to enable stdin mode
44+
- Fixed JSON parsing to find LAST valid JSON array in noisy CLI output
45+
- Handles CLI banners and headers that could interfere with response parsing
46+
- Improved error capture with `errorDetails` field for debugging failures

PLAN.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ High-level project roadmap. For detailed phase documentation, see [docs/roadmap.
3838
| 15.19 | Normalize FamilySearch as downstream provider ||
3939
| 15.20 | Relationship linking (parents, spouses, children) | 📋 |
4040
| 15.22 | Ancestry free hints automation ||
41+
| 15.23 | Migration Map visualization ||
4142
| 16 | Multi-platform sync architecture | 📋 |
4243
| 17 | Real-time event system (Socket.IO) | 📋 |
4344

@@ -561,6 +562,63 @@ UI Button (ProviderDataTable)
561562
- `POST /api/ancestry-hints/:dbId/cancel` - Cancel running operation
562563
- `GET /api/ancestry-hints/status` - Check if running
563564

565+
### Phase 15.23: Migration Map Visualization ✅
566+
567+
A 6th tree view mode plotting ancestors on an interactive Leaflet.js map with lineage-colored markers, parent-child migration lines, time filtering, and layer controls.
568+
569+
**Features:**
570+
- **Migration Map view mode** - Available in the tree view mode dropdown alongside Fan, Horizontal, Vertical, Columns, Focus
571+
- **Leaflet.js map** with OpenStreetMap tiles (light) and CartoDB dark tiles (dark theme)
572+
- **Lineage-colored markers** - Paternal (blue/teal), Maternal (red/coral), Self (purple)
573+
- **Migration polylines** connecting parent birth locations to child birth locations
574+
- **Time range slider** filtering ancestors by birth year
575+
- **Paternal/Maternal layer toggles** for lineage filtering
576+
- **Auto-fit bounds** on data load
577+
- **Click popups** with person name, lifespan, places, and link to person detail
578+
- **Geocoding service** using Nominatim with 1100ms rate limiting and permanent SQLite cache
579+
- **Geocode progress bar** with SSE streaming for batch geocoding
580+
- **Sparse tree map page** at `/favorites/sparse-tree/:dbId/map`
581+
582+
**Architecture:**
583+
```
584+
Database: place_geocode table (SQLite cache)
585+
→ Geocode Service (Nominatim + cache)
586+
→ Map Service (tree data + coordinate joining)
587+
→ Map Routes (REST + SSE geocode stream)
588+
→ MigrationMapView (Leaflet + react-leaflet)
589+
```
590+
591+
**Routes:**
592+
- `/tree/:dbId/:personId/map` - Ancestry tree migration map
593+
- `/favorites/sparse-tree/:dbId/map` - Sparse tree (favorites) migration map
594+
595+
**API Endpoints:**
596+
- `GET /api/map/:dbId/:personId` - Ancestry tree map data
597+
- `GET /api/map/:dbId/sparse` - Sparse tree map data
598+
- `GET /api/map/geocode/stream` - Batch geocode via SSE (EventSource)
599+
- `GET /api/map/geocode/stats` - Geocode cache statistics
600+
- `POST /api/map/geocode/reset-not-found` - Reset failed entries for retry
601+
602+
**Files Created:**
603+
- `server/src/db/migrations/006_place_geocode.ts` - Place geocode cache table
604+
- `server/src/services/geocode.service.ts` - Nominatim geocoding + SQLite cache
605+
- `server/src/services/map.service.ts` - Map data assembly
606+
- `server/src/routes/map.routes.ts` - REST + SSE endpoints
607+
- `client/src/components/ancestry-tree/views/MigrationMapView.tsx` - Leaflet map component
608+
- `client/src/components/favorites/SparseTreeMapPage.tsx` - Sparse tree map page
609+
- `client/src/components/map/GeocodeProgressBar.tsx` - Geocode progress UI
610+
- `client/src/components/map/mapUtils.ts` - Marker/line utilities
611+
612+
**Files Modified:**
613+
- `server/src/db/migrations/index.ts` - Register migration 006
614+
- `server/src/db/schema.sql` - Add place_geocode table
615+
- `server/src/index.ts` - Mount mapRouter
616+
- `shared/src/index.ts` - MapCoords, MapPerson, MapData, GeocodeProgress types
617+
- `client/package.json` - leaflet, react-leaflet, @types/leaflet deps
618+
- `client/src/services/api.ts` - Map API methods
619+
- `client/src/components/ancestry-tree/AncestryTreeView.tsx` - Add 'map' view mode
620+
- `client/src/App.tsx` - Sparse tree map route
621+
564622
### Phase 16: Multi-Platform Sync (Remaining Items)
565623

566624
- ~~Provider cache structure~~ (completed in 15.11)

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
A genealogy toolkit for creating local databases of your family tree, curating favorites, and generating sparse family tree visualizations.
44

5+
## Origins
6+
7+
This project is a web-based UI enhancement that evolved from the creator's early explorations into learning more about his ancestry using a CLI-based tool: [FamilySearchFinder](https://github.com/atomantic/FamilySearchFinder).
8+
59
## What is SparseTree?
610

711
SparseTree connects to genealogy providers (FamilySearch, Ancestry, WikiTree, 23andMe) to download and store your ancestry data locally. Once you have your data, you can:

client/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@fsf/client",
3-
"version": "0.6.33",
3+
"version": "0.7.12",
44
"type": "module",
55
"scripts": {
66
"dev": "vite --port 6373",
@@ -10,17 +10,20 @@
1010
"dependencies": {
1111
"@fsf/shared": "*",
1212
"d3": "^7.9.0",
13+
"leaflet": "^1.9.4",
1314
"lucide-react": "^0.562.0",
1415
"portos-ai-toolkit": "^0.1.0",
1516
"react": "^18.3.1",
1617
"react-dom": "^18.3.1",
1718
"react-hot-toast": "^2.6.0",
19+
"react-leaflet": "^4.2.1",
1820
"react-router-dom": "^7.1.1",
1921
"socket.io-client": "^4.8.3",
2022
"zustand": "^5.0.2"
2123
},
2224
"devDependencies": {
2325
"@types/d3": "^7.4.3",
26+
"@types/leaflet": "^1.9.21",
2427
"@types/react": "^18.3.18",
2528
"@types/react-dom": "^18.3.5",
2629
"@vitejs/plugin-react": "^4.3.4",

client/src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { BrowserSettingsPage } from './pages/BrowserSettingsPage';
1313
import { ReportsPage } from './pages/ReportsPage';
1414
import { FavoritesPage } from './components/favorites/FavoritesPage';
1515
import { SparseTreePage } from './components/favorites/SparseTreePage';
16+
import { SparseTreeMapPage } from './components/favorites/SparseTreeMapPage';
1617
import { DatabaseFavoritesPage } from './components/favorites/DatabaseFavoritesPage';
1718
import { IntegrityPage } from './components/integrity/IntegrityPage';
1819
import { AncestryUpdatePage } from './components/ancestry-update';
@@ -41,6 +42,7 @@ function App() {
4142
<Route path="tools/gedcom" element={<GedcomPage />} />
4243
<Route path="favorites" element={<FavoritesPage />} />
4344
<Route path="favorites/sparse-tree/:dbId" element={<SparseTreePage />} />
45+
<Route path="favorites/sparse-tree/:dbId/map" element={<SparseTreeMapPage />} />
4446
<Route path="db/:dbId/favorites" element={<DatabaseFavoritesPage />} />
4547
<Route path="db/:dbId/integrity" element={<IntegrityPage />} />
4648
<Route path="db/:dbId/integrity/:tab" element={<IntegrityPage />} />

0 commit comments

Comments
 (0)