做一次小小的备份,等会又删掉了
This commit is contained in:
382
specs/001-fiber-middleware-integration/plan.md
Normal file
382
specs/001-fiber-middleware-integration/plan.md
Normal file
@@ -0,0 +1,382 @@
|
||||
# Implementation Plan: Fiber Middleware Integration with Configuration Management
|
||||
|
||||
**Branch**: `001-fiber-middleware-integration` | **Date**: 2025-11-10 | **Spec**: [spec.md](./spec.md)
|
||||
**Input**: Feature specification from `/specs/001-fiber-middleware-integration/spec.md`
|
||||
|
||||
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/commands/plan.md` for the execution workflow.
|
||||
|
||||
## Summary
|
||||
|
||||
Integrate essential Fiber middleware (logger, recover, requestid, keyauth, limiter) with unified response structure, Viper configuration hot reload, and Zap+Lumberjack logging. This establishes the foundational middleware layer for the 君鸿卡管系统, ensuring proper authentication, logging, error recovery, and request tracing capabilities following Go idiomatic patterns.
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: Go 1.25.1
|
||||
**Primary Dependencies**:
|
||||
- Fiber v2.52.9 (HTTP framework)
|
||||
- Sonic v1.14.2 (JSON encoding/decoding - already integrated)
|
||||
- Viper (configuration with hot reload)
|
||||
- Zap (structured logging)
|
||||
- Lumberjack.v2 (log rotation)
|
||||
- Redis client (for keyauth token validation)
|
||||
|
||||
**Storage**:
|
||||
- Redis (for authentication token validation - token as key, user ID as value with TTL)
|
||||
- Log files (app.log for application logs, access.log for HTTP access logs)
|
||||
|
||||
**Testing**:
|
||||
- Go standard testing framework (`testing` package)
|
||||
- Table-driven tests for middleware logic
|
||||
- Integration tests for API endpoints with middleware
|
||||
- Mock Redis for keyauth testing
|
||||
|
||||
**Target Platform**: Linux server (production), macOS (development)
|
||||
|
||||
**Project Type**: Single backend web service (Go web application)
|
||||
|
||||
**Performance Goals**:
|
||||
- API response time P95 < 200ms, P99 < 500ms
|
||||
- Middleware overhead < 5ms per request
|
||||
- Configuration hot reload detection within 5 seconds
|
||||
- Log rotation without blocking requests
|
||||
|
||||
**Constraints**:
|
||||
- No external authentication service (Redis-only token validation)
|
||||
- Fail-closed authentication (Redis unavailable = HTTP 503)
|
||||
- Zero downtime for configuration changes (hot reload)
|
||||
- Separate log files with independent retention policies
|
||||
|
||||
**Scale/Scope**:
|
||||
- Foundation for multi-module card management system
|
||||
- ~10 initial API endpoints (will grow)
|
||||
- Expected 1000+ req/s capacity
|
||||
- 24/7 production availability requirement
|
||||
|
||||
## Constitution Check
|
||||
|
||||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||
|
||||
**Tech Stack Adherence**:
|
||||
- [x] Feature uses Fiber + Viper + Zap + Lumberjack.v2 + sonic JSON + Redis
|
||||
- [x] No native calls bypass framework (no `net/http` direct use)
|
||||
- [x] All HTTP operations use Fiber framework
|
||||
- [x] All async tasks use Asynq (N/A for this feature - no async tasks)
|
||||
- [x] Uses Go official toolchain: `go fmt`, `go vet`, `golangci-lint`
|
||||
- [x] Uses Go Modules for dependency management (already initialized)
|
||||
|
||||
**Code Quality Standards**:
|
||||
- [x] Follows Handler → Service → Store → Model architecture (keyauth validation follows this)
|
||||
- [x] Handler layer only handles HTTP, no business logic
|
||||
- [x] Service layer contains business logic with cross-module support
|
||||
- [x] Store layer manages all data access with transaction support
|
||||
- [x] Uses dependency injection via struct fields (not constructor patterns)
|
||||
- [x] Unified error codes in `pkg/errors/` (will define auth error codes: 1001-1004)
|
||||
- [x] Unified API responses via `pkg/response/` (core requirement: {code, data, msg})
|
||||
- [x] All constants defined in `pkg/constants/` (Redis keys, error messages)
|
||||
- [x] All Redis keys managed via key generation functions (no hardcoded strings)
|
||||
- [x] All exported functions/types have Go-style doc comments
|
||||
- [x] Code formatted with `gofmt`
|
||||
- [x] Follows Effective Go and Go Code Review Comments
|
||||
|
||||
**Go Idiomatic Design**:
|
||||
- [x] Package structure is flat (max 2-3 levels), organized by feature
|
||||
- Structure: `pkg/config/`, `pkg/logger/`, `pkg/response/`, `pkg/errors/`, `pkg/constants/`
|
||||
- Middleware: `internal/middleware/` (flat, no deep nesting)
|
||||
- [x] Interfaces are small (1-3 methods), defined at use site
|
||||
- TokenValidator interface (2 methods: ValidateToken, IsAvailable)
|
||||
- [x] No Java-style patterns: no I-prefix, no Impl-suffix, no getters/setters
|
||||
- [x] Error handling is explicit (return errors, no panic/recover abuse)
|
||||
- Recover middleware captures panics only, normal errors use error returns
|
||||
- [x] Uses composition over inheritance
|
||||
- [x] Uses goroutines and channels for config hot reload watcher
|
||||
- [x] Uses `context.Context` for cancellation and timeouts
|
||||
- [x] Naming follows Go conventions: short receivers, consistent abbreviations (URL, ID, HTTP)
|
||||
- [x] No Hungarian notation or type prefixes
|
||||
- [x] Simple constructors (New/NewXxx), no Builder pattern unless necessary
|
||||
|
||||
**Testing Standards**:
|
||||
- [x] Unit tests for all core business logic (token validation, config loading)
|
||||
- [x] Integration tests for all API endpoints with middleware chain
|
||||
- [x] Tests use Go standard testing framework
|
||||
- [x] Test files named `*_test.go` in same directory
|
||||
- [x] Test functions use `Test` prefix, benchmarks use `Benchmark` prefix
|
||||
- [x] Table-driven tests for multiple test cases (especially middleware scenarios)
|
||||
- [x] Test helpers marked with `t.Helper()`
|
||||
- [x] Tests are independent (mock Redis, no external dependencies)
|
||||
- [x] Target coverage: 70%+ overall, 90%+ for core business (auth, config)
|
||||
|
||||
**User Experience Consistency**:
|
||||
- [x] All APIs use unified JSON response format: `{code, data, msg}`
|
||||
- [x] Error responses include clear error codes and bilingual messages
|
||||
- 1001: Missing authentication token (缺失认证令牌)
|
||||
- 1002: Invalid or expired token (令牌无效或已过期)
|
||||
- 1003: Too many requests (请求过于频繁)
|
||||
- 1004: Authentication service unavailable (认证服务不可用)
|
||||
- [x] RESTful design principles followed
|
||||
- [x] Unified pagination parameters (N/A for this feature)
|
||||
- [x] Time fields use ISO 8601 format (RFC3339) - in log timestamps
|
||||
- [x] Currency amounts use integers (N/A for this feature)
|
||||
|
||||
**Performance Requirements**:
|
||||
- [x] API response time (P95) < 200ms, (P99) < 500ms
|
||||
- Middleware overhead budgeted at < 5ms per request
|
||||
- [x] Batch operations use bulk queries/inserts (N/A for this feature)
|
||||
- [x] All database queries have appropriate indexes (N/A - Redis only)
|
||||
- [x] List queries implement pagination (N/A for this feature)
|
||||
- [x] Non-realtime operations use async tasks (N/A - all operations are realtime)
|
||||
- [x] Database and Redis connection pools properly configured
|
||||
- Redis: PoolSize=10, MinIdleConns=5
|
||||
- [x] Uses goroutines/channels for concurrency (config watcher)
|
||||
- [x] Uses `context.Context` for timeout control (Redis operations)
|
||||
- [x] Uses `sync.Pool` for frequently allocated objects (if needed for performance)
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/001-fiber-middleware-integration/
|
||||
├── 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)
|
||||
│ └── api.yaml # OpenAPI spec for unified response format
|
||||
└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
|
||||
```
|
||||
|
||||
### Source Code (repository root)
|
||||
|
||||
```text
|
||||
junhong_cmp_fiber/
|
||||
├── cmd/
|
||||
│ ├── api/
|
||||
│ │ └── main.go # HTTP server entry point (updated)
|
||||
│ └── worker/
|
||||
│ └── main.go # Worker process (no changes for this feature)
|
||||
│
|
||||
├── internal/
|
||||
│ └── middleware/ # Fiber middleware implementations
|
||||
│ ├── auth.go # keyauth middleware integration
|
||||
│ ├── ratelimit.go # limiter middleware integration (commented)
|
||||
│ └── recover.go # Custom recover middleware with Zap logging
|
||||
│
|
||||
├── pkg/
|
||||
│ ├── config/
|
||||
│ │ ├── config.go # Viper configuration management
|
||||
│ │ ├── loader.go # Config loading and validation
|
||||
│ │ └── watcher.go # Hot reload implementation
|
||||
│ │
|
||||
│ ├── logger/
|
||||
│ │ ├── logger.go # Zap logger initialization
|
||||
│ │ ├── rotation.go # Lumberjack integration
|
||||
│ │ └── middleware.go # Fiber logger middleware adapter
|
||||
│ │
|
||||
│ ├── response/
|
||||
│ │ ├── response.go # Unified response structure and helpers
|
||||
│ │ └── codes.go # Response code constants
|
||||
│ │
|
||||
│ ├── errors/
|
||||
│ │ ├── errors.go # Custom error types
|
||||
│ │ └── codes.go # Error code constants (1001-1004)
|
||||
│ │
|
||||
│ ├── constants/
|
||||
│ │ ├── constants.go # Business constants
|
||||
│ │ └── redis.go # Redis key generation functions
|
||||
│ │
|
||||
│ └── validator/
|
||||
│ └── token.go # Token validation service (Redis interaction)
|
||||
│
|
||||
├── configs/
|
||||
│ ├── config.yaml # Default configuration
|
||||
│ ├── config.dev.yaml # Development environment
|
||||
│ ├── config.staging.yaml # Staging environment
|
||||
│ └── config.prod.yaml # Production environment
|
||||
│
|
||||
├── logs/ # Log output directory (gitignored)
|
||||
│ ├── app.log # Application logs
|
||||
│ └── access.log # HTTP access logs
|
||||
│
|
||||
└── tests/
|
||||
├── integration/
|
||||
│ ├── middleware_test.go # Integration tests for middleware chain
|
||||
│ └── auth_test.go # Auth flow integration tests
|
||||
└── unit/
|
||||
├── config_test.go # Config loading and validation tests
|
||||
├── logger_test.go # Logger tests
|
||||
├── response_test.go # Response format tests
|
||||
└── validator_test.go # Token validation tests
|
||||
```
|
||||
|
||||
**Structure Decision**: Single project structure (Option 1) as this is a backend-only Go web service. The project follows Go's standard layout with `cmd/` for entry points, `internal/` for private application code, and `pkg/` for reusable packages. Configuration files are centralized in `configs/` with environment-specific overrides. This structure aligns with Go best practices and the constitution's flat package organization principle.
|
||||
|
||||
## Complexity Tracking
|
||||
|
||||
> **Fill ONLY if Constitution Check has violations that must be justified**
|
||||
|
||||
*No violations detected. All requirements align with constitution principles.*
|
||||
|
||||
## Phase 0: Research & Discovery
|
||||
|
||||
**Status**: Starting research phase
|
||||
|
||||
**Research Tasks**:
|
||||
1. Viper configuration hot reload best practices and implementation patterns
|
||||
2. Zap + Lumberjack integration patterns for dual log files (app.log, access.log)
|
||||
3. Fiber middleware execution order and error handling patterns
|
||||
4. Fiber keyauth middleware customization for Redis token validation
|
||||
5. Fiber limiter middleware configuration options and IP extraction
|
||||
6. Redis client selection and connection pool configuration for Go
|
||||
7. UUID v4 generation in Go (standard library vs third-party)
|
||||
8. Graceful shutdown patterns for config watchers and HTTP server
|
||||
|
||||
**Unknowns to Resolve**:
|
||||
- Best Redis client library for Go (go-redis vs redigo)
|
||||
- Optimal Viper hot reload implementation (polling vs fsnotify)
|
||||
- How to properly separate Fiber logger middleware output to access.log
|
||||
- How to inject custom Zap logger into Fiber recover middleware
|
||||
- Request ID propagation through Fiber context
|
||||
- Testing strategies for middleware integration tests
|
||||
|
||||
**Output**: `research.md` with decisions and rationale
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Design & Contracts
|
||||
|
||||
**Prerequisites**: Phase 0 research complete
|
||||
|
||||
**Design Artifacts**:
|
||||
1. **data-model.md**: Entity definitions
|
||||
- Configuration structure (server, redis, logging, middleware settings)
|
||||
- AuthToken entity (Redis key-value structure)
|
||||
- Request Context structure (request ID, user ID, metadata)
|
||||
- Log Entry structure (JSON fields for app.log and access.log)
|
||||
- Rate Limit State (IP-based tracking structure)
|
||||
|
||||
2. **contracts/api.yaml**: OpenAPI specification
|
||||
- Unified response format schema
|
||||
- Error response schemas (1001-1004)
|
||||
- Common headers (X-Request-ID, token)
|
||||
- Example endpoints demonstrating middleware integration
|
||||
|
||||
3. **quickstart.md**: Developer setup guide
|
||||
- Environment setup (Go, Redis)
|
||||
- Configuration file setup (config.yaml)
|
||||
- Running the server
|
||||
- Testing middleware (curl examples)
|
||||
- Enabling/disabling rate limiter
|
||||
|
||||
**Output**: data-model.md, contracts/api.yaml, quickstart.md
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Task Generation
|
||||
|
||||
**Status**: To be completed by `/speckit.tasks` command (NOT part of `/speckit.plan`)
|
||||
|
||||
This phase will generate `tasks.md` with implementation steps ordered by dependencies.
|
||||
|
||||
---
|
||||
|
||||
## Notes & Decisions
|
||||
|
||||
### Key Design Decisions (from spec clarifications):
|
||||
|
||||
1. **Log Separation**: Application logs (app.log) and HTTP access logs (access.log) in separate files with independent rotation and retention policies
|
||||
2. **Token Storage**: Simple Redis key-value (token → user ID) with Redis TTL for expiration
|
||||
3. **Auth Failure Mode**: Fail closed when Redis unavailable (HTTP 503, no fallback)
|
||||
4. **Rate Limiting**: Per-IP address with configurable requests/time window, disabled by default
|
||||
5. **Request ID Format**: UUID v4 for distributed tracing compatibility
|
||||
6. **Config Hot Reload**: 5-second detection window, atomic updates, invalid config = keep previous
|
||||
|
||||
### Technical Choices (to be validated in Phase 0):
|
||||
|
||||
- Use `github.com/go-redis/redis/v8` for Redis client (widely adopted, good performance)
|
||||
- Use `github.com/fsnotify/fsnotify` (Viper's native watcher) for hot reload
|
||||
- Use `github.com/google/uuid` (already in go.mod) for UUID v4 generation
|
||||
- Separate Zap logger instances for app.log and access.log
|
||||
- Middleware order: recover → requestid → logger → keyauth → limiter → handler
|
||||
|
||||
### Risk Mitigation:
|
||||
|
||||
- **Risk**: Configuration hot reload causes in-flight request issues
|
||||
- **Mitigation**: Use atomic pointer swap for config updates, don't affect in-flight requests
|
||||
|
||||
- **Risk**: Log rotation blocks request processing
|
||||
- **Mitigation**: Lumberjack handles rotation atomically, Zap is non-blocking
|
||||
|
||||
- **Risk**: Redis connection pool exhaustion under load
|
||||
- **Mitigation**: Proper pool sizing (10 connections), timeout configuration, circuit breaker consideration
|
||||
|
||||
- **Risk**: Rate limiter memory leak with many unique IPs
|
||||
- **Mitigation**: Use Fiber's built-in limiter with storage backend (memory or Redis), TTL cleanup
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 Constitution Re-Check
|
||||
|
||||
**Status**: ✅ PASSED - All design artifacts comply with constitution
|
||||
|
||||
**Verification Results**:
|
||||
|
||||
1. **Go Idiomatic Design** ✅
|
||||
- ✅ Flat package structure: `pkg/config/`, `pkg/logger/`, `pkg/response/`, `pkg/errors/`
|
||||
- ✅ Small interfaces: TokenValidator (2 methods only)
|
||||
- ✅ No Java patterns: No IService, no Impl suffix, no getters/setters
|
||||
- ✅ Simple structs with direct field access (Config, Response, LogEntry)
|
||||
- ✅ Explicit error handling with custom error types
|
||||
- ✅ Composition: Config composed of sub-configs, no inheritance
|
||||
|
||||
2. **Tech Stack Compliance** ✅
|
||||
- ✅ Fiber for all HTTP operations (middleware, routing)
|
||||
- ✅ Viper for configuration with hot reload
|
||||
- ✅ Zap + Lumberjack for logging
|
||||
- ✅ go-redis/redis/v8 for Redis client
|
||||
- ✅ google/uuid for request ID generation
|
||||
- ✅ No `net/http`, `database/sql`, or `encoding/json` direct usage
|
||||
|
||||
3. **Architecture Alignment** ✅
|
||||
- ✅ Clear separation: Middleware → Handler → Service (TokenValidator) → Store (Redis)
|
||||
- ✅ Dependency injection via struct fields
|
||||
- ✅ Unified response format in `pkg/response/`
|
||||
- ✅ Error codes centralized in `pkg/errors/`
|
||||
- ✅ Constants and Redis key functions in `pkg/constants/`
|
||||
|
||||
4. **Performance Requirements** ✅
|
||||
- ✅ Middleware overhead budgeted at <5ms per request
|
||||
- ✅ Redis connection pool configured (10 connections, 5 idle)
|
||||
- ✅ Goroutines for config watcher (non-blocking)
|
||||
- ✅ Context timeouts for Redis operations (50ms)
|
||||
- ✅ Lumberjack non-blocking log rotation
|
||||
|
||||
5. **Testing Strategy** ✅
|
||||
- ✅ Table-driven tests planned (Go idiomatic)
|
||||
- ✅ Mock Redis for unit tests
|
||||
- ✅ Integration tests with testcontainers
|
||||
- ✅ Target coverage defined (70%+ overall, 90%+ core)
|
||||
|
||||
**Design Quality Metrics**:
|
||||
- Zero Java-style anti-patterns detected
|
||||
- All error handling explicit (no panic/recover abuse)
|
||||
- Configuration validation implemented
|
||||
- Graceful shutdown pattern defined
|
||||
- Security: Fail-closed auth, explicit timeout handling
|
||||
|
||||
**Conclusion**: Design is ready for implementation. All artifacts (research.md, data-model.md, contracts/api.yaml, quickstart.md) align with constitution principles. No violations or exceptions required.
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. ✅ Plan created and constitution check passed
|
||||
2. ✅ Execute Phase 0 research (research.md)
|
||||
3. ✅ Execute Phase 1 design (data-model.md, contracts/, quickstart.md)
|
||||
4. ✅ Update agent context with new technologies
|
||||
5. ✅ Phase 1 Constitution re-check passed
|
||||
6. ⏳ Run `/speckit.tasks` to generate implementation tasks
|
||||
7. ⏳ Run `/speckit.implement` to execute tasks
|
||||
|
||||
**Command**: `/speckit.plan` complete. All design artifacts generated and validated.
|
||||
|
||||
**Ready for**: `/speckit.tasks` command to generate actionable implementation tasks.
|
||||
Reference in New Issue
Block a user