
efitenandClaude Sonnet 4.6
51f823bf7e
feat: one-click prune nodes outside geofilter (#669 M4) (#738)
## Summary
- Adds `POST /api/admin/prune-geo-filter` endpoint — dry-run by default,
`?confirm=true` to permanently delete nodes outside the current
geofilter polygon + buffer. Requires `X-API-Key` header.
- Adds **Prune nodes** section inside the GeoFilter customizer tab
(write-access only, same `writeEnabled` gate as PUT). **Preview** lists
affected nodes; **Confirm delete** removes them.
- Adds `GetNodesForGeoPrune` and `DeleteNodesByPubkeys` DB helpers.
- Updates `docs/user-guide/geofilter.md` — documents the UI button as
primary workflow, CLI script as alternative.
> **Depends on M3** (`feat/geofilter-m3-customizer`, PR #736). Merge M3
first.
## Test plan
- [x] `cd cmd/server && go test ./...` — all pass
- [x] Customizer GeoFilter tab without `apiKey` — Prune section not
visible
- [x] With `apiKey` + polygon active — Prune section visible
- [x] **Preview** returns list of nodes outside polygon (no deletions)
- [x] **Confirm delete** removes nodes, list clears
- [x] `POST /api/admin/prune-geo-filter` without `X-API-Key` → 401
- [x] `POST /api/admin/prune-geo-filter` with no polygon configured →
400
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 03:19:31 +00:00
..
2026-04-21 09:09:39 -07:00
2026-04-03 13:51:13 -07:00
2026-05-17 17:33:30 +00:00
2026-05-18 12:27:44 -07:00
2026-04-05 14:50:40 -07:00
2026-05-03 17:56:42 -07:00
2026-05-03 17:56:42 -07:00
2026-05-17 16:13:11 +00:00
2026-05-18 22:51:23 -07:00
2026-05-18 22:51:23 -07:00
2026-05-18 22:51:23 -07:00
2026-05-18 22:51:23 -07:00
2026-04-12 18:09:23 -07:00
2026-05-03 17:41:22 -07:00
2026-04-20 21:46:34 -07:00
2026-05-19 01:17:12 -07:00
2026-05-18 12:27:44 -07:00
2026-05-19 01:17:12 -07:00
2026-05-19 01:17:12 -07:00
2026-04-16 00:18:25 -07:00
2026-05-19 23:53:41 -07:00
2026-04-17 09:24:40 -07:00
2026-05-21 03:19:31 +00:00
2026-05-02 12:04:37 -07:00
2026-05-02 12:04:37 -07:00
2026-05-15 22:46:25 -07:00
2026-05-16 17:28:40 +00:00
2026-05-06 23:50:44 -07:00
2026-05-21 03:19:31 +00:00
2026-05-15 22:34:21 -07:00
2026-05-15 22:34:21 -07:00
2026-05-19 08:08:28 -07:00
2026-05-05 01:16:57 -07:00
2026-05-05 01:16:57 -07:00
2026-05-16 20:56:52 +00:00
2026-04-16 00:09:36 -07:00
2026-05-16 20:56:52 +00:00
2026-05-05 01:58:52 -07:00
2026-05-19 23:53:41 -07:00
2026-03-31 01:10:56 -07:00
2026-05-21 03:19:31 +00:00
2026-03-27 01:16:59 -07:00
2026-04-18 11:52:22 -07:00
2026-04-18 11:52:22 -07:00
2026-05-19 23:53:41 -07:00
2026-05-06 23:50:44 -07:00
2026-04-03 13:11:59 -07:00
2026-05-15 16:21:14 +00:00
2026-05-16 19:55:00 +00:00
2026-05-15 22:46:28 -07:00
2026-05-15 20:24:55 -07:00
2026-05-15 22:46:25 -07:00
2026-05-17 16:13:11 +00:00
2026-04-20 22:15:02 -07:00
2026-05-03 20:10:02 -07:00
2026-04-21 04:51:24 +00:00
2026-05-02 20:35:15 -07:00
2026-05-17 16:13:11 +00:00
2026-05-19 08:08:28 -07:00
2026-05-18 23:19:27 -07:00
2026-05-21 03:19:31 +00:00
2026-05-05 01:33:23 -07:00
2026-05-05 01:33:23 -07:00
2026-04-20 23:10:33 -07:00
2026-04-18 11:39:13 -07:00
2026-05-03 08:56:09 -07:00
2026-05-05 06:42:58 +00:00
2026-05-17 16:13:11 +00:00
2026-05-16 10:14:44 -07:00
2026-04-02 23:45:03 -07:00
2026-05-15 09:16:39 -07:00
2026-05-15 09:16:39 -07:00
2026-05-16 10:14:44 -07:00
2026-04-30 09:25:51 -07:00
2026-05-16 19:55:00 +00:00
2026-05-19 23:53:41 -07:00
2026-05-19 23:53:41 -07:00
2026-05-19 23:53:41 -07:00
2026-05-05 01:41:00 -07:00
2026-05-05 01:41:00 -07:00
2026-04-17 23:43:05 +00:00
2026-05-18 09:22:27 -07:00
2026-05-18 07:36:33 -07:00
2026-04-03 13:33:26 -07:00
2026-05-01 23:11:27 -07:00
2026-04-05 15:05:20 -07:00
2026-05-18 23:52:27 -07:00
2026-05-17 16:13:11 +00:00
2026-03-30 03:42:11 +00:00
2026-05-15 22:46:28 -07:00
2026-05-15 22:46:28 -07:00
2026-05-15 22:46:28 -07:00
2026-05-15 22:46:28 -07:00
2026-05-15 22:46:28 -07:00
2026-05-15 22:46:28 -07:00
2026-05-15 22:46:28 -07:00
2026-05-18 23:19:30 -07:00
2026-05-02 11:15:25 -07:00
2026-05-08 16:29:23 -07:00
2026-05-08 16:29:23 -07:00
2026-05-08 16:29:23 -07:00
2026-05-08 16:29:23 -07:00
2026-05-05 17:56:56 -07:00
2026-05-08 16:29:23 -07:00
2026-04-01 19:26:11 -07:00
2026-05-15 09:16:39 -07:00
2026-05-21 03:19:31 +00:00
2026-05-03 19:50:01 -07:00
2026-05-18 07:36:33 -07:00
2026-05-18 09:22:27 -07:00
2026-05-05 02:33:27 -07:00
2026-05-05 02:33:27 -07:00
2026-05-05 01:34:08 -07:00
2026-05-05 01:34:08 -07:00
2026-05-15 16:21:14 +00:00
2026-05-15 09:16:39 -07:00
2026-05-17 16:42:01 -07:00
2026-04-20 19:55:00 -07:00
2026-04-21 04:51:24 +00:00
2026-05-18 07:36:28 -07:00
2026-05-03 17:56:12 -07:00
2026-05-18 07:36:28 -07:00
2026-05-21 03:19:31 +00:00
2026-05-21 03:19:31 +00:00
2026-05-15 16:21:14 +00:00
2026-05-03 17:40:54 -07:00
2026-04-20 23:10:33 -07:00
2026-04-21 09:09:39 -07:00
2026-05-19 23:53:41 -07:00
2026-05-03 17:41:22 -07:00
2026-05-03 17:41:22 -07:00
2026-05-17 16:13:11 +00:00
2026-04-20 19:55:00 -07:00
2026-04-20 19:55:00 -07:00
2026-05-17 16:13:11 +00:00
2026-03-30 03:42:11 +00:00
2026-04-01 12:19:20 -07:00