release: bump version to 0.66.0
Some checks failed
ci / backend (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / delivery (push) Has been cancelled
release / images (push) Has been cancelled

This commit is contained in:
rayd1o
2026-05-26 03:41:47 +08:00
parent e65267fe21
commit 5bf5c73ca0
173 changed files with 8669 additions and 13210 deletions

View File

@@ -8,6 +8,24 @@ This project follows the repository versioning rule:
- `improvement` -> `+0.0.1`bugfix + 小功能混合)
- `bugfix` -> `+0.0.1`
## [0.66.0] — 2026-05-26
Released: 2026-05-26
### Highlights
- 将 Admin 正式化为唯一控制台入口,移除旧 AntD 后台、Admin Next 路由痕迹和相关依赖。
- 引入 PostgreSQL 数据作业队列、Earth outbox 同步和可交互对象管线,让采集、清理和 Earth 刷新进入可追踪异步链路。
- 强化 AI、AI 工具、设置连接测试和采集任务的结构化业务日志,关键事件可在系统日志中检索。
- CelesTrak 轨道根数采集改为完整 `active` 目录下载、续传和重试,避免部分分组失败时保存不完整卫星数据。
### Added / Fixed / Improved
- Admin 数据源页修复内置源调度启停按钮,使用 `is_active` 判断 `/enable``/disable`,避免采集状态误导调度开关。
- Earth 新增通用 interactables 层和平台数据流文档,支持对象级 delta 同步与后续小图层扩展。
- `planet.sh init/start/destroy` 补齐 uv 镜像回退、Bun unzip 依赖、HTTPS/LAN 跳转协议和 OOBE 清理语义。
- Markdown code block、数据源队列、演示模式、About 版本展示、TV 链接协议和文档索引同步完成。
---
## [0.65.2] — 2026-05-22
Released: 2026-05-22

View File

@@ -16,7 +16,24 @@
- 已被正式实现替代、继续放在 `docs/` 根目录会误导后续开发的计划,归档
- 仍然指导未来开发、尚未完成或仍有明确执行价值的文档,继续保留在 `docs/`
当前替代入口:
- 业务和数据产品链路见 [业务架构与数据流转](/home/ray/dev/linkong/planet/docs/technical/zh/platform-data-flows.md)。
- 当前后端作业、outbox 和 Earth 同步实现见 [数据作业与 Outbox 技术架构](/home/ray/dev/linkong/planet/docs/technical/zh/data-job-earth-sync-architecture.md)。
- 用户操作流程见 [Planet 使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/manual.md)。
- 当前代码结构见 [技术文档索引](/home/ray/dev/linkong/planet/docs/technical/zh/README.md)。
补充说明:
- 一部分归档文档来自外部或临时工作流草案,例如 sisyphus 生成的初稿
- 这类文档如果有可用内容,应先吸收到 `docs/plans/``docs/technical/`,再归档保留来源记录
## 近期归档
- [Docs Gatekeeper 鉴权系统计划](/home/ray/dev/linkong/planet/docs/deprecated/docs-gatekeeper-auth-plan.md):已落地,当前实现见技术文档。
- [Location Resolver 共享管线计划](/home/ray/dev/linkong/planet/docs/deprecated/location-resolver-shared-pipeline-plan.md):已落地,当前实现见技术文档。
- [Earth Surface Hover Info Plan](/home/ray/dev/linkong/planet/docs/deprecated/earth-surface-hover-info-plan.md):已实现,保留为历史记录。
- [Admin Next Dual Track Full Migration Plan](/home/ray/dev/linkong/planet/docs/deprecated/admin-next-dual-track-full-migration-plan.md):已被当前 `frontend/src/admin/` 控制台结构替代。
- [Admin Next Soft Glass Goal Driven Plan](/home/ray/dev/linkong/planet/docs/deprecated/admin-next-soft-glass-goal-driven-plan.md):已被当前 `frontend/src/admin/` 控制台结构替代。
- [Admin Next Parity Checklist](/home/ray/dev/linkong/planet/docs/deprecated/admin-next-parity-checklist.md):旧 `/admin-next/*` 验收资料,保留为迁移历史。
- [Admin Next Parity Audit Closeout](/home/ray/dev/linkong/planet/docs/deprecated/admin-next-parity-audit-closeout-plan.md):旧 `/admin-next/*` 审计资料,保留为迁移历史。

View File

@@ -104,7 +104,7 @@ The old AntD page itself treated these Earth content tabs as placeholder-level c
- `models_3d`
- `news_anchor_strategy`
If backend endpoints are later added, these items must be promoted into `docs/plans/admin-next-parity-checklist.md` with concrete API and UI acceptance criteria.
If backend endpoints are later added, these items must be promoted into a new active plan under `docs/plans/` with concrete API and UI acceptance criteria.
## Final Gate
@@ -114,7 +114,7 @@ After the route promotion, the final gate is no longer “switch old routes.”
2. Run the static checks:
- `rg "map: \\(\\) => \\[\\]|暂不支持保存|placeholder" frontend/src/admin-next`
- `rg "ShadowPage|FeatureConsole|GlassPanel|InspectorDrawer" frontend/src/admin-next`
3. Manually verify every official route listed in `docs/plans/admin-next-parity-checklist.md`.
3. Manually verify every official route listed in `docs/deprecated/admin-next-parity-checklist.md`.
4. Confirm `/legacy/admin/*` still opens old AntD pages during the validation window.
5. Delete old AntD pages and remove AntD dependencies only as a separate final cleanup task after explicit confirmation.

View File

@@ -8,7 +8,7 @@ The redesign must cover desktop and mobile. Data display, icon semantics, table
## Criteria For Success
- This plan exists at `docs/plans/admin-next-soft-glass-goal-driven-plan.md`.
- This archived plan exists at `docs/deprecated/admin-next-soft-glass-goal-driven-plan.md`.
- `/admin-next/*` has real pages for every route; route usage of `ShadowPage` is removed.
- Admin Next supports `system`, `light`, and `dark` theme modes using the same persistence and system-theme idea as Docs.
- The visual language reads as soft-glass / light-neumorphic instead of an AntD reskin: translucent panels, fine borders, subtle glow, cool backgrounds, restrained accent colors, crisp icons, and tactile controls.
@@ -214,4 +214,3 @@ Manual viewport checks:
- low height;
- 125% / 150% browser zoom;
- light / dark / system theme modes.

View File

@@ -1,6 +1,6 @@
# Location Resolver Shared Pipeline Plan
**状态**:已实现,当前用户流程见 [Earth 位置候选采集使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-user.md),开发接口见 [通用位置估算管线开发说明](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-development.md)。
**状态**:已实现,当前用户流程见 [Planet 使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/manual.md) 的 Earth 位置候选采集章节,开发接口见 [通用位置估算管线开发说明](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-development.md)。
## Goal

View File

@@ -37,7 +37,7 @@ If the same action has both a UI and a CLI path (e.g. user creation), describe t
- a `credential_provider` in `backend/app/core/datasource_defaults.py`;
- a default credential guide in `backend/app/services/credential_guides.py`;
- a supported connectivity provider in `backend/app/services/datasource_connectivity.py`;
- settings UI guidance or a credential form in `frontend/src/pages/Settings/Settings.tsx`;
- settings UI guidance or a credential form in `frontend/src/admin/pages/PlainResourcePages.tsx`;
- a regression test that fails if the guide/provider is missing.
## Recommended Checks

View File

@@ -7,6 +7,12 @@
- 分几期做
- 当前差距和下一步是什么
当前实现、业务架构和数据链路不放在这里。它们分别进入:
- [业务架构与数据流转](/home/ray/dev/linkong/planet/docs/technical/zh/platform-data-flows.md)
- [数据作业与 Outbox 技术架构](/home/ray/dev/linkong/planet/docs/technical/zh/data-job-earth-sync-architecture.md)
- [技术文档索引](/home/ray/dev/linkong/planet/docs/technical/zh/README.md)
适合放入这里的内容:
- Earth / BGP / 地形 / 天球实施方案
@@ -16,38 +22,40 @@
当前重点入口:
- [earth-mobile-drawer-ui-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-mobile-drawer-ui-plan.md)
- [earth-compute-center-bgp-style-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-compute-center-bgp-style-plan.md)
- [earth-renderer-architecture-separation-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-renderer-architecture-separation-plan.md)
- [Earth Mobile Drawer UI Plan](/home/ray/dev/linkong/planet/docs/plans/earth-mobile-drawer-ui-plan.md)
- [Earth Compute Center BGP Style Plan](/home/ray/dev/linkong/planet/docs/plans/earth-compute-center-bgp-style-plan.md)
- [Earth Renderer Architecture Separation Plan](/home/ray/dev/linkong/planet/docs/plans/earth-renderer-architecture-separation-plan.md)
- [Earth 高精度国界静态瓦片计划](/home/ray/dev/linkong/planet/docs/plans/earth-high-precision-boundary-tiles-plan.md)
- [earth-predicted-orbit-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-predicted-orbit-plan.md)
- [earth-webgl-instancing-satellites-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-webgl-instancing-satellites-plan.md)
- [earth-real-terrain-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-real-terrain-plan.md)
- [earth-news-source-configuration-and-collector-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-news-source-configuration-and-collector-plan.md)
- [earth-news-cruise-summary-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-news-cruise-summary-plan.md)
- [Earth Predicted Orbit Plan](/home/ray/dev/linkong/planet/docs/plans/earth-predicted-orbit-plan.md)
- [Earth WebGL Instancing Satellites Plan](/home/ray/dev/linkong/planet/docs/plans/earth-webgl-instancing-satellites-plan.md)
- [Earth Real Terrain Plan](/home/ray/dev/linkong/planet/docs/plans/earth-real-terrain-plan.md)
- [Earth News Source Configuration And Collector Plan](/home/ray/dev/linkong/planet/docs/plans/earth-news-source-configuration-and-collector-plan.md)
- [Earth News Cruise Summary Plan](/home/ray/dev/linkong/planet/docs/plans/earth-news-cruise-summary-plan.md)
- [Earth 动作捕捉手势控制计划](/home/ray/dev/linkong/planet/docs/plans/earth-motion-capture-gesture-control-plan.md)
- [Earth 动捕交互语义 V2 计划](/home/ray/dev/linkong/planet/docs/plans/earth-motion-gesture-interaction-v2-plan.md)
- [Earth Presentation 解耦架构计划](/home/ray/dev/linkong/planet/docs/plans/earth-presentation-decoupled-architecture-plan.md)
- [earth-vessel-rendering-performance-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-vessel-rendering-performance-plan.md)
- [Earth Vessel Rendering Performance Plan](/home/ray/dev/linkong/planet/docs/plans/earth-vessel-rendering-performance-plan.md)
- [AIS 多源采集、冲突记录与聚合接口计划](/home/ray/dev/linkong/planet/docs/plans/earth-vessel-ais-aggregation-plan.md)
- [earth-interactable-layer-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-interactable-layer-plan.md)
- [frontend-public-docs-site-plan.md](/home/ray/dev/linkong/planet/docs/plans/frontend-public-docs-site-plan.md)
- [Docs Gatekeeper 鉴权系统计划](/home/ray/dev/linkong/planet/docs/plans/docs-gatekeeper-auth-plan.md)
- [Location Resolver 共享管线计划](/home/ray/dev/linkong/planet/docs/plans/location-resolver-shared-pipeline-plan.md)
- [frontend-ai-playground-development-plan.md](/home/ray/dev/linkong/planet/docs/plans/frontend-ai-playground-development-plan.md)
- [Earth Interactable Layer Plan](/home/ray/dev/linkong/planet/docs/plans/earth-interactable-layer-plan.md)
- [Frontend Public Docs Site Plan](/home/ray/dev/linkong/planet/docs/plans/frontend-public-docs-site-plan.md)
- [Frontend AI Playground Development Plan](/home/ray/dev/linkong/planet/docs/plans/frontend-ai-playground-development-plan.md)
- [AI Provider OpenClaw-Style Routing Plan](/home/ray/dev/linkong/planet/docs/plans/ai-provider-openclaw-style-routing-plan.md)
- [统一集成配置 Schema 系统计划](/home/ray/dev/linkong/planet/docs/plans/integration-config-schema-system-plan.md)
- [Lightweight Agent Orchestrator 与 WebSearch 证据层计划](/home/ray/dev/linkong/planet/docs/plans/agents-light-orchestrator-websearch-plan.md)
- [Admin Next Parity Checklist](/home/ray/dev/linkong/planet/docs/plans/admin-next-parity-checklist.md)
- [Admin Next Parity Audit Closeout](/home/ray/dev/linkong/planet/docs/plans/admin-next-parity-audit-closeout-plan.md)
- [ue5-mvp-fused-plan.md](/home/ray/dev/linkong/planet/docs/plans/ue5-mvp-fused-plan.md)
- [UE5 MVP Fused Plan](/home/ray/dev/linkong/planet/docs/plans/ue5-mvp-fused-plan.md)
历史计划入口:
- 已完成、已替代或只作为历史决策背景保留的文档,统一放在 [Deprecated Docs](/home/ray/dev/linkong/planet/docs/deprecated/README.md)。
不适合放入这里的内容:
- 当前代码结构说明
- 组件现状和实现入口
- 已经落地的技术上下文说明
- 已经成为当前行为的“架构说明”
这些应放入:
- [docs/technical/README.md](/home/ray/dev/linkong/planet/docs/technical/README.md)
- [技术文档索引](/home/ray/dev/linkong/planet/docs/technical/zh/README.md)
- [Technical Docs Index](/home/ray/dev/linkong/planet/docs/technical/en/README.md)

View File

@@ -178,5 +178,5 @@ Runtime 选择规则:
- `backend/app/services/ai_client.py`
- `aiprovider/main.py`
- `aiprovider/provider_service.py`
- `frontend/src/admin-next/pages/PlainResourcePages.tsx`
- `docs/plans/admin-next-parity-audit-closeout-plan.md`
- `frontend/src/admin/pages/PlainResourcePages.tsx`
- `docs/deprecated/admin-next-parity-audit-closeout-plan.md`

View File

@@ -1,46 +1,52 @@
# Technical Docs
This directory holds "current implementation and current structure" documentation, focusing on:
This is the current Planet documentation entry point. Docs are organized by reader path: start with business architecture to understand data products, then move into user manuals or implementation references.
- How the code is organized right now
- Where the current entry points are
- How state and components work
- Which implementation boundaries future changes should follow
## Business Architecture
What belongs here:
- [Business Architecture and Data Flows](/home/ray/dev/linkong/planet/docs/technical/en/platform-data-flows.md): purpose, collection flow, fact tables, derived tables, cache, and WebSocket broadcast path for each Earth data product
- [Naming Glossary](/home/ray/dev/linkong/planet/docs/technical/en/naming-glossary.md): English/Chinese terms used across the console, Earth, backend, and docs
- Quickstart and user manual
- Frontend context
- Earth frontend structure
- Earth satellite footprint policy
- Earth render layer order
- Earth layer style property index
- Backend runtime control
- Collector status
- Collector settings and connectivity validation
- Earth Interactable integration
- Collection format conventions
## Manual
## Entry Points
- [Quickstart](/home/ray/dev/linkong/planet/docs/technical/en/quickstart.md): shortest path to getting Planet running from scratch
- [Planet Manual](/home/ray/dev/linkong/planet/docs/technical/en/manual.md): user workflows for the console, Earth, Docs, and common features
- [FAQ](/home/ray/dev/linkong/planet/docs/technical/en/faq.md): troubleshooting for Windows / WSL, ports, dependencies, motion capture, credentials, and Docs permissions
- [Quickstart](/home/ray/dev/linkong/planet/docs/technical/en/quickstart.md): The shortest path to getting Planet running from scratch
- [Planet Manual](/home/ray/dev/linkong/planet/docs/technical/en/manual.md): Complete usage guide for the console, `planet.sh`, Earth, and Docs
- [FAQ](/home/ray/dev/linkong/planet/docs/technical/en/faq.md): Central troubleshooting entry for Windows / WSL, ports, dependencies, motion capture, credentials, and Docs permissions
- [Earth Location Candidate Collection User Guide](/home/ray/dev/linkong/planet/docs/technical/en/location-pipeline-user.md): Collect and preview coordinate candidates for compute centers and BGP collectors on Earth
- [Collector Settings and Connectivity Validation](/home/ray/dev/linkong/planet/docs/technical/en/datasource-collector-settings-connectivity.md): Data source catalog, collector settings, connectivity validation, and BarentsWatch credentials
- [Shared Location Resolution Pipeline Development Guide](/home/ray/dev/linkong/planet/docs/technical/en/location-pipeline-development.md): Backend location resolver / pipeline interfaces, registries, and extension points
- [Docs Gatekeeper Development Guide](/home/ray/dev/linkong/planet/docs/technical/en/docs-gatekeeper-development.md): Backend Docs catalog, Markdown content loading, and Gatekeeper permission groups
- [Naming Glossary](/home/ray/dev/linkong/planet/docs/technical/en/naming-glossary.md): English/Chinese term mapping for the console, Earth, backend, and docs
- [Earth Interactable Usage](/home/ray/dev/linkong/planet/docs/technical/en/earth-interactable-usage.md): API, lifecycle, and integration examples for Earth surface icon Interactable
- [Earth Toolbar and Overlay Coordination](/home/ray/dev/linkong/planet/docs/technical/en/earth-toolbar-overlay-coordination.md): Closing matrix and integration rules for toolbar buttons, search, settings, news, and layer overlays
- [Tactile UI Components](/home/ray/dev/linkong/planet/docs/technical/en/tactile-ui-components.md): Portable button, switch, tooltip, and scrollbar APIs, theme tokens, and migration rules
## Earth Implementation
What does not belong here:
- [Earth Frontend Context](/home/ray/dev/linkong/planet/docs/technical/en/earth-frontend-context.md): Earth modules, state, WebSocket refresh, and layer lifecycle
- [Earth Layer Style Reference](/home/ray/dev/linkong/planet/docs/technical/en/earth-layer-style-reference.md): layer colors, symbols, materials, and visual parameters
- [Earth Render Layer Order](/home/ray/dev/linkong/planet/docs/technical/en/earth-render-layer-order.md): renderOrder, depth strategy, picking, and collision avoidance
- [Earth Satellite Footprint Policy](/home/ray/dev/linkong/planet/docs/technical/en/earth-satellite-footprint-policy.md): satellite footprint display boundaries and strategy
- [BGP Context](/home/ray/dev/linkong/planet/docs/technical/en/earth-bgp-context.md): BGP rendering, aggregation, and collector implementation in Earth
- [Earth Interactable Usage](/home/ray/dev/linkong/planet/docs/technical/en/earth-interactable-usage.md): `Interactable` API, lifecycle, and integration examples
- [Earth Toolbar and Overlay Coordination](/home/ray/dev/linkong/planet/docs/technical/en/earth-toolbar-overlay-coordination.md): close matrix for toolbar buttons, search, settings, news, and layer overlays
- Incomplete roadmaps
- Future iteration plans
- Large-scale refactor proposals
## Frontend Implementation
Those belong in:
- [Admin Frontend Context](/home/ray/dev/linkong/planet/docs/technical/en/frontend-admin-frontend-context.md): console page structure, state boundaries, and lazy loading
- [Frontend Layout Guidelines](/home/ray/dev/linkong/planet/docs/technical/en/frontend-layout-guidelines.md): layout, tables, panels, and responsive constraints
- [Tactile UI Components](/home/ray/dev/linkong/planet/docs/technical/en/tactile-ui-components.md): button, switch, tooltip, scrollbar APIs, and theme tokens
- [Plans Index](/home/ray/dev/linkong/planet/docs/plans/README.md)
## Backend Implementation
- [Data Collectors](/home/ray/dev/linkong/planet/docs/technical/en/backend-collectors.md): collectors, task types, save layer, and status updates
- [System Service Control](/home/ray/dev/linkong/planet/docs/technical/en/backend-system-service-control.md): backend service control and system operation APIs
- [Datasource Collector Settings and Connectivity](/home/ray/dev/linkong/planet/docs/technical/en/datasource-collector-settings-connectivity.md): datasource catalog, collector settings, connectivity validation, and credentials
- [Datasource API Performance](/home/ray/dev/linkong/planet/docs/technical/en/backend-datasources-api-performance.md): DataSources list API performance and caching
- [Data Jobs and Outbox Architecture](/home/ray/dev/linkong/planet/docs/technical/en/data-job-earth-sync-architecture.md): PostgreSQL job queue, outbox, listener, and Kafka / Spark evolution boundaries
- [Shared Location Resolution Pipeline Development Guide](/home/ray/dev/linkong/planet/docs/technical/en/location-pipeline-development.md): location resolver / pipeline interfaces, registries, and extension points
- [News Live Streams Collector Format](/home/ray/dev/linkong/planet/docs/technical/en/earth-news-live-streams-collector-format.md): news, live stream, and media collection payload conventions
- [Docs Gatekeeper Development Guide](/home/ray/dev/linkong/planet/docs/technical/en/docs-gatekeeper-development.md): backend Docs catalog, Markdown content loading, and Gatekeeper permission groups
## Agents and Operations
- [AI Provider Guide](/home/ray/dev/linkong/planet/docs/technical/en/agents-aiprovider.md): model provider adapters, task prompts, and invocation boundaries
- [Planet Ops Runbook](/home/ray/dev/linkong/planet/docs/technical/en/ops-runbook.md): deployment, startup, troubleshooting, and sensitive operations
- [Docker + Compose + Buildx Upgrade](/home/ray/dev/linkong/planet/docs/technical/en/ops-docker-compose-buildx-upgrade.md): Docker toolchain upgrade steps
- [planet.sh Startup](/home/ray/dev/linkong/planet/docs/technical/en/ops-planet-sh-startup.md): startup script, health checks, and performance optimization
## Plans and History
Incomplete roadmaps, large refactor proposals, and future plans live in the repository path `docs/plans/README.md`. Completed, outdated, or replaced designs live in `docs/deprecated/README.md`.

View File

@@ -101,7 +101,7 @@ The AI settings page uses:
These endpoints require an authenticated user. The `secrets` endpoint is only used when the settings page reveals a key or token; hiding the field restores the masked preview.
Admin Next keeps the AI page aligned with the legacy information architecture:
Admin keeps the AI page aligned with the legacy information architecture:
- `Model Providers`
- Manages provider, wire adapter, default model, LLM API key, proxy URL, proxy token, model refresh, set-as-default, and lightweight connectivity testing.
@@ -272,7 +272,7 @@ Each provider has its own key slot. Resolution order is:
`.env` is only a fallback. After the settings page saves successfully, or after the connection test succeeds, PostgreSQL becomes the global default source.
Admin Next must compute key status per provider or tool:
Admin must compute key status per provider or tool:
- If the database has a key for the current provider/tool, show `configured`.
- If the database has no key but the fallback provider, model, or tool matches the current item, show the fallback masked preview.
@@ -283,7 +283,7 @@ Tool keys follow the same rule. WebSearch and OCR must match the current tool an
### Lightweight Connectivity Testing
The Admin Next plug button performs a lightweight connectivity check and does not save configuration. Common API-platform practice is two-tiered:
The Admin plug button performs a lightweight connectivity check and does not save configuration. Common API-platform practice is two-tiered:
- Check a provider catalog or low-cost endpoint to validate base URL, authentication, and model reachability.
- Send full model requests only when the user explicitly runs Playground or a business task.

View File

@@ -73,6 +73,8 @@ async def run(self, db):
**Core file**: `backend/app/services/collectors/base.py`
Manual trigger, data clearing, and cache clearing now enter the PostgreSQL data job queue. `collection_tasks` remains the task ledger. Collectors only own `fetch -> transform -> save`; the `data_jobs.py` worker claims `collect` / `clear_data` / `clear_cache` / `earth_refresh` jobs and writes progress back. Earth layer refresh relationships live in `earth_layer_adapters.py`; do not hand-code cache invalidation or WebSocket broadcasts inside individual collectors or buttons.
## III. Collector List
| Collector | Data type | Content | Frequency |
@@ -93,7 +95,7 @@ Earth boundaries are no longer data collectors. They are Earth static rendering
TOP500 and Epoch AI compute sources do not always provide usable coordinates. The unified Earth compute-center endpoint uses only valid source-provided coordinates or `compute_center_locations` dimension-table coordinates during the main map startup path; records without coordinates are returned as `unresolved` instead of being rendered from a local registry, country centroid, or guessed city. When users manually collect candidates, the backend queries ROR and Nominatim/OpenStreetMap from source fields; accepted candidates are saved into `compute_center_locations` and rendered from that table on the next layer refresh.
Admin Next collection management follows the business hierarchy instead of flattening every endpoint into one table:
Admin collection management follows the business hierarchy instead of flattening every endpoint into one table:
- `Collectors`: endpoint, authentication, headers, base parameters, enabled state, and credential guides.
- `Collection Schedule`: scheduler state and task controls.

View File

@@ -96,4 +96,4 @@ if (res.data.task_id) {
## Related Files
- [datasources.py](/home/ray/dev/linkong/planet/backend/app/api/v1/datasources.py): `_load_datasource_list_context`, `list_datasources`
- [DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/DataSources/DataSources.tsx): `BuiltInDataSource`, `triggerDatasource`
- [DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx): `BuiltInDataSource`, `triggerDatasource`

View File

@@ -0,0 +1,141 @@
# Data Jobs and Outbox Architecture
This document records the technical boundary for Planet v1 data jobs, database outbox, and Earth refresh. For each data product's business purpose and end-to-end flow, see [Business Architecture and Data Flows](/home/ray/dev/linkong/planet/docs/technical/en/platform-data-flows.md).
## Architecture Boundary
- PostgreSQL is the durable v1 job ledger and outbox. Kafka, Celery, and RQ are intentionally not part of v1.
- `collection_tasks` records collection, data clearing, cache clearing, and non-database Earth refresh jobs.
- `earth_data_change_events` records fact-table or derived-table changes and is the reliable source for Earth sync.
- `LISTEN/NOTIFY` is only the low-latency wakeup path; the listener still polls unconsumed outbox rows.
- Redis is mainly cache, auth helper, OTP / rate limit, temporary logs, and WebSocket support. It is not the durable queue.
## Database Change Sync
```mermaid
flowchart LR
Write["Fact or derived table write"] --> Trigger["PostgreSQL trigger"]
Trigger --> Outbox["earth_data_change_events"]
Trigger --> Notify["planet_earth_data_changes"]
Outbox --> Listener["earth_db_change_listener"]
Notify --> Listener
Listener --> Adapter["earth_layer_adapters"]
Adapter --> Cache["cache invalidation"]
Cache --> WS["earth_updates"]
```
1. Collection, clearing, location resolution, or projection jobs write fact or derived tables.
2. Statement triggers write outbox rows for `INSERT` / `UPDATE` / `DELETE`.
3. The listener wakes through notify or finds pending rows through polling.
4. The listener maps `table + source` to Earth layers, refresh strategy, and cache patterns through `earth_layer_adapters.py`.
5. The listener merges short-window same-layer events, invalidates cache, and broadcasts `earth_updates`.
6. The outbox row is marked consumed only after successful broadcast; failed rows stay retryable.
DB changes no longer create default `earth_refresh` jobs, so they are not blocked by long same-source collection or clearing jobs. `earth_refresh` remains for manual cache clearing and non-DB refresh hints.
## Data Job Queue
`collection_tasks` is the unified job ledger. Workers claim `queued` jobs with PostgreSQL `FOR UPDATE SKIP LOCKED`; write jobs for the same `source` run serially, while different sources may run in parallel.
| task_type | Purpose |
| --- | --- |
| `collect` | Run a built-in datasource collector |
| `clear_data` | Delete collected rows and declared derived rows for the source |
| `clear_cache` | Delete Earth / dashboard cache for the source |
| `earth_refresh` | Invalidate Earth layer cache and broadcast a refresh hint for non-DB changes |
API handlers only create jobs and return `task_id`. Execution, progress, cancellation, and terminal state are written back by workers and pushed to the frontend through the `datasource_tasks` channel.
Cancellation means “keep committed batches”: clicking stop marks the job as `cancelling` and cancels the in-memory coroutine. Already committed batches remain; unfinished batches follow the collector or cleanup rollback path.
## Earth Sync Event Model
The unified event model is `earth.layer.changed`:
```json
{
"event": "earth.layer.changed",
"action": "database_changed",
"source": "celestrak_tle",
"table": "collected_data",
"operation": "DELETE",
"layers": ["satellites"],
"refresh_strategy": "clear_then_reload",
"records_processed": 11125,
"occurred_at": "2026-05-25T10:20:30Z"
}
```
| strategy | Purpose |
| --- | --- |
| `clear_then_reload` | Clear local frontend layer objects first, then force a refetch. Prefer this for deletes. |
| `reload` | Keep old objects until fresh data returns. Use it for location, metadata, or non-destructive updates. |
| `delta` | Used only for `earth_interactables`; upsert or remove objects by id. |
APIs must return HTTP 200 with an empty collection for real zero-data states; 5xx is reserved for real endpoint failures. After a delete event, if refetch fails, the frontend should keep the cleared state and show a lightweight error instead of restoring stale objects.
## Layer Adapter Contract
`earth_layer_adapters.py` is the single registry for sources, derived tables, Earth layers, cache patterns, and refresh strategy. New layers should be added through an adapter entry, not through one-off button handlers, collector branches, or frontend special cases.
Each adapter must declare:
- Which source or table feeds which Earth layer.
- Which Earth cache key patterns must be invalidated.
- Which owned derived tables must be removed during `clear_data`.
- The default refresh strategy for that layer.
When a source is cleared, the `clear_data` job first deletes `collected_data.source = <source>`, then deletes adapter-owned derived rows. Direct derived-table edits also trigger the outbox, so background jobs, admin APIs, and SQL repair scripts reach Earth as long as they mutate fact or derived tables.
## Operations and Troubleshooting
Check whether outbox rows are piling up:
```sql
SELECT id, table_name, operation, source, occurred_at
FROM earth_data_change_events
WHERE consumed_at IS NULL
ORDER BY id
LIMIT 20;
```
Check that triggers exist:
```sql
SELECT tgname, tgrelid::regclass
FROM pg_trigger
WHERE tgname LIKE 'tr_planet_%_changed_%'
ORDER BY 2, 1;
```
Useful log events:
- `earth.db_changes.connected`: the listener connected to PostgreSQL and started listening.
- `earth.db_changes.outbox_polled`: polling found unconsumed outbox rows.
- `earth.db_changes.broadcasted`: an Earth refresh broadcast was produced.
- `data_job.started` / `data_job.completed`: job execution state.
If Earth does not update, check in order: fact table changed, outbox was consumed, adapter covers the `source/table`, the listener is online, frontend WebSocket is connected, and the visualization API returns HTTP 200 with either an empty collection or fresh data.
## Kafka-ready Boundaries
Business code avoids depending on a concrete queue implementation by preserving these boundaries:
- `JobQueue`: submit, claim, cancel, and complete data jobs.
- `DataChangeBus`: publish database fact changes.
- `EarthLayerAdapterRegistry`: declare source, layer, cache, and derived-data relationships.
Kafka becomes appropriate when:
- Several independent services must consume the same data-change stream.
- AIS, BGP, or sensor streams become sustained high-throughput inputs.
- Consumer groups, replay, and service decoupling are required.
Spark becomes appropriate when:
- Historical data reaches tens or hundreds of millions of rows and PostgreSQL aggregation becomes expensive.
- Cross-source, long-window, spatiotemporal analysis is needed.
- Raw data lands in Parquet / Iceberg / Delta and the system starts producing offline derived data products.
For second-level continuous stream processing, evaluate Flink first. Spark is a better fit for batch or micro-batch analytics.

View File

@@ -32,8 +32,8 @@ If endpoint, headers, base configuration, or credential fingerprint changes afte
Files:
- [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/pages/PlainResourcePages.tsx)
- [AdminNextRoutes.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/AdminNextRoutes.tsx)
- [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
- [AdminRoutes.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/AdminRoutes.tsx)
Current behavior:
@@ -57,7 +57,7 @@ Current behavior:
File:
- [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/pages/PlainResourcePages.tsx)
- [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
Current behavior:

View File

@@ -83,7 +83,7 @@ The user API:
- Validates group names on update: only `docs_user`, `docs_developer`, and `docs_admin` are accepted.
- Allows only `super_admin` to modify Gatekeeper groups.
Frontend [Users.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Users/Users.tsx) displays group tags and provides a multi-select in the edit form. Non-`super_admin` users see the field disabled, and submission removes `gatekeeper_groups` before sending.
Frontend [Users.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/Users.tsx) displays group tags and provides a multi-select in the edit form. Non-`super_admin` users see the field disabled, and submission removes `gatekeeper_groups` before sending.
## Frontend Docs Loading

View File

@@ -188,7 +188,7 @@ Current reality:
- that is expected, because incidents are aggregated and de-noised
- but incident-first rendering makes the Earth view look too quiet unless there is another always-available activity layer
Implementation detail for the recommended `activity layer` is expanded in the [BGP Region Aggregation Plan](/home/ray/dev/linkong/planet/docs/plans/earth-bgp-region-aggregation-plan.md).
Implementation detail for the recommended `activity layer` is kept in the repository path `docs/plans/earth-bgp-region-aggregation-plan.md`.
So the immediate next milestone is:
@@ -259,7 +259,7 @@ Reference inspiration:
Relevant page:
- `frontend/src/pages/BGP/BGP.tsx`
- `frontend/src/admin/pages/PlainResourcePages.tsx`
Current BGP console page has three levels:
@@ -321,7 +321,7 @@ Backend:
Frontend:
- `frontend/src/pages/BGP/BGP.tsx`
- `frontend/src/admin/pages/PlainResourcePages.tsx`
- `frontend/public/earth/js/bgp.js`
- `frontend/public/earth/js/main.js`
- `frontend/public/earth/js/info-card.js`

View File

@@ -4,7 +4,7 @@ This document describes the current real structure of the Earth display frontend
Related references:
- [Project Rules](/home/ray/dev/linkong/planet/rules.md)
- Repository root `rules.md`
- [Frontend Layout Guidelines](/home/ray/dev/linkong/planet/docs/technical/en/frontend-layout-guidelines.md)
## Current Goal
@@ -56,6 +56,8 @@ Responsibilities:
- Layer module integration
- Earth-level state synchronization
Earth treats `/ws` `earth_updates` as refresh hints only; real data is fetched again from `/api/v1/visualization/...`. Backend database-driven refresh now has the listener clear cache and broadcast directly instead of going through the default `earth_refresh` job queue. After `database_changed`, the frontend applies the per-layer `clear_then_reload`, `reload`, or `delta` strategy. `clear_then_reload` must clear Three.js objects before a no-store refetch, and summary is only a consistency check, not a reason to skip a layer reload when the count is `0`. See [Data Jobs and Outbox Architecture](/home/ray/dev/linkong/planet/docs/technical/en/data-job-earth-sync-architecture.md) for the technical pipeline and [Business Architecture and Data Flows](/home/ray/dev/linkong/planet/docs/technical/en/platform-data-flows.md) for business data flows.
### 3. Earth Control Layer
- [controls.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/controls.js)
@@ -151,11 +153,11 @@ Each module is responsible for its own:
`brand.js` manages Earth HUD brand resources. Static assets provide the default brand; runtime overrides come from `/api/v1/earth/brand`, and uploaded images are served from `/earth-brand-assets/...`. The frontend must treat logo/title images and text fallback separately: if an image fails, show the text title; if text fields are empty, rely on backend defaults so the HUD brand area never renders blank. The console Earth Content page owns saving and resetting brand configuration; the Earth frontend only consumes it.
`about.js` manages the About card inside Earth settings. Frontend defaults remain as a fallback, while runtime content is loaded from `/api/v1/earth/about`. If the request fails or fields are missing, the renderer must fall back per field so the settings page never renders an empty card. Admin Next exposes an Earth Content `About` tab; saving uses `PUT /api/v1/earth/about`, and restoring defaults uses `DELETE /api/v1/earth/about`.
`about.js` manages the About card inside Earth settings. Frontend defaults remain as a fallback, while runtime content is loaded from `/api/v1/earth/about`. If the request fails or fields are missing, the renderer must fall back per field so the settings page never renders an empty card. Admin exposes an Earth Content `About` tab; saving uses `PUT /api/v1/earth/about`, and restoring defaults uses `DELETE /api/v1/earth/about`.
`oobe.js` manages the first-run Earth initialization guide. OOBE visibility must be driven by `/api/v1/earth/oobe-status` and its `ready` field, not by `localStorage`. `localStorage` may only store a short-lived "skip on this browser" flag; if the backend reports `ready: true`, logout, cleared browser storage, or a different browser must not show OOBE again. Desktop uses a dark starfield scrim and glass startup panel, while mobile uses a bottom sheet and respects `prefers-reduced-motion`.
The Admin Next Earth Content page must preserve runtime semantics:
The Admin Earth Content page must preserve runtime semantics:
- `Brand`: brand preview should use the same dark starfield background, size, spacing, logo/title rendering, and text fallback as the Earth HUD top-left brand block, not a generic form preview.
- `About`: configures the About card in Earth settings, including logo, kicker, title, version, description, and metadata items. Earth runtime reads `/earth/about` and falls back to defaults on failure.

View File

@@ -17,26 +17,15 @@ Related context:
## Current Local Categories
Current CelesTrak satellite groups in [backend/app/services/collectors/celestrak.py](/home/ray/dev/linkong/planet/backend/app/services/collectors/celestrak.py) include:
The CelesTrak collector now downloads the complete active satellite catalog from `GROUP=active&FORMAT=json` instead of fetching several smaller groups and merging them. This prevents one failed CelesTrak group request from being saved as a successful but incomplete batch. The collector only proceeds when the downloaded JSON is a parseable array and records include `NORAD_CAT_ID`; network, resume, or parsing failures are retried, and final failure preserves the previous current dataset.
- `starlink`
- `gps-ops`
- `galileo`
- `glonass`
- `beidou`
- `leo`
- `geo`
- `iridium-next`
The collector still provides `metadata.constellation_group` to the frontend, but the value now comes from executable inference:
Non-Starlink categories:
- `OBJECT_NAME` starting with `STARLINK` is marked as `starlink`
- `OBJECT_NAME` starting with `IRIDIUM` is marked as `iridium-next`
- Other active satellites are not forced into the old CelesTrak small-group labels, because a broad source group is not an exact constellation
- `gps-ops`
- `galileo`
- `glonass`
- `beidou`
- `leo`
- `geo`
- `iridium-next`
The product policy therefore still discusses GNSS/RNSS, GEO, generic LEO, and Iridium NEXT semantics, but code should no longer assume that saved CelesTrak rows carry the old `gps-ops`, `galileo`, `glonass`, `beidou`, `leo`, or `geo` group labels.
## Research Conclusions
@@ -136,7 +125,8 @@ This implementation only does the minimum executable version and does not change
1. Backend passes constellation group and footprint policy hint to the frontend
- CelesTrak collector stores `GROUP` in `metadata.constellation_group`
- CelesTrak collector stores the source query in `metadata.celestrak_query_group = active`
- `metadata.constellation_group` only stores inferred business constellations such as `starlink` and `iridium-next`
- Visualization API outputs:
- `properties.constellation_group`
- `properties.footprint_policy`

View File

@@ -4,7 +4,7 @@ This document describes the current real structure of the console frontend. The
Related references:
- [Project Rules](/home/ray/dev/linkong/planet/rules.md)
- Repository root `rules.md`
- [Frontend Layout Guidelines](/home/ray/dev/linkong/planet/docs/technical/en/frontend-layout-guidelines.md)
## Current Goal
@@ -22,7 +22,7 @@ Main entry point:
- [App.tsx](/home/ray/dev/linkong/planet/frontend/src/App.tsx)
Admin Next now owns the official admin routes:
Admin now owns the official admin routes:
- `/admin`
- `/users`
@@ -37,23 +37,7 @@ Admin Next now owns the official admin routes:
- `/collection-management`
- `/settings`
These routes render [AdminNextRoutes.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/AdminNextRoutes.tsx). Page metadata and menu entries come from [manifest.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/routes/manifest.tsx). `/admin-next/*` remains only as a compatibility entry and redirects to the official route; it is no longer a parallel primary entry.
The old AntD console remains available under `/legacy/admin/*` for comparison and rollback:
- `/legacy/admin`
- `/legacy/admin/datasources`
- `/legacy/admin/data`
- `/legacy/admin/collection-management`
- `/legacy/admin/earth-content`
- `/legacy/admin/ai`
- `/legacy/admin/logs`
- `/legacy/admin/settings`
- `/legacy/admin/users`
- `/legacy/admin/bgp`
- `/legacy/admin/alerts/*`
Legacy pages, `AppLayout`, `antd`, and `@ant-design/icons` stay in place during the legacy validation window. Do not remove them before Admin Next parity is accepted.
These routes render [AdminRoutes.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/AdminRoutes.tsx). Page metadata and menu entries come from [manifest.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/routes/manifest.tsx). Admin is the only console entry point; there is no parallel console or rollback route.
`/earth` is a standalone display page and is not part of the console shell.
@@ -61,7 +45,7 @@ Legacy pages, `AppLayout`, `antd`, and `@ant-design/icons` stay in place during
The official admin shell is at:
- [AdminNextLayout.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/components/layout/AdminNextLayout.tsx)
- [AdminLayout.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/components/layout/AdminLayout.tsx)
Responsibilities:
@@ -69,38 +53,13 @@ Responsibilities:
- Current account, version, logout, and theme switching
- Top search, breadcrumbs, and page shortcuts
- Single-screen content-area height closure
- Coordination for Admin Next internal scrolling, tables, detail panels, and mobile detail views
- Coordination for Admin internal scrolling, tables, detail panels, and mobile detail views
The old AntD legacy shell remains at:
Future official admin pages should adapt to `AdminLayout` and Admin page patterns; do not reintroduce a parallel admin shell.
- [AppLayout.tsx](/home/ray/dev/linkong/planet/frontend/src/components/AppLayout/AppLayout.tsx)
## Admin Section Loading
Legacy responsibilities:
- Left-side navigation
- Collapse and expand
- Current account / version information
- Content area height closure
- Site-wide unified sidebar scrollbar
Current structure:
```tsx
<Layout className="dashboard-layout">
<Sider className="dashboard-sider">...</Sider>
<Layout>
<Content className="dashboard-content">
<div className="dashboard-content-inner">{children}</div>
</Content>
</Layout>
</Layout>
```
Future official admin pages should adapt to `AdminNextLayout` and Admin Next page patterns rather than adding new capability to the old `AppLayout`. Only `/legacy/admin/*` maintenance should change the old shell.
## Admin Next Section Loading
Multi-tab pages are currently coordinated by [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/pages/PlainResourcePages.tsx), which hosts the current management and information workbench patterns. Section loading follows these rules:
Multi-tab pages are currently coordinated by [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx), which hosts the current management and information workbench patterns. Section loading follows these rules:
- Initial page load requests only the active tab; it does not prefetch every tab endpoint.
- Switching tabs lazily loads that tab. Loaded tabs stay cached in local `states`, so returning to a tab reuses the previous data.
@@ -112,20 +71,22 @@ This keeps Earth, AI, collection management, and other multi-section pages from
## Datasource Collection Queue
The Admin Next datasource page routes single-source trigger, table-selected trigger, and trigger-all into a browser-download-list style collection queue:
The Admin datasource page routes single-source trigger, table-selected trigger, and trigger-all into a browser-download-list style collection queue:
- Queue state is managed by [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/pages/PlainResourcePages.tsx). It is a current-session visibility layer and does not fake task history in `localStorage`.
- Queue state is managed by [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx). It is a current-session visibility layer and does not fake task history in `localStorage`.
- Progress first consumes the `/ws` `datasource_tasks` channel. If the socket is unavailable or stale, the page polls `/api/v1/datasources/{id}/task-status`.
- Trigger responses immediately insert `triggered`, `skipped`, and `failed` items. After a refresh, the queue restores only real backend rows that are still `running`, `pending`, or `queued`.
- The `Built-in Sources` section uses the table selection column for selected-source triggering. With no rows selected, the primary button is `Trigger All`; after selection, the same button becomes `Trigger Selected N`, replacing the old manual-ID batch button.
- The expanded queue no longer lives in the page content flow, so trigger-all cannot squeeze the table and detail panel. The top-right actions area uses the existing `Button` styling; the empty state shows a `ListChecks` icon, and active queues show only a pure circular total-progress indicator. Clicking it opens a floating panel grouped by running, failed, completed, and skipped.
- Queue rows can jump to the datasource detail panel, and failed rows can retry. The detail panel's task summary only reports the selected source's latest task; it does not save configuration.
- While a single-source collection is running, the action button becomes `Stop Collection`; unfinished queue rows expose a cancel action on the right. Cancellation calls `/api/v1/datasources/{source_id}/tasks/{task_id}/cancel`; the backend keeps committed batches and rolls back unfinished work.
- Clearing database data and clearing display cache enter the same queue. The frontend shows task state and does not assume the API completed synchronously.
This queue is a user-perception layer. Backend task status remains the only source of truth for running, completion, failure, and skipped decisions.
## Admin Next Theme Slider
## Admin Theme Slider
The Admin Next sidebar theme switcher still reuses shared [SegmentedControl.tsx](/home/ray/dev/linkong/planet/frontend/src/components/SegmentedControl/SegmentedControl.tsx), while [styles.css](/home/ray/dev/linkong/planet/frontend/src/admin-next/styles.css) overrides the segment variables by `data-theme`:
The Admin sidebar theme switcher still reuses shared [SegmentedControl.tsx](/home/ray/dev/linkong/planet/frontend/src/components/SegmentedControl/SegmentedControl.tsx), while [styles.css](/home/ray/dev/linkong/planet/frontend/src/admin/styles.css) overrides the segment variables by `data-theme`:
- Light mode uses `--d-segment-bg: #eef3f9`, a white slider, and a light external shadow.
- Dark mode uses the same dark base, `#202938` slider, and dark external shadow semantics as Docs.
@@ -164,7 +125,7 @@ Purpose:
Current usage:
- Admin Next data sources, collected data, collection management, logs, alerts, and BGP pages
- Admin data sources, collected data, collection management, logs, alerts, and BGP pages
- Old AntD legacy pages continue using shared scrolling behavior through compatibility wrappers
### 3. `TableScrollRegion`
@@ -188,7 +149,7 @@ Files:
Purpose:
- Admin Next global tool buttons and detail-panel toolbars
- Admin global tool buttons and detail-panel toolbars
- Icon-only ordinary actions with tooltips
- Strong-intent actions such as save, create, confirm, delete, and stop
- Compact switches aligned with the Docs theme slider
@@ -246,39 +207,19 @@ Current constraints:
- Internal document links should be converted to `/docs/:slug` through `transformLink`
- Heading anchors are injected through `getHeadingId`, keeping route state outside the renderer
### 7. `ConnectionTestInput`
### 7. Admin UI Primitives
File:
Files:
- [ConnectionTestInput.tsx](/home/ray/dev/linkong/planet/frontend/src/components/ConnectionTestInput/ConnectionTestInput.tsx)
- [button.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/components/ui/button.tsx)
- [dialog.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/components/ui/dialog.tsx)
- [switch.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/components/ui/switch.tsx)
Purpose:
Use:
- Console form fields that combine an endpoint/Base URL value with a connection check
- Connection-test entry points for AI Provider and WebSearch
- Future collector configuration fields should reuse it when the test action belongs inside the input
Current constraints:
- The input suffix shows a single plug/connector icon, not an adjacent text button
- Disabled integrations must grey out both the input and its connection-test action
- The component only combines the input and action; callers still own form state, loading, disabled state, and the request itself
### 8. `TableActions`
File:
- [TableActions.tsx](/home/ray/dev/linkong/planet/frontend/src/components/TableActions/TableActions.tsx)
Purpose:
- Shared action entry for table operation columns
- Shows inline actions when expanded
- Uses a more-actions dropdown when collapsed
Companion export:
- `actionCellProps`: for action-column `onCell`, preventing action buttons from being ellipsized or wrapped
- Global tool buttons, detail actions, confirmation dialogs, and binary settings.
- Aligned with Tactile UI tokens so Admin controls keep consistent size, hover, disabled, and dark-mode behavior.
- Row actions should prefer icon buttons plus tooltip/title; do not reintroduce a separate action-menu component.
## Current State Sources
@@ -301,7 +242,7 @@ Responsibilities:
File:
- [AISettings.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/AISettings/AISettings.tsx)
- [AISettings.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
Responsibilities:
@@ -337,7 +278,7 @@ Constraints:
Example:
- [Dashboard.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Dashboard/Dashboard.tsx)
- [Dashboard.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/Dashboard.tsx)
Priority goals:
@@ -349,10 +290,10 @@ Priority goals:
Examples:
- [DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/DataSources/DataSources.tsx)
- [DataList.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/DataList/DataList.tsx)
- [Users.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Users/Users.tsx)
- [Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Settings/Settings.tsx)
- [DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
- [DataList.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/DataList.tsx)
- [Users.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/Users.tsx)
- [Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
Constraints:
@@ -362,7 +303,7 @@ Constraints:
### Datasource Directory Page
[DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/DataSources/DataSources.tsx) is the datasource directory and collection operation page. It should not grow back into a configuration editor.
[DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx) is the datasource directory and collection operation page. It should not grow back into a configuration editor.
Current page boundary:
@@ -376,7 +317,9 @@ Keep this boundary: do not put custom datasource editing, built-in endpoint over
### Collectors Page
[Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Settings/Settings.tsx) has three route modes: `/settings` for System Settings, `/earth-content` for Earth Content, and `/collection-management` for Collection Management. The `collector_credentials` tab is shown as `Collectors` under `/collection-management`.
[Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx) has three route modes: `/settings` for System Settings, `/earth-content` for Earth Content, and `/collection-management` for Collection Management. The `collector_credentials` tab is shown as `Collectors` under `/collection-management`.
The `System Display` section under `/settings` includes the `Demo Mode` switch. When enabled, Earth OOBE ignores existing current collected data and the local `browse first` temporary skip state, then opens the initialization guide directly. This switch is only for demos and acceptance checks; it does not change datasources, collection queues, or Earth content resources.
Current boundary:
@@ -388,7 +331,7 @@ Current boundary:
### Earth Content Page
`/earth-content` reuses the same single-screen tab container from [Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Settings/Settings.tsx), but its ownership is separate from System Settings:
`/earth-content` reuses the same single-screen tab container from [Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx), but its ownership is separate from System Settings:
- `TV Livestream` owns the Earth media-panel source configuration.
- `Boundary Precision` owns the Earth static boundary asset state: provider, low-precision fallback, high-precision manifest/PMTiles, source JSON, and build action.
@@ -400,8 +343,8 @@ Do not add Earth experience resources or collection-lifecycle tabs back into `/s
Examples:
- [BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/BGP/BGP.tsx)
- [Playground.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Playground/Playground.tsx)
- [BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
- [Playground.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
Constraints:

View File

@@ -8,7 +8,8 @@ Admin pages in this project default to a "single-screen workspace" layout standa
Current recommended reference implementations:
- [frontend/src/pages/BGP/BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/BGP/BGP.tsx)
- [frontend/src/admin/pages/PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
- [frontend/src/admin/pages/DataList.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/DataList.tsx)
- [frontend/src/index.css](/home/ray/dev/linkong/planet/frontend/src/index.css)
## Core Principles
@@ -23,15 +24,15 @@ Admin pages default to:
Recommended structure:
```tsx
<AppLayout>
<AdminLayout>
<div className="page-shell">
<div className="page-shell__header">...</div>
<div className="page-shell__body">...</div>
</div>
</AppLayout>
</AdminLayout>
```
Total page height should be bounded within the `AppLayout` content area, not allowed to grow naturally downward without limit.
Total page height should be bounded within the `AdminLayout` content area, not allowed to grow naturally downward without limit.
### 2. Scrolling Should Happen Inside Modules

View File

@@ -2,7 +2,7 @@
`backend/app/services/location/` is the shared abstraction for any "given a record, decide its lat/lon" workflow. Compute centers, BGP collectors, and BGP events now run on this pipeline. Future entities such as satellite ground stations, user-claimed points, and IXP facilities should plug in here instead of creating another geocoding path.
For the user workflow, see [Earth Location Candidate Collection User Guide](/home/ray/dev/linkong/planet/docs/technical/en/location-pipeline-user.md).
For the user workflow, see the Earth coordinate-candidate section in [Planet Manual](/home/ray/dev/linkong/planet/docs/technical/en/manual.md).
## Design Goals

View File

@@ -280,7 +280,17 @@ Search finds cables, landing points, satellites, compute centers, BGP events, BG
Compute center and BGP observer detail cards support automatic coordinate-candidate collection. Click the object then use "Collect Coordinate Candidates" or "Re-collect Coordinates". The backend assembles candidates from source coordinates, public-org registry APIs, and online geocoders. When regular sources have no candidate, the current default AI Provider runs one LLM factcheck fallback. BGP observers' stored coordinates only fill query context; they are not returned as candidates.
Candidates preview on Earth directly. Saving a compute-center candidate writes to the `compute_center_locations` dimension table and refreshes the layer immediately. The notification badge at the top-left of the compute-center layer shows the unresolved count; clicking it opens the queue, supports single collection, or "Adopt All" to save the top-confidence candidates from top to bottom. Records without candidates stay in the queue rather than being faked to country centroids. See [Earth Location Candidate Collection User Guide](/home/ray/dev/linkong/planet/docs/technical/en/location-pipeline-user.md).
Candidates preview on Earth directly. Saving a compute-center candidate writes to the `compute_center_locations` dimension table and refreshes the layer immediately. The notification badge at the top-left of the compute-center layer shows the unresolved count; clicking it opens the queue, supports single collection, or "Adopt All" to save the top-confidence candidates from top to bottom. Records without candidates stay in the queue rather than being faked to country centroids.
Recommended single-object flow:
1. Open a compute center or BGP observer detail card.
2. Click "Collect Coordinate Candidates".
3. Wait for candidates; entries that depend on WebSearch / AI factcheck show collection state.
4. Preview candidate positions on Earth.
5. Save the candidate when it is credible; closing the card does not lose the current task state.
Adopt All is for batch processing the compute-center unresolved queue. It starts from the top and adopts the highest-confidence candidate. Records without factual support remain in the queue. When WebSearch is disabled, single locate and Adopt All are disabled because location validation depends on factual lookup.
### Settings
@@ -351,7 +361,7 @@ Mobile uses a drawer layout: layer control moves into a drawer; search/settings/
Docs at `http://localhost:3000/docs` are served by the backend with access control, not bundled into the frontend build.
Anonymous visitors see only `public` docs: README, Quickstart, Manual, FAQ, Earth Location Candidate Collection User Guide. Authenticated users with Gatekeeper groups see more:
Anonymous visitors see only `public` docs: README, Quickstart, Manual, and FAQ. Authenticated users with Gatekeeper groups see more:
- `docs_user`: end-user operational docs
- `docs_developer`: Earth, frontend, backend, collectors, AI Provider development docs
@@ -365,5 +375,4 @@ Docs supports: category navigation, Markdown rendering, tables and code blocks,
- [Quickstart](/home/ray/dev/linkong/planet/docs/technical/en/quickstart.md)
- [FAQ](/home/ray/dev/linkong/planet/docs/technical/en/faq.md)
- [Earth Location Candidate Collection User Guide](/home/ray/dev/linkong/planet/docs/technical/en/location-pipeline-user.md)
- [Planet Ops Runbook](/home/ray/dev/linkong/planet/docs/technical/en/ops-runbook.md)

View File

@@ -15,7 +15,7 @@ This document standardizes terms used across the Planet console, Earth, backend
| English / Key | Chinese Display Name | Usage |
| --- | --- | --- |
| Planet | Planet | Product name |
| Admin Next | 控制台 | New admin console |
| Admin | 控制台 | Admin console context |
| Earth | Earth | Visualization product name |
| datasource | 数据源 | APIs, lists, filters |
| collector | 采集器 | Collection jobs and credential configuration |

View File

@@ -136,6 +136,20 @@ Useful for:
- Demoing Earth from a phone or tablet
- Other LAN machines reaching the same dev instance
On Windows, the repository-root `planet.cmd` can be used as a one-click entrypoint. It requests Administrator privileges, enters the `Ubuntu` WSL distribution at `/home/linkong/planet`, runs `./planet.sh restart --allow-lan`, opens `http://localhost:3000/earth` after a successful restart, and leaves the terminal inside a WSL shell for log inspection. If the local WSL distribution name or checkout path differs, adjust the `wsl.exe -d ... --cd ...` arguments in `planet.cmd` first.
On a new Windows machine, check the WSL generation first:
```powershell
wsl -l -v
```
Planet development should use WSL2. WSL1 has different networking, filesystem, and process behavior, and can surface as Bun package-manager commands returning only `An unknown error occurred (Unexpected)`, unstable port release, or LAN behavior that does not match the script's assumptions. Convert the distribution if it still runs as WSL1:
```powershell
wsl --set-version Ubuntu 2
```
`--allow-lan` directly exposes the frontend, backend, and AI Provider from the development machine: frontend `3000`, backend `8000`, and AI Provider `8010`. Before startup, the script checks all three ports. If WSL/Linux cannot release a port and a Windows-side listener or stale `portproxy` rule owns it, the script requests Administrator PowerShell cleanup. When Planet runs in WSL, Windows can usually reach it through `localhost`; other LAN machines reaching the Windows LAN IP still need Windows Firewall allow rules.
Diagnose in this order:
@@ -200,13 +214,32 @@ The AI Provider image only rebuilds when code, Dockerfile, Compose config, or Py
./planet.sh restart -a
```
Rebuild detection is based on a content fingerprint rather than only file mtimes. `planet.sh` hashes the `aiprovider/` files, `aiprovider/Dockerfile`, `pyproject.toml`, `uv.lock`, `PYTHON_IMAGE`, `UV_IMAGE`, and the dependency fingerprint into `AI_PROVIDER_BUILD_FINGERPRINT`; Docker writes it into the image label `planet.aiprovider.build-fingerprint`. If the existing `planet-aiprovider:latest` image has a matching label, the script skips rebuild and refreshes the local stamp. Older images without the label fall back to the state/cache stamp.
Docker builds use `uv sync --frozen`. To make container builds reuse the host uv mirror configuration, the script resolves the first config file in this order and mounts it into the build as a BuildKit secret at `/root/.config/uv/uv.toml`:
1. The current `UV_CONFIG_FILE`
2. Repository-root `uv.toml`
3. `${XDG_CONFIG_HOME:-~/.config}/uv/uv.toml`
4. `~/.uv/uv.toml`
If none exists, the script creates an empty state file for the secret so Compose does not fail on a missing file. Before Docker build it unsets `UV_DEFAULT_INDEX`, `UV_INDEX_URL`, and `UV_EXTRA_INDEX_URL`, keeping the build tied to the explicit `UV_CONFIG_FILE`. For a temporary Tsinghua mirror, place this in repository-root `uv.toml`:
```toml
[[index]]
name = "tsinghua"
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/"
default = true
```
Diagnose slow builds:
| Symptom | Common cause | Fix |
| --- | --- | --- |
| Large `transferring context` | build context includes unrelated frontend / data files | `.dockerignore` ships only required files |
| `uv sync` is slow | first build or cold cache | wait for the first build; later runs reuse BuildKit cache |
| `uv sync --frozen` is slow | first build, cold cache, or missing uv mirror config | wait for the first build; later runs reuse BuildKit cache; configure `uv.toml` when needed |
| Old keys still in effect after edit | container not restarted | `./planet.sh restart -a` |
| Code changed but the image did not rebuild | fingerprint still matches the image label | Confirm the change is under `aiprovider/`, Dockerfile, or Python dependency inputs; delete `planet-aiprovider:latest` and retry if needed |
## SMTP Email (Required for Public Registration)
@@ -233,6 +266,15 @@ One-time codes are stored in Redis under `otp:{purpose}:{email}` with a 600-seco
## Development Command Conventions
Backend setup and script initialization use the lockfile:
```bash
uv python install 3.14
uv sync --frozen --group dev
```
`--frozen` rejects implicit `uv.lock` rewrites, which is the desired behavior on new machines, CI, and Docker builds. Dependency upgrades should explicitly update `pyproject.toml` / `uv.lock` on a development machine and commit the lockfile.
Frontend must use Bun:
```bash

View File

@@ -0,0 +1,160 @@
# Business Architecture and Data Flows
This document is the business entry point for Planet data products. It explains why each Earth data type exists, where it is collected from, which fact or derived tables it uses, and how cache invalidation plus WebSocket hints reach Earth. Frontend, backend, and Earth docs should focus on implementation details; start here when you need the cross-system data flow.
## Overview
Planet data moves through three stages:
1. **Collect and normalize**: built-in collectors, admin actions, or the location pipeline write PostgreSQL. Generic raw output lands in `collected_data`; layer-ready projections land in derived tables.
2. **Project and broadcast**: database triggers write fact changes to the `earth_data_change_events` outbox and wake the backend listener with `LISTEN/NOTIFY`. The listener maps the change through layer adapters, invalidates cache, and broadcasts `earth_updates`.
3. **Reload and render in Earth**: Earth receives layer-level refresh hints, applies `clear_then_reload`, `reload`, or `delta`, then refetches `/api/v1/visualization/...`.
```mermaid
flowchart LR
Source["External source / admin action"] --> Collector["Collector or data job"]
Collector --> Facts["collected_data"]
Collector --> Derived["Derived tables"]
Facts --> Outbox["earth_data_change_events"]
Derived --> Outbox
Outbox --> Listener["DB change listener"]
Listener --> Cache["Earth cache invalidation"]
Listener --> WS["earth_updates"]
WS --> Earth["Earth layer reload"]
Earth --> API["Visualization APIs"]
```
`LISTEN/NOTIFY` is only the low-latency wakeup path. The reliable source is the outbox. A real zero-data state is valid and APIs should return HTTP 200 with an empty collection; only actual endpoint failures should return 5xx.
## Data Products
```mermaid
flowchart TB
Satellites["Satellite TLE"] --> SatelliteLayer["satellites layer"]
Cables["Cables + landing points"] --> CableLayer["cables layer"]
Compute["TOP500 / AI GPU / HF"] --> ComputeLocations["compute_center_locations"]
ComputeLocations --> ComputeLayer["computeCenters layer"]
BgpRaw["RIS Live / BGPStream / Prefix"] --> BgpDerived["bgp_observations / anomalies / incidents"]
BgpDerived --> BgpLayer["bgp layer"]
VesselRaw["AIS / BarentsWatch"] --> VesselDerived["vessel_static / vessel_position"]
VesselDerived --> VesselLayer["vessels layer"]
Interactables["earth_interactables"] --> InteractableLayer["interactables layer"]
NewsRaw["RSS / Live / News"] --> NewsItems["earth_news_items"]
NewsItems --> NewsLayer["news / media layer"]
```
| Data product | Business use | Fact sources | Derived / dimension tables | Earth layer | Strategy |
| --- | --- | --- | --- | --- | --- |
| Satellites | In-orbit objects, tracks, coverage, and cruise targets | `celestrak_tle`, `spacetrack_tle` | No long-lived projection; APIs convert TLE on demand | `satellites` | `clear_then_reload` |
| Cables and landing points | Submarine connectivity, landing cities, cable detail, and search | `arcgis_cables`, `arcgis_landing_points`, TeleGeography / FAO landing sources | Cable relation and landing aggregation data | `cables` | `clear_then_reload` |
| Compute centers | TOP500, AI GPU, model platform facilities, and location-completion state | `top500`, `epoch_ai_gpu`, HuggingFace sources | `compute_center_locations` | `computeCenters` | `reload` |
| BGP context | Collectors, anomalies, incidents, route events, and regional context | `ris_live_bgp`, `bgpstream_bgp`, prefix geography sources | `bgp_observations`, `bgp_anomalies`, `bgp_incidents`, `bgp_collector_locations` | `bgp` | `clear_then_reload` |
| Vessels | AIS vessels, positions, tracks, legend, and source health | AIS sources, `barentswatch_vessels` | `vessel_static`, `vessel_position`, `ais_raw_observations`, `ais_source_health` | `vessels` | `clear_then_reload` |
| Interactables | Generic surface icons, manual objects, and future small layers | `earth_interactables` | None | `interactables` | `delta` |
| News and media | Earth news, live streams, cruise summaries, and situation content | news sources | `earth_news_items` | `news` / `media` | `reload` |
## Satellites
Satellite data powers online satellite markers, tracks, footprint policy, and cruise lists. CelesTrak or Space-Track collectors fetch TLE and write `collected_data`. The visualization API converts TLE into current positions and trails on request.
- **Collection entry**: CelesTrak TLE, Space-Track TLE.
- **Fact table**: `collected_data.source IN ('celestrak_tle', 'spacetrack_tle')`.
- **API**: satellite visualization API reads TLE and builds the Earth payload.
- **Delete semantics**: deleting the source broadcasts `satellites` with `clear_then_reload`; the frontend clears satellite markers and trails before refetching. With no TLE, the API returns an empty list.
- **Common failure**: summary is zero but Earth still shows satellites. Usually WS did not fire, the adapter did not cover the source, or the frontend did not clear existing Three.js objects.
## Cables and Landing Points
Cables and landing points show global network connectivity, landing cities, cable details, and search targets. Cable lines and landing points are one business layer; deleting either side must refresh `cables`.
- **Collection entry**: ArcGIS cables, ArcGIS landing points, and TeleGeography / FAO landing related sources.
- **Fact table**: cable and landing point sources in `collected_data`.
- **Derived data**: cable relation tables, landing point aggregation, interface cache.
- **API**: cable visualization API returns cables, landing points, and relation data.
- **Delete semantics**: deleting cable or landing source clears owned projections and broadcasts `cables` with `clear_then_reload`. Empty data returns HTTP 200, not 404.
- **Common failure**: cables disappear for a second and return. Usually a collection replacement or cache refresh window reuses old cache; check duplicate broadcasts and cache patterns.
## Compute Centers
Compute centers represent supercomputers, AI GPU sites, model-platform facilities, and unresolved-location state. Raw sources often only provide organization, country, site, or fuzzy location, so Earth rendering depends on `compute_center_locations`.
- **Collection entry**: TOP500, Epoch AI GPU, HuggingFace related sources.
- **Fact table**: compute sources in `collected_data`.
- **Dimension table**: `compute_center_locations` stores adopted coordinate candidates.
- **API**: compute center visualization API merges raw records with location rows.
- **Delete semantics**: deleting TOP500 or similar sources refreshes `computeCenters`; changing the location table also refreshes the layer. The default is `reload`, because location updates do not always need an immediate clear.
- **Common failure**: collection finished but Earth count did not change. Check visualization cache, location rows, and adapter coverage.
## BGP
BGP data shows route collectors, anomalies, incidents, diffusion rings, and situation summaries. Earth does not render raw BGP rows directly; it renders projected observations, anomalies, and incidents. This is the most common path where deleting raw data can leave old objects visible.
```mermaid
sequenceDiagram
participant UI as Admin delete button
participant Job as clear_data job
participant DB as PostgreSQL
participant Outbox as earth_data_change_events
participant Listener as DB change listener
participant Earth as Earth frontend
UI->>Job: Submit delete for ris_live_bgp / bgpstream_bgp
Job->>DB: Delete collected_data raw rows
Job->>DB: Delete BGP-owned derived tables
DB->>Outbox: trigger writes bgp layer changed
DB-->>Listener: LISTEN/NOTIFY wakeup
Listener->>Listener: merge events and clear bgp cache
Listener-->>Earth: broadcast earth_updates clear_then_reload
Earth->>Earth: clear BGP objects
Earth->>DB: refetch projections through visualization API
```
- **Collection entry**: RIPE RIS Live BGP, CAIDA BGPStream Backfill, IPtoASN / OpenGeoFeed / NRO prefix geography.
- **Fact table**: BGP and prefix sources in `collected_data`.
- **Derived tables**: `bgp_observations`, `bgp_anomalies`, `bgp_incidents`, `bgp_collector_locations`.
- **API**: BGP visualization API reads projections and combines stored or candidate locations.
- **Delete semantics**: deleting RIS Live or BGPStream raw sources must also clear BGP-owned projections and broadcast `bgp` with `clear_then_reload`. Direct derived-table deletes also write outbox events.
- **Common failure**: collectors or incidents remain after raw rows are removed. Check derived tables first, not only `collected_data`.
## Vessels
Vessel data shows AIS vessels, navigation state, vessel-type legend, and source health. Earth rendering uses position snapshots and static vessel information; it should not render every raw AIS observation.
- **Collection entry**: AIS sources, BarentsWatch vessels.
- **Fact table**: `collected_data` or AIS raw observation tables.
- **Derived tables**: `vessel_static`, `vessel_position`, `ais_raw_observations`, `ais_source_health`.
- **API**: vessel visualization API returns current vessel markers and detail fields.
- **Delete semantics**: deleting any vessel source lets owned projections broadcast `vessels` with `clear_then_reload`.
- **Common failure**: the count panel changes but vessels remain. Summary and layer data are separate; Earth should clear objects based on layer updates.
## Interactables
`earth_interactables` is the generic surface-icon capability for manual objects, extensions, and future small layers. Unlike most layers, it keeps object-level delta.
- **Fact table**: `earth_interactables`.
- **API**: interactable API and Earth generic icon interface.
- **Strategy**: upsert for create/update and removeItem for delete; no full layer reload.
- **Delete semantics**: delete payloads must include a stable id so the frontend can remove the object.
- **Common failure**: an object cannot be removed. Usually the stable id is missing, the delta handler did not match the object type, or an older duplicate render path still exists.
## News and Media
News and media support the Earth news ticker, live stream panel, news cruise, and situation summaries. They are content refresh paths rather than stable geographic object layers, so they default to `reload`.
- **Collection entry**: RSS, live streams, news sources.
- **Fact table**: news source rows in `collected_data`.
- **Derived table**: `earth_news_items`.
- **API**: news, live stream, and media content APIs.
- **Delete semantics**: deleting news sources or `earth_news_items` broadcasts `news` / `media` reload; empty responses hide the corresponding content.
- **Common failure**: the live panel shows stale content. Usually the media component ignored the layer update or the content API cache was not invalidated.
## Adding a New Layer
Add a new Earth data product in this order:
1. Define the business purpose and Earth layer name.
2. Identify fact sources, fact tables, and derived tables.
3. Register source/table coverage, cache patterns, owned derived cleanup, and default strategy in the backend layer adapter.
4. Ensure the visualization API returns HTTP 200 with an empty collection for zero data.
5. Keep the Earth frontend driven only by layer and strategy, not database table names.
6. Update this document with the data product flow, then document implementation details in the relevant frontend, backend, or Earth technical doc.

View File

@@ -64,5 +64,5 @@ Open `/forgot-password`, enter your email, receive a code, then enter the code p
- Full UI walkthrough: [Planet Manual](/home/ray/dev/linkong/planet/docs/technical/en/manual.md)
- Troubleshooting and configuration questions: [FAQ](/home/ray/dev/linkong/planet/docs/technical/en/faq.md)
- Detailed Earth coordinate candidate flow: [Earth Location Candidate Collection User Guide](/home/ray/dev/linkong/planet/docs/technical/en/location-pipeline-user.md)
- Detailed Earth coordinate candidate flow: see the Earth section in [Planet Manual](/home/ray/dev/linkong/planet/docs/technical/en/manual.md)
- Deployment / operations commands: [Planet Ops Runbook](/home/ray/dev/linkong/planet/docs/technical/en/ops-runbook.md)

View File

@@ -1,6 +1,6 @@
# Tactile UI Components
Tactile UI is Planet's portable React control layer. It was extracted from the Admin Next button, switch, scrollbar, and tooltip work, but the components themselves do not depend on Admin Next, AntD, Radix, Tailwind, or `an-*` classes. The immediate goal is stable in-repo usage; the structure is intentionally close to something that can later be published as an npm package.
Tactile UI is Planet's portable React control layer. It was extracted from the Admin button, switch, scrollbar, and tooltip work, but the components themselves do not depend on Admin, AntD, Radix, Tailwind, or `an-*` classes. The immediate goal is stable in-repo usage; the structure is intentionally close to something that can later be published as an npm package.
## Design Goals
@@ -51,19 +51,19 @@ Most controls also accept a `tactile` prop for local width, height, radius, back
## Portals and Dark Theme
`TactileTooltip` and the Admin Next `Dialog`, `Select`, and toast controls that use Tactile UI may render through a portal attached to `document.body`. Those nodes are not descendants of `.admin-next-theme-root[data-theme='dark']`, so dark tokens cannot rely only on an ancestor selector inside the Admin Next root.
`TactileTooltip` and the Admin `Dialog`, `Select`, and toast controls that use Tactile UI may render through a portal attached to `document.body`. Those nodes are not descendants of `.admin-theme-root[data-theme='dark']`, so dark tokens cannot rely only on an ancestor selector inside the Admin root.
The Admin Next theme provider mirrors the active theme to `body[data-admin-next-theme]`. Shared styles need to support both selector paths:
The Admin theme provider mirrors the active theme to `body[data-admin-theme]`. Shared styles need to support both selector paths:
```css
[data-theme='dark'] .tui-button,
body[data-admin-next-theme='dark'] .tui-button {
body[data-admin-theme='dark'] .tui-button {
--tui-surface: #172033;
--tui-text: #e5edf8;
}
```
When adding a portal-based control, first check whether it renders into body. If it does, add a `body[data-admin-next-theme='dark']` branch in that component's style entry, or reuse the already covered `--tui-*` / `--an-*` tokens. Avoid hard-coding a one-off dark modal style, because the same contrast problem can reappear in dropdowns, tooltips, toasts, and confirmation dialogs.
When adding a portal-based control, first check whether it renders into body. If it does, add a `body[data-admin-theme='dark']` branch in that component's style entry, or reuse the already covered `--tui-*` / `--an-*` tokens. Avoid hard-coding a one-off dark modal style, because the same contrast problem can reappear in dropdowns, tooltips, toasts, and confirmation dialogs.
## `TactileButton`
@@ -195,7 +195,7 @@ Do not force overlay scrollbars onto textareas. Text selection and the resize gr
## `TableScrollRegion`
`TableScrollRegion` is a convenience wrapper for table scroll areas. The default target selector is `.tui-scroll-target`; Admin Next passes its table viewport selector explicitly so package code does not contain product-specific names.
`TableScrollRegion` is a convenience wrapper for table scroll areas. The default target selector is `.tui-scroll-target`; Admin passes its table viewport selector explicitly so package code does not contain product-specific names.
```tsx
<TableScrollRegion targetSelector=".table-viewport">
@@ -210,9 +210,9 @@ Do not force overlay scrollbars onto textareas. Text selection and the resize gr
- Tooltip text is explanatory only; state must still be represented by text, badges, or `aria-*` attributes.
- Disabled and loading states set `aria-disabled`; real `button` elements also receive `disabled`.
## Admin Next Migration Rules
## Admin Migration Rules
Admin Next should use Tactile UI for global tool buttons, detail-panel toolbars, and list footer actions:
Admin should use Tactile UI for global tool buttons, detail-panel toolbars, and list footer actions:
- Unambiguous actions: `TactileButton iconOnly tooltip`
- Save/create/confirm: `TactileButton variant="primary"`, usually with text

View File

@@ -1,44 +1,52 @@
# 技术文档
这里放“当前实现和当前结构”的文档,重点回答:
这里是 Planet 当前文档入口。文档按读者和问题类型分层:先看业务架构理解数据产品,再进入使用手册或技术实现文档。
- 现在代码是怎么组织的
- 当前入口在哪
- 状态和组件如何工作
## 业务架构
适合放入这里的内容:
- [业务架构与数据流转](/home/ray/dev/linkong/planet/docs/technical/zh/platform-data-flows.md):每类 Earth 数据的用途、采集链路、事实表、派生表、缓存和 WebSocket 广播链路
- [命名与术语对照](/home/ray/dev/linkong/planet/docs/technical/zh/naming-glossary.md)控制台、Earth、后端和文档常见名词的中英对照
- 快速开始和使用手册
- 前端上下文
- Earth 前端结构
- Earth 卫星覆盖策略
- Earth 渲染图层顺序
- Earth 图层样式属性索引
- 后端运行控制
- 采集器现状
- 采集器设置与连接验证
- 采集格式约定
## 使用入口
## 使用手册
- [快速开始](/home/ray/dev/linkong/planet/docs/technical/zh/quickstart.md):从零启动 Planet 的最短路径
- [Planet 使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/manual.md):控制台、`planet.sh`EarthDocs 的完整使用手册
- [常见问题](/home/ray/dev/linkong/planet/docs/technical/zh/faq.md)Windows / WSL、端口、依赖、动捕、凭证和 Docs 权限的集中排障入口
- [Earth 位置候选采集使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-user.md):在 Earth 上为算力中心和 BGP 观测站采集、预览坐标候选
- [数据源、采集器设置与连接验证](/home/ray/dev/linkong/planet/docs/technical/zh/datasource-collector-settings-connectivity.md)数据源目录、采集器设置、连接验证、BarentsWatch 凭证链路
- [通用位置估算管线开发说明](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-development.md):后端 location resolver / pipeline 的接口、注册表和扩展方式
- [Planet 使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/manual.md)控制台、EarthDocs 和常用功能的用户操作说明
- [常见问题](/home/ray/dev/linkong/planet/docs/technical/zh/faq.md)Windows / WSL、端口、依赖、动捕、凭证和 Docs 权限排障
## Earth 技术实现
- [Earth 前端结构](/home/ray/dev/linkong/planet/docs/technical/zh/earth-frontend-context.md)Earth 页面模块、状态、WebSocket 刷新和图层生命周期
- [Earth 图层样式属性索引](/home/ray/dev/linkong/planet/docs/technical/zh/earth-layer-style-reference.md):图层颜色、符号、材质和视觉参数
- [Earth 渲染图层顺序](/home/ray/dev/linkong/planet/docs/technical/zh/earth-render-layer-order.md)renderOrder、深度策略、拾取和同坐标避让
- [Earth 卫星覆盖策略](/home/ray/dev/linkong/planet/docs/technical/zh/earth-satellite-footprint-policy.md):卫星 footprint 的显示边界和策略
- [BGP 态势上下文](/home/ray/dev/linkong/planet/docs/technical/zh/earth-bgp-context.md)BGP 在 Earth 中的渲染、聚合和观测站实现
- [Earth 可交互图标接入](/home/ray/dev/linkong/planet/docs/technical/zh/earth-interactable-usage.md)`Interactable` 的接口、生命周期和接入示例
- [Earth 工具栏与浮层协同](/home/ray/dev/linkong/planet/docs/technical/zh/earth-toolbar-overlay-coordination.md):工具栏按钮与搜索、设置、新闻、图层浮层的关闭矩阵
## 前端技术实现
- [控制台前端结构](/home/ray/dev/linkong/planet/docs/technical/zh/frontend-admin-frontend-context.md):控制台页面结构、状态边界和懒加载策略
- [前端布局指南](/home/ray/dev/linkong/planet/docs/technical/zh/frontend-layout-guidelines.md):布局、表格、面板和响应式约束
- [Tactile UI 组件库](/home/ray/dev/linkong/planet/docs/technical/zh/tactile-ui-components.md)按钮、开关、tooltip、滚动条组件 API 和主题 token
## 后端技术实现
- [数据采集系统](/home/ray/dev/linkong/planet/docs/technical/zh/backend-collectors.md):采集器、任务类型、保存层和状态回写
- [系统服务控制](/home/ray/dev/linkong/planet/docs/technical/zh/backend-system-service-control.md):后端服务控制和系统操作接口
- [数据源、采集器设置与连接验证](/home/ray/dev/linkong/planet/docs/technical/zh/datasource-collector-settings-connectivity.md):数据源目录、采集器设置、连接验证和凭证链路
- [数据源 API 性能](/home/ray/dev/linkong/planet/docs/technical/zh/backend-datasources-api-performance.md)DataSources 列表接口性能和缓存策略
- [数据作业与 Outbox 技术架构](/home/ray/dev/linkong/planet/docs/technical/zh/data-job-earth-sync-architecture.md)PostgreSQL 作业队列、outbox、listener 和 Kafka / Spark 演进边界
- [通用位置估算管线开发说明](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-development.md)location resolver / pipeline 的接口、注册表和扩展方式
- [新闻直播采集格式](/home/ray/dev/linkong/planet/docs/technical/zh/earth-news-live-streams-collector-format.md):新闻、直播和媒体采集 payload 约定
- [Docs Gatekeeper 开发说明](/home/ray/dev/linkong/planet/docs/technical/zh/docs-gatekeeper-development.md):后端 Docs 目录、正文读取和 Gatekeeper 权限组实现
- [命名与术语对照](/home/ray/dev/linkong/planet/docs/technical/zh/naming-glossary.md)控制台、Earth、后端和文档常见名词的中英对照
- [Earth 可交互图标接入](/home/ray/dev/linkong/planet/docs/technical/zh/earth-interactable-usage.md)Earth 地表可交互图标 `Interactable` 的接口、生命周期和接入示例
- [Earth 工具栏与浮层协同](/home/ray/dev/linkong/planet/docs/technical/zh/earth-toolbar-overlay-coordination.md):工具栏按钮与搜索 / 设置 / 新闻 / 图层浮层之间的关闭矩阵和接入规则
- [Tactile UI 组件库](/home/ray/dev/linkong/planet/docs/technical/zh/tactile-ui-components.md)可移植按钮、开关、tooltip 和滚动条组件的 API、主题 token 与迁移约定
不适合放入这里的内容:
## 智能体与运维
- 尚未完成的路线图
- 未来迭代方案
- 大范围重构计划
- [AI Provider 指南](/home/ray/dev/linkong/planet/docs/technical/zh/agents-aiprovider.md):模型供应商适配、任务 prompt 和调用边界
- [Planet 运维手册](/home/ray/dev/linkong/planet/docs/technical/zh/ops-runbook.md):部署、启动、排障和敏感操作
- [Docker + Compose + Buildx 升级](/home/ray/dev/linkong/planet/docs/technical/zh/ops-docker-compose-buildx-upgrade.md)Docker 工具链升级步骤
- [planet.sh 启动机制](/home/ray/dev/linkong/planet/docs/technical/zh/ops-planet-sh-startup.md):启动脚本、健康检查和性能优化
这些应放入:
## 计划与历史
- [计划文档索引](/home/ray/dev/linkong/planet/docs/plans/README.md)
尚未完成的路线图、大范围重构方案和未来计划放在仓库路径 `docs/plans/README.md`。已完成、过时或被新实现替代的方案放在 `docs/deprecated/README.md`

View File

@@ -101,7 +101,7 @@ AI 配置页使用的接口:
这些接口都需要用户登录。`secrets` 接口只用于配置页点击显示 key/token 时取回明文,隐藏时前端恢复为脱敏预览。
Admin Next 的 AI 页面按旧版信息架构组织为:
Admin 的 AI 页面按业务信息架构组织为:
- `模型供应商`
- 管理 provider、协议适配、默认模型、LLM API Key、代理地址、代理 token、模型列表刷新、设为默认和轻量连通性测试。
@@ -272,7 +272,7 @@ AI 配置仍保存在 PostgreSQL不写入 JSON 文件。核心结构如下:
`.env` 只是兜底。配置页保存或测试连接成功后PostgreSQL 中的配置会成为全局默认。
Admin Next 的密钥状态必须按 provider / tool 精确判断:
Admin 的密钥状态必须按 provider / tool 精确判断:
- 数据库中当前 provider/tool 有密钥时,显示为“已配置”。
- 数据库没有密钥,但 fallback provider、model 或 tool 与当前项匹配时,可以显示 fallback 的脱敏预览。
@@ -283,7 +283,7 @@ Admin Next 的密钥状态必须按 provider / tool 精确判断:
### 轻量连通性测试
Admin Next 的插头按钮走轻量连通性测试,不承担保存职责。业界常见做法是分两层:
Admin 的插头按钮走轻量连通性测试,不承担保存职责。业界常见做法是分两层:
- 快速检查 provider 目录或低成本 endpoint确认 base URL、鉴权和当前模型是否可达。
- 只有在用户明确运行 Playground 或业务任务时才发完整模型请求。

View File

@@ -73,6 +73,8 @@ async def run(self, db):
**核心文件**: `backend/app/services/collectors/base.py`
手动触发、删除数据、清理缓存现在统一进入 PostgreSQL 数据作业队列,任务账本仍是 `collection_tasks`。采集器只负责 `fetch -> transform -> save`,由 `data_jobs.py` worker 领取 `collect` / `clear_data` / `clear_cache` / `earth_refresh` 任务并回写进度。Earth 图层刷新关系集中在 `earth_layer_adapters.py`,不要再在单个采集器或按钮里手写缓存失效和 WebSocket 广播。
## 三、采集器列表
| 采集器 | 数据类型 | 数据内容 | 采集频率 |
@@ -230,7 +232,7 @@ if datasource.last_status == "success":
### 采集管理与快照
Admin Next 的采集管理入口按业务层级组织:
Admin 的采集管理入口按业务层级组织:
- `采集器`:配置 endpoint、认证方式、请求头、基础参数、启用状态和凭证教程。
- `采集调度`:查看和调整调度状态,触发、停止或刷新采集任务。

View File

@@ -96,4 +96,4 @@ if (res.data.task_id) {
## 相关文件
- `backend/app/api/v1/datasources.py``_load_datasource_list_context``list_datasources`
- `frontend/src/pages/DataSources/DataSources.tsx``BuiltInDataSource` interface、`triggerDatasource`
- `frontend/src/admin/pages/PlainResourcePages.tsx``BuiltInDataSource` interface、`triggerDatasource`

View File

@@ -0,0 +1,141 @@
# 数据作业与 Outbox 技术架构
本文记录 Planet v1 的任务队列、数据库 outbox 和 Earth 刷新技术边界。每类数据产品的业务用途和端到端链路见 [业务架构与数据流转](/home/ray/dev/linkong/planet/docs/technical/zh/platform-data-flows.md)。
## 架构边界
- PostgreSQL 是 v1 的可靠任务账本和 outbox不引入 Kafka、Celery 或 RQ。
- `collection_tasks` 记录采集、删除、清缓存和非数据库触发的 Earth refresh 任务。
- `earth_data_change_events` 记录事实表或派生表变化,是 Earth 同步的可靠来源。
- `LISTEN/NOTIFY` 只做低延迟唤醒listener 仍会轮询未消费 outbox。
- Redis 主要用于缓存、认证辅助、OTP / rate limit、临时日志和 WebSocket 辅助,不是可靠队列。
## 数据库变化同步
```mermaid
flowchart LR
Write["Fact or derived table write"] --> Trigger["PostgreSQL trigger"]
Trigger --> Outbox["earth_data_change_events"]
Trigger --> Notify["planet_earth_data_changes"]
Outbox --> Listener["earth_db_change_listener"]
Notify --> Listener
Listener --> Adapter["earth_layer_adapters"]
Adapter --> Cache["cache invalidation"]
Cache --> WS["earth_updates"]
```
1. 采集、删除、定位或派生任务写入事实表或派生表。
2. statement trigger 为 `INSERT` / `UPDATE` / `DELETE` 写入 outbox。
3. listener 被 notify 唤醒,或通过轮询发现未消费事件。
4. listener 使用 `earth_layer_adapters.py``table + source` 映射成 Earth layer、刷新策略和 cache pattern。
5. listener 短窗口合并同 layer 事件,失效缓存并广播 `earth_updates`
6. 广播成功后标记 outbox consumed失败时保留待重试。
DB 变化不再默认创建 `earth_refresh` 任务,因此不会被同 source 的长采集或删除任务阻塞。`earth_refresh` 只保留给手动清缓存和非 DB 变化刷新提示。
## 数据作业队列
`collection_tasks` 是统一 job ledger。worker 使用 PostgreSQL `FOR UPDATE SKIP LOCKED` 领取 `queued` 任务;同一 `source` 的写任务串行,不同 source 可并行。
| task_type | 作用 |
| --- | --- |
| `collect` | 执行内置 datasource 采集 |
| `clear_data` | 删除该 source 的采集数据和声明过的派生数据 |
| `clear_cache` | 删除该 source 对应的 Earth / dashboard 缓存 |
| `earth_refresh` | 非 DB 变化场景下失效 Earth 图层缓存并广播刷新提示 |
接口只创建任务并返回 `task_id`。任务执行、进度、取消和终态由 worker 写回 `collection_tasks`,并通过 `datasource_tasks` channel 通知前端。
取消语义是“保留已提交批次”:点击停止后,后端把任务标记为 `cancelling` 并取消内存中的执行协程;已经提交的批次保留,未完成批次按采集器或清理任务的回滚逻辑处理。
## Earth 同步事件模型
统一事件模型是 `earth.layer.changed`
```json
{
"event": "earth.layer.changed",
"action": "database_changed",
"source": "celestrak_tle",
"table": "collected_data",
"operation": "DELETE",
"layers": ["satellites"],
"refresh_strategy": "clear_then_reload",
"records_processed": 11125,
"occurred_at": "2026-05-25T10:20:30Z"
}
```
| strategy | 用途 |
| --- | --- |
| `clear_then_reload` | 先清前端本地图层对象,再强制重拉接口。删除数据时优先使用。 |
| `reload` | 保留旧对象直到新数据返回,适合定位、元数据或非破坏性更新。 |
| `delta` | 只用于 `earth_interactables`,按 id upsert 或 remove。 |
接口在真实 0 数据时必须返回 200 和空集合;只有真实接口异常才返回 5xx。前端收到删除事件后如果重拉失败应保持已清空状态并显示轻量错误不恢复旧对象。
## Layer Adapter 约定
`earth_layer_adapters.py` 是 source、派生表、Earth layer、缓存和刷新策略的唯一注册表。新图层只应新增 adapter不应在按钮 handler、采集器或前端分支里手写同步逻辑。
Adapter 必须声明:
- source 或 table 由哪个 Earth layer 消费。
- 需要清理哪些 Earth cache key pattern。
- `clear_data` 删除 source 时是否需要同时删除 owned 派生表。
- 该 layer 的默认刷新策略。
删除 source 时,`clear_data` 作业先删除 `collected_data.source = <source>`,再根据 adapter 删除 owned 派生表。直接修改派生表也会触发 outbox所以后台任务、管理接口和 SQL 修复脚本只要落到事实表或派生表Earth 都能感知变化。
## 运维排障
检查 outbox 是否堆积:
```sql
SELECT id, table_name, operation, source, occurred_at
FROM earth_data_change_events
WHERE consumed_at IS NULL
ORDER BY id
LIMIT 20;
```
检查触发器是否存在:
```sql
SELECT tgname, tgrelid::regclass
FROM pg_trigger
WHERE tgname LIKE 'tr_planet_%_changed_%'
ORDER BY 2, 1;
```
常用日志事件:
- `earth.db_changes.connected`listener 已连接 PostgreSQL 并开始监听。
- `earth.db_changes.outbox_polled`:轮询到了未消费 outbox。
- `earth.db_changes.broadcasted`:已产生 Earth 刷新广播。
- `data_job.started` / `data_job.completed`:任务执行状态。
如果 Earth 没更新按顺序检查事实表是否变化、outbox 是否消费、adapter 是否覆盖对应 `source/table`、listener 是否在线、前端 WebSocket 是否连接、visualization 接口是否返回 200 空集合或新数据。
## Kafka-ready 边界
业务代码不直接依赖具体队列实现,而是通过这些边界组织:
- `JobQueue`:提交、领取、取消、完成数据作业。
- `DataChangeBus`:发布数据库事实变化。
- `EarthLayerAdapterRegistry`:声明 source、layer、缓存和派生数据关系。
需要 Kafka 的信号:
- 多个独立服务需要消费同一批数据变化。
- AIS、BGP 或传感器流达到持续高吞吐。
- 需要 consumer group、事件回放、跨服务解耦。
需要 Spark 的信号:
- 历史数据到千万或亿级PostgreSQL 聚合开始吃力。
- 需要跨源、长时间窗口、空间时间关联分析。
- 原始数据进入 Parquet / Iceberg / Delta 等湖仓,并开始生产离线派生数据产品。
若目标是秒级连续流计算,优先评估 FlinkSpark 更适合批量或微批分析。

View File

@@ -32,8 +32,8 @@
文件:
- [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/pages/PlainResourcePages.tsx)
- [AdminNextRoutes.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/AdminNextRoutes.tsx)
- [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
- [AdminRoutes.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/AdminRoutes.tsx)
当前行为:
@@ -57,11 +57,11 @@
文件:
- [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/pages/PlainResourcePages.tsx)
- [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
当前行为:
- `/collection-management`旧版层级收敛为 `采集器``采集调度``采集历史 / 快照`
- `/collection-management`业务层级收敛为 `采集器``采集调度``采集历史 / 快照`
- `采集器` 是配置页,左侧列表展示采集器配置;右侧表单编辑 endpoint、认证、请求头、采集参数和启用状态。
- 新增采集器和目标 Schema 使用草稿详情页,不再用透明 JSON 弹窗;保存后才固化到列表,取消会销毁草稿。
- 连接按钮只做连通性测试,不保存配置;保存按钮只持久化表单。
@@ -80,7 +80,7 @@
- `目标 Schema` 维护可写入目标结构。
- `run-mapped``stop-mapped``stream-status` 负责运行映射后的自定义采集器。
这些入口在新版中需要表单化,只有高级字段才折叠为 JSON。不要把模板、Schema、运行状态和采集器配置拍平成同一张表。
这些入口在 Admin 中需要表单化,只有高级字段才折叠为 JSON。不要把模板、Schema、运行状态和采集器配置拍平成同一张表。
## 后端接口

View File

@@ -83,7 +83,7 @@ DocsMetadata(
- 更新用户时校验组名只能是 `docs_user``docs_developer``docs_admin`
- 只有 `super_admin` 能修改 Gatekeeper 权限组。
前端 [Users.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Users/Users.tsx) 展示权限组标签,并在编辑表单中提供多选框。非 `super_admin` 打开的表单会禁用该字段,并在提交前移除 `gatekeeper_groups`
前端 [Users.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/Users.tsx) 展示权限组标签,并在编辑表单中提供多选框。非 `super_admin` 打开的表单会禁用该字段,并在提交前移除 `gatekeeper_groups`
## 前端 Docs 加载

View File

@@ -188,7 +188,7 @@ Earth info-card 策略:
- 这是预期行为,因为 incident 是聚合和去噪后的结果
- 但 incident-first 渲染会让 Earth 显得过于安静,除非有另一层始终可用的 activity layer
推荐 `activity layer` 的实现细节在 [BGP 区域聚合计划](/home/ray/dev/linkong/planet/docs/plans/earth-bgp-region-aggregation-plan.md) 中展开
推荐 `activity layer`未来实现细节保存在仓库路径 `docs/plans/earth-bgp-region-aggregation-plan.md`
因此最近的里程碑是:
@@ -259,7 +259,7 @@ Earth 的 `incident` 层不应该像一大片发光区域,而应该像紧凑
相关页面:
- `frontend/src/pages/BGP/BGP.tsx`
- `frontend/src/admin/pages/PlainResourcePages.tsx`
当前 BGP 控制台页面有三层:
@@ -321,7 +321,7 @@ BGP 专项测试位于:
前端:
- `frontend/src/pages/BGP/BGP.tsx`
- `frontend/src/admin/pages/PlainResourcePages.tsx`
- `frontend/public/earth/js/bgp.js`
- `frontend/public/earth/js/main.js`
- `frontend/public/earth/js/info-card.js`

View File

@@ -4,7 +4,7 @@
相关规则建议一起参考:
- [项目规则](/home/ray/dev/linkong/planet/rules.md)
- 仓库根目录 `rules.md`
- [前端布局指南](/home/ray/dev/linkong/planet/docs/technical/zh/frontend-layout-guidelines.md)
## 当前目标
@@ -56,6 +56,8 @@ React 路由入口:
- 各图层集成
- Earth 级别状态同步
Earth 收到 `/ws``earth_updates` 时只把它当作刷新提示,真实数据仍通过 `/api/v1/visualization/...` 接口重新 GET。数据库驱动的刷新由后端 listener 直接清理缓存再广播,不再默认经过 `earth_refresh` 作业队列;前端收到 `database_changed` 后会按 layer 读取 `clear_then_reload``reload``delta` 策略。`clear_then_reload` 必须先清 Three.js 对象再 no-store 重拉summary 只做一致性校验,不能用 `0` 作为跳过图层重拉的理由。技术链路见 [数据作业与 Outbox 技术架构](/home/ray/dev/linkong/planet/docs/technical/zh/data-job-earth-sync-architecture.md),业务数据流见 [业务架构与数据流转](/home/ray/dev/linkong/planet/docs/technical/zh/platform-data-flows.md)。
### 3. 地球控制层
- [controls.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/controls.js)
@@ -162,11 +164,11 @@ Earth 地表是多层近似同心球,不是单一 mesh。`earth.js` 的基座
`brand.js` 管理 Earth HUD 品牌资源。默认品牌来自静态资源,运行时覆盖值来自 `/api/v1/earth/brand`,上传的图片通过 `/earth-brand-assets/...` 读取。前端必须把 logo/title 图片和文本 fallback 分开处理:图片加载失败时显示文本标题,文本字段为空时使用后端默认值,避免 HUD 品牌区空白。控制台的 Earth 内容页负责保存和重置品牌配置Earth 前端只消费结果。
`about.js` 管理 Earth 设置里的“关于”卡片。默认内容仍保留在前端作为兜底,运行时优先读取 `/api/v1/earth/about`。接口失败或字段缺失时必须回退默认值避免设置页出现空白。Admin Next 的 Earth 内容页提供“关于”tab保存走 `PUT /api/v1/earth/about`,恢复默认走 `DELETE /api/v1/earth/about`
`about.js` 管理 Earth 设置里的“关于”卡片。默认内容仍保留在前端作为兜底,运行时优先读取 `/api/v1/earth/about`。接口失败或字段缺失时必须回退默认值避免设置页出现空白。Admin 的 Earth 内容页提供“关于”tab保存走 `PUT /api/v1/earth/about`,恢复默认走 `DELETE /api/v1/earth/about`
`oobe.js` 管理 Earth 首次初始化引导。是否显示 OOBE 必须由 `/api/v1/earth/oobe-status``ready` 字段决定,不能依赖 `localStorage` 判断系统是否初始化。`localStorage` 只允许记录“本浏览器暂时跳过”的短时状态;如果后端已经认为 `ready: true`,退出登录、清空本地缓存或换浏览器都不应再次弹出 OOBE。桌面端使用深色星空遮罩和毛玻璃启动面板移动端改为底部 sheet并尊重 `prefers-reduced-motion`
Admin Next 的 Earth 内容页必须按运行时语义组织这些配置:
Admin 的 Earth 内容页必须按运行时语义组织这些配置:
- `品牌标识`:品牌预览应使用与 Earth HUD 左上角一致的深色星空背景、尺寸、间距、logo/title 渲染和文本 fallback而不是普通表单预览。
- `关于`:配置 Earth 设置里的 About 卡片,包括 logo、眉标、标题、版本、描述和元信息条目Earth 运行时从 `/earth/about` 读取,失败时回退默认内容。
@@ -197,9 +199,7 @@ TV 预览需要尽量复用 Earth 运行时的直播卡片结构和状态标签
当前 BGP 巡航只是这套能力的一个调用方不应再把“按队列巡航”和“BGP 事件展示”混写在同一个状态机里。
新闻巡航摘要计划见:
- [Earth 新闻巡航摘要计划](/home/ray/dev/linkong/planet/docs/plans/earth-news-cruise-summary-plan.md)
新闻巡航摘要的未来计划保存在仓库路径 `docs/plans/earth-news-cruise-summary-plan.md`,不作为公开 Docs 页面入口。
## 当前样式分层

View File

@@ -17,26 +17,15 @@
## 本地实际类别
当前 CelesTrak 卫星分组在 [backend/app/services/collectors/celestrak.py](/home/ray/dev/linkong/planet/backend/app/services/collectors/celestrak.py) 中包括:
当前 CelesTrak 采集器从 `GROUP=active&FORMAT=json` 拉取完整活跃卫星目录,而不是逐个小分组拉取后合并。这样可以避免某个 CelesTrak 分组请求失败时仍把不完整结果保存为成功批次。采集器只在完整 JSON 数组可解析、且记录含 `NORAD_CAT_ID` 时进入转换和保存;网络、续传或解析失败会重试,最终失败时保留上一批 current 数据。
- `starlink`
- `gps-ops`
- `galileo`
- `glonass`
- `beidou`
- `leo`
- `geo`
- `iridium-next`
采集结果仍会给前端提供 `metadata.constellation_group`,但该字段现在来自可执行推断:
其中非 Starlink 类别是:
- `OBJECT_NAME``STARLINK` 开头时标记为 `starlink`
- `OBJECT_NAME``IRIDIUM` 开头时标记为 `iridium-next`
- 其它活跃卫星不强行归入旧 CelesTrak 小分组,避免把泛化类别当成精确星座
- `gps-ops`
- `galileo`
- `glonass`
- `beidou`
- `leo`
- `geo`
- `iridium-next`
因此,非 Starlink 类别在产品策略中仍包括 GNSS/RNSS、GEO、generic LEO 和 Iridium NEXT 等语义,但不能再假设采集器保存了旧的 `gps-ops``galileo``glonass``beidou``leo``geo` 分组标签。
## 资料结论
@@ -136,7 +125,8 @@
1. 后端把星座分组和 footprint 策略提示透给前端
- CelesTrak collector 会把 `GROUP` 记入 `metadata.constellation_group`
- CelesTrak collector 会把原始查询来源记入 `metadata.celestrak_query_group = active`
- `metadata.constellation_group` 只保存可推断的业务星座,例如 `starlink``iridium-next`
- Visualization API 会输出:
- `properties.constellation_group`
- `properties.footprint_policy`

View File

@@ -4,7 +4,7 @@
相关规则建议一起参考:
- [项目规则](/home/ray/dev/linkong/planet/rules.md)
- 仓库根目录 `rules.md`
- [前端布局指南](/home/ray/dev/linkong/planet/docs/technical/zh/frontend-layout-guidelines.md)
## 当前目标
@@ -22,7 +22,7 @@
- [App.tsx](/home/ray/dev/linkong/planet/frontend/src/App.tsx)
当前正式后台路由已经由 Admin Next 接管:
当前正式后台路由已经由 Admin 接管:
- `/admin`
- `/users`
@@ -37,23 +37,7 @@
- `/collection-management`
- `/settings`
这些路径渲染 [AdminNextRoutes.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/AdminNextRoutes.tsx),页面清单和菜单元信息来自 [manifest.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/routes/manifest.tsx)。`/admin-next/*` 仅作为兼容入口存在,会重定向到上面的正式路径,不再作为并行主入口
旧 AntD 控制台保留在 `/legacy/admin/*`,用于对照和回退:
- `/legacy/admin`
- `/legacy/admin/datasources`
- `/legacy/admin/data`
- `/legacy/admin/collection-management`
- `/legacy/admin/earth-content`
- `/legacy/admin/ai`
- `/legacy/admin/logs`
- `/legacy/admin/settings`
- `/legacy/admin/users`
- `/legacy/admin/bgp`
- `/legacy/admin/alerts/*`
旧页面、`AppLayout``antd``@ant-design/icons` 在 legacy 验收期继续保留。不要在新版 parity 验收前删除这些文件或依赖。
这些路径渲染 [AdminRoutes.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/AdminRoutes.tsx),页面清单和菜单元信息来自 [manifest.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/routes/manifest.tsx)。Admin 是唯一后台控制台入口,不再维护并行控制台或回退路由
`/earth` 是独立展示页,不属于控制台骨架。
@@ -61,7 +45,7 @@
正式后台公共壳层在:
- [AdminNextLayout.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/components/layout/AdminNextLayout.tsx)
- [AdminLayout.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/components/layout/AdminLayout.tsx)
职责:
@@ -69,38 +53,13 @@
- 当前账号、版本、退出登录和主题切换
- 顶部搜索、面包屑和页面快捷入口
- 内容区单屏高度闭合
- Admin Next 内部滚动、表格、详情面板和移动端详情视图协调
- Admin 内部滚动、表格、详情面板和移动端详情视图协调
旧 AntD legacy 壳层仍在:
后续正式控制台页面应适配 `AdminLayout` 和 Admin 页面模式;不要重新引入并行后台壳层。
- [AppLayout.tsx](/home/ray/dev/linkong/planet/frontend/src/components/AppLayout/AppLayout.tsx)
## Admin 分区加载策略
legacy 职责
- 左侧导航
- 折叠与展开
- 当前账号/版本信息
- 内容区高度闭合
- 全站统一侧边栏滚动条
当前结构是:
```tsx
<Layout className="dashboard-layout">
<Sider className="dashboard-sider">...</Sider>
<Layout>
<Content className="dashboard-content">
<div className="dashboard-content-inner">{children}</div>
</Content>
</Layout>
</Layout>
```
后续正式控制台页面应优先适配 `AdminNextLayout` 和 Admin Next 页面模式,而不是继续往旧 `AppLayout` 增加新能力。只有维护 `/legacy/admin/*` 时才应修改旧壳层。
## Admin Next 分区加载策略
多 tab 页面由 [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/pages/PlainResourcePages.tsx) 统一承载当前的管理型和信息型工作台。分区加载规则是:
多 tab 页面由 [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx) 统一承载当前的管理型和信息型工作台。分区加载规则是
- 初次进入页面只请求当前 active tab不预先拉取所有 tab 的接口。
- 用户切换 tab 时懒加载该 tab已经加载过的 tab 保留在本地 `states` 缓存中,切回时直接复用。
@@ -112,20 +71,22 @@ legacy 职责:
## 数据源采集队列
Admin Next 的数据源页把单源触发、表格勾选触发和触发全部统一接入浏览器下载列表式采集队列:
Admin 的数据源页把单源触发、表格勾选触发和触发全部统一接入浏览器下载列表式采集队列:
- 队列状态由 [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin-next/pages/PlainResourcePages.tsx) 管理,只保存当前会话中的可见任务,不用 `localStorage` 伪造历史。
- 队列状态由 [PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx) 管理,只保存当前会话中的可见任务,不用 `localStorage` 伪造历史。
- 任务进度优先消费 `/ws``datasource_tasks` channel如果 WebSocket 未连接或没有及时返回,则轮询 `/api/v1/datasources/{id}/task-status`
- 触发接口返回的 `triggered``skipped``failed` 会立即进入队列;刷新页面后只根据后端当前仍在 `running/pending/queued` 的数据源恢复队列。
- `内置源` 分区通过表格选择列收敛批量触发。没有勾选时主按钮是“触发全部”;勾选后同一个主按钮变成“触发已选 N”不再提供手填 ID 的独立批量按钮。
- 页面内容流不再承载展开队列,避免全量触发后挤压列表和详情面板。右上角 actions 区的队列按钮沿用现有 `Button` 样式;空态使用 `ListChecks` 图标,有任务时只显示纯圆环总进度。点击后打开浮层,按运行中、失败、完成、跳过分组。
- 队列项可以跳转到对应数据源详情,失败项可以重试。详情页内的“采集任务”摘要只展示当前数据源最近任务,不承担保存配置职责。
- 运行中的单源采集按钮显示为“停止采集”;队列中未完成项右侧提供取消按钮。取消调用 `/api/v1/datasources/{source_id}/tasks/{task_id}/cancel`,后端语义是保留已提交批次并回滚未完成批次。
- 删除数据库数据和清理展示缓存也会进入同一队列,前端只展示任务状态,不假定接口同步完成。
这个队列是用户感知层,不替代后端调度状态。后端仍然是任务是否运行、完成、失败或跳过的唯一事实来源。
## Admin Next 主题滑块
## Admin 主题滑块
Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/home/ray/dev/linkong/planet/frontend/src/components/SegmentedControl/SegmentedControl.tsx),但主题变量在 [styles.css](/home/ray/dev/linkong/planet/frontend/src/admin-next/styles.css) 内跟随 `data-theme` 覆盖:
Admin 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/home/ray/dev/linkong/planet/frontend/src/components/SegmentedControl/SegmentedControl.tsx),但主题变量在 [styles.css](/home/ray/dev/linkong/planet/frontend/src/admin/styles.css) 内跟随 `data-theme` 覆盖:
- light 下使用 `--d-segment-bg: #eef3f9`、白色 slider 和轻投影。
- dark 下使用与 Docs 一致的深色底座、`#202938` slider 和深色外投影。
@@ -164,8 +125,7 @@ Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/ho
当前使用场景:
- Admin Next 数据源、采集数据、采集管理、日志、告警和 BGP 页面
- 旧 AntD legacy 页面通过兼容封装继续使用共享滚动能力
- Admin 数据源、采集数据、采集管理、日志、告警和 BGP 页面
### 3. `TableScrollRegion`
@@ -188,7 +148,7 @@ Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/ho
用途:
- Admin Next 全局工具按钮和详情页工具按钮
- Admin 全局工具按钮和详情页工具按钮
- icon-only + tooltip 的普通操作
- 保存、创建、确认、删除、停止等强意图操作
- 与 Docs 主题滑块一致的紧凑开关
@@ -246,39 +206,19 @@ Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/ho
- 文档内部链接应通过 `transformLink` 转成 `/docs/:slug`
- 标题锚点由 `getHeadingId` 注入,避免渲染器自己理解路由状态
### 7. `ConnectionTestInput`
### 7. Admin UI primitives
文件:
- [ConnectionTestInput.tsx](/home/ray/dev/linkong/planet/frontend/src/components/ConnectionTestInput/ConnectionTestInput.tsx)
- [button.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/components/ui/button.tsx)
- [dialog.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/components/ui/dialog.tsx)
- [switch.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/components/ui/switch.tsx)
用途:
- Endpoint、Base URL 这类“输入值 + 连接验证”的控制台表单项
- AI Provider 和 WebSearch 的连接测试入口
- 后续采集器配置如果把连接测试放进输入框,也应复用它
当前约束:
- 输入框末端只显示一个插头/连接器图标,不再并排放“测试连接”文字按钮
- 禁用的集成能力必须同时置灰输入框和连接测试按钮
- 组件只负责输入框与测试入口组合不保存业务状态调用方仍负责表单值、loading、disabled 和连接请求
### 8. `TableActions`
文件:
- [TableActions.tsx](/home/ray/dev/linkong/planet/frontend/src/components/TableActions/TableActions.tsx)
用途:
- 表格操作列的统一操作入口
- 展开状态下直接展示按钮
- 收起状态下用更多菜单承载操作
配套导出:
- `actionCellProps`:用于操作列 `onCell`,防止操作按钮被省略号截断或换行
- 全局工具按钮、详情页动作、确认弹窗和二元设置。
- 与 Tactile UI token 对齐,保持 Admin 内部控件尺寸、hover、disabled 和 dark mode 一致。
- 表格行内动作优先使用 icon button + tooltip/title不重新引入独立操作菜单组件。
## 当前状态来源
@@ -301,7 +241,7 @@ Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/ho
文件:
- [AISettings.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/AISettings/AISettings.tsx)
- [AISettings.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
职责:
@@ -337,7 +277,7 @@ Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/ho
例如:
- [Dashboard.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Dashboard/Dashboard.tsx)
- [Dashboard.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/Dashboard.tsx)
优先目标:
@@ -349,10 +289,10 @@ Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/ho
例如:
- [DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/DataSources/DataSources.tsx)
- [DataList.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/DataList/DataList.tsx)
- [Users.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Users/Users.tsx)
- [Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Settings/Settings.tsx)
- [DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
- [DataList.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/DataList.tsx)
- [Users.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/Users.tsx)
- [Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
约束:
@@ -362,7 +302,7 @@ Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/ho
### 数据源目录页
[DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/DataSources/DataSources.tsx) 当前不再承担配置编辑职责,而是数据源目录和采集操作页。
[DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx) 当前不再承担配置编辑职责,而是数据源目录和采集操作页。
当前页面边界:
@@ -386,7 +326,9 @@ Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/ho
### 采集器设置页
[Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Settings/Settings.tsx) 会按路由进入三种模式:`/settings` 是系统设置,`/earth-content` 是 Earth 内容,`/collection-management` 是采集管理。`collector_credentials` tab 当前在 `/collection-management` 下显示为“采集器”。
[Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx) 会按路由进入三种模式:`/settings` 是系统设置,`/earth-content` 是 Earth 内容,`/collection-management` 是采集管理。`collector_credentials` tab 当前在 `/collection-management` 下显示为“采集器”。
`/settings` 的“系统显示”分区包含 `演示模式` 开关。开启后Earth 的 OOBE 会忽略“已有当前采集数据”和本地“先浏览”临时跳过状态,直接展示初始化引导;该开关仅用于演示/验收流程,不改变数据源、采集队列或 Earth 内容资源配置。
当前页面边界:
@@ -419,7 +361,7 @@ Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/ho
### Earth 内容页
`/earth-content` 复用 [Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Settings/Settings.tsx) 的单屏 tab 容器,但页面责任与系统设置分离:
`/earth-content` 复用 [Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx) 的单屏 tab 容器,但页面责任与系统设置分离:
- `电视直播` 迁移原直播源配置,继续管理 Earth 媒体面板内容源。
- `国界精度` 管理 Earth 静态国界资产provider 状态、低精 fallback、高精 manifest/PMTiles、源配置 JSON 和构建动作。
@@ -431,8 +373,8 @@ Admin Next 侧栏底部主题切换继续复用共享 [SegmentedControl.tsx](/ho
例如:
- [BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/BGP/BGP.tsx)
- [Playground.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Playground/Playground.tsx)
- [BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
- [Playground.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
约束:

View File

@@ -8,7 +8,8 @@
当前推荐参考实现:
- [frontend/src/pages/BGP/BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/BGP/BGP.tsx)
- [frontend/src/admin/pages/PlainResourcePages.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/PlainResourcePages.tsx)
- [frontend/src/admin/pages/DataList.tsx](/home/ray/dev/linkong/planet/frontend/src/admin/pages/DataList.tsx)
- [frontend/src/index.css](/home/ray/dev/linkong/planet/frontend/src/index.css)
## 核心原则
@@ -23,15 +24,15 @@
推荐结构:
```tsx
<AppLayout>
<AdminLayout>
<div className="page-shell">
<div className="page-shell__header">...</div>
<div className="page-shell__body">...</div>
</div>
</AppLayout>
</AdminLayout>
```
页面总高度应被限制在 `AppLayout` 内容区内,而不是继续让整个页面自然向下增长。
页面总高度应被限制在 `AdminLayout` 内容区内,而不是继续让整个页面自然向下增长。
### 2. 滚动优先发生在模块内部

View File

@@ -2,7 +2,7 @@
`backend/app/services/location/` 是所有“给定一条记录,决定它的 lat/lon”业务的共享抽象。算力中心、BGP 观测站、BGP 事件目前都跑在这条管线上。未来需要位置估算的实体例如卫星地面站、用户认领点位、IXP 设施,也应接入这里,而不是各自再写地理解析逻辑。
用户侧流程见 [Earth 位置候选采集使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-user.md)
用户侧流程见 [Planet 使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/manual.md) 的 Earth 位置候选采集章节
## 设计目标

View File

@@ -283,7 +283,17 @@ AIS 船只图例按船型显示颜色:货轮、油轮、客船、渔船、军
算力中心和 BGP 观测站详情卡支持自动采集坐标候选。点击对象后用"自动采集坐标候选"或"重新自动采集坐标"按钮,后端会从源坐标、开放组织注册 API 和在线地理编码中整理候选;常规来源没有候选时使用当前默认 AI Provider 做 LLM factcheck 兜底。BGP 观测站的已存储位置只用于补齐查询上下文,不会作为候选直接返回。
候选可以直接在 Earth 预览。算力中心候选点击"保存"后写入 `compute_center_locations` 维表并刷新图层。算力中心图层左上角的通知气泡显示无法渲染的待定位数量;点击查看列表,单条采集候选,或用"一键采用"从上到下保存最高置信候选。没有可用候选的记录会留在列表中,不会被国家中心点或硬编码 hint 伪造位置。详细流程见 [Earth 位置候选采集使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-user.md)。
候选可以直接在 Earth 预览。算力中心候选点击"保存"后写入 `compute_center_locations` 维表并刷新图层。算力中心图层左上角的通知气泡显示无法渲染的待定位数量;点击查看列表,单条采集候选,或用"一键采用"从上到下保存最高置信候选。没有可用候选的记录会留在列表中,不会被国家中心点或硬编码 hint 伪造位置。
单个对象的推荐流程:
1. 打开算力中心或 BGP 观测站详情卡。
2. 点击"自动采集坐标候选"。
3. 等待候选列表返回;有 WebSearch / AI factcheck 依赖的候选会显示采集中状态。
4. 在 Earth 上预览候选位置。
5. 确认可用候选后点击"保存";不确定时关闭卡片不会丢失当前任务状态。
一键定位用于批量处理算力中心待定位队列。它会从列表顶部开始采用最高置信候选;仍没有事实依据的记录会保留在队列中。未开启 WebSearch 时,单个定位和一键定位会置灰,因为位置核验依赖事实查询。
### 设置
@@ -354,7 +364,7 @@ Earth 预留了动作捕捉控制入口。实时链路两种输入源:
文档站 `http://localhost:3000/docs` 由后端按权限读取,不再把全部 Markdown 直接打进前端构建产物。
未登录访客默认只能看到 `public` 文档:首页、快速开始、使用手册、常见问题、Earth 位置候选采集使用手册。登录用户被分配 Gatekeeper 权限组后可以看到更多技术文档:
未登录访客默认只能看到 `public` 文档:首页、快速开始、使用手册、常见问题。登录用户被分配 Gatekeeper 权限组后可以看到更多技术文档:
- `docs_user`:用户操作类文档
- `docs_developer`Earth、前端、后端、采集器和 AI Provider 等开发文档
@@ -368,5 +378,4 @@ Docs 支持分类导航、Markdown 渲染、表格和代码块、文档内目录
- [快速开始](/home/ray/dev/linkong/planet/docs/technical/zh/quickstart.md)
- [常见问题](/home/ray/dev/linkong/planet/docs/technical/zh/faq.md)
- [Earth 位置候选采集使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-user.md)
- [Planet 运维手册](/home/ray/dev/linkong/planet/docs/technical/zh/ops-runbook.md)

View File

@@ -15,7 +15,7 @@
| English / Key | 中文显示名 | 使用场景 |
| --- | --- | --- |
| Planet | Planet | 产品名,保留英文 |
| Admin Next | 控制台 | 新版管理端上下文 |
| Admin | 控制台 | 管理端上下文 |
| Earth | Earth | 地球可视化产品名,保留英文 |
| datasource | 数据源 | API、列表、筛选 |
| collector | 采集器 | 采集任务、凭证配置 |

View File

@@ -136,6 +136,20 @@
- 手机或平板演示 Earth
- 局域网其他机器访问同一开发实例
Windows 侧可以使用仓库根目录的 `planet.cmd` 作为一键入口。它会请求管理员权限,进入 `Ubuntu` WSL 发行版的 `/home/linkong/planet`,执行 `./planet.sh restart --allow-lan`,成功后打开 `http://localhost:3000/earth`,并把终端停留在 WSL shell 中便于继续排查日志。若本机发行版名称或项目路径不同,需要先按实际环境调整 `planet.cmd` 中的 `wsl.exe -d ... --cd ...` 参数。
新机器优先确认 WSL 版本:
```powershell
wsl -l -v
```
Planet 开发环境建议使用 WSL2。WSL1 下网络、文件系统和进程模型与 Linux 差异更大,可能表现为 Bun 包管理命令只返回 `An unknown error occurred (Unexpected)`、端口释放不稳定,或局域网访问行为与脚本预期不一致。若发行版仍是 WSL1可转换
```powershell
wsl --set-version Ubuntu 2
```
`--allow-lan` 会让前端、后端和 AI Provider 直接对开发机开放:前端 `3000`、后端 `8000`、AI Provider `8010`。脚本启动前会检查这三个端口;如果 WSL/Linux 侧无法释放端口,并检测到 Windows 侧 listener 或旧 `portproxy`,会请求管理员 PowerShell 清理。WSL 中运行时Windows 本机一般可以通过 `localhost` 访问,局域网其他机器访问 Windows 局域网 IP 时还需要 Windows 防火墙放行。
建议按顺序排查:
@@ -200,13 +214,32 @@ AI Provider 镜像只在代码、Dockerfile、Compose 配置或相关 Python 依
./planet.sh restart -a
```
重建判断使用内容 fingerprint而不是只看文件 mtime。`planet.sh` 会把 `aiprovider/` 文件、`aiprovider/Dockerfile``pyproject.toml``uv.lock``PYTHON_IMAGE``UV_IMAGE` 和依赖指纹合成 `AI_PROVIDER_BUILD_FINGERPRINT`,构建时写入镜像 label `planet.aiprovider.build-fingerprint`。如果现有 `planet-aiprovider:latest` 镜像的 label 与当前 fingerprint 一致,脚本会跳过 rebuild 并刷新本地 stamp旧镜像没有 label 时才回退到 state/cache 里的 stamp 判断。
Docker 构建统一使用 `uv sync --frozen`。为了让容器构建也能复用本机 uv 镜像源配置,脚本会解析以下顺序中的第一个配置文件,并通过 BuildKit secret 挂到容器内 `/root/.config/uv/uv.toml`
1. 当前环境的 `UV_CONFIG_FILE`
2. 仓库根目录 `uv.toml`
3. `${XDG_CONFIG_HOME:-~/.config}/uv/uv.toml`
4. `~/.uv/uv.toml`
如果都不存在,脚本会创建一个空的 state 文件作为 secret避免 Compose 的 secret file 缺失。进入 Docker 构建前会清掉 `UV_DEFAULT_INDEX``UV_INDEX_URL``UV_EXTRA_INDEX_URL` 这类环境变量,只保留明确的 `UV_CONFIG_FILE`,让本地和容器里的依赖解析更可复现。需要临时使用清华源时,可在仓库根目录准备:
```toml
[[index]]
name = "tsinghua"
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/"
default = true
```
构建较慢时按层排查:
| 现象 | 常见原因 | 处理方式 |
| --- | --- | --- |
| `transferring context` 很大 | build context 含前端资源等无关文件 | `.dockerignore` 只发送必需文件 |
| `uv sync` 下载较慢 | 首次构建缓存为空 | 等待首次完成,后续复用 BuildKit 缓存 |
| `uv sync --frozen` 下载较慢 | 首次构建缓存为空或 uv 镜像源未配置 | 等待首次完成,后续复用 BuildKit 缓存;必要时配置 `uv.toml` |
| 改密钥后仍是旧配置 | 容器未重启 | `./planet.sh restart -a` |
| 修改代码但镜像未重建 | fingerprint 与镜像 label 一致 | 确认改动是否进入 `aiprovider/`、Dockerfile 或 Python 依赖;必要时删除 `planet-aiprovider:latest` 后重试 |
## SMTP 邮件(公开注册依赖)
@@ -233,6 +266,15 @@ OTP 一次性验证码走 Rediskey 格式 `otp:{purpose}:{email}`TTL 600
## 开发命令约定
后端和脚本初始化统一使用锁文件:
```bash
uv python install 3.14
uv sync --frozen --group dev
```
`--frozen` 会拒绝隐式改写 `uv.lock`适合新机器、CI 和 Docker 构建。需要升级依赖时,应先在开发机明确更新 `pyproject.toml` / `uv.lock`,再提交锁文件。
前端必须使用 Bun
```bash

View File

@@ -0,0 +1,160 @@
# 业务架构与数据流转
本文是 Planet 数据产品的业务入口。它解释每类 Earth 数据为什么存在、从哪里采集、落到哪些事实表或派生表、如何通过缓存和 WebSocket 反映到 Earth。前端、后端和 Earth 技术文档只记录实现细节;跨端理解数据链路时优先从这里开始。
## 总览
Planet 的核心数据链路分三段:
1. **采集与整理**:内置采集器、后台操作或定位管线写入 PostgreSQL。通用原始结果进入 `collected_data`,图层需要的二次结果进入派生表。
2. **投影与广播**:数据库触发器把事实变化写入 `earth_data_change_events` outbox并用 `LISTEN/NOTIFY` 唤醒后端 listener。listener 通过 layer adapter 找到 Earth 图层,失效缓存并广播 `earth_updates`
3. **Earth 重拉与呈现**Earth 前端收到 layer 级刷新提示后,按 `clear_then_reload``reload``delta` 策略清理本地图层对象,再从 `/api/v1/visualization/...` 重拉数据。
```mermaid
flowchart LR
Source["外部数据源 / 后台操作"] --> Collector["采集器或数据作业"]
Collector --> Facts["collected_data"]
Collector --> Derived["派生表"]
Facts --> Outbox["earth_data_change_events"]
Derived --> Outbox
Outbox --> Listener["DB change listener"]
Listener --> Cache["Earth cache invalidation"]
Listener --> WS["earth_updates"]
WS --> Earth["Earth layer reload"]
Earth --> API["Visualization APIs"]
```
`LISTEN/NOTIFY` 只负责低延迟唤醒,可靠来源是 outbox。真实 0 数据是正常状态,接口应返回 200 和空集合;只有接口异常才返回 5xx。
## 数据产品清单
```mermaid
flowchart TB
Satellites["卫星 TLE"] --> SatelliteLayer["satellites 图层"]
Cables["海缆 + 登陆点"] --> CableLayer["cables 图层"]
Compute["TOP500 / AI GPU / HF"] --> ComputeLocations["compute_center_locations"]
ComputeLocations --> ComputeLayer["computeCenters 图层"]
BgpRaw["RIS Live / BGPStream / Prefix"] --> BgpDerived["bgp_observations / anomalies / incidents"]
BgpDerived --> BgpLayer["bgp 图层"]
VesselRaw["AIS / BarentsWatch"] --> VesselDerived["vessel_static / vessel_position"]
VesselDerived --> VesselLayer["vessels 图层"]
Interactables["earth_interactables"] --> InteractableLayer["interactables 图层"]
NewsRaw["RSS / Live / News"] --> NewsItems["earth_news_items"]
NewsItems --> NewsLayer["news / media 图层"]
```
| 数据产品 | 业务用途 | 事实来源 | 派生 / 维表 | Earth 图层 | 刷新策略 |
| --- | --- | --- | --- | --- | --- |
| 卫星 | 展示在轨目标、轨迹、覆盖和巡航目标 | `celestrak_tle``spacetrack_tle` | 无稳定独立派生表TLE 由接口实时转换 | `satellites` | `clear_then_reload` |
| 海缆与登陆点 | 展示跨洋连接、登陆点和 cable 详情 | `arcgis_cables``arcgis_landing_points`、TeleGeography / FAO landing sources | 海缆关系和登陆点聚合数据 | `cables` | `clear_then_reload` |
| 算力中心 | 展示 TOP500、AI GPU、HuggingFace 等算力节点 | `top500``epoch_ai_gpu`、HuggingFace sources | `compute_center_locations` | `computeCenters` | `reload` |
| BGP 态势 | 展示观测站、异常事件、路由事件和区域态势 | `ris_live_bgp``bgpstream_bgp`、prefix geography sources | `bgp_observations``bgp_anomalies``bgp_incidents``bgp_collector_locations` | `bgp` | `clear_then_reload` |
| 船舶 | 展示 AIS 船只、位置、轨迹和源健康 | AIS sources、`barentswatch_vessels` | `vessel_static``vessel_position``ais_raw_observations``ais_source_health` | `vessels` | `clear_then_reload` |
| 可交互对象 | 支撑通用地表图标、人工点位和未来扩展对象 | `earth_interactables` | 无 | `interactables` | `delta` |
| 新闻与媒体 | 支撑 Earth 新闻、直播和巡航摘要 | news sources | `earth_news_items` | `news` / `media` | `reload` |
## 卫星链路
卫星数据用于 Earth 的在线卫星点、轨迹线、覆盖策略和巡航列表。采集器从 CelesTrak 或 Space-Track 拉取 TLE写入 `collected_data`。可视化接口按请求把 TLE 转成当前时刻的位置和轨迹,不依赖长期派生表。
- **采集入口**CelesTrak TLE、Space-Track TLE。
- **事实表**`collected_data.source IN ('celestrak_tle', 'spacetrack_tle')`
- **接口**:卫星 visualization API 读取 TLE 并生成 Earth payload。
- **删除语义**:删除对应 source 后listener 广播 `satellites``clear_then_reload`,前端先清卫星点和轨迹,再重拉接口。接口若无 TLE应返回空列表。
- **常见异常**summary 已变 0 但 Earth 仍显示,通常是 WS 未触发、adapter 未覆盖 source或前端没有在 `clear_then_reload` 中清掉已有 Three.js 对象。
## 海缆与登陆点链路
海缆和登陆点用于展示跨海网络连接、登陆城市、线路详情和搜索对象。海缆线与登陆点都属于同一个业务图层;删除任一侧数据都必须刷新 `cables`,否则会出现线消失但点残留,或点消失但线残留。
- **采集入口**ArcGIS cables、ArcGIS landing points以及 TeleGeography / FAO landing 相关 source。
- **事实表**`collected_data` 中的 cable 和 landing point source。
- **派生数据**海缆关系表、landing point 聚合结果、接口缓存。
- **接口**:海缆 visualization API 返回 cables、landing points 和关系数据。
- **删除语义**:删除海缆或登陆点 source 后adapter 清理 owned 派生数据并广播 `cables``clear_then_reload`。接口没有数据时返回 200 空集合,不返回 404。
- **常见异常**:海缆短暂变 0 又回来,多半是采集替换或缓存刷新窗口内旧缓存被重新命中,需要检查数据作业是否重复广播或 cache pattern 是否覆盖完整。
## 算力中心链路
算力中心用于展示超算、AI GPU、模型平台相关设施和位置补全状态。原始 source 通常只有机构、国家、站点名或模糊位置Earth 渲染依赖 `compute_center_locations` 维表提供可用坐标。
- **采集入口**TOP500、Epoch AI GPU、HuggingFace 相关 source。
- **事实表**`collected_data` 中的算力 source。
- **维表**`compute_center_locations` 保存人工或自动采集到的坐标候选采用结果。
- **接口**:算力中心 visualization API 合并原始记录和位置维表。
- **删除语义**:删除 TOP500 等 source 后必须刷新 `computeCenters`;删除位置维表则也要刷新该图层。通常用 `reload`,因为位置更新不一定需要先清空。
- **常见异常**:采集已完成但 Earth 数量不变,通常是接口使用缓存、位置维表未更新,或 source 删除没有触发 adapter。
## BGP 链路
BGP 数据用于展示路由观测站、异常事件、事件扩散圈和态势摘要。Earth 不直接展示原始 BGP 行,而是展示聚合后的观测、异常和事件。因此 BGP 是最容易出现“原始数据删了但 Earth 还在”的链路。
```mermaid
sequenceDiagram
participant UI as 后台删除按钮
participant Job as clear_data 作业
participant DB as PostgreSQL
participant Outbox as earth_data_change_events
participant Listener as DB change listener
participant Earth as Earth 前端
UI->>Job: 提交删除 ris_live_bgp / bgpstream_bgp
Job->>DB: 删除 collected_data 原始记录
Job->>DB: 删除 BGP owned 派生表
DB->>Outbox: trigger 写入 bgp layer changed
DB-->>Listener: LISTEN/NOTIFY 唤醒
Listener->>Listener: 合并事件并清理 bgp cache
Listener-->>Earth: broadcast earth_updates clear_then_reload
Earth->>Earth: 清空 BGP 对象
Earth->>DB: 通过 visualization API 重拉派生结果
```
- **采集入口**RIPE RIS Live BGP、CAIDA BGPStream Backfill、IPtoASN / OpenGeoFeed / NRO prefix geography。
- **事实表**`collected_data` 中的 BGP 和 prefix source。
- **派生表**`bgp_observations``bgp_anomalies``bgp_incidents``bgp_collector_locations`
- **接口**BGP visualization API 读取派生表,并结合定位候选或已保存位置。
- **删除语义**:删除 RIS Live 或 BGPStream 原始 source 时,必须同步清理 BGP owned 派生表并广播 `bgp``clear_then_reload`。直接删除派生表也要触发 outbox。
- **常见异常**:观测站或异常事件没有消失,优先查派生表是否还保留旧记录,而不是只看 `collected_data`
## 船舶链路
船舶数据用于展示 AIS 船只、航行状态、船型图例和源健康。Earth 渲染使用位置快照和静态船舶信息,不应依赖原始 AIS 记录逐条渲染。
- **采集入口**AIS sources、BarentsWatch vessels。
- **事实表**`collected_data` 或 AIS 原始观测表。
- **派生表**`vessel_static``vessel_position``ais_raw_observations``ais_source_health`
- **接口**vessels visualization API 返回当前船只 marker 和必要详情。
- **删除语义**:删除任一船舶 source 后owned 派生表变化会广播 `vessels``clear_then_reload`
- **常见异常**:数量面板变化但船只仍在,多半是 summary 和图层数据分离,前端应以 layer update 为准清空对象。
## 可交互对象链路
`earth_interactables` 是通用地表图标能力,用于人工对象、扩展对象和未来小型图层。它和大多数图层不同,保留对象级 delta。
- **事实表**`earth_interactables`
- **接口**interactable API 和 Earth 通用图标接口。
- **刷新策略**:新增或更新用 upsert删除用 removeItem不重拉整个图层。
- **删除语义**:删除一条 interactable 后WS payload 必须包含稳定 id让前端移除对应对象。
- **常见异常**:对象删不掉,通常是缺少稳定 id、前端 delta handler 没有命中 object type或旧图层还有重复渲染路径。
## 新闻与媒体链路
新闻与媒体数据用于 Earth 顶部新闻条、直播面板、新闻巡航和态势摘要。它们的视觉状态比地理对象更偏内容刷新,因此默认使用 `reload`
- **采集入口**RSS、直播源、新闻 source。
- **事实表**:新闻 source 的 `collected_data`
- **派生表**`earth_news_items`
- **接口**:新闻、直播和媒体 visualization / content API。
- **删除语义**:删除新闻 source 或 `earth_news_items` 后广播 `news` / `media` reload前端重拉后列表为空即隐藏对应内容。
- **常见异常**:直播面板仍显示旧内容,通常是媒体组件本地状态没有响应 layer update或内容接口缓存未失效。
## 扩展新图层
新增 Earth 数据产品时,按这个顺序接入:
1. 定义业务用途和 Earth 图层名。
2. 明确事实 source、事实表和派生表。
3. 在后端 layer adapter 注册 source/table、cache pattern、owned derived cleanup 和默认刷新策略。
4. 确保 visualization API 对空数据返回 200 空集合。
5. 让 Earth 前端只按 layer 和 strategy 刷新,不理解数据库表名。
6. 在本文补充该数据产品的链路,再到对应前端、后端或 Earth 技术文档记录实现细节。

View File

@@ -64,5 +64,5 @@
- 完整 UI 操作说明:[Planet 使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/manual.md)
- 排障与配置疑问:[常见问题](/home/ray/dev/linkong/planet/docs/technical/zh/faq.md)
- Earth 坐标候选采集详细流程:[Earth 位置候选采集使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/location-pipeline-user.md)
- Earth 坐标候选采集流程见 [Planet 使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/manual.md) 的 Earth 章节
- 部署 / 运维相关命令:[Planet 运维手册](/home/ray/dev/linkong/planet/docs/technical/zh/ops-runbook.md)

View File

@@ -1,13 +1,13 @@
# Tactile UI 组件库
Tactile UI 是 Planet 内部抽出的可移植 React 控件层。它来自 Admin Next 的按钮、开关、滚动条和 tooltip 收口,但组件本身不依赖 Admin Next、AntD、Radix、Tailwind 或 `an-*` class。目标是先在仓库内稳定使用后续可以作为独立 npm 包发布。
Tactile UI 是 Planet 内部抽出的可移植 React 控件层。它来自 Admin 的按钮、开关、滚动条和 tooltip 收口,但组件本身不依赖 Admin、AntD、Radix、Tailwind 或 `an-*` class。目标是先在仓库内稳定使用后续可以作为独立 npm 包发布。
## 设计目标
- **轻触感**:默认控件使用白色或主题表面、细边框和外部投影,接近 Docs 主题滑块的轻微立体感,不使用大色块或发光效果。
- **可移植**:组件 class 使用 `tui-*` 前缀,样式集中在 `frontend/src/components/tactile-ui/styles.css`
- **低依赖**:组件只假设 React/React DOM图标预设当前使用 `lucide-react`,调用方也可以传自定义 React 节点。
- **主题友好**:默认样式通过 CSS variables 暴露Planet 可以在 Admin Next 或其它页面按主题覆盖 token。
- **主题友好**:默认样式通过 CSS variables 暴露Planet 可以在 Admin 或其它页面按主题覆盖 token。
- **语义清楚**:无歧义操作优先 icon-only + tooltip保存、确认、创建、执行这类强意图操作可以保留文字。
## 导入
@@ -51,19 +51,19 @@ import '@planet/tactile-ui/styles.css'
## Portal 与深色主题
`TactileTooltip` 和使用 Tactile UI 的 Admin Next `Dialog``Select`、Toast 都可能通过 portal 挂到 `document.body`。这类节点不在 `.admin-next-theme-root[data-theme='dark']` 下面,不能只依赖局部祖先选择器读取深色 token。
`TactileTooltip` 和使用 Tactile UI 的 Admin `Dialog``Select`、Toast 都可能通过 portal 挂到 `document.body`。这类节点不在 `.admin-theme-root[data-theme='dark']` 下面,不能只依赖局部祖先选择器读取深色 token。
Admin Next 的主题 provider 会把当前主题同步到 `body[data-admin-next-theme]`。共享样式必须同时支持两类选择器:
Admin 的主题 provider 会把当前主题同步到 `body[data-admin-theme]`。共享样式必须同时支持两类选择器:
```css
[data-theme='dark'] .tui-button,
body[data-admin-next-theme='dark'] .tui-button {
body[data-admin-theme='dark'] .tui-button {
--tui-surface: #172033;
--tui-text: #e5edf8;
}
```
新增 portal 控件时,先确认它是否渲染到 body。如果是就要在组件自己的样式入口补 `body[data-admin-next-theme='dark']` 分支,或复用已经覆盖过的 `--tui-*` / `--an-*` token。不要在单个弹窗里手写固定深色因为同一问题会在下拉菜单、tooltip、toast 和确认弹窗里重复出现。
新增 portal 控件时,先确认它是否渲染到 body。如果是就要在组件自己的样式入口补 `body[data-admin-theme='dark']` 分支,或复用已经覆盖过的 `--tui-*` / `--an-*` token。不要在单个弹窗里手写固定深色因为同一问题会在下拉菜单、tooltip、toast 和确认弹窗里重复出现。
## `TactileButton`
@@ -195,7 +195,7 @@ Textarea 不建议强行套 overlay 滚动条,因为浏览器 resize grip 和
## `TableScrollRegion`
`TableScrollRegion` 是表格滚动区域的便利封装。默认目标选择器是 `.tui-scroll-target`Admin Next 会显式传自己的 table viewport selector避免组件库里出现业务命名。
`TableScrollRegion` 是表格滚动区域的便利封装。默认目标选择器是 `.tui-scroll-target`Admin 会显式传自己的 table viewport selector避免组件库里出现业务命名。
```tsx
<TableScrollRegion targetSelector=".table-viewport">
@@ -210,9 +210,9 @@ Textarea 不建议强行套 overlay 滚动条,因为浏览器 resize grip 和
- tooltip 只是说明不承担唯一状态表达状态仍应通过文本、badge 或 `aria-*` 呈现。
- 禁用和 loading 状态会设置 `aria-disabled`button 元素会同步 `disabled`
## Admin Next 迁移约定
## Admin 迁移约定
Admin Next 中所有全局工具按钮、详情页工具按钮和列表底部动作应使用 Tactile UI
Admin 中所有全局工具按钮、详情页工具按钮和列表底部动作应使用 Tactile UI
- 无歧义动作:`TactileButton iconOnly tooltip`
- 保存/创建/确认:`TactileButton variant="primary"`,通常保留文字

View File

@@ -16,12 +16,13 @@
## Current Version
- `main` 当前主线历史推导到:`0.16.5`
- `dev` 当前开发分支历史推导到:`0.65.2`
- `dev` 当前开发分支历史推导到:`0.66.0`
## Timeline
| Version | Type | Branch | Commit | Summary |
| --- | --- | --- | --- | --- |
| `0.66.0` | feature | `dev` | `pending` | Admin 正式化为唯一控制台,新增数据作业/outbox 与 Earth interactables 管线,补齐 AI/采集日志,修复 CelesTrak 完整 active 目录采集和内置源启停判断 |
| `0.65.2` | bugfix | `dev` | `pending` | AI Provider 镜像重建判定改为内容 fingerprint 与镜像 label启动链路改用 frozen uv避免用户级镜像源污染 `uv.lock`,并加入 Windows 一键启动脚本 |
| `0.65.1` | bugfix | `dev` | `pending` | 统一 `planet.sh` 与 Compose 的 AI Provider 镜像名,并让本地和 Docker build 通过用户级 `uv.toml` 共享 uv 源配置,避免镜像源污染 `uv.lock` |
| `0.65.0` | feature | `dev` | `pending` | Admin Next 数据源触发入口收敛为“触发全部/触发已选 N”队列改为右上角浮层按钮并强化 `planet.sh destroy` 的 OOBE 数据清理 |