From 4306b54c9f01f7c98d78b7fd2d4f082d1ade7a63 Mon Sep 17 00:00:00 2001 From: 5027 <326748487@qq.com> Date: Fri, 11 Sep 2026 13:41:16 +0800 Subject: [PATCH] =?UTF-8?q?chore(repo):=20Remove=20unused=20files=20/=20?= =?UTF-8?q?=E6=B8=85=E7=90=86=E6=97=A0=E7=94=A8=E6=96=87=E4=BB=B6=E4=B8=8E?= =?UTF-8?q?=E8=BF=87=E6=97=B6=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit English: - Remove 24 redundant or unused files: duplicate READMEs, the one-off handoff prompt, an obsolete change note, debug HTML, five empty packages, the disconnected planner and its tests, ten unused SVGs, and a generated region report. - Update references, actual architecture, deployment credential semantics, completed handoff status and report ignore rules. Keep historical release and promotion material clearly marked instead of treating it as current instructions. - Add a maintenance audit with seven unresolved issues and five verified missing region files. Active runtime logic, real geometry, compatibility tables and UI regressions remain; no production deployment or region download was performed. 中文: - 删除 24 个重复或无用文件,包括重复 README、一次性交接提示、旧变更说明、调试页面、五个空包、未接入的 planner 及测试、十个无引用 SVG 和生成报告。 - 修正引用、实际架构、部署账号语义、已完成交接状态及报告忽略规则;历史发布和推广材料明确标为旧资料。 - 新增维护清单,列出七项未解决问题及五个已核实缺失区域;保留有效运行逻辑、真实几何、兼容表和页面回归,没有生产部署或区域下载。 Validation: - From apps/admin-region-tiler: node scripts/release_preflight.mjs passed, including go test ./..., JavaScript syntax, rendering security, real API lifecycle tests, 390/768/1440px browser regressions, preview renewal, session re-login, sensitive-value and generated-file scans / 完整发布预检通过。 - From apps/admin-region-tiler: go vet ./... passed / 通过。 - Inline Node assertions passed: 35 local documentation links, 24 direct static references, 11 dynamic icons, six unused package dependencies absent, both report paths ignored / 链接、资源、导入和忽略规则校验通过。 - Region catalog metadata audit: 3227 entries and exactly five missing files; no geometry writes / 区域目录核对确认五项缺口,未修改几何。 - python C:/Users/32674/.codex/skills/deep-execution-upgrade/scripts/audit_environment.py --mode workspace --workspace . --format text: no high-signal drift / 无明显漂移。 - python C:/Users/32674/.codex/skills/deep-execution-upgrade/scripts/validate_handoff_contract.py --path docs/long-term-memory.md --format text: valid / 通过。 - git diff --check and changed-document sensitive-value review passed / 差异及新增文档敏感值检查通过。 - Local race checks not run because Windows lacks the required C compiler; Linux CI runs go test -race ./... before merge / 本地 race 受编译器限制,合并前由 Linux CI 验证。 - Python region maintenance tools were reviewed but not executed against providers or deployment directories / 区域维护工具仅审查,未调用真实服务或覆盖部署目录。 --- .gitignore | 2 + README_ZH.md | 110 ---------- RELEASE_HANDOFF_PROMPT.md | 44 ---- apps/admin-region-tiler/.dockerignore | 2 + apps/admin-region-tiler/CHANGES.md | 6 - apps/admin-region-tiler/README-EN.md | 79 -------- apps/admin-region-tiler/README.md | 22 +- apps/admin-region-tiler/deploy/DEPLOYMENT.md | 32 ++- .../geojson/materialize-report.json | 30 --- apps/admin-region-tiler/internal/api/doc.go | 3 - .../internal/artifact/doc.go | 3 - apps/admin-region-tiler/internal/auth/doc.go | 2 - .../admin-region-tiler/internal/config/doc.go | 3 - .../internal/downloader/doc.go | 4 +- .../internal/planner/doc.go | 4 - .../internal/planner/model.go | 191 ------------------ .../internal/planner/model_test.go | 89 -------- apps/admin-region-tiler/internal/web/doc.go | 2 - .../static/assets/icons/calendar.svg | 5 - .../static/assets/icons/clock.svg | 5 - .../static/assets/icons/error.svg | 5 - .../static/assets/icons/filter.svg | 5 - .../static/assets/icons/folder.svg | 5 - .../static/assets/icons/pause.svg | 5 - .../static/assets/icons/play.svg | 5 - .../static/assets/icons/search.svg | 5 - .../static/assets/logo/logo.svg | 7 - apps/admin-region-tiler/static/favicon.svg | 6 - apps/admin-region-tiler/static/test.html | 38 ---- docs/ai-operating-handbook.md | 16 +- docs/automation-guardrails.md | 4 +- docs/github-growth-playbook.md | 4 + docs/long-term-memory.md | 19 +- docs/maintenance-audit-2026-09-11.md | 70 +++++++ docs/merge-plan.md | 16 +- docs/project-map.md | 14 +- docs/releases/v0.1.0.md | 4 + 37 files changed, 159 insertions(+), 707 deletions(-) delete mode 100644 README_ZH.md delete mode 100644 RELEASE_HANDOFF_PROMPT.md delete mode 100644 apps/admin-region-tiler/CHANGES.md delete mode 100644 apps/admin-region-tiler/README-EN.md delete mode 100644 apps/admin-region-tiler/geojson/materialize-report.json delete mode 100644 apps/admin-region-tiler/internal/api/doc.go delete mode 100644 apps/admin-region-tiler/internal/artifact/doc.go delete mode 100644 apps/admin-region-tiler/internal/auth/doc.go delete mode 100644 apps/admin-region-tiler/internal/config/doc.go delete mode 100644 apps/admin-region-tiler/internal/planner/doc.go delete mode 100644 apps/admin-region-tiler/internal/planner/model.go delete mode 100644 apps/admin-region-tiler/internal/planner/model_test.go delete mode 100644 apps/admin-region-tiler/internal/web/doc.go delete mode 100644 apps/admin-region-tiler/static/assets/icons/calendar.svg delete mode 100644 apps/admin-region-tiler/static/assets/icons/clock.svg delete mode 100644 apps/admin-region-tiler/static/assets/icons/error.svg delete mode 100644 apps/admin-region-tiler/static/assets/icons/filter.svg delete mode 100644 apps/admin-region-tiler/static/assets/icons/folder.svg delete mode 100644 apps/admin-region-tiler/static/assets/icons/pause.svg delete mode 100644 apps/admin-region-tiler/static/assets/icons/play.svg delete mode 100644 apps/admin-region-tiler/static/assets/icons/search.svg delete mode 100644 apps/admin-region-tiler/static/assets/logo/logo.svg delete mode 100644 apps/admin-region-tiler/static/favicon.svg delete mode 100644 apps/admin-region-tiler/static/test.html create mode 100644 docs/maintenance-audit-2026-09-11.md diff --git a/.gitignore b/.gitignore index 6d14ec6..2b8d997 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,8 @@ run.stderr.log .tmp-region-data/ tmp/ .playwright-mcp/ +apps/admin-region-tiler/geojson/materialize-report.json +apps/admin-region-tiler/geojson/download-report.json # OS/editor noise .DS_Store diff --git a/README_ZH.md b/README_ZH.md deleted file mode 100644 index e7f8890..0000000 --- a/README_ZH.md +++ /dev/null @@ -1,110 +0,0 @@ -# Map Tile Fetcher - -一个自托管的 Go Web 地图瓦片下载工具,支持按地图框选范围或 -GeoJSON/行政区划创建下载任务,并导出 ZIP 文件树或 MBTiles。 - -> 请只用于你有权访问和下载的地图瓦片服务。项目提供限速、重试和本地 -> token 配置能力,但不会授权绕过任何第三方服务条款、配额或访问限制。 - - - -## 适合谁 - -- 需要在内网或自己的服务器上运行地图瓦片下载工具的 GIS/地图开发者。 -- 需要按矩形 bbox、行政区划或 GeoJSON 范围批量生成离线瓦片的人。 -- 需要把授权地图源导出为 ZIP 文件树或 MBTiles 的项目维护者。 -- 想要一个 Go + SQLite + 静态 Web UI 的轻量自托管方案的团队。 - -## 核心能力 - -- **范围框选下载**:在 Leaflet 地图上框选 bbox,自动估算瓦片数量和体积。 -- **行政区划/GeoJSON 下载**:按内置区域目录或 GeoJSON 层级创建任务。 -- **多地图源配置**:支持天地图、Mapbox、OSM、Google 样例和自定义瓦片 URL。 -- **任务和产物管理**:查看进度、失败记录、重试失败瓦片,并下载 ZIP/MBTiles。 - -## 三分钟启动 - -```powershell -git clone https://github.com/Joe5027/map-tile-fetcher.git -cd map-tile-fetcher\apps\admin-region-tiler -go run . -``` - -打开 `http://127.0.0.1:8081/`。 - -开发默认账号: - -- 用户名:`admin` -- 密码:`adminmap` - -生产部署时请复制 `.env.example` 为 `.env`,并修改默认账号和密码。 - -## Docker 启动 - -```powershell -cd apps\admin-region-tiler -Copy-Item .env.example .env -docker compose up --build -``` - -默认端口是 `8081`。可以在 `.env` 中调整 `HOST_PORT`、`APP_PORT`、 -`APP_DATABASE`、`AUTH_DEFAULT_USERNAME` 和 `AUTH_DEFAULT_PASSWORD`。 - -## 使用流程 - -### 1. 范围框选下载 - - - -1. 登录后选择“范围框选下载”。 -2. 输入授权服务的 token,或选择不需要 token 的自定义地图源。 -3. 在地图上框选范围,设置最小/最大 zoom。 -4. 选择 ZIP 文件树或 MBTiles,创建任务。 - -### 2. 任务和产物下载 - - - -任务完成后可以在任务列表中查看成功数、失败数、产物状态,并下载生成的 -ZIP 或 MBTiles。失败记录会持久化,便于调整并发、请求间隔或代理后重试。 - -## 配置地图源 - -示例配置在 `apps/admin-region-tiler/conf.toml`。 - -安全占位符: - -- `YOUR_TIANDITU_TOKEN` -- `YOUR_MAPBOX_TOKEN` -- `YOUR_MAPBOX_SKU` - -真实 token 只应保存在本地 `.env`、本地配置或部署平台的密钥管理中,不要提交到 Git。 - -## 发布和安装 - -- 发布说明:[`docs/releases/v0.1.0.md`](docs/releases/v0.1.0.md) -- 中文用户手册:[`docs/user-manual-zh.md`](docs/user-manual-zh.md) -- English manual: [`docs/user-manual.md`](docs/user-manual.md) - -当前仓库可通过源码或 Docker 直接运行。GitHub Release 创建后,`v0.1.0` -会提供 Windows 和 Linux 二进制资产。 - -## 开发者验证 - -```powershell -cd apps\admin-region-tiler -node .\scripts\release_preflight.mjs -``` - -发布预检会运行 Go 测试、JavaScript 检查、浏览器 UI 冒烟、敏感值扫描和 -tracked 生成物扫描。 - -## 项目历史 - -旧 .NET 范围下载器运行代码已退休。bbox 框选流程已经迁移到 -`apps/admin-region-tiler` 的 Go Web 应用中;历史说明见 -[`docs/range-migration.md`](docs/range-migration.md)。 - -## 许可证 - -Apache License 2.0。详见 [`LICENSE`](LICENSE)。 diff --git a/RELEASE_HANDOFF_PROMPT.md b/RELEASE_HANDOFF_PROMPT.md deleted file mode 100644 index 464db26..0000000 --- a/RELEASE_HANDOFF_PROMPT.md +++ /dev/null @@ -1,44 +0,0 @@ -# Release Handoff Prompt - -你正在接手一个准备 GitHub 开源的 Map Tile Fetcher 仓库。当前仓库只保留一个可运行项目: - -- `apps/admin-region-tiler` - - Go 1.25+ Web 项目 - - 功能重点:范围框选下载、行政区划 GeoJSON 下载、多地图源、多任务/子任务、计划任务、SQLite 控制数据库、失败记录、产物下载、Docker/服务部署 - -旧 .NET 范围下载器已退休: - -- 原目录:`apps/range-downloader` -- 原交接来源:`01-TianDiTuDownLoader_web` -- 迁移说明:`docs/range-migration.md` -- 不要重新把旧运行代码、旧发布包、截图、UI 设计包、tmp、templates 或运行数据混进仓库。 - -请按这个顺序接手: - -1. 先阅读 `PROJECT_MANIFEST.md`,确认当前只包含 `apps/admin-region-tiler` 一个可运行项目。 -2. 检查敏感信息: - - 运行当前交接要求的敏感值扫描。 - - 同时参考 `docs/done-definition.md` 中的通用扫描规则。 - 期望没有真实 token 或密码,只允许看到 `YOUR_TIANDITU_TOKEN`、`YOUR_MAPBOX_TOKEN` 这种占位符。 -3. 验证 Go 项目: - - `cd apps/admin-region-tiler` - - 安装/使用 Go 1.25+ - - 安装/使用 Node.js 22+ 或当前稳定版本 - - 如需运行 UI 冒烟测试,确保本地或全局可用 Playwright,并安装 Chromium: - `npm install -g playwright` 和 `npx playwright install chromium` - - 执行 `go test ./...` - - 前端脚本变更后执行 `node --check .\static\script.js` - - 发布前执行完整预检:`node .\scripts\release_preflight.mjs` -4. 不要提交运行目录或构建目录:`.env`、`data/`、`output/`、`tiles/`、`bin/`、`obj/`、`publish*/`、历史二进制和压缩包都不应进 Git。 -5. README 语言分工: - - `README.md`: English - - `README_ZH.md`: 中文 -6. 每一次验证完成的变动都需要立即提交 git,且 commit body 必须有英文、中文和 Validation 三段。 - -当前仓库已完成的合并状态: - -- Go 后端是唯一运行后端。 -- 范围框选下载已迁移到 Go app 的 `mode: "bbox"` 任务。 -- 行政区划下载保留在同一 Go app 中。 -- SQLite 保留为控制数据库,只存任务、运行、任务源、产物和失败记录等元数据。 -- 下载瓦片、MBTiles、ZIP 产物和运行日志走文件系统,不进入 Git。 diff --git a/apps/admin-region-tiler/.dockerignore b/apps/admin-region-tiler/.dockerignore index 1b374da..7f1a6c8 100644 --- a/apps/admin-region-tiler/.dockerignore +++ b/apps/admin-region-tiler/.dockerignore @@ -8,6 +8,8 @@ tiles/ dist/ build/ .tmp-region-data/ +geojson/materialize-report.json +geojson/download-report.json tiler tiler.exe diff --git a/apps/admin-region-tiler/CHANGES.md b/apps/admin-region-tiler/CHANGES.md deleted file mode 100644 index ebbb657..0000000 --- a/apps/admin-region-tiler/CHANGES.md +++ /dev/null @@ -1,6 +0,0 @@ -### 变更说明 - -#### 2022-10-01 - -- 添加 `timedelay` 限速参数 -> 最小延迟时间`timedelay`,单位`ms`,用于请求限速,最准确的控制是将`works`设置为`1`,限速是为最准确最小间隔,若`works > 1`则`timedelay`只是个调和参数 \ No newline at end of file diff --git a/apps/admin-region-tiler/README-EN.md b/apps/admin-region-tiler/README-EN.md deleted file mode 100644 index 0ab3536..0000000 --- a/apps/admin-region-tiler/README-EN.md +++ /dev/null @@ -1,79 +0,0 @@ -# Map Tile Fetcher - -Self-hosted Go Web app for downloading authorized map tiles by bounding box or -GeoJSON/admin regions. It provides a tabbed UI for task creation and task -history, plus ZIP/MBTiles artifacts, retries, and Docker deployment assets. - -> Use this tool only with map tile services that you are authorized to access -> and download. The project does not grant permission to bypass third-party -> terms, quotas, or access controls. - -## Features - -- Bounding-box task creation with a Leaflet map. -- GeoJSON/admin-region task creation. -- Configurable map sources, including Tianditu, Mapbox, OSM, Google examples, - and custom tile URLs. -- Immediate or one-time scheduled tasks. -- ZIP file-tree and MBTiles outputs. -- Task history, progress, failure records, retries, pause/resume/cancel, and - artifact downloads. - -## Run From Source - -```powershell -go run . -``` - -Open `http://127.0.0.1:8081/`. - -Development login: - -- Username: `admin` -- Password: `adminmap` - -Override the default credentials before production deployment. - -## Docker - -This directory already includes the Docker assets needed to build the image: - -- `Dockerfile` -- `docker-compose.yml` -- `.dockerignore` - -Recommended Docker Compose workflow: - -```powershell -Copy-Item .env.example .env -docker compose up --build -d -``` - -Manual image build: - -```powershell -docker build -t map-tile-fetcher:latest . -``` - -Manual run: - -```powershell -docker run --rm --name map-tile-fetcher ` - -p 8081:8081 ` - --env-file .env ` - -v "${PWD}\data:/app/data" ` - -v "${PWD}\output:/app/output" ` - -v "${PWD}\geojson:/app/geojson" ` - -v "${PWD}\conf.toml:/app/conf.toml:ro" ` - map-tile-fetcher:latest -``` - -Use `.env.example` for port, database, timezone, and default auth settings. - -## Validation - -```powershell -go test ./... -node --check .\static\script.js -node .\scripts\release_preflight.mjs -``` diff --git a/apps/admin-region-tiler/README.md b/apps/admin-region-tiler/README.md index d6ee439..e4fce2a 100644 --- a/apps/admin-region-tiler/README.md +++ b/apps/admin-region-tiler/README.md @@ -168,15 +168,17 @@ node .\scripts\release_preflight.mjs ## 当前架构 -新的内部包结构从 `internal/` 开始: - -- `internal/api`:统一 HTTP API。 -- `internal/auth`:可选登录和会话。 -- `internal/config`:应用配置、地图源和输出路径。 -- `internal/area`:bbox 和行政区划区域选择。 -- `internal/planner`:任务定义、运行记录和子任务规划。 -- `internal/downloader`:瓦片枚举、下载、重试和写入。 -- `internal/artifact`:ZIP、MBTiles 和兼容产物。 -- `internal/web`:统一静态前端辅助。 +当前内部包和主应用的职责如下: + +- `internal/area`:bbox 和行政区划参数校验。 +- `internal/downloader`:bbox 瓦片坐标及数量计算。 +- `server.go`、`main.go`、`db.go`:HTTP API、配置、登录、SQLite 事务与迁移。 +- `runtime.go`、`queue.go`:任务控制、持久排队和工作进程调度。 +- `task.go`、`enumeration.go`、`worker_process.go`:枚举、下载、重试和写入。 +- `artifact_lifecycle.go`、`integrity.go`、`reconcile.go`:产物发布、删除、累计完整度与历史核对。 +- `static/`:登录、新建计划、任务管理及地图预览页面。 + +详细入口见 [项目地图](../../docs/project-map.md),清理结果和后续问题见 +[维护清单](../../docs/maintenance-audit-2026-09-11.md)。 旧 `.NET` 范围下载器的框选交互和简单天地图流程已迁移到当前 Go 应用,旧运行代码已退役。 diff --git a/apps/admin-region-tiler/deploy/DEPLOYMENT.md b/apps/admin-region-tiler/deploy/DEPLOYMENT.md index 26c4369..6befef3 100644 --- a/apps/admin-region-tiler/deploy/DEPLOYMENT.md +++ b/apps/admin-region-tiler/deploy/DEPLOYMENT.md @@ -11,8 +11,12 @@ ## Docker 部署 +首次启动前,复制 `.env.example` 为 `.env` 并在本地编辑 +`AUTH_DEFAULT_USERNAME`、`AUTH_DEFAULT_PASSWORD`,保持登录启用。 + ```bash cp .env.example .env +# 编辑 .env 中的初始账号后再启动 docker compose up -d --build ``` @@ -36,8 +40,11 @@ useradd -r -s /usr/sbin/nologin tiler chown -R tiler:tiler /opt/tiler ``` -4. 安装 `deploy/systemd/tiler.service` -5. 执行: +4. 首次启动前,在本地 `conf.toml` 的 `[auth]` 中设置初始用户名和密码,并限制 + 配置文件读取权限。二进制不会自动读取 `.env`;当前 systemd 示例也未配置 + `EnvironmentFile`,仅复制 `.env` 不会生效。 +5. 安装 `deploy/systemd/tiler.service` +6. 执行: ```bash systemctl daemon-reload @@ -59,20 +66,26 @@ systemctl status tiler nginx -t && systemctl reload nginx ``` -## 首次登录 +## 初始账号 - 用户名:`admin` - 密码:`adminmap` -建议上线后第一时间修改默认密码。 +以上仅为开发默认值,部署时需在首次启动前替换。应用没有已实现的改密页面或接口, +修改 `AUTH_DEFAULT_PASSWORD` 不会重置数据库里已有同名用户的密码;不要通过删除 +数据库来改密,以免丢失任务记录。已有默认账号的处置需单独安排。 -`.env` 中可以覆盖: +Docker 的 `.env` 中可以覆盖以下配置;源码或二进制需使用进程环境变量或 +`conf.toml`(`HOST_PORT` 仅用于 Docker 端口映射): - `HOST_PORT` - `APP_PORT` - `APP_DATABASE` - `AUTH_DEFAULT_USERNAME` - `AUTH_DEFAULT_PASSWORD` +- `TASK_MAX_TILES` +- `TASK_MAX_ACTIVE` +- `TASK_WORKERS` ## 数据持久化目录 @@ -107,8 +120,7 @@ nginx -t && systemctl reload nginx ## 删除任务说明 - `取消` 只改变任务状态,不会删除记录 -- `删除` 会彻底删除: - - `plans` 中的任务记录 - - `task_runs` 中的运行记录 - - 该任务对应的产物文件与输出目录 -- `删除` 不会删除共享的 `geojson/` 区域文件 +- `删除` 会清理任务记录、历史运行、产物、失败记录和关联元数据;父任务包括全部子任务。 +- 运行、暂停或打包中的任务需要先取消并等待结束。清理失败后可重试。 +- 内置区域文件和仍有其他任务引用的文件受保护;任务生成的区域文件在最后一个引用解除后清理。 +- 升级前的备份、副本验证和历史核对方式见 [修复验收记录](../../../docs/repair-acceptance-2026-09-11.md)。 diff --git a/apps/admin-region-tiler/geojson/materialize-report.json b/apps/admin-region-tiler/geojson/materialize-report.json deleted file mode 100644 index f112ab1..0000000 --- a/apps/admin-region-tiler/geojson/materialize-report.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "written": 3221, - "missing": [ - { - "id": "460323", - "name": "中沙群岛的岛礁及其海域", - "level": "district" - }, - { - "id": "653228", - "name": "和康县", - "level": "district" - }, - { - "id": "653229", - "name": "和安县", - "level": "district" - }, - { - "id": "659011", - "name": "新星市", - "level": "district" - }, - { - "id": "659012", - "name": "白杨市", - "level": "district" - } - ] -} \ No newline at end of file diff --git a/apps/admin-region-tiler/internal/api/doc.go b/apps/admin-region-tiler/internal/api/doc.go deleted file mode 100644 index e7cf54a..0000000 --- a/apps/admin-region-tiler/internal/api/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package api will own the unified HTTP surface for task creation, task -// controls, configuration, artifacts, and optional authentication. -package api diff --git a/apps/admin-region-tiler/internal/artifact/doc.go b/apps/admin-region-tiler/internal/artifact/doc.go deleted file mode 100644 index 23952af..0000000 --- a/apps/admin-region-tiler/internal/artifact/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package artifact will build and index downloadable outputs such as ZIP, -// MBTiles, and compatibility archives. -package artifact diff --git a/apps/admin-region-tiler/internal/auth/doc.go b/apps/admin-region-tiler/internal/auth/doc.go deleted file mode 100644 index 40cb761..0000000 --- a/apps/admin-region-tiler/internal/auth/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package auth will contain optional local authentication and session helpers. -package auth diff --git a/apps/admin-region-tiler/internal/config/doc.go b/apps/admin-region-tiler/internal/config/doc.go deleted file mode 100644 index 64f4661..0000000 --- a/apps/admin-region-tiler/internal/config/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package config will normalize application settings, map sources, token -// placeholders, output paths, and deployment defaults. -package config diff --git a/apps/admin-region-tiler/internal/downloader/doc.go b/apps/admin-region-tiler/internal/downloader/doc.go index 26cc4ad..d9739bd 100644 --- a/apps/admin-region-tiler/internal/downloader/doc.go +++ b/apps/admin-region-tiler/internal/downloader/doc.go @@ -1,3 +1,3 @@ -// Package downloader will own tile enumeration, fetching, retry, throttling, -// and file or MBTiles writes for unified task runs. +// Package downloader provides bounding-box tile math shared by validation and +// enumeration. Fetching and output writes remain in the main application. package downloader diff --git a/apps/admin-region-tiler/internal/planner/doc.go b/apps/admin-region-tiler/internal/planner/doc.go deleted file mode 100644 index 0775d7a..0000000 --- a/apps/admin-region-tiler/internal/planner/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package planner translates unified task requests into validated task -// definitions that can later be persisted and expanded into child source/layer -// work items. -package planner diff --git a/apps/admin-region-tiler/internal/planner/model.go b/apps/admin-region-tiler/internal/planner/model.go deleted file mode 100644 index 94138be..0000000 --- a/apps/admin-region-tiler/internal/planner/model.go +++ /dev/null @@ -1,191 +0,0 @@ -package planner - -import ( - "errors" - "strings" - "time" - - "tiler/internal/area" -) - -const ( - ScheduleImmediate ScheduleMode = "immediate" - ScheduleOnce ScheduleMode = "once" - - OutputFiles OutputFormat = "files" - OutputMBTiles OutputFormat = "mbtiles" - - PackageZIP PackageFormat = "zip" - PackageTarGZ PackageFormat = "tar.gz" -) - -type ScheduleMode string -type OutputFormat string -type PackageFormat string - -type Request struct { - Name string `json:"name"` - Mode area.Mode `json:"mode"` - Area area.Spec `json:"area"` - Sources []Source `json:"sources"` - Zoom area.ZoomRange `json:"zoom"` - Schedule Schedule `json:"schedule"` - Output Output `json:"output"` -} - -type Source struct { - Name string `json:"name"` - URL string `json:"url"` - Layer string `json:"layer,omitempty"` - Format string `json:"format"` - Schema string `json:"schema"` -} - -type Schedule struct { - Mode ScheduleMode `json:"mode"` - RunAt string `json:"runAt,omitempty"` -} - -type Output struct { - Format OutputFormat `json:"format"` - Package PackageFormat `json:"package"` -} - -type TaskDefinition struct { - Name string - Mode area.Mode - Area area.Spec - Sources []Source - Zoom area.ZoomRange - Schedule Schedule - RunAt *time.Time - Output Output -} - -func NormalizeRequest(req Request) (*TaskDefinition, error) { - name := strings.TrimSpace(req.Name) - if name == "" { - return nil, errors.New("name is required") - } - if len(name) > 80 { - return nil, errors.New("name must be 80 characters or fewer") - } - - normalizedArea, err := area.Normalize(req.Area, req.Mode) - if err != nil { - return nil, err - } - if err := req.Zoom.Validate(); err != nil { - return nil, err - } - - sources, err := normalizeSources(req.Sources) - if err != nil { - return nil, err - } - schedule, runAt, err := normalizeSchedule(req.Schedule) - if err != nil { - return nil, err - } - output, err := normalizeOutput(req.Output) - if err != nil { - return nil, err - } - - return &TaskDefinition{ - Name: name, - Mode: normalizedArea.Mode, - Area: normalizedArea, - Sources: sources, - Zoom: req.Zoom, - Schedule: schedule, - RunAt: runAt, - Output: output, - }, nil -} - -func normalizeSources(input []Source) ([]Source, error) { - if len(input) == 0 { - return nil, errors.New("at least one source is required") - } - sources := make([]Source, 0, len(input)) - for _, source := range input { - source.Name = strings.TrimSpace(source.Name) - source.URL = strings.TrimSpace(source.URL) - source.Layer = strings.TrimSpace(source.Layer) - source.Format = strings.ToLower(strings.TrimSpace(source.Format)) - source.Schema = strings.ToLower(strings.TrimSpace(source.Schema)) - if source.URL == "" { - return nil, errors.New("source url is required") - } - if source.Name == "" { - if source.Layer != "" { - source.Name = source.Layer - } else { - source.Name = source.URL - } - } - if !supportedFormat(source.Format) { - return nil, errors.New("unsupported source format") - } - if source.Schema == "" { - source.Schema = "xyz" - } - if source.Schema != "xyz" && source.Schema != "tms" { - return nil, errors.New("source schema must be xyz or tms") - } - sources = append(sources, source) - } - return sources, nil -} - -func normalizeSchedule(input Schedule) (Schedule, *time.Time, error) { - input.Mode = ScheduleMode(strings.ToLower(strings.TrimSpace(string(input.Mode)))) - if input.Mode == "" { - input.Mode = ScheduleImmediate - } - switch input.Mode { - case ScheduleImmediate: - input.RunAt = "" - return input, nil, nil - case ScheduleOnce: - input.RunAt = strings.TrimSpace(input.RunAt) - if input.RunAt == "" { - return Schedule{}, nil, errors.New("runAt is required for scheduled tasks") - } - parsed, err := time.Parse(time.RFC3339, input.RunAt) - if err != nil { - return Schedule{}, nil, errors.New("runAt must be RFC3339 time") - } - return input, &parsed, nil - default: - return Schedule{}, nil, errors.New("unsupported schedule mode") - } -} - -func normalizeOutput(input Output) (Output, error) { - input.Format = OutputFormat(strings.ToLower(strings.TrimSpace(string(input.Format)))) - if input.Format == "" { - input.Format = OutputMBTiles - } - if input.Format != OutputFiles && input.Format != OutputMBTiles { - return Output{}, errors.New("output format must be files or mbtiles") - } - input.Package = PackageFormat(strings.ToLower(strings.TrimSpace(string(input.Package)))) - if input.Package == "" { - input.Package = PackageZIP - } - if input.Package != PackageZIP && input.Package != PackageTarGZ { - return Output{}, errors.New("output package must be zip or tar.gz") - } - return input, nil -} - -func supportedFormat(format string) bool { - switch format { - case "jpg", "png", "pbf", "webp": - return true - default: - return false - } -} diff --git a/apps/admin-region-tiler/internal/planner/model_test.go b/apps/admin-region-tiler/internal/planner/model_test.go deleted file mode 100644 index a57c741..0000000 --- a/apps/admin-region-tiler/internal/planner/model_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package planner - -import ( - "testing" - - "tiler/internal/area" -) - -func TestNormalizeRequestBBox(t *testing.T) { - definition, err := NormalizeRequest(Request{ - Name: " Range task ", - Mode: area.ModeBBox, - Area: area.Spec{BBox: &area.BBox{MinLon: 100, MinLat: 20, MaxLon: 101, MaxLat: 21}}, - Zoom: area.ZoomRange{Min: 1, Max: 3}, - Sources: []Source{{ - URL: "https://example.test/{z}/{x}/{y}.png", - Layer: "img", - Format: "PNG", - }}, - }) - if err != nil { - t.Fatalf("NormalizeRequest returned error: %v", err) - } - if definition.Name != "Range task" { - t.Fatalf("unexpected name: %q", definition.Name) - } - if definition.Mode != area.ModeBBox || definition.Area.BBox == nil { - t.Fatalf("unexpected area: %#v", definition.Area) - } - if definition.Sources[0].Schema != "xyz" || definition.Sources[0].Format != "png" { - t.Fatalf("unexpected source normalization: %#v", definition.Sources[0]) - } - if definition.Schedule.Mode != ScheduleImmediate { - t.Fatalf("unexpected schedule: %#v", definition.Schedule) - } - if definition.Output.Format != OutputMBTiles || definition.Output.Package != PackageZIP { - t.Fatalf("unexpected output: %#v", definition.Output) - } -} - -func TestNormalizeRequestRegion(t *testing.T) { - definition, err := NormalizeRequest(Request{ - Name: "Region task", - Mode: area.ModeRegion, - Area: area.Spec{RegionID: "china"}, - Zoom: area.ZoomRange{Min: 6, Max: 8}, - Sources: []Source{{ - Name: "vec", - URL: "https://example.test/{z}/{x}/{y}.png", - Format: "png", - Schema: "tms", - }}, - }) - if err != nil { - t.Fatalf("NormalizeRequest returned error: %v", err) - } - if definition.Mode != area.ModeRegion || definition.Area.RegionID != "china" { - t.Fatalf("unexpected region definition: %#v", definition) - } -} - -func TestNormalizeRequestRejectsMissingSource(t *testing.T) { - _, err := NormalizeRequest(Request{ - Name: "missing source", - Mode: area.ModeRegion, - Area: area.Spec{GeoJSON: "./geojson/china.geojson"}, - Zoom: area.ZoomRange{Min: 1, Max: 2}, - }) - if err == nil { - t.Fatal("expected missing source error") - } -} - -func TestNormalizeRequestRejectsScheduledWithoutRunAt(t *testing.T) { - _, err := NormalizeRequest(Request{ - Name: "scheduled", - Mode: area.ModeRegion, - Area: area.Spec{GeoJSON: "./geojson/china.geojson"}, - Zoom: area.ZoomRange{Min: 1, Max: 2}, - Sources: []Source{{ - URL: "https://example.test/{z}/{x}/{y}.png", - Format: "png", - }}, - Schedule: Schedule{Mode: ScheduleOnce}, - }) - if err == nil { - t.Fatal("expected runAt error") - } -} diff --git a/apps/admin-region-tiler/internal/web/doc.go b/apps/admin-region-tiler/internal/web/doc.go deleted file mode 100644 index 3e89b32..0000000 --- a/apps/admin-region-tiler/internal/web/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package web will hold helpers for the unified static frontend. -package web diff --git a/apps/admin-region-tiler/static/assets/icons/calendar.svg b/apps/admin-region-tiler/static/assets/icons/calendar.svg deleted file mode 100644 index ca2462a..0000000 --- a/apps/admin-region-tiler/static/assets/icons/calendar.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/apps/admin-region-tiler/static/assets/icons/clock.svg b/apps/admin-region-tiler/static/assets/icons/clock.svg deleted file mode 100644 index ec5c2d0..0000000 --- a/apps/admin-region-tiler/static/assets/icons/clock.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/apps/admin-region-tiler/static/assets/icons/error.svg b/apps/admin-region-tiler/static/assets/icons/error.svg deleted file mode 100644 index 9aa1d55..0000000 --- a/apps/admin-region-tiler/static/assets/icons/error.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/apps/admin-region-tiler/static/assets/icons/filter.svg b/apps/admin-region-tiler/static/assets/icons/filter.svg deleted file mode 100644 index c085aff..0000000 --- a/apps/admin-region-tiler/static/assets/icons/filter.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/apps/admin-region-tiler/static/assets/icons/folder.svg b/apps/admin-region-tiler/static/assets/icons/folder.svg deleted file mode 100644 index 239fc83..0000000 --- a/apps/admin-region-tiler/static/assets/icons/folder.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/apps/admin-region-tiler/static/assets/icons/pause.svg b/apps/admin-region-tiler/static/assets/icons/pause.svg deleted file mode 100644 index 4058efb..0000000 --- a/apps/admin-region-tiler/static/assets/icons/pause.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/apps/admin-region-tiler/static/assets/icons/play.svg b/apps/admin-region-tiler/static/assets/icons/play.svg deleted file mode 100644 index 30788fe..0000000 --- a/apps/admin-region-tiler/static/assets/icons/play.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/apps/admin-region-tiler/static/assets/icons/search.svg b/apps/admin-region-tiler/static/assets/icons/search.svg deleted file mode 100644 index 15ed8e4..0000000 --- a/apps/admin-region-tiler/static/assets/icons/search.svg +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/apps/admin-region-tiler/static/assets/logo/logo.svg b/apps/admin-region-tiler/static/assets/logo/logo.svg deleted file mode 100644 index 2a48f00..0000000 --- a/apps/admin-region-tiler/static/assets/logo/logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/apps/admin-region-tiler/static/favicon.svg b/apps/admin-region-tiler/static/favicon.svg deleted file mode 100644 index 2d17039..0000000 --- a/apps/admin-region-tiler/static/favicon.svg +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/apps/admin-region-tiler/static/test.html b/apps/admin-region-tiler/static/test.html deleted file mode 100644 index 2601ef4..0000000 --- a/apps/admin-region-tiler/static/test.html +++ /dev/null @@ -1,38 +0,0 @@ - - -
- - -