update
This commit is contained in:
34
specs/006-module-hook-refactor/checklists/requirements.md
Normal file
34
specs/006-module-hook-refactor/checklists/requirements.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Specification Quality Checklist: Module Hook Refactor
|
||||
|
||||
**Purpose**: Validate specification completeness and quality before proceeding to planning
|
||||
**Created**: 2025-11-17
|
||||
**Feature**: specs/006-module-hook-refactor/spec.md
|
||||
|
||||
## Content Quality
|
||||
|
||||
- [x] No implementation details (languages, frameworks, APIs)
|
||||
- [x] Focused on user value and business needs
|
||||
- [x] Written for non-technical stakeholders
|
||||
- [x] All mandatory sections completed
|
||||
|
||||
## Requirement Completeness
|
||||
|
||||
- [x] No [NEEDS CLARIFICATION] markers remain
|
||||
- [x] Requirements are testable and unambiguous
|
||||
- [x] Success criteria are measurable
|
||||
- [x] Success criteria are technology-agnostic (no implementation details)
|
||||
- [x] All acceptance scenarios are defined
|
||||
- [x] Edge cases are identified
|
||||
- [x] Scope is clearly bounded
|
||||
- [x] Dependencies and assumptions identified
|
||||
|
||||
## Feature Readiness
|
||||
|
||||
- [x] All functional requirements have clear acceptance criteria
|
||||
- [x] User scenarios cover primary flows
|
||||
- [x] Feature meets measurable outcomes defined in Success Criteria
|
||||
- [x] No implementation details leak into specification
|
||||
|
||||
## Notes
|
||||
|
||||
- Checklist complete; ready for `/speckit.plan`.
|
||||
16
specs/006-module-hook-refactor/contracts/README.md
Normal file
16
specs/006-module-hook-refactor/contracts/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Contracts: Module Hook Refactor
|
||||
|
||||
## `/ - /modules` Diagnostics
|
||||
|
||||
- **Purpose**: 列出所有模块的 metadata 与 Hook 注册状态,SRE 可检查模块是否迁移到 Hook 模式。
|
||||
- **Response Additions**:
|
||||
- `hook_status`: `registered | legacy-only | missing`
|
||||
- `handler_status`: `ok | missing | panic`
|
||||
- **Usage**: SRE 通过 `curl http://host:port/-/modules` 观察所有模块状态;缺失 Hook 或 handler 时需在日志与响应中同步体现。
|
||||
|
||||
## Error Responses
|
||||
|
||||
- `module_handler_missing`: 500 JSON `{ "error": "module_handler_missing" }`
|
||||
- `module_handler_panic`: 500 JSON `{ "error": "module_handler_panic" }`
|
||||
|
||||
这些错误需出现在日志中并附带 `hub/domain/module_key/request_id`。
|
||||
37
specs/006-module-hook-refactor/data-model.md
Normal file
37
specs/006-module-hook-refactor/data-model.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Data Model: Module Hook Refactor
|
||||
|
||||
## Entities
|
||||
|
||||
- **ModuleHook**
|
||||
- Attributes: `module_key`, `normalize_path`, `resolve_upstream`, `rewrite_response`, `cache_policy`, `content_type`(函数指针/接口)。
|
||||
- Behavior: 由模块在 init() 或启动阶段注册;proxy handler 在请求生命周期调用。
|
||||
- Constraints: 所有函数可选;若未实现则 fallback 到通用逻辑;禁止造成路径逃逸或空 handler。
|
||||
|
||||
- **HookRegistry**
|
||||
- Attributes: `map[module_key]ModuleHook`、并发安全读写锁。
|
||||
- Behavior: 提供 `Register`, `MustRegister`, `Fetch`;在启动时验证唯一性。
|
||||
- Constraints: module_key 小写唯一;重复注册报错。
|
||||
|
||||
- **LegacyHandler**
|
||||
- Attributes: 使用旧行为的 handler(默认缓存策略、路径重写)。
|
||||
- Behavior: 作为默认 handler;Hook 缺失时退回,并在日志/诊断中标记。
|
||||
|
||||
- **ProxyDispatcher**
|
||||
- Attributes: handler map(module_key→handler),默认 handler,日志指针。
|
||||
- Behavior: lookup handler → 调用并做错误捕获;缺失时返回 `module_handler_missing`。
|
||||
|
||||
- **Diagnostics Snapshot**
|
||||
- Attributes: 模块元数据 + Hook 状态(`registered`/`legacy`/`missing`)。
|
||||
- Behavior: `/ - /modules` 接口读取 HookRegistry 与 HubRegistry,生成 JSON。
|
||||
|
||||
## Relationships
|
||||
|
||||
- Hub module 注册时同时在 HookRegistry 与 Forwarder handler map 建立关联。
|
||||
- ProxyDispatcher 在请求进入后根据 route.ModuleKey 查询 Hook + handler。
|
||||
- Diagnostics 依赖 HookRegistry 与 HubRegistry 联合输出状态。
|
||||
|
||||
## Lifecycle
|
||||
|
||||
1. 启动:加载 `config.toml` → 初始化 HookRegistry(legacy 默认) → 模块 init() 注册 Hook。
|
||||
2. 运行时:请求 → Dispatcher 查找 handler + Hook → 调用 Hook 执行特定逻辑 → 通用缓存/回源流程。
|
||||
3. 诊断:`/-/modules` 读取当前 Hook 状态并输出。
|
||||
68
specs/006-module-hook-refactor/plan.md
Normal file
68
specs/006-module-hook-refactor/plan.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Implementation Plan: Module Hook Refactor
|
||||
|
||||
**Branch**: `006-module-hook-refactor` | **Date**: 2025-11-17 | **Spec**: specs/006-module-hook-refactor/spec.md
|
||||
**Input**: Feature specification from `/specs/006-module-hook-refactor/spec.md`
|
||||
|
||||
**Note**: This file captures planning up to Phase 2 (tasks generated separately).
|
||||
|
||||
## Summary
|
||||
|
||||
目标:让每个 hubmodule 完整自管缓存/代理逻辑(路径重写、缓存策略、上游解析、响应重写等),proxy handler 仅负责调度、缓存读写及统一日志/错误包装。技术路线:\n1. 定义 Hook/Handler 契约与注册机制。\n2. 将 Docker/NPM/PyPI/Composer/Go 的特化逻辑迁移到各自 Hook。\n3. legacy handler 仅做兜底;proxy handler 移除所有 `hub_type` 分支并加强错误观测。
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: Go 1.25+ (静态链接,单二进制交付)
|
||||
**Primary Dependencies**: Fiber v3(HTTP 服务)、Viper(配置)、Logrus + Lumberjack(结构化日志 & 滚动)、标准库 `net/http`/`io`
|
||||
**Storage**: 本地文件系统缓存目录 `StoragePath/<Hub>/<path>`(由模块 Hook 定义布局)
|
||||
**Testing**: `go test ./...`,使用 `httptest`、临时目录与模块 Hook 示例验证缓存/代理路径
|
||||
**Target Platform**: Linux/Unix CLI 进程,由 systemd/supervisor 管理,匿名下游客户端
|
||||
**Project Type**: 单 Go 项目(`cmd/` 入口 + `internal/*` 包)
|
||||
**Performance Goals**: 缓存命中直接返回;回源路径需流式转发,单请求常驻内存 <256MB;命中/回源日志可追踪
|
||||
**Constraints**: 禁止 Web UI 或账号体系;所有行为受单一 TOML 控制;每个 Hub 需独立 Domain 绑定;仅匿名访问
|
||||
**Scale/Scope**: 支撑 Docker/NPM/Go/PyPI/Composer,多仓 Hook 自治,面向弱网及离线缓存复用场景
|
||||
|
||||
## Constitution Check
|
||||
|
||||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||
|
||||
- Feature 仍然是“轻量多仓 CLI 代理”,未引入 Web UI、账号体系或与代理无关的能力。
|
||||
- 仅使用 Go + 宪法指定依赖;任何新第三方库都已在本计划中说明理由与审核结论。
|
||||
- 行为完全由 `config.toml` 控制,新增配置项已规划默认值、校验与迁移策略。
|
||||
- 方案维持缓存优先 + 流式回源路径,并给出命中/回源/失败的日志与观测手段。
|
||||
- 计划内列出了配置解析、缓存读写、Host Header 路由等强制测试与中文注释交付范围。
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/[###-feature]/
|
||||
├── plan.md # This file (/speckit.plan command output)
|
||||
├── research.md # Phase 0 output (/speckit.plan command)
|
||||
├── data-model.md # Phase 1 output (/speckit.plan command)
|
||||
├── quickstart.md # Phase 1 output (/speckit.plan command)
|
||||
├── contracts/ # Phase 1 output (/speckit.plan command)
|
||||
└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
|
||||
```
|
||||
|
||||
### Source Code (repository root)
|
||||
```text
|
||||
cmd/any-hub/main.go # CLI 入口、参数解析
|
||||
internal/config/ # TOML 加载、默认值、校验
|
||||
internal/server/ # Fiber 服务、路由、中间件
|
||||
internal/cache/ # 磁盘/内存缓存与 .meta 管理
|
||||
internal/proxy/ # 上游访问、缓存策略、流式复制
|
||||
configs/ # 示例 config.toml(如需)
|
||||
tests/ # `go test` 下的单元/集成测试,用临时目录
|
||||
```
|
||||
|
||||
**Structure Decision**: 采用单 Go 项目结构,特性代码应放入上述现有目录;如需新增包或目录,必须解释其与 `internal/*` 的关系并给出后续维护策略。
|
||||
|
||||
## Complexity Tracking
|
||||
|
||||
> **Fill ONLY if Constitution Check has violations that must be justified**
|
||||
|
||||
| Violation | Why Needed | Simpler Alternative Rejected Because |
|
||||
|-----------|------------|-------------------------------------|
|
||||
| [e.g., 4th project] | [current need] | [why 3 projects insufficient] |
|
||||
| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |
|
||||
44
specs/006-module-hook-refactor/quickstart.md
Normal file
44
specs/006-module-hook-refactor/quickstart.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Quickstart: Module Hook Refactor
|
||||
|
||||
1) 检出分支并安装依赖
|
||||
```bash
|
||||
git checkout 006-module-hook-refactor
|
||||
/home/rogee/.local/go/bin/go test ./...
|
||||
```
|
||||
|
||||
2) 定义模块 Hook
|
||||
```go
|
||||
func init() {
|
||||
proxy.RegisterModule(proxy.ModuleRegistration{
|
||||
Key: "npm",
|
||||
Handler: proxyHandler,
|
||||
})
|
||||
hooks.MustRegister("npm", hooks.Hooks{
|
||||
NormalizePath: myNormalize,
|
||||
ResolveUpstream: myResolve,
|
||||
RewriteResponse: myRewrite,
|
||||
CachePolicy: myPolicy,
|
||||
ContentType: myContentType,
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
3) 迁移逻辑
|
||||
- 读取 `internal/proxy/handler.go` 里的类型分支,对应迁移到模块 Hook。
|
||||
- 更新模块单元测试验证缓存、路径、响应重写等行为。
|
||||
|
||||
4) 验证
|
||||
```bash
|
||||
/home/rogee/.local/go/bin/go test ./...
|
||||
```
|
||||
- 针对迁移模块执行“第一次 miss → 第二次 hit”端到端测试。
|
||||
- 触发缺失 handler/panic,确保返回 `module_handler_missing`/`module_handler_panic`。
|
||||
|
||||
5) 诊断检查
|
||||
```bash
|
||||
curl -s http://localhost:8080/-/modules | jq '.modules[].hook_status'
|
||||
```
|
||||
- 确认新模块标记为 `registered`,未注册模块显示 `missing`,legacy handler 仍可作为兜底。
|
||||
- 如果需要查看全局状态,可检查 `hook_registry` 字段,它返回每个 module_key 的注册情况。
|
||||
- `hubs[].legacy_only` 为 `true` 时表示该 Hub 仍绑定 legacy 模块;迁移完成后应显式设置 `[[Hub]].Module`。
|
||||
- 启动阶段会验证每个模块是否注册 Hook,缺失则直接退出,避免运行期静默回退。
|
||||
23
specs/006-module-hook-refactor/research.md
Normal file
23
specs/006-module-hook-refactor/research.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Research: Module Hook Refactor
|
||||
|
||||
## Decisions
|
||||
|
||||
- **Hook Contract Scope**: 模块 Hook 将覆盖 5 个扩展点(路径/locator 重写、上游 URL 解析、响应重写、缓存策略、内容类型推断),并提供统一注册 API。
|
||||
- *Rationale*: 这些环节是当前 `handler.go` 中所有类型分支的来源;一次性覆盖可保证 proxy handler 只保留调度/缓存写入。
|
||||
- *Alternatives*: 仅重写部分(如响应)会导致残余分支;完全改写为“每模块自己的 ProxyHandler”则重复缓存代码,风险更高。
|
||||
|
||||
- **Legacy Handler Role**: 保留 legacy handler 作为默认兜底(未迁移模块或外部插件),但日志/诊断会标记为 `legacy-only`。
|
||||
- *Rationale*: 确保迁移期间功能可用,同时提示 SRE 识别未迁移模块。
|
||||
- *Alternatives*: 强制所有模块一次迁移;风险大且不利于渐进上线。
|
||||
|
||||
- **Diagnostics Visibility**: `/ - /modules` 输出增加 Hook 状态(已注册/缺失/legacy 默认),并用于 SRE 排查。
|
||||
- *Rationale*: 迁移阶段需要监控 Hook 注册情况,避免静默回退。
|
||||
- *Alternatives*: 单靠日志搜索,排查效率低。
|
||||
|
||||
- **Testing Approach**: 每个模块迁移后需要端到端“Miss → Hit”回归,同时新增 Hook 单元测试覆盖缺失/panic 等异常路径。
|
||||
- *Rationale*: 确认行为等价且新错误处理生效。
|
||||
- *Alternatives*: 仅依赖现有集成测试,不足以验证 Hook 入口。
|
||||
|
||||
## Clarifications
|
||||
|
||||
- 无须额外澄清;假设各模块团队可修改其包并维护 Hook 实现。
|
||||
99
specs/006-module-hook-refactor/spec.md
Normal file
99
specs/006-module-hook-refactor/spec.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Feature Specification: Module Hook Refactor
|
||||
|
||||
**Feature Branch**: `006-module-hook-refactor`
|
||||
**Created**: 2025-11-17
|
||||
**Status**: Draft
|
||||
**Input**: User description: "模块内部自管理缓存/代理逻辑、proxy handler 仅负责调度"
|
||||
|
||||
> 宪法对齐(v1.0.0):
|
||||
> - 保持 CLI 多仓代理定位,不引入 UI 或账号体系。
|
||||
> - 仅依赖 Go 1.25+ 单二进制及 Fiber/Viper/Logrus/Lumberjack/标准库,不新增无关依赖。
|
||||
> - 全局 `config.toml` 控制所有行为;若新增配置项需描述字段、默认值、验证与迁移。
|
||||
> - 缓存优先 + 流式回源是基础能力;必须定义命中/回源/失败时的结构化日志与观测策略。
|
||||
> - 验收需覆盖配置解析、缓存读写、Host Header 绑定及中文注释要求。
|
||||
|
||||
## User Scenarios & Testing *(mandatory)*
|
||||
|
||||
### User Story 1 - 定义模块 Hook 契约 (Priority: P1)
|
||||
|
||||
作为平台架构师,我可以定义一套模块 Hook/Handler 契约,使缓存键、路径重写、上游解析、响应重写等逻辑都由模块实现,proxy handler 只负责调度与共享的缓存写入。
|
||||
|
||||
**Why this priority**: 没有统一 Hook,就无法让模块自控逻辑,后续迁移无法落地。
|
||||
|
||||
**Independent Test**: 提供一个示例模块实现 Hook,注册后能独立覆盖缓存策略/路径重写,proxy handler 不含类型分支仍可处理请求。
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** 定义好 Hook 接口与注册机制,**When** 模块注册自定义 Hook,**Then** proxy handler 在日志/缓存流程中调用模块 Hook,代码中不再出现 `hub_type` 分支。
|
||||
2. **Given** 模块缺少 Hook,**When** 注册时,**Then** 启动/测试阶段给出明确错误提示,防止运行期回退到旧逻辑。
|
||||
|
||||
---
|
||||
|
||||
### User Story 2 - 迁移现有模块 (Priority: P1)
|
||||
|
||||
作为平台工程师,我希望 Docker/NPM/PyPI/Composer/Go 等模块全部迁移到 Hook 模式,自行管理缓存与代理逻辑,保证行为与改造前一致。
|
||||
|
||||
**Why this priority**: 生产仓库必须可用,迁移后必须验证命中/回源与日志字段无差异。
|
||||
|
||||
**Independent Test**: 对每个仓库执行“首次 miss、二次 hit”流程并观察日志字段,与改造前对比一致。
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** Docker 模块已实现 Hook,**When** 请求 manifest/层文件,**Then** 路径重写、缓存键、内容类型判断都由模块完成,proxy handler 不含 Docker 特化。
|
||||
2. **Given** PyPI/Composer 模块已迁移,**When** 请求 simple index、packages.json、dist 文件,**Then** 响应重写与内容类型准确,日志字段/缓存命中行为与现状一致。
|
||||
|
||||
---
|
||||
|
||||
### User Story 3 - 清理 legacy 逻辑并增强观测 (Priority: P2)
|
||||
|
||||
作为 SRE,我希望 proxy handler 只提供通用调度和错误包装;模块未注册或 Hook panic 时能输出统一 5xx 与结构化日志;legacy 模块成为纯兜底实现。
|
||||
|
||||
**Why this priority**: 防止运行期静默回退,简化排查路径。
|
||||
|
||||
**Independent Test**: 刻意注入未注册模块或 Hook panic,观察返回 `module_handler_missing`/`module_handler_panic` 错误及日志字段完整。
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** 模块未注册 Hook,**When** 发起请求,**Then** proxy handler 返回 5xx JSON 并记录 hub/module_key/request_id 等字段。
|
||||
2. **Given** Hook panic,**When** 请求执行,**Then** panic 被捕获,返回统一错误并在日志中包含 panic 信息。
|
||||
|
||||
---
|
||||
|
||||
### Edge Cases
|
||||
|
||||
- 模块未注册或重复注册时需在启动阶段失败,避免运行期 fallback。
|
||||
- Hook 返回非法路径/URL 时需防止逃逸缓存目录或访问非预期上游。
|
||||
- 不同模块并行迁移时,需保证 legacy 模块仍可作为默认 handler。
|
||||
- Hook 不得影响 diagnostics (`/-/modules`) 或健康检查路径。
|
||||
- 模块 Hook 需兼容 HEAD/GET;不支持方法应返回合规状态码。
|
||||
|
||||
## Requirements *(mandatory)*
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
- **FR-001**: 定义模块 Hook/Handler 契约,覆盖路径重写、缓存策略、上游解析、响应重写、内容类型推断等扩展点,proxy handler 不再含 `hub_type` 分支。
|
||||
- **FR-002**: 提供 Hook 注册/验证机制,要求模块在注册时同时提供元数据与 Hook;缺失或重复时启动失败并输出明确日志。
|
||||
- **FR-003**: 将 Docker/NPM/PyPI/Composer/Go 模块现有特化逻辑全部迁移到各自 Hook,实现缓存键/TTL/验证、路径 fallback、响应重写的等价行为。
|
||||
- **FR-004**: legacy/default 模块作为兜底 handler,确保未迁移模块仍可运行,但会记录“legacy-only”状态,便于观测。
|
||||
- **FR-005**: proxy handler 仅负责调度、缓存读写和日志包装;模块 Hook panic 或缺失时返回统一 5xx JSON(`module_handler_panic`/`module_handler_missing`),日志包含 hub/domain/module_key/request_id。
|
||||
- **FR-006**: Diagnostics (`/-/modules`) 需展示模块 Hook 注册状态(正常/缺失),并保持现有输出字段。
|
||||
- **FR-007**: 文档/quickstart 更新,说明如何实现 Hook、注册模块,以及如何验证新模块缓存/日志。
|
||||
|
||||
### Key Entities
|
||||
|
||||
- **Module Hook**: 一组可选函数(normalize path、resolve upstream、rewrite response、cache policy、content type)。
|
||||
- **Module Registration**: 绑定 module_key、元数据、Hook handler 的机构,负责唯一性与完整性校验。
|
||||
- **Proxy Dispatcher**: 使用 module_key→Hook/handler map 调度请求,输出统一日志与错误。
|
||||
|
||||
### Assumptions
|
||||
|
||||
- 现有模块的缓存策略及接口稳定,可迁移到 Hook 而无需额外外部依赖。
|
||||
- 模块团队可接受在各自包内实现 Hook;无需跨团队共享逻辑。
|
||||
|
||||
## Success Criteria *(mandatory)*
|
||||
|
||||
- **SC-001**: proxy handler 代码中不包含任何 `hub_type`/类型特化分支;静态分析或代码审查确认类型判断被完全移除。
|
||||
- **SC-002**: 对 docker/npm/pypi/composer/go 每个仓执行“首次 miss、二次 hit”测试,首/次响应头与日志字段与改造前一致,功能回归通过。
|
||||
- **SC-003**: 新增模块仅需在 hubmodule 中实现 Hook 并注册,无需修改 proxy handler;示例模块演示该流程并通过集成测试。
|
||||
- **SC-004**: 缺失 handler 或 Hook panic 时返回统一 5xx JSON,日志包含 hub/domain/module_key/request_id,错误率控制在 0(测试场景)。
|
||||
- **SC-005**: `/ - /modules` 诊断接口展示所有模块 Hook 状态,SRE 可识别缺失或 legacy-only 模块;与文档描述一致。
|
||||
100
specs/006-module-hook-refactor/tasks.md
Normal file
100
specs/006-module-hook-refactor/tasks.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Tasks: Module Hook Refactor
|
||||
|
||||
**Input**: Design documents from `/specs/006-module-hook-refactor/`
|
||||
**Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/, quickstart.md
|
||||
|
||||
**Tests**: 包含配置解析、缓存读写、代理命中/回源、Host Header 绑定、模块 Hook 行为(缺失/异常)的端到端与单元测试。
|
||||
|
||||
**Organization**: Tasks are grouped by user story so each delivers independent value.
|
||||
|
||||
## Phase 1: Setup
|
||||
|
||||
- [X] T001 阅读 spec/plan/research,整理 Hook 目标与迁移范围(specs/006-module-hook-refactor/)
|
||||
- [X] T002 运行现有基线 `GOCACHE=$(pwd)/.cache/go-build /home/rogee/.local/go/bin/go test ./...`,记录失败用例(当前因 handler 尚未实现 Hook 接口导致编译失败)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Foundational
|
||||
|
||||
- [X] T003a 定义 Hook/RequestContext/CachePolicy 接口骨架(internal/proxy/hooks/hooks.go)
|
||||
- [X] T003b [P] 实现 HookRegistry 注册/查询/重复检测,并暴露 diagnostics 所需状态(internal/proxy/hooks/registry.go, internal/server/routes/modules.go)
|
||||
- [X] T003c [P] 添加 Hook 契约单元测试(internal/proxy/hooks/hooks_test.go)
|
||||
- [X] T004 更新 diagnostics 接口,显示注册状态但仍未接入 handler(internal/server/routes/modules.go)
|
||||
- [X] T005 建立示例模块 Hook(internal/hubmodule/template/, internal/hubmodule/template/module_test.go)
|
||||
- [X] T006 更新 quickstart/README 说明 Hook 用法(specs/006-module-hook-refactor/quickstart.md, README.md)
|
||||
|
||||
**Checkpoint**: Hook 契约与注册机制 ready。
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: User Story 1 - 定义模块 Hook 契约 (Priority: P1) 🎯 MVP
|
||||
|
||||
**Goal**: proxy handler 仅调度 + 缓存读写;Hook 提供各种扩展点。
|
||||
|
||||
**Independent Test**: 使用示例模块覆盖路径/缓存策略 → proxy handler 中无 `hub_type` 分支也可完成请求。
|
||||
|
||||
- [X] T007 [US1] 重构 handler,接入 Hook 扩展点(internal/proxy/handler.go)
|
||||
- [X] T008 [P] [US1] 在 forwarder 中注入 Hook/handler 错误处理(internal/proxy/forwarder.go)
|
||||
- [X] T009 [US1] 编写 Hook 单元测试覆盖缺失/重复/panic 场景(internal/proxy/hooks/, internal/proxy/forwarder_test.go)
|
||||
- [X] T010 [US1] 更新 diagnostics `/ - /modules` 输出 Hook 状态(internal/server/routes/modules.go, docs)
|
||||
|
||||
**Checkpoint**: Hook 契约落地并可验证。
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: User Story 2 - 迁移现有模块 (Priority: P1)
|
||||
|
||||
**Goal**: Docker/NPM/PyPI/Composer/Go 等模块将特化逻辑迁移到 Hook,行为保持等价。
|
||||
|
||||
**Independent Test**: 对每个仓执行“第一次 miss、第二次 hit”测试,比对日志与响应头与改造前一致。
|
||||
|
||||
- [X] T011 [US2] 迁移 Docker Hook(路径 fallback、内容类型、缓存策略等)(internal/hubmodule/docker/)
|
||||
- [X] T012 [P] [US2] 迁移 npm Hook(包 metadata、tarball 缓存)(internal/hubmodule/npm/)
|
||||
- [X] T013 [P] [US2] 迁移 PyPI Hook(simple HTML/JSON 重写、files 路径)(internal/hubmodule/pypi/)
|
||||
- [X] T014 [P] [US2] 迁移 Composer Hook(packages.json/p2 重写、dist URL)(internal/hubmodule/composer/)
|
||||
- [X] T015 [US2] 迁移 Go Hook(模组路径、sumdb 重写)(internal/hubmodule/go/)
|
||||
- [X] T016 [US2] 更新 legacy/default handler 说明及行为(internal/hubmodule/legacy/, docs)
|
||||
- [X] T017 [US2] 为每个模块增加/更新 e2e 测试覆盖 miss/hit 及日志字段(tests/integration/*)
|
||||
|
||||
**Checkpoint**: 现有仓库 Hook 化并通过回归。
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: User Story 3 - 清理 legacy 逻辑并增强观测 (Priority: P2)
|
||||
|
||||
**Goal**: proxy handler 统一错误路径;legacy 仅兜底并在诊断输出 legacy-only。
|
||||
|
||||
**Independent Test**: 模拟缺失 handler 或 Hook panic,返回 `module_handler_missing`/`module_handler_panic`,日志含 hub/domain/module_key/request_id。
|
||||
|
||||
- [X] T018 [US3] 实现 handler 缺失/重复时启动失败与运行期 5xx 响应(internal/proxy/forwarder.go, internal/hubmodule/registry.go)
|
||||
- [X] T019 [P] [US3] 添加 Hook panic 捕获与结构化日志(internal/proxy/forwarder.go)
|
||||
- [X] T020 [US3] 扩展 diagnostics 与日志写入,使 legacy-only 模块可观测(internal/server/routes/modules.go, internal/logging/fields.go)
|
||||
- [X] T021 [P] [US3] 更新文档/quickstart,描述错误处理与 legacy-only 标记(specs/006-module-hook-refactor/contracts/README.md, quickstart.md)
|
||||
|
||||
**Checkpoint**: Hook 错误与 legacy 观测全面覆盖。
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Polish & Cross-Cutting
|
||||
|
||||
- [X] T022 整理 README/DEVELOPMENT 文档、样例配置,指导如何创建 Hook(README.md, configs/config.example.toml)
|
||||
- [X] T023 [P] 最终 `gofmt` + `GOCACHE=$(pwd)/.cache/go-build /home/rogee/.local/go/bin/go test ./...`,确保无回归
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & Order
|
||||
|
||||
1. Phase1 Setup → Phase2 Hook 契约 → Phase3 (US1) → Phase4 (US2) → Phase5 (US3) → Phase6 polish。
|
||||
2. US2 依赖 Hook 契约完成;US3 依赖 US1/US2。
|
||||
|
||||
## Parallel Execution Examples
|
||||
|
||||
- T012/T013/T014/T015(各模块 Hook)可并行,互不干扰。
|
||||
- 文档更新(T016/T021/T022)可与测试任务并行。
|
||||
- Hook 契约(T003)完成后,可并行推进 diagnostics (T010) 与 forwarder 错误处理 (T008)。
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
- **MVP**:完成 US1(T007-T010)即可让 proxy handler 不再依赖类型分支。
|
||||
- **迭代**:依次迁移模块 (US2) 并加强观测 (US3);每阶段运行 `go test ./...`。
|
||||
- **验证**:每个模块迁移后执行“Miss→Hit”回归 + 特殊错误场景测试。
|
||||
Reference in New Issue
Block a user