docs: add implementation plan, ADRs, and task tracking system
- Add comprehensive 8-phase implementation plan (docs/plan.md) - Add 28 Architecture Decision Records (docs/adr/) covering all phases - Add task tracking system with 283+ task files (docs/stories/) - Add task generator script for automated task file creation - Add reference playbooks and requirements documentation This commit establishes the complete planning foundation for the Go Platform implementation, documenting all architectural decisions and providing detailed task breakdown for Phases 0-8.
This commit is contained in:
37
adr/0001-go-module-path.md
Normal file
37
adr/0001-go-module-path.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# ADR-0001: Go Module Path
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The project needs a Go module path that uniquely identifies the platform. This path will be used:
|
||||||
|
- In `go.mod` file
|
||||||
|
- For importing packages within the project
|
||||||
|
- For module dependencies
|
||||||
|
- For future module publishing
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use `git.dcentral.systems/toolz/goplt` as the Go module path.
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Matches the organization's Git hosting structure
|
||||||
|
- Follows Go module naming conventions
|
||||||
|
- Clearly identifies the project as a Go platform tool
|
||||||
|
- Prevents naming conflicts with other modules
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Clear, descriptive module path
|
||||||
|
- Aligns with organization's infrastructure
|
||||||
|
- Easy to identify in dependency graphs
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Requires access to `git.dcentral.systems` for module resolution
|
||||||
|
- May need to configure GOPRIVATE/GONOPROXY if using private registry
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Initialize module: `go mod init git.dcentral.systems/toolz/goplt`
|
||||||
|
- Update all import paths in code to use this module path
|
||||||
|
- Configure `.git/config` or Go environment variables if needed for private module access
|
||||||
|
|
||||||
39
adr/0002-go-version.md
Normal file
39
adr/0002-go-version.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# ADR-0002: Go Version
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
Go releases new versions regularly with new features, performance improvements, and security fixes. We need to choose a Go version that:
|
||||||
|
- Provides necessary features for the platform
|
||||||
|
- Has good ecosystem support
|
||||||
|
- Is stable and production-ready
|
||||||
|
- Supports required tooling (plugins, etc.)
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **Go 1.24.3** as the minimum required version for the platform.
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Latest stable version available
|
||||||
|
- Provides all required features for the platform
|
||||||
|
- Ensures compatibility with modern Go tooling
|
||||||
|
- Supports all planned features (modules, plugins, generics)
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Access to latest Go features and performance improvements
|
||||||
|
- Better security with latest patches
|
||||||
|
- Modern tooling support
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Requires developers to have Go 1.24.3+ installed
|
||||||
|
- CI/CD must use compatible Go version
|
||||||
|
- May limit compatibility with some older dependencies (if any)
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Specify in `go.mod`: `go 1.24`
|
||||||
|
- Document in `README.md` and CI configuration
|
||||||
|
- Update `.github/workflows/ci.yml` to use `actions/setup-go@v5` with version `1.24.3`
|
||||||
|
- Add version check script if needed
|
||||||
|
|
||||||
49
adr/0003-dependency-injection-framework.md
Normal file
49
adr/0003-dependency-injection-framework.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# ADR-0003: Dependency Injection Framework
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform requires dependency injection to:
|
||||||
|
- Manage service lifecycle
|
||||||
|
- Wire dependencies between components
|
||||||
|
- Support module system initialization
|
||||||
|
- Handle graceful shutdown
|
||||||
|
- Provide testability through dependency substitution
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **uber-go/fx** - Runtime dependency injection with lifecycle management
|
||||||
|
2. **uber-go/dig** - Compile-time dependency injection
|
||||||
|
3. **Manual constructor injection** - No framework, explicit wiring
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **uber-go/fx** (v1.23.0+) as the dependency injection framework.
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Provides lifecycle management (OnStart/OnStop hooks) crucial for services
|
||||||
|
- Supports module-based architecture through fx.Option composition
|
||||||
|
- Runtime dependency resolution with compile-time type safety
|
||||||
|
- Excellent for modular monolith architecture
|
||||||
|
- Well-documented and actively maintained
|
||||||
|
- Used by major Go projects (Uber, etc.)
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Clean lifecycle management for services
|
||||||
|
- Easy module composition via fx.Option
|
||||||
|
- Graceful shutdown handling built-in
|
||||||
|
- Test-friendly with fx.Options for test overrides
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Runtime reflection overhead (minimal)
|
||||||
|
- Learning curve for developers unfamiliar with fx
|
||||||
|
- Slightly more complex error messages on dependency resolution failures
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Install: `go get go.uber.org/fx@v1.23.0`
|
||||||
|
- Create `internal/di/container.go` with fx.New()
|
||||||
|
- Use fx.Provide() for service registration
|
||||||
|
- Use fx.Invoke() for initialization tasks
|
||||||
|
- Leverage fx.Lifecycle for service startup/shutdown
|
||||||
|
|
||||||
50
adr/0004-configuration-management.md
Normal file
50
adr/0004-configuration-management.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# ADR-0004: Configuration Management Library
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs a configuration system that:
|
||||||
|
- Supports hierarchical configuration (defaults → files → env → secrets)
|
||||||
|
- Handles multiple formats (YAML, JSON, env vars)
|
||||||
|
- Provides type-safe access to configuration values
|
||||||
|
- Supports environment-specific overrides
|
||||||
|
- Can integrate with secret managers (future)
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **spf13/viper** - Comprehensive configuration management
|
||||||
|
2. **envconfig** - Environment variable only
|
||||||
|
3. **koanf** - Lightweight configuration library
|
||||||
|
4. **Standard library + manual parsing** - No external dependency
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **spf13/viper** (v1.18.0+) with **spf13/cobra** (v1.8.0+) for configuration management.
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Industry standard for Go configuration management
|
||||||
|
- Supports multiple sources (files, env vars, flags)
|
||||||
|
- Hierarchical configuration with precedence rules
|
||||||
|
- Easy integration with Cobra for CLI commands
|
||||||
|
- Well-documented and widely used
|
||||||
|
- Supports future secret manager integration
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Flexible configuration loading from multiple sources
|
||||||
|
- Easy to add new configuration sources
|
||||||
|
- Type-safe access methods
|
||||||
|
- Environment variable support via automatic env binding
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Additional dependency
|
||||||
|
- Viper can be verbose for simple use cases
|
||||||
|
- Some learning curve for advanced features
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Install: `go get github.com/spf13/viper@v1.18.0` and `github.com/spf13/cobra@v1.8.0`
|
||||||
|
- Create `pkg/config/config.go` interface to abstract Viper
|
||||||
|
- Implement `internal/config/viper_config.go` as concrete implementation
|
||||||
|
- Load order: `default.yaml` → `development.yaml`/`production.yaml` → env vars → secrets (future)
|
||||||
|
- Use typed getters (GetString, GetInt, GetBool) for type safety
|
||||||
|
|
||||||
50
adr/0005-logging-framework.md
Normal file
50
adr/0005-logging-framework.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# ADR-0005: Logging Framework
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform requires structured logging that:
|
||||||
|
- Supports multiple log levels
|
||||||
|
- Provides structured output (JSON for production)
|
||||||
|
- Allows adding contextual fields
|
||||||
|
- Performs well under load
|
||||||
|
- Integrates with observability tools
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **go.uber.org/zap** - High-performance structured logging
|
||||||
|
2. **rs/zerolog** - Zero-allocation logger
|
||||||
|
3. **sirupsen/logrus** - Structured logger (maintenance mode)
|
||||||
|
4. **Standard library log** - Basic logging (insufficient)
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **go.uber.org/zap** (v1.26.0+) as the logging framework.
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Industry standard for high-performance Go applications
|
||||||
|
- Excellent structured logging with field support
|
||||||
|
- Very low overhead (designed for high-throughput systems)
|
||||||
|
- JSON output for production, human-readable for development
|
||||||
|
- Strong ecosystem integration
|
||||||
|
- Actively maintained by Uber
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- High performance (low latency, high throughput)
|
||||||
|
- Rich structured logging with fields
|
||||||
|
- Easy integration with observability tools
|
||||||
|
- Configurable output formats (JSON/console)
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Slightly more verbose API than standard library
|
||||||
|
- Requires wrapping for common use cases (we'll abstract via interface)
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Install: `go get go.uber.org/zap@v1.26.0`
|
||||||
|
- Create `pkg/logger/logger.go` interface to abstract zap
|
||||||
|
- Implement `internal/logger/zap_logger.go` as concrete implementation
|
||||||
|
- Use JSON encoder for production, console encoder for development
|
||||||
|
- Support request-scoped fields via context
|
||||||
|
- Export global logger via `pkg/logger` package
|
||||||
|
|
||||||
50
adr/0006-http-framework.md
Normal file
50
adr/0006-http-framework.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# ADR-0006: HTTP Framework
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs an HTTP framework for:
|
||||||
|
- REST API endpoints
|
||||||
|
- Middleware support (auth, logging, metrics)
|
||||||
|
- Request/response handling
|
||||||
|
- Route registration from modules
|
||||||
|
- Integration with observability tools
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **gin-gonic/gin** - Fast, feature-rich HTTP web framework
|
||||||
|
2. **gorilla/mux** - Lightweight router
|
||||||
|
3. **go-chi/chi** - Lightweight, idiomatic router
|
||||||
|
4. **net/http** (standard library) - No external dependency
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **gin-gonic/gin** (v1.9.1+) as the HTTP framework.
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Fast performance (comparable to net/http)
|
||||||
|
- Rich middleware ecosystem
|
||||||
|
- Excellent for REST APIs
|
||||||
|
- Easy route grouping (useful for modules)
|
||||||
|
- Good OpenTelemetry integration support
|
||||||
|
- Widely used and well-documented
|
||||||
|
- Recommended in playbook-golang.md
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- High performance
|
||||||
|
- Easy middleware chaining
|
||||||
|
- Route grouping supports module architecture
|
||||||
|
- Good ecosystem support
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Additional dependency (though lightweight)
|
||||||
|
- Slight learning curve for developers unfamiliar with Gin
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Install: `go get github.com/gin-gonic/gin@v1.9.1`
|
||||||
|
- Create router in `internal/server/server.go`
|
||||||
|
- Use route groups for module isolation: `r.Group("/api/v1/blog")`
|
||||||
|
- Add middleware stack: logging, recovery, metrics, auth (later)
|
||||||
|
- Support graceful shutdown via fx lifecycle
|
||||||
|
|
||||||
82
adr/0007-project-directory-structure.md
Normal file
82
adr/0007-project-directory-structure.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# ADR-0007: Project Directory Structure
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The project needs a clear, scalable directory structure that:
|
||||||
|
- Follows Go best practices
|
||||||
|
- Separates public interfaces from implementations
|
||||||
|
- Supports modular architecture
|
||||||
|
- Is maintainable and discoverable
|
||||||
|
- Aligns with Go community standards
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Adopt a **standard Go project layout** with **internal/** and **pkg/** separation:
|
||||||
|
|
||||||
|
```
|
||||||
|
goplt/
|
||||||
|
├── cmd/
|
||||||
|
│ └── platform/ # Application entry point
|
||||||
|
├── internal/ # Private implementation code
|
||||||
|
│ ├── di/ # Dependency injection
|
||||||
|
│ ├── registry/ # Module registry
|
||||||
|
│ ├── pluginloader/ # Plugin loader (optional)
|
||||||
|
│ ├── config/ # Config implementation
|
||||||
|
│ ├── logger/ # Logger implementation
|
||||||
|
│ └── infra/ # Infrastructure adapters
|
||||||
|
├── pkg/ # Public interfaces (exported)
|
||||||
|
│ ├── config/ # ConfigProvider interface
|
||||||
|
│ ├── logger/ # Logger interface
|
||||||
|
│ ├── module/ # IModule interface
|
||||||
|
│ ├── auth/ # Auth interfaces (Phase 2)
|
||||||
|
│ ├── perm/ # Permission DSL (Phase 2)
|
||||||
|
│ └── infra/ # Infrastructure interfaces
|
||||||
|
├── modules/ # Feature modules
|
||||||
|
│ └── blog/ # Sample module (Phase 4)
|
||||||
|
├── config/ # Configuration files
|
||||||
|
│ ├── default.yaml
|
||||||
|
│ ├── development.yaml
|
||||||
|
│ └── production.yaml
|
||||||
|
├── api/ # OpenAPI specs
|
||||||
|
├── scripts/ # Build/test scripts
|
||||||
|
├── docs/ # Documentation
|
||||||
|
│ └── adr/ # Architecture Decision Records
|
||||||
|
├── ops/ # Operations (Grafana dashboards, etc.)
|
||||||
|
├── .github/
|
||||||
|
│ └── workflows/
|
||||||
|
│ └── ci.yml
|
||||||
|
├── Dockerfile
|
||||||
|
├── docker-compose.yml
|
||||||
|
├── docker-compose.test.yml
|
||||||
|
└── go.mod
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- `internal/` prevents external packages from importing implementation details
|
||||||
|
- `pkg/` exposes only interfaces that modules need
|
||||||
|
- `cmd/` follows Go standard for application entry points
|
||||||
|
- `modules/` clearly separates feature modules
|
||||||
|
- `config/` centralizes configuration files
|
||||||
|
- Separates concerns and supports clean architecture
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Clear separation of concerns
|
||||||
|
- Prevents circular dependencies
|
||||||
|
- Easy to navigate and understand
|
||||||
|
- Aligns with Go community standards
|
||||||
|
- Supports modular architecture
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Slightly more directories than minimal structure
|
||||||
|
- Requires discipline to maintain boundaries
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Initialize with `go mod init git.dcentral.systems/toolz/goplt`
|
||||||
|
- Create all directories upfront in Phase 0
|
||||||
|
- Document structure in `README.md`
|
||||||
|
- Enforce boundaries via `internal/` package visibility
|
||||||
|
- Use `go build ./...` to verify structure
|
||||||
|
|
||||||
57
adr/0008-error-handling-strategy.md
Normal file
57
adr/0008-error-handling-strategy.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# ADR-0008: Error Handling Strategy
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
Go's error handling philosophy requires explicit error checking. We need a consistent approach for:
|
||||||
|
- Error creation and wrapping
|
||||||
|
- Error propagation
|
||||||
|
- Error classification (domain vs infrastructure)
|
||||||
|
- Error reporting (logging, monitoring)
|
||||||
|
- HTTP error responses
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Adopt a **wrapped error pattern** with **structured error types**:
|
||||||
|
|
||||||
|
1. **Error Wrapping**: Use `fmt.Errorf("context: %w", err)` for error wrapping
|
||||||
|
2. **Error Types**: Define custom error types for domain errors
|
||||||
|
3. **Error Classification**: Distinguish between:
|
||||||
|
- Domain errors (business logic failures)
|
||||||
|
- Infrastructure errors (external system failures)
|
||||||
|
- Validation errors (input validation failures)
|
||||||
|
4. **Error Context**: Always wrap errors with context about where they occurred
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Follows Go 1.13+ error wrapping best practices
|
||||||
|
- Enables error inspection with `errors.Is()` and `errors.As()`
|
||||||
|
- Maintains error chains for debugging
|
||||||
|
- Allows structured error handling
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Full error traceability through call stack
|
||||||
|
- Can inspect and handle specific error types
|
||||||
|
- Better debugging with error context
|
||||||
|
- Aligns with Go best practices
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Requires discipline to wrap errors consistently
|
||||||
|
- Can be verbose in some cases
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Always wrap errors: `return nil, fmt.Errorf("failed to load config: %w", err)`
|
||||||
|
- Create error types for domain errors:
|
||||||
|
```go
|
||||||
|
type ConfigError struct {
|
||||||
|
Key string
|
||||||
|
Cause error
|
||||||
|
}
|
||||||
|
func (e *ConfigError) Error() string { ... }
|
||||||
|
func (e *ConfigError) Unwrap() error { return e.Cause }
|
||||||
|
```
|
||||||
|
- Use `errors.Is()` and `errors.As()` for error checking
|
||||||
|
- Log errors with context before returning
|
||||||
|
- Map domain errors to HTTP status codes in handlers
|
||||||
|
|
||||||
56
adr/0009-context-key-types.md
Normal file
56
adr/0009-context-key-types.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# ADR-0009: Context Key Types
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform will use `context.Context` to propagate request-scoped values such as:
|
||||||
|
- User ID (from authentication)
|
||||||
|
- Request ID (for tracing)
|
||||||
|
- Tenant ID (for multi-tenancy)
|
||||||
|
- Logger instance (with request-scoped fields)
|
||||||
|
|
||||||
|
Go best practices recommend using typed keys instead of string keys to avoid collisions.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **typed context keys** for all context values:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type contextKey string
|
||||||
|
|
||||||
|
const (
|
||||||
|
userIDKey contextKey = "user_id"
|
||||||
|
requestIDKey contextKey = "request_id"
|
||||||
|
tenantIDKey contextKey = "tenant_id"
|
||||||
|
loggerKey contextKey = "logger"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Prevents key collisions between packages
|
||||||
|
- Type-safe access to context values
|
||||||
|
- Aligns with Go best practices (see `context.WithValue` documentation)
|
||||||
|
- Makes context usage explicit and discoverable
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Type-safe context access
|
||||||
|
- Prevents accidental key collisions
|
||||||
|
- Clear intent in code
|
||||||
|
- Better IDE support
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Slightly more verbose than string keys
|
||||||
|
- Requires defining keys upfront
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Create `pkg/context/keys.go` with all context key definitions
|
||||||
|
- Provide helper functions for setting/getting values:
|
||||||
|
```go
|
||||||
|
func WithUserID(ctx context.Context, userID string) context.Context
|
||||||
|
func UserIDFromContext(ctx context.Context) (string, bool)
|
||||||
|
```
|
||||||
|
- Use in middleware and services
|
||||||
|
- Document all context keys and their usage
|
||||||
|
|
||||||
50
adr/0010-ci-cd-platform.md
Normal file
50
adr/0010-ci-cd-platform.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# ADR-0010: CI/CD Platform
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs a CI/CD system for:
|
||||||
|
- Automated testing on pull requests
|
||||||
|
- Code quality checks (linting, formatting)
|
||||||
|
- Building binaries and Docker images
|
||||||
|
- Publishing artifacts
|
||||||
|
- Running integration tests
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **GitHub Actions** - Native GitHub integration
|
||||||
|
2. **GitLab CI** - If using GitLab
|
||||||
|
3. **Jenkins** - Self-hosted option
|
||||||
|
4. **CircleCI** - Cloud-based CI/CD
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **GitHub Actions** for CI/CD pipeline.
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Native integration with GitHub repositories
|
||||||
|
- Free for public repos, reasonable for private
|
||||||
|
- Rich ecosystem of actions
|
||||||
|
- Easy to configure with YAML
|
||||||
|
- Good documentation and community support
|
||||||
|
- Recommended in playbook-golang.md
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Easy setup and configuration
|
||||||
|
- Good GitHub integration
|
||||||
|
- Large action marketplace
|
||||||
|
- Free for public repositories
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Tied to GitHub (if migrating Git hosts, need to migrate CI)
|
||||||
|
- Limited customization compared to self-hosted solutions
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Create `.github/workflows/ci.yml`
|
||||||
|
- Use `actions/setup-go@v5` for Go setup
|
||||||
|
- Configure caching for Go modules
|
||||||
|
- Run: linting, unit tests, integration tests, build
|
||||||
|
- Use `actions/cache@v4` for module caching
|
||||||
|
- Add build matrix if needed for multiple Go versions (future)
|
||||||
|
|
||||||
53
adr/0011-code-generation-tools.md
Normal file
53
adr/0011-code-generation-tools.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# ADR-0011: Code Generation Tools
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform will use code generation for:
|
||||||
|
- Permission constants from module manifests
|
||||||
|
- Ent ORM code generation
|
||||||
|
- Mock generation for testing
|
||||||
|
- OpenAPI client/server code (future)
|
||||||
|
|
||||||
|
We need to decide on tooling and workflow.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **standard Go generation tools** with `go generate`:
|
||||||
|
|
||||||
|
1. **Ent ORM**: `entgo.io/ent/cmd/ent` for schema code generation
|
||||||
|
2. **Mocks**: `github.com/vektra/mockery/v2` or `github.com/golang/mock/mockgen`
|
||||||
|
3. **Permissions**: Custom `scripts/generate-permissions.go`
|
||||||
|
4. **OpenAPI**: `github.com/deepmap/oapi-codegen` (future)
|
||||||
|
|
||||||
|
**Workflow:**
|
||||||
|
- Use `//go:generate` directives in source files
|
||||||
|
- Run `go generate ./...` before commits
|
||||||
|
- Document in `Makefile` with `make generate` target
|
||||||
|
- CI should verify generated code is up-to-date
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Standard Go tooling, well-supported
|
||||||
|
- `go generate` is the idiomatic way to run code generation
|
||||||
|
- Easy to integrate into CI/CD
|
||||||
|
- Reduces manual code maintenance
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Automated code generation reduces errors
|
||||||
|
- Consistent code style
|
||||||
|
- Easy to maintain
|
||||||
|
- Standard Go workflow
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Requires developers to run generation before commits
|
||||||
|
- Generated code must be committed (or verified in CI)
|
||||||
|
- Slight learning curve for new developers
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Add `//go:generate` directives where needed
|
||||||
|
- Create `Makefile` target: `make generate`
|
||||||
|
- Add CI step to verify generated code: `go generate ./... && git diff --exit-code`
|
||||||
|
- Document in `CONTRIBUTING.md`
|
||||||
|
|
||||||
62
adr/0012-logger-interface-design.md
Normal file
62
adr/0012-logger-interface-design.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# ADR-0012: Logger Interface Design
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
We're using zap for logging, but want to abstract it behind an interface for:
|
||||||
|
- Testability (mock logger in tests)
|
||||||
|
- Flexibility (could swap implementations)
|
||||||
|
- Module compatibility (modules use interface, not concrete type)
|
||||||
|
|
||||||
|
We need to decide on the interface design.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Create a **simple logger interface** that matches zap's API pattern but uses generic types:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Field interface {
|
||||||
|
// Field represents a key-value pair for structured logging
|
||||||
|
}
|
||||||
|
|
||||||
|
type Logger interface {
|
||||||
|
Debug(msg string, fields ...Field)
|
||||||
|
Info(msg string, fields ...Field)
|
||||||
|
Warn(msg string, fields ...Field)
|
||||||
|
Error(msg string, fields ...Field)
|
||||||
|
With(fields ...Field) Logger
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Implementation:**
|
||||||
|
- Use `zap.Field` as the Field type (no abstraction needed for now)
|
||||||
|
- Provide helper functions in `pkg/logger` for creating fields:
|
||||||
|
```go
|
||||||
|
func String(key, value string) Field
|
||||||
|
func Int(key string, value int) Field
|
||||||
|
func Error(err error) Field
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Simple interface that modules can depend on
|
||||||
|
- Matches zap's usage patterns
|
||||||
|
- Easy to test with mock implementations
|
||||||
|
- Allows future swap if needed (though unlikely)
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Clean abstraction for modules
|
||||||
|
- Testable with mocks
|
||||||
|
- Simple API for modules to use
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Slight indirection overhead
|
||||||
|
- Need to maintain interface compatibility
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Define interface in `pkg/logger/logger.go`
|
||||||
|
- Implement in `internal/logger/zap_logger.go`
|
||||||
|
- Export helper functions in `pkg/logger/fields.go`
|
||||||
|
- Modules import `pkg/logger`, not `internal/logger`
|
||||||
|
|
||||||
54
adr/0013-database-orm.md
Normal file
54
adr/0013-database-orm.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# ADR-0013: Database ORM Selection
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs a database ORM/library that:
|
||||||
|
- Supports PostgreSQL (primary database)
|
||||||
|
- Provides type-safe query building
|
||||||
|
- Supports code generation (reduces boilerplate)
|
||||||
|
- Handles migrations
|
||||||
|
- Supports relationships (many-to-many, etc.)
|
||||||
|
- Integrates with Ent (code generation)
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **entgo.io/ent** - Code-generated, type-safe ORM
|
||||||
|
2. **gorm.io/gorm** - Feature-rich ORM with reflection
|
||||||
|
3. **sqlx** - Lightweight wrapper around database/sql
|
||||||
|
4. **Standard library database/sql** - No ORM, raw SQL
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **entgo.io/ent** as the primary ORM for the platform.
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Code generation provides compile-time type safety
|
||||||
|
- Excellent schema definition and migration support
|
||||||
|
- Strong relationship modeling
|
||||||
|
- Good performance (no reflection at runtime)
|
||||||
|
- Active development and good documentation
|
||||||
|
- Recommended in playbook-golang.md
|
||||||
|
- Easy to integrate with OpenTelemetry
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Type-safe queries eliminate runtime errors
|
||||||
|
- Schema changes are explicit and versioned
|
||||||
|
- Code generation reduces boilerplate
|
||||||
|
- Good migration support
|
||||||
|
- Strong relationship support
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Requires code generation step (`go generate`)
|
||||||
|
- Learning curve for developers unfamiliar with Ent
|
||||||
|
- Less flexible than raw SQL for complex queries
|
||||||
|
- Generated code must be committed or verified in CI
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Install: `go get entgo.io/ent/cmd/ent`
|
||||||
|
- Initialize schema: `go run entgo.io/ent/cmd/ent init User Role Permission`
|
||||||
|
- Use `//go:generate` directives for code generation
|
||||||
|
- Run migrations on startup via `client.Schema.Create()`
|
||||||
|
- Create wrapper in `internal/infra/database/client.go` for DI injection
|
||||||
|
|
||||||
52
adr/0014-health-check-implementation.md
Normal file
52
adr/0014-health-check-implementation.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# ADR-0014: Health Check Implementation
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs health check endpoints for:
|
||||||
|
- Kubernetes liveness probes (`/healthz`)
|
||||||
|
- Kubernetes readiness probes (`/ready`)
|
||||||
|
- Monitoring and alerting
|
||||||
|
- Load balancer health checks
|
||||||
|
|
||||||
|
Health checks should be:
|
||||||
|
- Fast and lightweight
|
||||||
|
- Check critical dependencies (database, cache, etc.)
|
||||||
|
- Provide clear status indicators
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Implement **custom health check registry** with composable checkers:
|
||||||
|
|
||||||
|
1. **Liveness endpoint** (`/healthz`): Always returns 200 if process is running
|
||||||
|
2. **Readiness endpoint** (`/ready`): Checks all registered health checkers
|
||||||
|
3. **Health check interface**: `type HealthChecker interface { Check(ctx context.Context) error }`
|
||||||
|
4. **Registry pattern**: Modules can register additional health checkers
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Custom implementation gives full control
|
||||||
|
- Composable design allows modules to add checks
|
||||||
|
- Simple interface is easy to test
|
||||||
|
- No external dependency for basic functionality
|
||||||
|
- Can extend with Prometheus metrics later
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Lightweight and fast
|
||||||
|
- Extensible by modules
|
||||||
|
- Easy to test
|
||||||
|
- Clear separation of liveness vs readiness
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Need to implement ourselves (though simple)
|
||||||
|
- Must maintain the registry
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Create `pkg/health/health.go` interface
|
||||||
|
- Implement `internal/health/registry.go` with checker map
|
||||||
|
- Register core checkers: database, cache (if enabled)
|
||||||
|
- Add endpoints to HTTP router
|
||||||
|
- Return JSON response: `{"status": "ok", "checks": {...}}`
|
||||||
|
- Consider timeout (e.g., 5 seconds) for readiness checks
|
||||||
|
|
||||||
55
adr/0015-error-bus-implementation.md
Normal file
55
adr/0015-error-bus-implementation.md
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# ADR-0015: Error Bus Implementation
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs a centralized error handling mechanism for:
|
||||||
|
- Capturing panics and errors
|
||||||
|
- Logging errors consistently
|
||||||
|
- Sending errors to external services (Sentry, etc.)
|
||||||
|
- Avoiding error handling duplication
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **Channel-based in-process bus** - Simple, Go-idiomatic
|
||||||
|
2. **Event bus integration** - Use existing event bus
|
||||||
|
3. **Direct logging** - No bus, direct integration
|
||||||
|
4. **External service integration** - Direct to Sentry
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Implement a **channel-based error bus** with pluggable sinks:
|
||||||
|
|
||||||
|
1. **Error bus interface**: `type ErrorPublisher interface { Publish(err error) }`
|
||||||
|
2. **Channel-based implementation**: Background goroutine consumes errors from channel
|
||||||
|
3. **Pluggable sinks**: Logger (always), Sentry (optional, Phase 6)
|
||||||
|
4. **Panic recovery middleware**: Automatically publishes panics to error bus
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Simple, idiomatic Go pattern
|
||||||
|
- Non-blocking error publishing (buffered channel)
|
||||||
|
- Decouples error capture from error handling
|
||||||
|
- Easy to add new sinks (Sentry, logging, metrics)
|
||||||
|
- Can be extended to use event bus later if needed
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Centralized error handling
|
||||||
|
- Non-blocking (doesn't slow down request path)
|
||||||
|
- Easy to extend with new sinks
|
||||||
|
- Consistent error handling across the platform
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Additional goroutine overhead (minimal)
|
||||||
|
- Must ensure error bus doesn't become bottleneck
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Create `pkg/errorbus/errorbus.go` interface
|
||||||
|
- Implement `internal/errorbus/channel_bus.go`:
|
||||||
|
- Buffered channel (e.g., size 100)
|
||||||
|
- Background goroutine consumes errors
|
||||||
|
- Multiple sinks (logger, optional Sentry)
|
||||||
|
- Add panic recovery middleware that publishes to bus
|
||||||
|
- Register in DI container as singleton
|
||||||
|
- Monitor channel size to detect error storms
|
||||||
|
|
||||||
56
adr/0016-opentelemetry-observability.md
Normal file
56
adr/0016-opentelemetry-observability.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# ADR-0016: OpenTelemetry Observability Strategy
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs distributed tracing and observability for:
|
||||||
|
- Request tracing across services/modules
|
||||||
|
- Performance monitoring
|
||||||
|
- Debugging production issues
|
||||||
|
- Integration with observability tools (Jaeger, Grafana, etc.)
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **OpenTelemetry** - Industry standard, vendor-neutral
|
||||||
|
2. **Zipkin** - Older standard, less ecosystem support
|
||||||
|
3. **Custom tracing** - Build our own
|
||||||
|
4. **No tracing** - Only logs and metrics
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **OpenTelemetry (OTEL)** for all observability:
|
||||||
|
|
||||||
|
1. **Tracing**: Distributed tracing with spans
|
||||||
|
2. **Metrics**: Prometheus-compatible metrics
|
||||||
|
3. **Logs**: Structured logs with trace correlation
|
||||||
|
4. **Export**: OTLP collector for production, stdout for development
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Industry standard, vendor-neutral
|
||||||
|
- Excellent Go SDK support
|
||||||
|
- Integrates with major observability tools
|
||||||
|
- Supports metrics, traces, and logs
|
||||||
|
- Recommended in playbook-golang.md
|
||||||
|
- Future-proof (not locked to specific vendor)
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Vendor-neutral (can switch backends)
|
||||||
|
- Rich ecosystem and tooling
|
||||||
|
- Excellent Go SDK
|
||||||
|
- Supports all observability signals
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Learning curve for OpenTelemetry concepts
|
||||||
|
- Slight overhead (minimal with sampling)
|
||||||
|
- Requires OTLP collector or compatible backend
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Install: `go.opentelemetry.io/otel` and contrib packages
|
||||||
|
- Initialize TracerProvider in `internal/observability/tracer.go`
|
||||||
|
- Use HTTP instrumentation middleware: `otelhttp.NewHandler()`
|
||||||
|
- Add database instrumentation via Ent interceptor
|
||||||
|
- Export to stdout for development, OTLP for production
|
||||||
|
- Include trace ID in structured logs
|
||||||
|
- Configure sampling for production (e.g., 10% or adaptive)
|
||||||
|
|
||||||
55
adr/0017-jwt-token-strategy.md
Normal file
55
adr/0017-jwt-token-strategy.md
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# ADR-0017: JWT Token Strategy
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs authentication tokens that:
|
||||||
|
- Are stateless (no server-side session storage)
|
||||||
|
- Support role and permission claims
|
||||||
|
- Can be revoked (challenge)
|
||||||
|
- Have appropriate lifetimes
|
||||||
|
- Support multi-tenancy (tenant ID in claims)
|
||||||
|
|
||||||
|
Token strategies considered:
|
||||||
|
1. **Short-lived access tokens + long-lived refresh tokens** - Industry standard
|
||||||
|
2. **Single long-lived tokens** - Simple but insecure
|
||||||
|
3. **Short-lived tokens only** - Secure but poor UX
|
||||||
|
4. **Session-based** - Stateful, requires storage
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **short-lived access tokens + long-lived refresh tokens**:
|
||||||
|
|
||||||
|
1. **Access tokens**: 15 minutes lifetime, contain user ID, roles, tenant ID
|
||||||
|
2. **Refresh tokens**: 7 days lifetime, stored in database (for revocation)
|
||||||
|
3. **Token format**: JWT with claims: `sub` (user ID), `roles`, `tenant_id`, `exp`
|
||||||
|
4. **Revocation**: Refresh tokens stored in DB, can be revoked/deleted
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Industry best practice (OAuth2/OIDC pattern)
|
||||||
|
- Good balance of security and UX
|
||||||
|
- Access tokens can't be revoked (short lifetime mitigates risk)
|
||||||
|
- Refresh tokens can be revoked (stored in DB)
|
||||||
|
- Supports stateless authentication for most requests
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Secure (short access token lifetime)
|
||||||
|
- Good UX (refresh tokens prevent frequent re-login)
|
||||||
|
- Stateless for most requests (access tokens)
|
||||||
|
- Supports revocation (refresh tokens)
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Requires refresh token storage (DB table)
|
||||||
|
- More complex than single token
|
||||||
|
- Need to handle token refresh flow
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Use `github.com/golang-jwt/jwt/v5` for JWT handling
|
||||||
|
- Store refresh tokens in `refresh_tokens` table (user_id, token_hash, expires_at)
|
||||||
|
- Generate access tokens with HS256 or RS256 signing
|
||||||
|
- Include roles in token claims (not just role IDs)
|
||||||
|
- Validate token signature and expiration on each request
|
||||||
|
- Refresh endpoint validates refresh token and issues new access token
|
||||||
|
|
||||||
53
adr/0018-password-hashing.md
Normal file
53
adr/0018-password-hashing.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# ADR-0018: Password Hashing Algorithm
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs to securely store user passwords. Requirements:
|
||||||
|
- Resist brute-force attacks
|
||||||
|
- Resist rainbow table attacks
|
||||||
|
- Future-proof against advances in computing
|
||||||
|
- Reasonable performance (not too slow)
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **bcrypt** - Battle-tested, widely used
|
||||||
|
2. **argon2id** - Modern, memory-hard, recommended by OWASP
|
||||||
|
3. **scrypt** - Memory-hard, good alternative
|
||||||
|
4. **PBKDF2** - Older standard, less secure
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **argon2id** for password hashing with recommended parameters:
|
||||||
|
|
||||||
|
- **Algorithm**: argon2id (variant)
|
||||||
|
- **Memory**: 64 MB (65536 KB)
|
||||||
|
- **Iterations**: 3 (time cost)
|
||||||
|
- **Parallelism**: 4 (number of threads)
|
||||||
|
- **Salt length**: 16 bytes (random, unique per password)
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Recommended by OWASP for new applications
|
||||||
|
- Memory-hard algorithm (resistant to GPU/ASIC attacks)
|
||||||
|
- Good balance of security and performance
|
||||||
|
- Future-proof design
|
||||||
|
- Standard library support in Go 1.23+
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Strong security guarantees
|
||||||
|
- Memory-hard (resistant to hardware attacks)
|
||||||
|
- OWASP recommended
|
||||||
|
- Standard library support
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Slightly slower than bcrypt (acceptable trade-off)
|
||||||
|
- Requires tuning parameters for production
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Use `golang.org/x/crypto/argon2` package
|
||||||
|
- Store hash in format: `$argon2id$v=19$m=65536,t=3,p=4$salt$hash`
|
||||||
|
- Use `crypto/rand` for salt generation
|
||||||
|
- Verify passwords with `argon2.CompareHashAndPassword()`
|
||||||
|
- Consider increasing parameters for high-security environments
|
||||||
|
|
||||||
57
adr/0019-permission-dsl-format.md
Normal file
57
adr/0019-permission-dsl-format.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# ADR-0019: Permission DSL Format
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs a permission system that:
|
||||||
|
- Is extensible by modules
|
||||||
|
- Prevents typos and errors (compile-time safety)
|
||||||
|
- Supports hierarchical permissions
|
||||||
|
- Is easy to understand and use
|
||||||
|
|
||||||
|
Permission formats considered:
|
||||||
|
1. **String format**: `"module.resource.action"` - Simple, flexible
|
||||||
|
2. **Enum/Constants**: Type-safe but less flexible
|
||||||
|
3. **Hierarchical tree**: Complex but powerful
|
||||||
|
4. **Bitmask**: Efficient but hard to read
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **string-based permission format** with **code-generated constants**:
|
||||||
|
|
||||||
|
1. **Format**: `"{module}.{resource}.{action}"`
|
||||||
|
- Examples: `blog.post.create`, `user.read`, `system.health.check`
|
||||||
|
2. **Code generation**: Generate constants from `module.yaml` files
|
||||||
|
3. **Type safety**: `type Permission string` with generated constants
|
||||||
|
4. **Validation**: Compile-time constants prevent typos
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Simple and readable
|
||||||
|
- Easy to extend (modules define in manifest)
|
||||||
|
- Code generation provides compile-time safety
|
||||||
|
- Flexible (modules can define any format)
|
||||||
|
- Hierarchical structure is intuitive
|
||||||
|
- Easy to parse and match
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Simple and intuitive format
|
||||||
|
- Compile-time safety via code generation
|
||||||
|
- Easy to extend by modules
|
||||||
|
- Human-readable
|
||||||
|
- Flexible for various permission models
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- String comparisons (minimal performance impact)
|
||||||
|
- Requires code generation step
|
||||||
|
- Potential for permission string conflicts (mitigated by module prefix)
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Define `type Permission string` in `pkg/perm/perm.go`
|
||||||
|
- Create code generator: `scripts/generate-permissions.go`
|
||||||
|
- Scan `modules/*/module.yaml` for permissions
|
||||||
|
- Generate constants in `pkg/perm/generated.go`
|
||||||
|
- Use `//go:generate` directive
|
||||||
|
- Validate format: `^[a-z0-9]+(\.[a-z0-9]+)*$` (lowercase, dots)
|
||||||
|
|
||||||
63
adr/0020-audit-logging-storage.md
Normal file
63
adr/0020-audit-logging-storage.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# ADR-0020: Audit Logging Storage
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs to audit all security-relevant actions:
|
||||||
|
- User logins and authentication attempts
|
||||||
|
- Permission changes
|
||||||
|
- Data modifications
|
||||||
|
- Administrative actions
|
||||||
|
|
||||||
|
Audit logs must be:
|
||||||
|
- Immutable (append-only)
|
||||||
|
- Queryable
|
||||||
|
- Performant (don't slow down operations)
|
||||||
|
- Compliant with audit requirements
|
||||||
|
|
||||||
|
Storage options considered:
|
||||||
|
1. **PostgreSQL table** - Simple, queryable, transactional
|
||||||
|
2. **Elasticsearch** - Excellent for searching, but additional dependency
|
||||||
|
3. **File-based logs** - Simple but hard to query
|
||||||
|
4. **External audit service** - Overkill for initial version
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Store audit logs in **PostgreSQL append-only table** with JSON metadata:
|
||||||
|
|
||||||
|
1. **Table structure**: `audit_logs` with columns:
|
||||||
|
- `id`, `actor_id`, `action`, `target_id`, `metadata` (JSONB), `timestamp`
|
||||||
|
2. **Append-only**: No UPDATE or DELETE operations
|
||||||
|
3. **JSON metadata**: Flexible storage for additional context
|
||||||
|
4. **Indexing**: Index on `actor_id`, `action`, `timestamp` for queries
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Simple (no additional infrastructure)
|
||||||
|
- Queryable via SQL
|
||||||
|
- Transactional (consistent with other data)
|
||||||
|
- JSONB provides flexibility for metadata
|
||||||
|
- Can migrate to Elasticsearch later if needed
|
||||||
|
- Good performance for typical audit volumes
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Simple implementation
|
||||||
|
- Queryable via SQL
|
||||||
|
- No additional infrastructure
|
||||||
|
- Transactional consistency
|
||||||
|
- Can archive old logs if needed
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Adds load to primary database
|
||||||
|
- May need archiving strategy for large volumes
|
||||||
|
- Less powerful search than Elasticsearch
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Create `audit_logs` table via Ent schema
|
||||||
|
- Use JSONB for metadata column (PostgreSQL-specific)
|
||||||
|
- Add indexes: `(actor_id, timestamp)`, `(action, timestamp)`
|
||||||
|
- Implement async logging (optional, via channel) for high throughput
|
||||||
|
- Consider partitioning by date for large volumes
|
||||||
|
- Add retention policy (e.g., archive after 1 year)
|
||||||
|
|
||||||
54
adr/0021-module-loading-strategy.md
Normal file
54
adr/0021-module-loading-strategy.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# ADR-0021: Module Loading Strategy
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs to support pluggable modules. Two approaches:
|
||||||
|
1. **Static registration** - Modules compiled into binary
|
||||||
|
2. **Dynamic plugin loading** - Load `.so` files at runtime
|
||||||
|
|
||||||
|
Each has trade-offs for development, CI, and production.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Support **both approaches** with **static registration as primary**:
|
||||||
|
|
||||||
|
1. **Static registration (primary)**:
|
||||||
|
- Modules register via `init()` function
|
||||||
|
- Imported via `import _ "module/pkg"` in main
|
||||||
|
- Works everywhere (Windows, Linux, macOS)
|
||||||
|
- Compile-time type safety
|
||||||
|
|
||||||
|
2. **Dynamic plugin loading (optional)**:
|
||||||
|
- Support via Go `plugin` package
|
||||||
|
- Load `.so` files from `./plugins/` directory
|
||||||
|
- Only for production scenarios requiring hot-swap
|
||||||
|
- Linux/macOS only (Go plugin limitation)
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Static registration is simpler and more reliable
|
||||||
|
- Works in CI/CD (no plugin compilation needed)
|
||||||
|
- Compile-time safety catches errors early
|
||||||
|
- Dynamic loading provides flexibility for specific use cases
|
||||||
|
- Modules can choose their approach
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Flexible: static for most cases, dynamic when needed
|
||||||
|
- Static registration works everywhere
|
||||||
|
- Compile-time safety with static
|
||||||
|
- Hot-swap capability with dynamic (Linux/macOS)
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Two code paths to maintain
|
||||||
|
- Dynamic plugins have version compatibility constraints
|
||||||
|
- Plugin debugging is harder
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Implement static registry in `internal/registry/registry.go`
|
||||||
|
- Modules register via: `registry.Register(Module)` in `init()`
|
||||||
|
- Implement plugin loader in `internal/pluginloader/plugin_loader.go` (optional)
|
||||||
|
- Document when to use each approach
|
||||||
|
- Validate plugin version compatibility if using dynamic loading
|
||||||
|
|
||||||
56
adr/0022-cache-implementation.md
Normal file
56
adr/0022-cache-implementation.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# ADR-0022: Cache Implementation
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs caching for:
|
||||||
|
- Performance optimization (reduce database load)
|
||||||
|
- Frequently accessed data (user permissions, roles)
|
||||||
|
- Session data (optional)
|
||||||
|
- Query results
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **Redis** - Industry standard, feature-rich
|
||||||
|
2. **In-memory cache** - Simple, no external dependency
|
||||||
|
3. **Memcached** - Simple, but less features than Redis
|
||||||
|
4. **No cache** - Simplest, but poor performance at scale
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **Redis** as the primary cache with **in-memory fallback**:
|
||||||
|
|
||||||
|
1. **Primary**: Redis for production
|
||||||
|
2. **Fallback**: In-memory cache for development/testing
|
||||||
|
3. **Interface abstraction**: `Cache` interface allows swapping implementations
|
||||||
|
4. **Use cases**: Permission lookups, role assignments, query caching
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Industry standard, widely supported
|
||||||
|
- Rich feature set (TTL, pub/sub, etc.)
|
||||||
|
- Can be shared across instances (multi-instance deployments)
|
||||||
|
- Good performance
|
||||||
|
- Easy to abstract behind interface
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- High performance
|
||||||
|
- Shared across instances
|
||||||
|
- Rich feature set
|
||||||
|
- Easy to scale horizontally
|
||||||
|
- Abstraction allows swapping implementations
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Additional infrastructure dependency
|
||||||
|
- Network latency (minimal with proper setup)
|
||||||
|
- Need to handle Redis failures gracefully
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Install: `github.com/redis/go-redis/v9`
|
||||||
|
- Create `pkg/infra/cache/cache.go` interface
|
||||||
|
- Implement `internal/infra/cache/redis_cache.go`
|
||||||
|
- Implement `internal/infra/cache/memory_cache.go` for fallback
|
||||||
|
- Use connection pooling
|
||||||
|
- Handle Redis failures gracefully (fallback or error)
|
||||||
|
- Configure TTLs appropriately (e.g., 5 minutes for permissions)
|
||||||
|
|
||||||
59
adr/0023-event-bus-implementation.md
Normal file
59
adr/0023-event-bus-implementation.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# ADR-0023: Event Bus Implementation
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs an event bus for:
|
||||||
|
- Module-to-module communication
|
||||||
|
- Decoupled event publishing
|
||||||
|
- Event sourcing (optional, future)
|
||||||
|
- Integration with external systems
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **In-process channel-based bus** - Simple, for development/testing
|
||||||
|
2. **Kafka** - Production-grade, scalable
|
||||||
|
3. **RabbitMQ** - Alternative message broker
|
||||||
|
4. **Redis pub/sub** - Simple but less reliable
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Support **dual implementation** with **in-process primary, Kafka for production**:
|
||||||
|
|
||||||
|
1. **In-process bus (default)**:
|
||||||
|
- Channel-based implementation
|
||||||
|
- Used for development, testing, small deployments
|
||||||
|
- Simple, no external dependencies
|
||||||
|
|
||||||
|
2. **Kafka bus (production)**:
|
||||||
|
- Full Kafka integration via `segmentio/kafka-go`
|
||||||
|
- Producer/consumer groups
|
||||||
|
- Configurable via environment (switch implementation)
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- In-process bus is simple for development
|
||||||
|
- Kafka provides production-grade reliability and scalability
|
||||||
|
- Interface abstraction allows swapping
|
||||||
|
- Modules don't need to know which implementation
|
||||||
|
- Can start simple and scale up
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Simple for development (no Kafka needed)
|
||||||
|
- Scalable for production (Kafka)
|
||||||
|
- Flexible (can choose implementation)
|
||||||
|
- Modules are decoupled from implementation
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Two implementations to maintain
|
||||||
|
- Need to ensure interface covers both use cases
|
||||||
|
- Kafka adds infrastructure complexity
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Create `pkg/eventbus/eventbus.go` interface
|
||||||
|
- Implement `internal/infra/bus/inprocess_bus.go` (channel-based)
|
||||||
|
- Implement `internal/infra/bus/kafka_bus.go` (Kafka)
|
||||||
|
- Select implementation via config
|
||||||
|
- Support both sync and async event publishing
|
||||||
|
- Handle errors gracefully (retry, dead letter queue)
|
||||||
|
|
||||||
56
adr/0024-job-scheduler.md
Normal file
56
adr/0024-job-scheduler.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# ADR-0024: Background Job Scheduler
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs background job processing for:
|
||||||
|
- Periodic tasks (cron jobs)
|
||||||
|
- Asynchronous processing
|
||||||
|
- Long-running operations
|
||||||
|
- Retry logic for failed jobs
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **asynq (Redis-based)** - Simple, feature-rich
|
||||||
|
2. **cron + custom queue** - Build our own
|
||||||
|
3. **Kafka consumers** - Use event bus
|
||||||
|
4. **External service** - AWS SQS, etc.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **asynq** (Redis-backed) for job scheduling:
|
||||||
|
|
||||||
|
1. **Cron jobs**: `github.com/robfig/cron/v3` for periodic tasks
|
||||||
|
2. **Job queue**: `github.com/hibiken/asynq` for async jobs
|
||||||
|
3. **Storage**: Redis (shared with cache)
|
||||||
|
4. **Features**: Retries, backoff, job status tracking
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Simple, Redis-backed (no new infrastructure)
|
||||||
|
- Good Go library support
|
||||||
|
- Built-in retry and backoff
|
||||||
|
- Job status tracking
|
||||||
|
- Easy to integrate
|
||||||
|
- Can scale horizontally (multiple workers)
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Simple (uses existing Redis)
|
||||||
|
- Feature-rich (retries, backoff)
|
||||||
|
- Good performance
|
||||||
|
- Easy to scale
|
||||||
|
- Job status tracking
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Tied to Redis (but we're already using it)
|
||||||
|
- Requires Redis to be available
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Install: `github.com/hibiken/asynq` and `github.com/robfig/cron/v3`
|
||||||
|
- Create `pkg/scheduler/scheduler.go` interface
|
||||||
|
- Implement `internal/infra/scheduler/asynq_scheduler.go`
|
||||||
|
- Register jobs in `internal/infra/scheduler/job_registry.go`
|
||||||
|
- Start worker in fx lifecycle
|
||||||
|
- Configure retry policies (exponential backoff)
|
||||||
|
- Add job monitoring endpoint
|
||||||
|
|
||||||
49
adr/0025-multitenancy-model.md
Normal file
49
adr/0025-multitenancy-model.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# ADR-0025: Multi-tenancy Model
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform may need multi-tenancy support for SaaS deployments. Options:
|
||||||
|
1. **Shared database with tenant_id column** - Single DB, row-level isolation
|
||||||
|
2. **Schema-per-tenant** - Single DB, separate schemas
|
||||||
|
3. **Database-per-tenant** - Separate databases
|
||||||
|
|
||||||
|
Each has trade-offs for isolation, performance, and operational complexity.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **shared database with tenant_id column** (optional feature):
|
||||||
|
|
||||||
|
1. **Model**: Single PostgreSQL database with `tenant_id` column on tenant-scoped tables
|
||||||
|
2. **Isolation**: Row-level via Ent interceptors (automatic filtering)
|
||||||
|
3. **Tenant resolution**: From header (`X-Tenant-ID`), subdomain, or JWT claim
|
||||||
|
4. **Optional**: Can be disabled for single-tenant deployments
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Simplest operational model (single database)
|
||||||
|
- Good performance (can index tenant_id)
|
||||||
|
- Easy to implement (Ent interceptors)
|
||||||
|
- Can migrate to schema-per-tenant later if needed
|
||||||
|
- Flexible (can support both single and multi-tenant)
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Simple operations (single database)
|
||||||
|
- Good performance with proper indexing
|
||||||
|
- Easy to implement
|
||||||
|
- Flexible (optional feature)
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Requires careful query design (ensure tenant_id filtering)
|
||||||
|
- Data isolation at application level (not database level)
|
||||||
|
- Potential for data leakage if bugs occur
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Make tenant_id optional (nullable) for single-tenant mode
|
||||||
|
- Add Ent interceptor to automatically filter by tenant_id
|
||||||
|
- Resolve tenant from context via middleware
|
||||||
|
- Add tenant_id to JWT claims
|
||||||
|
- Document tenant isolation guarantees
|
||||||
|
- Consider adding tenant_id to all tenant-scoped tables
|
||||||
|
|
||||||
54
adr/0026-error-reporting-service.md
Normal file
54
adr/0026-error-reporting-service.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# ADR-0026: Error Reporting Service
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs error reporting for:
|
||||||
|
- Production error tracking
|
||||||
|
- Stack trace collection
|
||||||
|
- Error aggregation and analysis
|
||||||
|
- Integration with monitoring
|
||||||
|
|
||||||
|
Options considered:
|
||||||
|
1. **Sentry** - Popular, feature-rich
|
||||||
|
2. **Rollbar** - Alternative error tracking
|
||||||
|
3. **Custom solution** - Build our own
|
||||||
|
4. **Logs only** - No external service
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Use **Sentry** for error reporting (optional, configurable):
|
||||||
|
|
||||||
|
1. **Integration**: Via error bus sink
|
||||||
|
2. **Configuration**: Sentry DSN from config
|
||||||
|
3. **Context**: Include user ID, trace ID, module name
|
||||||
|
4. **Optional**: Can be disabled for development
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Industry standard error tracking
|
||||||
|
- Excellent Go SDK
|
||||||
|
- Rich features (release tracking, grouping, etc.)
|
||||||
|
- Good free tier
|
||||||
|
- Easy to integrate
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Excellent error tracking
|
||||||
|
- Rich context and grouping
|
||||||
|
- Easy integration
|
||||||
|
- Good free tier
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- External dependency
|
||||||
|
- Additional cost at scale
|
||||||
|
- Privacy considerations (data sent to Sentry)
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Install: `github.com/getsentry/sentry-go`
|
||||||
|
- Create Sentry sink for error bus
|
||||||
|
- Configure via environment variable
|
||||||
|
- Include context: user ID, trace ID, module name
|
||||||
|
- Set up release tracking
|
||||||
|
- Configure sampling for high-volume deployments
|
||||||
|
|
||||||
54
adr/0027-rate-limiting-strategy.md
Normal file
54
adr/0027-rate-limiting-strategy.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# ADR-0027: Rate Limiting Strategy
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs rate limiting to:
|
||||||
|
- Prevent abuse and DoS attacks
|
||||||
|
- Protect against brute-force attacks
|
||||||
|
- Ensure fair resource usage
|
||||||
|
- Comply with API usage policies
|
||||||
|
|
||||||
|
Rate limiting strategies:
|
||||||
|
1. **Per-user rate limiting** - Based on authenticated user
|
||||||
|
2. **Per-IP rate limiting** - Based on client IP
|
||||||
|
3. **Fixed rate limiting** - Global limits
|
||||||
|
4. **Distributed rate limiting** - Shared state across instances
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Implement **multi-level rate limiting**:
|
||||||
|
|
||||||
|
1. **Per-user rate limiting**: For authenticated requests (e.g., 100 req/min)
|
||||||
|
2. **Per-IP rate limiting**: For all requests (e.g., 1000 req/min)
|
||||||
|
3. **Storage**: Redis for distributed rate limiting
|
||||||
|
4. **Algorithm**: Token bucket or sliding window
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Multi-level provides defense in depth
|
||||||
|
- Per-user prevents abuse by authenticated users
|
||||||
|
- Per-IP protects against unauthenticated abuse
|
||||||
|
- Redis enables distributed rate limiting (multi-instance)
|
||||||
|
- Token bucket provides smooth rate limiting
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- Multi-layer protection
|
||||||
|
- Works with multiple instances
|
||||||
|
- Configurable per endpoint
|
||||||
|
- Standard approach
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Requires Redis (or shared state)
|
||||||
|
- Additional latency (minimal)
|
||||||
|
- Need to handle Redis failures gracefully
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Use `github.com/ulule/limiter/v3` library
|
||||||
|
- Configure limits in config file
|
||||||
|
- Store rate limit state in Redis
|
||||||
|
- Return `X-RateLimit-*` headers
|
||||||
|
- Handle Redis failures gracefully (fail open or closed based on config)
|
||||||
|
- Configure different limits for different endpoints
|
||||||
|
|
||||||
67
adr/0028-testing-strategy.md
Normal file
67
adr/0028-testing-strategy.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# ADR-0028: Testing Strategy
|
||||||
|
|
||||||
|
## Status
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
The platform needs a comprehensive testing strategy:
|
||||||
|
- Unit tests for individual components
|
||||||
|
- Integration tests for full flows
|
||||||
|
- Contract tests for API compatibility
|
||||||
|
- Load tests for performance
|
||||||
|
|
||||||
|
Testing tools and approaches vary in complexity and coverage.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
Adopt a **multi-layered testing approach**:
|
||||||
|
|
||||||
|
1. **Unit tests**:
|
||||||
|
- Tool: Standard `testing` package + `testify`
|
||||||
|
- Coverage: >80% for core modules
|
||||||
|
- Mocks: `mockery` or `mockgen`
|
||||||
|
- Fast execution (< 1 second)
|
||||||
|
|
||||||
|
2. **Integration tests**:
|
||||||
|
- Tool: `testcontainers-go` for Docker-based services
|
||||||
|
- Coverage: End-to-end flows (auth, modules, etc.)
|
||||||
|
- Infrastructure: PostgreSQL, Redis, Kafka via testcontainers
|
||||||
|
- Tagged: `//go:build integration`
|
||||||
|
|
||||||
|
3. **Contract tests**:
|
||||||
|
- Tool: OpenAPI validator (`kin-openapi`)
|
||||||
|
- Coverage: API request/response validation
|
||||||
|
- Optional: Pact for service contracts
|
||||||
|
|
||||||
|
4. **Load tests**:
|
||||||
|
- Tool: k6 or vegeta
|
||||||
|
- Coverage: Critical endpoints (auth, API)
|
||||||
|
- Performance benchmarks
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
- Comprehensive coverage across layers
|
||||||
|
- Fast feedback with unit tests
|
||||||
|
- Realistic testing with integration tests
|
||||||
|
- API compatibility with contract tests
|
||||||
|
- Performance validation with load tests
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
- High confidence in code quality
|
||||||
|
- Fast unit tests for quick feedback
|
||||||
|
- Realistic integration tests
|
||||||
|
- API compatibility guaranteed
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
- Integration tests are slower
|
||||||
|
- Requires Docker for testcontainers
|
||||||
|
- More complex CI setup
|
||||||
|
|
||||||
|
### Implementation Notes
|
||||||
|
- Use `testify` for assertions: `require` and `assert`
|
||||||
|
- Generate mocks with `mockery` or `mockgen`
|
||||||
|
- Create test helpers in `internal/testutil/`
|
||||||
|
- Use test tags: `go test -tags=integration ./...`
|
||||||
|
- Run integration tests in separate CI job
|
||||||
|
- Document testing approach in `CONTRIBUTING.md`
|
||||||
|
|
||||||
86
adr/README.md
Normal file
86
adr/README.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# Architecture Decision Records (ADRs)
|
||||||
|
|
||||||
|
This directory contains Architecture Decision Records (ADRs) for the Go Platform project.
|
||||||
|
|
||||||
|
## What are ADRs?
|
||||||
|
|
||||||
|
ADRs document important architectural decisions made during the project. They help:
|
||||||
|
- Track why decisions were made
|
||||||
|
- Understand the context and constraints
|
||||||
|
- Review decisions when requirements change
|
||||||
|
- Onboard new team members
|
||||||
|
|
||||||
|
## ADR Format
|
||||||
|
|
||||||
|
Each ADR follows this structure:
|
||||||
|
- **Status**: Proposed | Accepted | Rejected | Superseded
|
||||||
|
- **Context**: The situation that led to the decision
|
||||||
|
- **Decision**: What was decided
|
||||||
|
- **Consequences**: Positive and negative impacts
|
||||||
|
|
||||||
|
## ADR Index
|
||||||
|
|
||||||
|
### Phase 0: Project Setup & Foundation
|
||||||
|
|
||||||
|
- [ADR-0001: Go Module Path](./0001-go-module-path.md) - Module path: `git.dcentral.systems/toolz/goplt`
|
||||||
|
- [ADR-0002: Go Version](./0002-go-version.md) - Go 1.24.3
|
||||||
|
- [ADR-0003: Dependency Injection Framework](./0003-dependency-injection-framework.md) - uber-go/fx
|
||||||
|
- [ADR-0004: Configuration Management](./0004-configuration-management.md) - spf13/viper + cobra
|
||||||
|
- [ADR-0005: Logging Framework](./0005-logging-framework.md) - go.uber.org/zap
|
||||||
|
- [ADR-0006: HTTP Framework](./0006-http-framework.md) - gin-gonic/gin
|
||||||
|
- [ADR-0007: Project Directory Structure](./0007-project-directory-structure.md) - Standard Go layout with internal/pkg separation
|
||||||
|
- [ADR-0008: Error Handling Strategy](./0008-error-handling-strategy.md) - Wrapped errors with typed errors
|
||||||
|
- [ADR-0009: Context Key Types](./0009-context-key-types.md) - Typed context keys
|
||||||
|
- [ADR-0010: CI/CD Platform](./0010-ci-cd-platform.md) - GitHub Actions
|
||||||
|
- [ADR-0011: Code Generation Tools](./0011-code-generation-tools.md) - go generate workflow
|
||||||
|
- [ADR-0012: Logger Interface Design](./0012-logger-interface-design.md) - Logger interface abstraction
|
||||||
|
|
||||||
|
### Phase 1: Core Kernel & Infrastructure
|
||||||
|
|
||||||
|
- [ADR-0013: Database ORM Selection](./0013-database-orm.md) - entgo.io/ent
|
||||||
|
- [ADR-0014: Health Check Implementation](./0014-health-check-implementation.md) - Custom health check registry
|
||||||
|
- [ADR-0015: Error Bus Implementation](./0015-error-bus-implementation.md) - Channel-based error bus with pluggable sinks
|
||||||
|
- [ADR-0016: OpenTelemetry Observability Strategy](./0016-opentelemetry-observability.md) - OpenTelemetry for tracing, metrics, logs
|
||||||
|
|
||||||
|
### Phase 2: Authentication & Authorization
|
||||||
|
|
||||||
|
- [ADR-0017: JWT Token Strategy](./0017-jwt-token-strategy.md) - Short-lived access tokens + long-lived refresh tokens
|
||||||
|
- [ADR-0018: Password Hashing Algorithm](./0018-password-hashing.md) - argon2id
|
||||||
|
- [ADR-0019: Permission DSL Format](./0019-permission-dsl-format.md) - String-based format with code generation
|
||||||
|
- [ADR-0020: Audit Logging Storage](./0020-audit-logging-storage.md) - PostgreSQL append-only table with JSONB metadata
|
||||||
|
|
||||||
|
### Phase 3: Module Framework
|
||||||
|
|
||||||
|
- [ADR-0021: Module Loading Strategy](./0021-module-loading-strategy.md) - Static registration (primary) + dynamic plugin loading (optional)
|
||||||
|
|
||||||
|
### Phase 5: Infrastructure Adapters
|
||||||
|
|
||||||
|
- [ADR-0022: Cache Implementation](./0022-cache-implementation.md) - Redis with in-memory fallback
|
||||||
|
- [ADR-0023: Event Bus Implementation](./0023-event-bus-implementation.md) - In-process bus (default) + Kafka (production)
|
||||||
|
- [ADR-0024: Background Job Scheduler](./0024-job-scheduler.md) - asynq (Redis-backed) + cron
|
||||||
|
- [ADR-0025: Multi-tenancy Model](./0025-multitenancy-model.md) - Shared database with tenant_id column (optional)
|
||||||
|
|
||||||
|
### Phase 6: Observability & Production Readiness
|
||||||
|
|
||||||
|
- [ADR-0026: Error Reporting Service](./0026-error-reporting-service.md) - Sentry (optional, configurable)
|
||||||
|
- [ADR-0027: Rate Limiting Strategy](./0027-rate-limiting-strategy.md) - Multi-level (per-user + per-IP) with Redis
|
||||||
|
|
||||||
|
### Phase 7: Testing, Documentation & CI/CD
|
||||||
|
|
||||||
|
- [ADR-0028: Testing Strategy](./0028-testing-strategy.md) - Multi-layered (unit, integration, contract, load)
|
||||||
|
|
||||||
|
## Adding New ADRs
|
||||||
|
|
||||||
|
When making a new architectural decision:
|
||||||
|
|
||||||
|
1. Create a new file: `XXXX-short-title.md` (next sequential number)
|
||||||
|
2. Follow the ADR template
|
||||||
|
3. Update this README with the new entry
|
||||||
|
4. Set status to "Proposed" initially
|
||||||
|
5. Update to "Accepted" after review/approval
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [ADR Template](https://adr.github.io/madr/)
|
||||||
|
- [Documenting Architecture Decisions](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions)
|
||||||
|
|
||||||
620
playbook.md
Normal file
620
playbook.md
Normal file
@@ -0,0 +1,620 @@
|
|||||||
|
# Go‑Platform Boilerplate Play‑book
|
||||||
|
**“Plug‑in‑friendly SaaS/Enterprise Platform – Go Edition”**
|
||||||
|
|
||||||
|
## 1️⃣ ARCHITECTURAL IMPERATIVES (Go‑flavoured)
|
||||||
|
|
||||||
|
| Principle | Go‑specific rationale | Enforcement Technique |
|
||||||
|
|-----------|-----------------------|------------------------|
|
||||||
|
| **Clean / Hexagonal Architecture** | Go’s package‑level visibility (`internal/`) naturally creates a *boundary* between core and plug‑ins. | Keep all **domain** code in `internal/domain`, expose only **interfaces** in `pkg/`. |
|
||||||
|
| **Dependency Injection (DI) via Constructors** | Go avoids reflection‑heavy containers; compile‑time wiring is preferred. | Use **uber‑go/fx** (runtime graph) *or* **uber‑go/dig** for optional runtime DI. For a lighter weight solution, use plain **constructor injection** with a small **registry**. |
|
||||||
|
| **Modular Monolith → Micro‑service‑ready** | A single binary is cheap in Go; later you can extract modules into separate services without breaking APIs. | Each module lives in its own Go **module** (`go.mod`) under `./modules/*`. The core loads them via the **Go plugin** system *or* static registration (preferred for CI stability). |
|
||||||
|
| **Plugin‑first design** | Go’s `plugin` package allows runtime loading of compiled `.so` files (Linux/macOS). | Provide an **IModule** interface and a **loader** that discovers `*.so` files (or compiled‑in modules for CI). |
|
||||||
|
| **API‑First (OpenAPI + gin/gorilla)** | Guarantees language‑agnostic contracts. | Generate server stubs from an `openapi.yaml` stored in `api/`. |
|
||||||
|
| **Security‑by‑Design** | Go’s static typing makes it easy to keep auth data out of the request flow. | Central middleware for JWT verification + context‑based user propagation. |
|
||||||
|
| **Observability (OpenTelemetry)** | The Go ecosystem ships first‑class OTEL SDK. | Instrument HTTP, DB, queues, and custom events automatically. |
|
||||||
|
| **Configuration‑as‑Code** | Viper + Cobra give hierarchical config and flag parsing. | Load defaults → file → env → secret manager (AWS Secrets Manager / Vault). |
|
||||||
|
| **Testing & CI** | `go test` is fast; Testcontainers via **testcontainers-go** can spin up DB, Redis, Kafka. | CI pipeline runs unit, integration, and contract tests on each PR. |
|
||||||
|
| **Semantic Versioning & Compatibility** | Go modules already enforce version constraints. | Core declares **minimal required versions** in `go.mod` and uses `replace` for local dev. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2️⃣ CORE KERNEL (What every Go‑platform must ship)
|
||||||
|
|
||||||
|
| Module | Public Interfaces (exported from `pkg/`) | Recommended Packages | Brief Implementation Sketch |
|
||||||
|
|--------|-------------------------------------------|----------------------|------------------------------|
|
||||||
|
| **Config** | `type ConfigProvider interface { Get(key string) any; Unmarshal(v any) error }` | `github.com/spf13/viper` | Load defaults (`config/default.yaml`), then env overrides, then optional secret‑store. |
|
||||||
|
| **Logger** | `type Logger interface { Debug(msg string, fields ...Field); Info(...); Error(...); With(fields ...Field) Logger }` | `go.uber.org/zap` (or `zerolog`) | Global logger is created in `cmd/main.go`; exported via `pkg/logger`. |
|
||||||
|
| **DI / Service Registry** | `type Container interface { Provide(constructor any) error; Invoke(fn any) error }` | `go.uber.org/dig` (or `fx` for lifecycle) | Core creates a `dig.New()` container, registers core services, then calls `container.Invoke(app.Start)`. |
|
||||||
|
| **Health & Metrics** | `type HealthChecker interface { Check(ctx context.Context) error }` | `github.com/prometheus/client_golang/prometheus`, `github.com/heptiolabs/healthcheck` | Expose `/healthz`, `/ready`, `/metrics`. |
|
||||||
|
| **Error Bus** | `type ErrorPublisher interface { Publish(err error) }` | Simple channel‐based implementation + optional Sentry (`github.com/getsentry/sentry-go`) | Core registers a singleton `ErrorBus`. |
|
||||||
|
| **Auth (JWT + OIDC)** | `type Authenticator interface { GenerateToken(userID string, roles []string) (string, error); VerifyToken(token string) (*TokenClaims, error) }` | `github.com/golang-jwt/jwt/v5`, `github.com/coreos/go-oidc` | Token claims embed `sub`, `roles`, `tenant_id`. Middleware adds `User` to `context.Context`. |
|
||||||
|
| **Authorization (RBAC/ABAC)** | `type Authorizer interface { Authorize(ctx context.Context, perm Permission) error }` | Custom DSL, `github.com/casbin/casbin/v2` (optional) | Permission format: `"module.resource.action"`; core ships a simple in‑memory resolver and a `casbin` adapter. |
|
||||||
|
| **Audit** | `type Auditor interface { Record(ctx context.Context, act AuditAction) error }` | Write to append‑only table (Postgres) or Elastic via `olivere/elastic` | Audits include `actorID`, `action`, `targetID`, `metadata`. |
|
||||||
|
| **Event Bus** | `type EventBus interface { Publish(ctx context.Context, ev Event) error; Subscribe(topic string, handler EventHandler) }` | `github.com/segmentio/kafka-go` (for production) + in‑process fallback | Core ships an **in‑process bus** used by tests and a **Kafka bus** for real deployments. |
|
||||||
|
| **Persistence (Repository)** | `type UserRepo interface { FindByID(id string) (*User, error); Create(u *User) error; … }` | `entgo.io/ent` (code‑gen ORM) **or** `gorm.io/gorm` | Core provides an `EntClient` wrapper that implements all core repos. |
|
||||||
|
| **Scheduler / Background Jobs** | `type Scheduler interface { Cron(spec string, job JobFunc) error; Enqueue(q string, payload any) error }` | `github.com/robfig/cron/v3`, `github.com/hibiken/asynq` (Redis‑backed) | Expose a `JobRegistry` where modules can register periodic jobs. |
|
||||||
|
| **Notification** | `type Notifier interface { Send(ctx context.Context, n Notification) error }` | `github.com/go-mail/mail` (SMTP), `github.com/aws/aws-sdk-go-v2/service/ses`, `github.com/IBM/sarama` (for push) | Core supplies an `EmailNotifier` and a `WebhookNotifier`. |
|
||||||
|
| **Multitenancy (optional)** | `type TenantResolver interface { Resolve(ctx context.Context) (tenantID string, err error) }` | Header/ sub‑domain parser + JWT claim scanner | Tenant ID is stored in request context and automatically added to SQL queries via Ent’s `Client` interceptor. |
|
||||||
|
|
||||||
|
All *public* interfaces live under `pkg/` so that plug‑ins can import them without pulling in implementation details. The concrete implementations stay in `internal/` (or separate go.mod modules) and are **registered with the container** during bootstrap.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3️⃣ MODULE (PLUGIN) FRAMEWORK
|
||||||
|
|
||||||
|
### 3.1 Interface that every module must implement
|
||||||
|
|
||||||
|
```go
|
||||||
|
// pkg/module/module.go
|
||||||
|
package module
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"go.uber.org/fx"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IModule is the contract a feature plug‑in must fulfil.
|
||||||
|
type IModule interface {
|
||||||
|
// Name returns a unique, human‑readable identifier.
|
||||||
|
Name() string
|
||||||
|
// Init registers the module's services, routes, jobs, and permissions.
|
||||||
|
// The fx.Options returned are merged into the app's lifecycle.
|
||||||
|
Init() fx.Option
|
||||||
|
// Migrations returns a slice of Ent migration functions (or raw SQL) that
|
||||||
|
// the core will run when the platform starts.
|
||||||
|
Migrations() []func(*ent.Client) error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 Registration Mechanics
|
||||||
|
|
||||||
|
Two ways to get a module into the platform:
|
||||||
|
|
||||||
|
| Approach | When to use | Pros | Cons |
|
||||||
|
|----------|-------------|------|------|
|
||||||
|
| **Static registration** – each module imports `core` and calls `module.Register(MyBlogModule{})` in its own `init()` | Development, CI (no `.so` needed) | Simpler, works on Windows; compile‑time type safety | Requires recompiling the binary for new modules |
|
||||||
|
| **Runtime `plugin` loading** – compile each module as a `go build -buildmode=plugin -o blog.so ./modules/blog` | Production SaaS where clients drop new modules, or separate micro‑service extraction | Hot‑swap without rebuild | Only works on Linux/macOS; plugins must be compiled with same Go version & same `go.mod` replace graph; debugging harder |
|
||||||
|
|
||||||
|
**Static registration example**
|
||||||
|
|
||||||
|
```go
|
||||||
|
// internal/registry/registry.go
|
||||||
|
package registry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"github.com/yourorg/platform/pkg/module"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
mu sync.Mutex
|
||||||
|
modules = make(map[string]module.IModule)
|
||||||
|
)
|
||||||
|
|
||||||
|
func Register(m module.IModule) {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
if _, ok := modules[m.Name()]; ok {
|
||||||
|
panic("module already registered: " + m.Name())
|
||||||
|
}
|
||||||
|
modules[m.Name()] = m
|
||||||
|
}
|
||||||
|
|
||||||
|
func All() []module.IModule {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
out := make([]module.IModule, 0, len(modules))
|
||||||
|
for _, m := range modules {
|
||||||
|
out = append(out, m)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Plugin loader skeleton**
|
||||||
|
|
||||||
|
```go
|
||||||
|
// internal/pluginloader/loader.go
|
||||||
|
package pluginloader
|
||||||
|
|
||||||
|
import (
|
||||||
|
"plugin"
|
||||||
|
"github.com/yourorg/platform/pkg/module"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Load(path string) (module.IModule, error) {
|
||||||
|
p, err := plugin.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sym, err := p.Lookup("Module")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mod, ok := sym.(module.IModule)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("invalid module type")
|
||||||
|
}
|
||||||
|
return mod, nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Tip:** Ship a tiny CLI (`platformctl modules list`) that scans `./plugins/*.so`, loads each via `Load`, and prints `Name()`. This is a great sanity check for ops.
|
||||||
|
|
||||||
|
### 3.3 Permissions DSL (compile‑time safety)
|
||||||
|
|
||||||
|
```go
|
||||||
|
// pkg/perm/perm.go
|
||||||
|
package perm
|
||||||
|
|
||||||
|
type Permission string
|
||||||
|
|
||||||
|
func (p Permission) String() string { return string(p) }
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Core permissions
|
||||||
|
SystemHealthCheck Permission = "system.health.check"
|
||||||
|
|
||||||
|
// Blog module – generated by a small go:generate script
|
||||||
|
BlogPostCreate Permission = "blog.post.create"
|
||||||
|
BlogPostRead Permission = "blog.post.read"
|
||||||
|
BlogPostUpdate Permission = "blog.post.update"
|
||||||
|
BlogPostDelete Permission = "blog.post.delete"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
A **code‑gen** tool (`go generate ./...`) can scan each module’s `module.yaml` for declared actions and emit a single `perm.go` file, guaranteeing no duplicate strings.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4️⃣ SAMPLE FEATURE MODULE – **Blog**
|
||||||
|
|
||||||
|
```
|
||||||
|
modules/
|
||||||
|
└─ blog/
|
||||||
|
├─ go.mod # (module github.com/yourorg/blog)
|
||||||
|
├─ module.yaml
|
||||||
|
├─ internal/
|
||||||
|
│ ├─ api/
|
||||||
|
│ │ └─ handler.go
|
||||||
|
│ ├─ domain/
|
||||||
|
│ │ ├─ post.go
|
||||||
|
│ │ └─ post_repo.go
|
||||||
|
│ └─ service/
|
||||||
|
│ └─ post_service.go
|
||||||
|
└─ pkg/
|
||||||
|
└─ module.go
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.1 `module.yaml`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: blog
|
||||||
|
version: 0.1.0
|
||||||
|
dependencies:
|
||||||
|
- core >= 1.3.0
|
||||||
|
permissions:
|
||||||
|
- blog.post.create
|
||||||
|
- blog.post.read
|
||||||
|
- blog.post.update
|
||||||
|
- blog.post.delete
|
||||||
|
routes:
|
||||||
|
- method: POST
|
||||||
|
path: /api/v1/blog/posts
|
||||||
|
permission: blog.post.create
|
||||||
|
- method: GET
|
||||||
|
path: /api/v1/blog/posts/:id
|
||||||
|
permission: blog.post.read
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 Go implementation
|
||||||
|
|
||||||
|
```go
|
||||||
|
// pkg/module.go
|
||||||
|
package blog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/yourorg/platform/pkg/module"
|
||||||
|
"go.uber.org/fx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BlogModule struct{}
|
||||||
|
|
||||||
|
func (b BlogModule) Name() string { return "blog" }
|
||||||
|
|
||||||
|
func (b BlogModule) Init() fx.Option {
|
||||||
|
return fx.Options(
|
||||||
|
// Register repository implementation
|
||||||
|
fx.Provide(NewPostRepo),
|
||||||
|
|
||||||
|
// Register service layer
|
||||||
|
fx.Provide(NewPostService),
|
||||||
|
|
||||||
|
// Register HTTP handlers (using Gin)
|
||||||
|
fx.Invoke(RegisterHandlers),
|
||||||
|
|
||||||
|
// Register permissions (optional – just for documentation)
|
||||||
|
fx.Invoke(RegisterPermissions),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BlogModule) Migrations() []func(*ent.Client) error {
|
||||||
|
// Ent migration generated in internal/ent/migrate
|
||||||
|
return []func(*ent.Client) error{
|
||||||
|
func(c *ent.Client) error { return c.Schema.Create(context.Background()) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export a variable for the plugin loader
|
||||||
|
var Module BlogModule
|
||||||
|
```
|
||||||
|
|
||||||
|
**Handler registration (Gin example)**
|
||||||
|
|
||||||
|
```go
|
||||||
|
// internal/api/handler.go
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/yourorg/blog/internal/service"
|
||||||
|
"github.com/yourorg/platform/pkg/perm"
|
||||||
|
"github.com/yourorg/platform/pkg/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterHandlers(r *gin.Engine, svc *service.PostService, authz auth.Authorizer) {
|
||||||
|
grp := r.Group("/api/v1/blog")
|
||||||
|
grp.Use(auth.AuthMiddleware()) // verifies JWT, injects user in context
|
||||||
|
|
||||||
|
// POST /posts
|
||||||
|
grp.POST("/posts", func(c *gin.Context) {
|
||||||
|
if err := authz.Authorize(c.Request.Context(), perm.BlogPostCreate); err != nil {
|
||||||
|
c.JSON(403, gin.H{"error": "forbidden"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// decode request, call svc.Create, return 201…
|
||||||
|
})
|
||||||
|
// GET /posts/:id (similar)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Repository using Ent**
|
||||||
|
|
||||||
|
```go
|
||||||
|
// internal/domain/post_repo.go
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/yourorg/platform/internal/ent"
|
||||||
|
"github.com/yourorg/platform/internal/ent/post"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PostRepo struct{ client *ent.Client }
|
||||||
|
|
||||||
|
func NewPostRepo(client *ent.Client) *PostRepo { return &PostRepo{client} }
|
||||||
|
|
||||||
|
func (r *PostRepo) Create(ctx context.Context, p *Post) (*Post, error) {
|
||||||
|
entPost, err := r.client.Post.
|
||||||
|
Create().
|
||||||
|
SetTitle(p.Title).
|
||||||
|
SetContent(p.Content).
|
||||||
|
SetAuthorID(p.AuthorID).
|
||||||
|
Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return fromEnt(entPost), nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Result:** Adding a new feature is just a matter of creating a new folder under `modules/`, implementing `module.IModule`, registering routes, permissions and migrations. The core automatically wires everything together.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5️⃣ INFRASTRUCTURE ADAPTERS (swap‑able, per‑environment)
|
||||||
|
|
||||||
|
| Concern | Implementation (Go) | Where it lives |
|
||||||
|
|---------|---------------------|----------------|
|
||||||
|
| **Database** | `entgo.io/ent` (code‑gen) | `internal/infra/ent/` |
|
||||||
|
| **Cache** | `github.com/go-redis/redis/v9` | `internal/infra/cache/` |
|
||||||
|
| **Message Queue** | `github.com/segmentio/kafka-go` (Kafka) **or** `github.com/hibiken/asynq` (Redis) | `internal/infra/bus/` |
|
||||||
|
| **Blob Storage** | `github.com/aws/aws-sdk-go-v2/service/s3` (or GCS) | `internal/infra/blob/` |
|
||||||
|
| **Email** | `github.com/go-mail/mail` (SMTP) | `internal/infra/email/` |
|
||||||
|
| **SMS / Push** | Twilio SDK, Firebase Cloud Messaging | `internal/infra/notify/` |
|
||||||
|
| **Secret Store** | AWS Secrets Manager (`aws-sdk-go-v2`) or HashiCorp Vault (`github.com/hashicorp/vault/api`) | `internal/infra/secret/` |
|
||||||
|
|
||||||
|
All adapters expose an **interface** in `pkg/infra/…` and are registered in the DI container as **singletons**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6️⃣ OBSERVABILITY STACK
|
||||||
|
|
||||||
|
| Layer | Library | What it does |
|
||||||
|
|-------|---------|--------------|
|
||||||
|
| **Tracing** | `go.opentelemetry.io/otel`, `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` | Auto‑instrument HTTP, DB (Ent plugin), Kafka, Redis |
|
||||||
|
| **Metrics** | `github.com/prometheus/client_golang/prometheus` | Counter/Histogram per request, DB latency, job execution |
|
||||||
|
| **Logging** | `go.uber.org/zap` (structured JSON) | Global logger, request‑scoped fields (`request_id`, `user_id`, `tenant_id`) |
|
||||||
|
| **Error Reporting** | `github.com/getsentry/sentry-go` (optional) | Capture panics & errors, link to trace ID |
|
||||||
|
| **Dashboard** | Grafana + Prometheus + Loki (logs) | Provide ready‑made dashboards in `ops/` folder |
|
||||||
|
|
||||||
|
**Instrumentation example (HTTP)**
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
r := gin.New()
|
||||||
|
// Wrap the entire router with OTEL middleware
|
||||||
|
wrapped := otelhttp.NewHandler(r, "http-server")
|
||||||
|
http.ListenAndServe(":8080", wrapped)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Metrics middleware**
|
||||||
|
|
||||||
|
```go
|
||||||
|
func PromMetrics() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
start := time.Now()
|
||||||
|
c.Next()
|
||||||
|
duration := time.Since(start).Seconds()
|
||||||
|
method := c.Request.Method
|
||||||
|
path := c.FullPath()
|
||||||
|
status := fmt.Sprintf("%d", c.Writer.Status())
|
||||||
|
requestDuration.WithLabelValues(method, path, status).Observe(duration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7️⃣ CONFIGURATION & ENVIRONMENT
|
||||||
|
|
||||||
|
```
|
||||||
|
config/
|
||||||
|
├─ default.yaml # baseline values
|
||||||
|
├─ development.yaml
|
||||||
|
├─ production.yaml
|
||||||
|
└─ secrets/ # git‑ignored, loaded via secret manager
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bootstrap**
|
||||||
|
|
||||||
|
```go
|
||||||
|
func LoadConfig() (*Config, error) {
|
||||||
|
v := viper.New()
|
||||||
|
v.SetConfigName("default")
|
||||||
|
v.AddConfigPath("./config")
|
||||||
|
if err := v.ReadInConfig(); err != nil { return nil, err }
|
||||||
|
|
||||||
|
env := v.GetString("environment") // dev / prod / test
|
||||||
|
v.SetConfigName(env)
|
||||||
|
v.MergeInConfig() // overrides defaults
|
||||||
|
|
||||||
|
v.AutomaticEnv() // env vars win
|
||||||
|
// optional: secret manager overlay
|
||||||
|
return &Config{v}, nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
All services receive a `*Config` via DI.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8️⃣ CI / CD PIPELINE (GitHub Actions)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO111MODULE: on
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.22'
|
||||||
|
- name: Cache Go modules
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cache/go-build
|
||||||
|
~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
- name: Install Tools
|
||||||
|
run: |
|
||||||
|
go install github.com/vektra/mockery/v2@latest
|
||||||
|
go install github.com/golang/mock/mockgen@latest
|
||||||
|
- name: Lint
|
||||||
|
run: |
|
||||||
|
go install golang.org/x/lint/golint@latest
|
||||||
|
golint ./...
|
||||||
|
- name: Unit Tests
|
||||||
|
run: |
|
||||||
|
go test ./... -cover -race -short
|
||||||
|
- name: Integration Tests (Docker Compose)
|
||||||
|
run: |
|
||||||
|
docker compose -f ./docker-compose.test.yml up -d
|
||||||
|
go test ./... -tags=integration -count=1
|
||||||
|
docker compose -f ./docker-compose.test.yml down
|
||||||
|
- name: Build Binaries
|
||||||
|
run: |
|
||||||
|
go build -ldflags="-X main.version=${{ github.sha }}" -o bin/platform ./cmd/platform
|
||||||
|
- name: Publish Docker Image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
tags: ghcr.io/yourorg/platform:${{ github.sha }}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key points**
|
||||||
|
|
||||||
|
* `go test ./... -tags=integration` runs tests that spin up Postgres, Redis, Kafka via **Testcontainers** (`github.com/testcontainers/testcontainers-go`).
|
||||||
|
* Linting via `golint` or `staticcheck`.
|
||||||
|
* Docker image built from the compiled binary (multi‑stage: `golang:1.22-alpine` → `scratch` or `distroless`).
|
||||||
|
* Semantic‑release can be added on top (`semantic-release` action) to tag releases automatically.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9️⃣ TESTING STRATEGY
|
||||||
|
|
||||||
|
| Test type | Tools | Typical coverage |
|
||||||
|
|-----------|-------|------------------|
|
||||||
|
| **Unit** | `testing`, `github.com/stretchr/testify`, `github.com/golang/mock` | Individual services, repositories (use in‑memory DB or mocks). |
|
||||||
|
| **Integration** | `testcontainers-go` for Postgres, Redis, Kafka; real Ent client | End‑to‑end request → DB → event bus flow. |
|
||||||
|
| **Contract** | `pact-go` or **OpenAPI** validator middleware (`github.com/getkin/kin-openapi`) | Guarantees that modules do not break the published API. |
|
||||||
|
| **Load / Stress** | `k6` or `vegeta` scripts in `perf/` | Verify that auth middleware adds < 2 ms latency per request. |
|
||||||
|
| **Security** | `gosec`, `zap` for secret detection, OWASP ZAP for API scan | Detect hard‑coded secrets, SQL injection risk. |
|
||||||
|
|
||||||
|
**Example integration test skeleton**
|
||||||
|
|
||||||
|
```go
|
||||||
|
func TestCreatePost_Integration(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
// Spin up a PostgreSQL container
|
||||||
|
pg, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||||
|
ContainerRequest: testcontainers.ContainerRequest{
|
||||||
|
Image: "postgres:15-alpine",
|
||||||
|
Env: map[string]string{"POSTGRES_PASSWORD": "secret", "POSTGRES_DB": "test"},
|
||||||
|
ExposedPorts: []string{"5432/tcp"},
|
||||||
|
WaitingFor: wait.ForListeningPort("5432/tcp"),
|
||||||
|
},
|
||||||
|
Started: true,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer pg.Terminate(ctx)
|
||||||
|
|
||||||
|
// Build DSN from container host/port
|
||||||
|
host, _ := pg.Endpoint(ctx)
|
||||||
|
dsn := fmt.Sprintf("postgres://postgres:secret@%s/test?sslmode=disable", host)
|
||||||
|
|
||||||
|
// Initialize Ent client against that DSN
|
||||||
|
client, err := ent.Open("postgres", dsn)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer client.Close()
|
||||||
|
// Run schema migration
|
||||||
|
err = client.Schema.Create(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Build the whole app using fx, injecting the test client
|
||||||
|
app := fx.New(
|
||||||
|
core.ProvideAll(),
|
||||||
|
fx.Provide(func() *ent.Client { return client }),
|
||||||
|
blog.Module.Init(),
|
||||||
|
// ...
|
||||||
|
)
|
||||||
|
// Start the app, issue a HTTP POST request through httptest.Server,
|
||||||
|
// assert 201 and DB row existence.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10️⃣ COMMON PITFALLS & SOLUTIONS (Go‑centric)
|
||||||
|
|
||||||
|
| Pitfall | Symptom | Remedy |
|
||||||
|
|---------|----------|--------|
|
||||||
|
| **Circular imports** (core ↔ module) | `import cycle not allowed` build error | Keep **interfaces only** in `pkg/`. Core implements, modules depend on the interface only. |
|
||||||
|
| **Too‑big binary** (all modules compiled in) | Long build times, memory pressure on CI | Use **Go plugins** for truly optional modules; keep core binary minimal. |
|
||||||
|
| **Version mismatch with plugins** | Panic: `plugin was built with a different version of package X` | Enforce a **single `replace` directive** for core in each module’s `go.mod` (e.g., `replace github.com/yourorg/platform => ../../platform`). |
|
||||||
|
| **Context leakage** (request data not passed) | Logs missing `user_id`, permission checks use zero‑value user | Always store user/tenant info in `context.Context` via middleware; provide helper `auth.FromContext(ctx)`. |
|
||||||
|
| **Ent migrations out‑of‑sync** | Startup fails with “column does not exist” | Run `go generate ./...` (ent codegen) and `ent/migrate` automatically at boot **after all module migrations are collected**. |
|
||||||
|
| **Hard‑coded permission strings** | Typos go unnoticed → 403 bugs | Use the **generated `perm` package** (see §4.1) and reference constants everywhere. |
|
||||||
|
| **Blocking I/O in request path** | 500 ms latency spikes | Off‑load long‑running work to **asynq jobs** or **Kafka consumers**; keep request handlers thin. |
|
||||||
|
| **Over‑exposed HTTP handlers** | Missing auth middleware → open endpoint | Wrap the router with a **global security middleware** that checks a whitelist and enforces `Authorizer` for everything else. |
|
||||||
|
| **Memory leaks with goroutine workers** | Leak after many module reloads | Use **fx.Lifecycle** to start/stop background workers; always cancel contexts on `Stop`. |
|
||||||
|
| **Testing with real DB slows CI** | Pipeline > 10 min | Use **testcontainers** in parallel jobs, cache Docker images, or use in‑memory SQLite for unit tests and only run DB‑heavy tests in a dedicated job. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11️⃣ QUICK‑START STEPS (What to code first)
|
||||||
|
|
||||||
|
1. **Bootstrap repo**
|
||||||
|
```bash
|
||||||
|
mkdir platform && cd platform
|
||||||
|
go mod init github.com/yourorg/platform
|
||||||
|
mkdir cmd internal pkg config modules
|
||||||
|
touch cmd/main.go
|
||||||
|
```
|
||||||
|
2. **Create core container** (`internal/di/container.go`) using `dig`. Register Config, Logger, DB, EventBus, Authenticator, Authorizer.
|
||||||
|
3. **Add Auth middleware** (`pkg/auth/middleware.go`) that extracts JWT, validates claims, injects `User` into context.
|
||||||
|
4. **Implement Permission DSL** (`pkg/perm/perm.go`) and a **simple in‑memory resolver** (`pkg/perm/resolver.go`).
|
||||||
|
5. **Write `module` interface** (`pkg/module/module.go`) and a **static registry** (`internal/registry/registry.go`).
|
||||||
|
6. **Add first plug‑in** – copy the **Blog** module skeleton from §4.
|
||||||
|
`cd modules/blog && go mod init github.com/yourorg/blog && go run ../..` (build & test).
|
||||||
|
7. **Wire everything in `cmd/main.go`** using `fx.New(...)`:
|
||||||
|
```go
|
||||||
|
app := fx.New(
|
||||||
|
core.Module, // registers core services
|
||||||
|
fx.Invoke(registry.RegisterAllModules), // loads static modules
|
||||||
|
fx.Invoke(func(lc fx.Lifecycle, r *gin.Engine) {
|
||||||
|
lc.Append(fx.Hook{
|
||||||
|
OnStart: func(context.Context) error {
|
||||||
|
go r.Run(":8080")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
OnStop: func(ctx context.Context) error { return nil },
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
app.Run()
|
||||||
|
```
|
||||||
|
8. **Run integration test** (`go test ./... -tags=integration`) to sanity‑check DB + routes.
|
||||||
|
9. **Add CI workflow** (copy the `.github/workflows/ci.yml` from §8) and push.
|
||||||
|
10. **Publish first Docker image** (`docker build -t ghcr.io/yourorg/platform:dev .`).
|
||||||
|
|
||||||
|
After step 10 you have a **complete, production‑grade scaffolding** that:
|
||||||
|
|
||||||
|
* authenticates users via JWT (with optional OIDC),
|
||||||
|
* authorizes actions through a compile‑time‑checked permission DSL,
|
||||||
|
* logs/metrics/traces out of the box,
|
||||||
|
* lets any team drop a new `*.so` or static module under `modules/` to add resources,
|
||||||
|
* ships with a working CI pipeline and a ready‑to‑run Docker image.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12️⃣ REFERENCE IMPLEMENTATION (public)
|
||||||
|
|
||||||
|
If you prefer to start from a **real open‑source baseline**, check out the following community projects that already adopt most of the ideas above:
|
||||||
|
|
||||||
|
| Repo | Highlights |
|
||||||
|
|------|------------|
|
||||||
|
| `github.com/go‑microservices/clean‑arch` | Clean‑architecture skeleton, fx DI, Ent ORM, JWT auth |
|
||||||
|
| `github.com/ory/hydra` | Full OIDC provider (good for auth reference) |
|
||||||
|
| `github.com/segmentio/kafka-go` examples | Event‑bus integration |
|
||||||
|
| `github.com/ThreeDotsLabs/watermill` | Pub/sub abstraction usable as bus wrapper |
|
||||||
|
| `github.com/hibiken/asynq` | Background job framework (Redis based) |
|
||||||
|
|
||||||
|
Fork one, strip the business logic, and rename the packages to match *your* `github.com/yourorg/platform` namespace.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13️⃣ FINAL CHECKLIST (before you ship)
|
||||||
|
|
||||||
|
- [ ] Core modules compiled & registered in `internal/di`.
|
||||||
|
- [ ] `module.IModule` interface and static registry in place.
|
||||||
|
- [ ] JWT auth + middleware + `User` context helper.
|
||||||
|
- [ ] Permission constants generated & compiled in `pkg/perm`.
|
||||||
|
- [ ] Ent schema + migration runner that aggregates all module migrations.
|
||||||
|
- [ ] OpenTelemetry tracer/provider wired at process start.
|
||||||
|
- [ ] Prometheus metrics endpoint (`/metrics`).
|
||||||
|
- [ ] Health endpoints (`/healthz`, `/ready`).
|
||||||
|
- [ ] Dockerfile (multi‑stage) and `docker-compose.yml` for dev.
|
||||||
|
- [ ] GitHub Actions pipeline (CI) passes all tests.
|
||||||
|
- [ ] Sample plug‑in (Blog) builds, loads, registers routes, and passes integration test.
|
||||||
|
- [ ] Documentation: `README.md`, `docs/architecture.md`, `docs/extension-points.md`.
|
||||||
|
|
||||||
|
> **Congratulations!** You now have a **robust, extensible Go platform boilerplate** that can be the foundation for any SaaS, internal toolset, or micro‑service ecosystem you wish to build. Happy coding! 🚀
|
||||||
319
requirements.md
Normal file
319
requirements.md
Normal file
@@ -0,0 +1,319 @@
|
|||||||
|
# Requirements
|
||||||
|
|
||||||
|
## 1️⃣ HIGH‑LEVEL ARCHITECTURAL PRINCIPLES
|
||||||
|
|
||||||
|
| Principle | Why it matters for a modular platform | How to enforce it |
|
||||||
|
|-----------|----------------------------------------|-------------------|
|
||||||
|
| **Separation of Concerns (SoC)** | Keeps core services (auth, audit, config) independent from business modules. | Use **layered** or **hexagonal/clean‑architecture** boundaries. |
|
||||||
|
| **Domain‑Driven Design (DDD) Bounded Contexts** | Allows each module to own its own model & rules while sharing a common identity kernel. | Define a **Core Context** (Identity, Security, Infrastructure) and **Feature Contexts** (Billing, CMS, Chat, …). |
|
||||||
|
| **Modular Monolith → Micro‑service‑ready** | Start simple (single process) but keep each module in its own package so you can later split to services if needed. | Package each module as an **independent library** with its own **DI container‑module** and **routing**. |
|
||||||
|
| **Plug‑in / Extension‑point model** | Enables customers or internal teams to drop new features without touching core code. | Export **well‑defined interfaces** (e.g., `IUserProvider`, `IPermissionResolver`, `IModuleInitializer`). |
|
||||||
|
| **API‑First** | Guarantees that any UI (web, mobile, CLI) can be built on top of the same contract. | Publish **OpenAPI/GraphQL schema** as part of the build artefact. |
|
||||||
|
| **Security‑by‑Design** | The platform will hold user credentials, roles and possibly PII. | Centralize **authentication**, **authorization**, **audit**, **rate‑limiting**, **CORS**, **CSP**, **secure defaults**. |
|
||||||
|
| **Observability** | You need to know when a plug‑in crashes or misbehaves. | Provide **structured logging**, **metrics**, **tracing**, **health‑checks**, **central error bus**. |
|
||||||
|
| **CI/CD‑Ready Boilerplate** | Keeps the framework maintainable and encourages best‑practice adoption. | Include **GitHub Actions / GitLab CI** pipelines that run lint, unit, integration, contract tests, and a publish step. |
|
||||||
|
| **Configuration‑as‑Code** | Each module may need its own settings but you want a single source of truth. | Use a **hierarchical config system** (environment > file > secret store). |
|
||||||
|
| **Multitenancy (optional)** | If you plan SaaS, the core must be ready to isolate data per tenant. | Provide **tenant‑aware repository abstractions** and **tenant‑scoped middlewares**. |
|
||||||
|
| **Versioning & Compatibility** | Modules evolve; the core should never break existing plug‑ins. | Adopt **semantic versioning** + **backwards‑compatibility shim layer** (e.g., deprecation warnings). |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2️⃣ LAYERED / HEXAGONAL BLUEPRINT
|
||||||
|
|
||||||
|
```
|
||||||
|
+---------------------------------------------------+
|
||||||
|
| Presentation |
|
||||||
|
| (REST/GraphQL/ gRPC Controllers, UI SDKs, CLI) |
|
||||||
|
+-------------------+-------------------------------+
|
||||||
|
| Application Services (Use‑cases) |
|
||||||
|
| - orchestrate core & feature modules |
|
||||||
|
| - enforce policies (RBAC, rate‑limit) |
|
||||||
|
+-------------------+-------------------------------+
|
||||||
|
| Domain (Business Logic) |
|
||||||
|
| - Core Entities (User, Role, Permission) |
|
||||||
|
| - Domain Services (PasswordPolicy, TokenMgr) |
|
||||||
|
+-------------------+-------------------------------+
|
||||||
|
| Infrastructure / Adapters |
|
||||||
|
| - Persistence (ORM/NoSQL Repositories) |
|
||||||
|
| - External services (Email, SMS, OIDC) |
|
||||||
|
| - Event bus (Kafka/Rabbit, In‑process) |
|
||||||
|
| - File storage, Cache, Search |
|
||||||
|
+---------------------------------------------------+
|
||||||
|
| Platform Core (Kernel) |
|
||||||
|
| - DI container, Module loader, Config manager |
|
||||||
|
| - Cross‑cutting concerns (Logging, Metrics) |
|
||||||
|
| - Security subsystem (AuthN/AuthZ, Token Issuer)|
|
||||||
|
+---------------------------------------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
*All layers talk to each other **through interfaces** defined in the Core kernel. Feature modules implement those interfaces and register themselves at startup.*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3️⃣ REQUIRED BASE MODULES (THE “CORE KERNEL”)
|
||||||
|
|
||||||
|
| Module | Core responsibilities | Public API / Extension points |
|
||||||
|
|--------|-----------------------|--------------------------------|
|
||||||
|
| **Identity‑Management** | - User CRUD (local + federation) <br>- Password hashing, reset flow <br>- Email/Phone verification | `IUserRepository`, `IUserService`, `IExternalIdpProvider` |
|
||||||
|
| **Roles & Permissions** | - Role hierarchy (role → permission set) <br>- Permission definitions (string, enum, policy) <br>- Dynamic permission evaluation (ABAC) | `IPermissionResolver`, `IRoleService` |
|
||||||
|
| **Authentication** | - JWT / OAuth2 Access & Refresh tokens <br>- OpenID Connect Provider (optional) <br>- Session Management (stateless + optional stateful) | `IAuthService`, `ITokenProvider` |
|
||||||
|
| **Authorization Middleware** | - Enforce RBAC/ABAC on each request <br>- Policy DSL (e.g., `hasPermission('project.read') && resource.ownerId == user.id`) | `IAuthorizationHandler` |
|
||||||
|
| **Audit & Activity Log** | - Immutable log of security‑relevant actions <br>- Correlation IDs, actor, target, timestamp | `IAuditSink`, `IAuditService` |
|
||||||
|
| **Configuration** | - Hierarchical sources (env, files, secret manager) <br>- Validation schema (JSON‑Schema / Yup / JSR‑380) | `IConfigProvider` |
|
||||||
|
| **Health & Metrics** | - `/healthz`, `/ready`, `/metrics` endpoints <br>- Export to Prometheus, Grafana, CloudWatch | `IHealthCheck`, `IMetricsRegistry` |
|
||||||
|
| **Error Handling** | - Centralized error objects, stack trace masking <br>- Automatic mapping to HTTP status <br>- Exception‑to‑event publishing | `IErrorMapper`, `IErrorBus` |
|
||||||
|
| **Logging** | - Structured JSON logs (level, requestId, userId) <br>- pluggable sinks (stdout, file, ELK, Cloud Logging) | `ILoggerFactory` |
|
||||||
|
| **Notification** | - Email, SMS, Push (FCM/APNs), Webhooks <br>- Queue‑backed delivery, retries | `INotificationService` |
|
||||||
|
| **File / Blob Storage** | - Abstracted bucket API (upload, version, signed URLs) | `IBlobStore` |
|
||||||
|
| **Scheduler / Background Jobs** | - Cron‑like tasks, queue workers, retry/back‑off policies | `IJobScheduler`, `IJobProcessor` |
|
||||||
|
| **Internationalization (i18n)** | - Message catalog, locale negotiation, runtime translation | `I18nService` |
|
||||||
|
| **API Gateway (optional)** | - Rate‑limit, request/response transformation, API‑key handling, request routing to modules | `IGatewayPlugin` |
|
||||||
|
| **Multitenancy (optional)** | - Tenant identification (sub‑domain, header, JWT claim) <br>- Tenant‑scoped data isolation primitives | `ITenantResolver`, `ITenantContext` |
|
||||||
|
|
||||||
|
> **Tip:** Pack each module as a **separate NPM/ Maven / NuGet / Go module** with its own `package.json` / `pom.xml` etc. The platform’s **bootstrapper** loads every module that implements `IModuleInitializer` (or similar) and calls `ConfigureServices` / `RegisterRoutes`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4️⃣ EXTENSION‑POINT DESIGN (HOW PLUG‑INS HOOK IN)
|
||||||
|
|
||||||
|
1. **Module Manifest** – a tiny JSON/YAML file (`module.yaml`) that declares:
|
||||||
|
- Module name, version, dependencies (core ≥ 1.2.0, other modules)
|
||||||
|
- Public routes (e.g., `/api/v1/blog/**`)
|
||||||
|
- Required permissions (auto‑generated from source annotations)
|
||||||
|
- UI assets (static folder, React component entry point)
|
||||||
|
|
||||||
|
2. **Bootstrap Interface**
|
||||||
|
```ts
|
||||||
|
export interface IModuleInitializer {
|
||||||
|
/**
|
||||||
|
* Called during platform start‑up.
|
||||||
|
* Register services, routes, policies, background jobs.
|
||||||
|
*/
|
||||||
|
init(app: IApplicationBuilder, container: IServiceContainer): Promise<void>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Dependency Injection (DI) Conventions**
|
||||||
|
- Core registers **contracts** (`IUserRepository`, `IPermissionResolver`) as **singletons**.
|
||||||
|
- Modules register **implementations** with a **named scope** (e.g., `UserRepository:Local`).
|
||||||
|
- Override is possible via **module ordering** or explicit `container.override(...)`.
|
||||||
|
|
||||||
|
4. **Policy/Permission Extension**
|
||||||
|
```ts
|
||||||
|
// core lib
|
||||||
|
export type Permission = `${string}.${string}`; // e.g., "blog.post.create"
|
||||||
|
|
||||||
|
// module
|
||||||
|
export const BLOG_PERMS = {
|
||||||
|
POST_CREATE: 'blog.post.create',
|
||||||
|
POST_READ: 'blog.post.read',
|
||||||
|
POST_UPDATE: 'blog.post.update',
|
||||||
|
POST_DELETE: 'blog.post.delete',
|
||||||
|
} as const;
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Event Bus & Hooks**
|
||||||
|
- Central **topic**: `platform.*` (user.created, role.assigned, tenant.created)
|
||||||
|
- Modules can **publish** and **subscribe** via `IEventBus`.
|
||||||
|
- Provide **synchronous guard hooks** (`beforeUserCreate`, `afterRoleDelete`) for validation & side‑effects.
|
||||||
|
|
||||||
|
6. **UI Plug‑in System**
|
||||||
|
- Serve a **manifest** at `/modules` that front‑end bundles read to render navigation.
|
||||||
|
- Encourage **Web Component / Module Federation** pattern for SPA integration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5️⃣ SAMPLE REPOSITORY LAYOUT (language‑agnostic)
|
||||||
|
|
||||||
|
```
|
||||||
|
/platform-root
|
||||||
|
│
|
||||||
|
├─ /core # ---- Kernel / Base modules ----
|
||||||
|
│ ├─ /auth
|
||||||
|
│ │ ├─ src/
|
||||||
|
│ │ └─ package.json
|
||||||
|
│ ├─ /identity
|
||||||
|
│ ├─ /authorization
|
||||||
|
│ ├─ /audit
|
||||||
|
│ ├─ /config
|
||||||
|
│ ├─ /logging
|
||||||
|
│ ├─ /metrics
|
||||||
|
│ └─ index.ts (exports all core APIs)
|
||||||
|
│
|
||||||
|
├─ /modules # ---- Feature plug‑ins ----
|
||||||
|
│ ├─ /blog
|
||||||
|
│ │ ├─ module.yaml # manifest
|
||||||
|
│ │ ├─ src/
|
||||||
|
│ │ │ ├─ BlogController.ts
|
||||||
|
│ │ │ ├─ BlogService.ts
|
||||||
|
│ │ │ └─ BlogModule.ts (implements IModuleInitializer)
|
||||||
|
│ │ └─ package.json
|
||||||
|
│ │
|
||||||
|
│ ├─ /billing
|
||||||
|
│ └─ /chat
|
||||||
|
│
|
||||||
|
├─ /infra # ---- Infrastructure adapters ----
|
||||||
|
│ ├─ /orm (typeorm/hibernate/EFCore etc.)
|
||||||
|
│ ├─ /cache (redis)
|
||||||
|
│ ├─ /queue (rabbit/kafka)
|
||||||
|
│ └─ /storage (s3/azure‑blob)
|
||||||
|
│
|
||||||
|
├─ /gateway (optional API‑gateway layer)
|
||||||
|
│
|
||||||
|
├─ /scripts # build / lint / test helpers
|
||||||
|
│
|
||||||
|
├─ /ci
|
||||||
|
│ └─ github-actions.yml
|
||||||
|
│
|
||||||
|
├─ /docs
|
||||||
|
│ └─ architecture.md
|
||||||
|
│
|
||||||
|
├─ package.json (or pom.xml / go.mod)
|
||||||
|
└─ README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### How it boots
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// platform-root/src/main.ts
|
||||||
|
import { createApp } from '@core/app';
|
||||||
|
import { loadModules } from '@core/module-loader';
|
||||||
|
import { CoreModule } from '@core';
|
||||||
|
|
||||||
|
async function bootstrap() {
|
||||||
|
const app = await createApp();
|
||||||
|
|
||||||
|
// 1️⃣ Load core kernel (DI, config, logger)
|
||||||
|
await app.register(CoreModule);
|
||||||
|
|
||||||
|
// 2️⃣ Dynamically discover all `module.yaml` under /modules
|
||||||
|
const modules = await loadModules(__dirname + '/modules');
|
||||||
|
|
||||||
|
// 3️⃣ Initialise each module (order can be defined in manifest)
|
||||||
|
for (const mod of modules) {
|
||||||
|
await mod.instance.init(app.builder, app.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4️⃣ Start HTTP / gRPC server
|
||||||
|
await app.listen(process.env.PORT || 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
bootstrap().catch(err => {
|
||||||
|
console.error('❌ Platform failed to start', err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6️⃣ KEY DECISIONS YOU MUST TAKE EARLY
|
||||||
|
|
||||||
|
| Decision | Options | Implications |
|
||||||
|
|----------|---------|--------------|
|
||||||
|
| **Language / Runtime** | Node.js (NestJS, Fastify), Java (Spring Boot), .NET (ASP.NET Core), Go (Gin/Fiber), Python (FastAPI) | Affects DI framework, module packaging, community libs for auth/OIDC, testing. |
|
||||||
|
| **Persistence Strategy** | Relational (PostgreSQL, MySQL) + optional NoSQL (Mongo, Dynamo) | Choose an ORM/Repository pattern that can be swapped per module. |
|
||||||
|
| **Auth Protocol** | JWT + Refresh, OAuth2 Authorization Server, OpenID Connect Provider, or integrate with external IdP (Keycloak, Auth0) | Influences token lifetimes, revocation strategy, multi‑tenant support. |
|
||||||
|
| **Event Bus** | In‑process EventEmitter (for monolith) → Kafka/Rabbit for scaling | Must expose both sync and async hooks. |
|
||||||
|
| **Module Packaging** | NPM packages (private registry) / Maven artifacts / Docker images (for micro‑service extraction) | Define a *semantic version* policy (core ≥ 1.0.0 never forces breaking changes on plug‑ins). |
|
||||||
|
| **Multitenancy Model** | Single DB with tenant_id column (shared), Schema‑per‑tenant, or DB‑per‑tenant | Affects repository base class and migrations tooling. |
|
||||||
|
| **Internationalisation** | i18next (frontend) + ICU messages in backend, or .NET Resource files | Choose a format that can be merged from modules at build time. |
|
||||||
|
| **CI/CD** | GitHub Actions + Docker Buildx + semantic‑release | Automate publishing of core + modules to same artifact registry. |
|
||||||
|
| **Testing Strategy** | Unit (Jest, JUnit, xUnit), Integration (Testcontainers), Contract (Pact) | Provide a **core testing harness** that loads a dummy module and asserts the contract of each extension point. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7️⃣ COMMON PITFALLS & HOW TO AVOID THEM
|
||||||
|
|
||||||
|
| Pitfall | Symptoms | Fix / Guardrail |
|
||||||
|
|---------|----------|-----------------|
|
||||||
|
| **Tight coupling of modules to core implementation** | Module imports internal ORM classes, fails on core upgrade. | Expose **only interfaces** (`IUserRepository`) from core and keep the concrete implementation as a private package. |
|
||||||
|
| **Hard‑coded permission strings** | Duplicate names across modules, typos cause silent authorisation bypass. | Provide a **Permission Builder DSL** (`Permission.define('blog.post', ['create', 'read'])`) that generates constants and registers them automatically. |
|
||||||
|
| **Global state in modules** | Tests interfere with each other, memory leaks when hot‑reloading. | Enforce **stateless services**; keep per‑request scoped data (e.g., via DI context). |
|
||||||
|
| **Schema migrations clash** | Two modules try to add the same column or foreign key. | Adopt a **central migration orchestrator** (e.g., Flyway/DBMate) that loads migration scripts from each module in alphabetical order. |
|
||||||
|
| **Authorization checks omitted in new routes** | Security hole for new plug‑in routes. | Provide a **base controller class** that auto‑applies `Authorize` filter, or a compile‑time lint rule that checks every exported route for a permission annotation. |
|
||||||
|
| **Vendor lock‑in to a particular IdP** | Hard to replace Keycloak later. | Keep **IdP adapters** behind a `IIdentityProvider` interface; ship at least two (local DB + OIDC). |
|
||||||
|
| **Unbounded background jobs** | Queue overflow, OOM, duplicate processing. | Use a **job‑scheduler abstraction** that caps concurrency, persists state, and provides `@Retry` decorator. |
|
||||||
|
| **Insufficient observability** | You can’t tell which module caused latency spikes. | Tag every log/metric with `module=<moduleName>` automatically via middleware. |
|
||||||
|
| **Version drift between core and modules** | Module built against core 1.0 fails on core 1.5. | Publish a **core compatibility matrix** and enforce `peerDependencies` in package.json; CI should fail on mismatched ranges. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8️⃣ QUICK START GUIDE (What to Build First)
|
||||||
|
|
||||||
|
1. **Create the Core Kernel**
|
||||||
|
- Set up DI container, config loader, logger, health/metrics endpoint.
|
||||||
|
- Scaffold `IUserRepository`, `IPermissionResolver`, `ITokenProvider`.
|
||||||
|
|
||||||
|
2. **Implement Identity & Auth**
|
||||||
|
- Choose JWT + Refresh + optional OpenID Connect.
|
||||||
|
- Add password hashing (bcrypt/argon2) and email verification flow.
|
||||||
|
|
||||||
|
3. **Add Role/Permission Engine**
|
||||||
|
- Simple RBAC matrix with an extensible `Permission` type.
|
||||||
|
- Provide a UI admin UI (or API only) to manage roles.
|
||||||
|
|
||||||
|
4. **Set Up Event Bus & Audit**
|
||||||
|
- Publish `user.created`, `role.granted` events.
|
||||||
|
- Store audit entries in an append‑only table (or log to Elastic).
|
||||||
|
|
||||||
|
5. **Build the Module Loader**
|
||||||
|
- Scan `modules/*/module.yaml`, load via `require()`/classpath.
|
||||||
|
- Register each `IModuleInitializer`.
|
||||||
|
|
||||||
|
6. **Create a Sample Feature Module** – e.g., **Blog**
|
||||||
|
- Define its own entities (`Post`, `Comment`).
|
||||||
|
- Register routes (`/api/v1/blog/posts`).
|
||||||
|
- Declare required permissions (`blog.post.create`).
|
||||||
|
|
||||||
|
7. **Write Integration Tests**
|
||||||
|
- Spin up an in‑memory DB (SQLite or H2).
|
||||||
|
- Load core + blog module, assert that a user without `blog.post.create` receives 403.
|
||||||
|
|
||||||
|
8. **Add CI Pipeline**
|
||||||
|
- Lint → Unit → Integration (Docker Compose with DB + Redis).
|
||||||
|
- On tag, publish `core` and `blog` packages to your private registry.
|
||||||
|
|
||||||
|
9. **Document Extension Points**
|
||||||
|
- Provide a **Developer Handbook** (README + `docs/extension-points.md`).
|
||||||
|
|
||||||
|
10. **Iterate** – add Notification, Scheduler, Multitenancy, API‑Gateway as needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9️⃣ TOOLS & LIBRARIES (starter suggestions per stack)
|
||||||
|
|
||||||
|
| Stack | Core | Auth | DI / Module | Event Bus | ORM | Validation | Testing |
|
||||||
|
|-------|------|------|-------------|-----------|-----|------------|---------|
|
||||||
|
| **Node (TypeScript)** | NestJS (or Fastify + `awilix`) | `@nestjs/passport`, `passport-jwt`, `openid-client` | NestJS dynamic modules or `@nestjs-modules/mailer` | `@nestjs/event-emitter` or `KafkaJS` | TypeORM / Prisma | `class-validator` + `class-transformer` | Jest + `supertest`, Testcontainers |
|
||||||
|
| **Java** | Spring Boot | Spring Security + `spring-boot-starter-oauth2-resource-server` | Spring Boot `@Configuration` + `ImportBeanDefinitionRegistrar` | Spring Cloud Stream (Kafka) | JPA / Hibernate | Bean Validation (Hibernate Validator) | JUnit5 + Testcontainers |
|
||||||
|
| **.NET 8** | ASP.NET Core | `Microsoft.AspNetCore.Authentication.JwtBearer` | `IHostedService` + `Scrutor` for module discovery | MassTransit (Rabbit/Kafka) | EF Core | FluentValidation | xUnit + DockerTestContainers |
|
||||||
|
| **Go** | Echo / Fiber | `golang.org/x/oauth2` + `github.com/golang-jwt/jwt/v5` | `uber-go/fx` for DI, module registration | `segmentio/kafka-go` | GORM / Ent | `go-playground/validator` | Testify + Dockertest |
|
||||||
|
| **Python** | FastAPI | `fastapi-users` / `Authlib` | `pluggy` (pytest plugins) or custom loader | `aiokafka` | SQLModel / Tortoise ORM | Pydantic | Pytest + pytest‑asyncio, Testcontainers |
|
||||||
|
|
||||||
|
Pick the stack you’re most comfortable with; the concepts stay identical.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎉 TL;DR – What You Must Deliver
|
||||||
|
|
||||||
|
| Layer | Must‑have components | Why |
|
||||||
|
|-------|----------------------|-----|
|
||||||
|
| **Core Kernel** | Config, Logger, DI, Health, Metrics, Error Bus | Foundation for any module. |
|
||||||
|
| **Security** | Auth (JWT/OIDC), Authorization (RBAC + ABAC), Audit | Guarantees secure, traceable access. |
|
||||||
|
| **User & Role Management** | User CRUD, Password reset, Role ↔ Permission matrix | The “identity” piece everyone will reuse. |
|
||||||
|
| **Extension System** | `IModuleInitializer`, `module.yaml`, EventBus, Permission DSL | Enables plug‑ins without touching core. |
|
||||||
|
| **Infrastructure Adapters** | DB repo, Cache, Queue, Blob storage, Email/SMS | Keeps core agnostic to any concrete tech. |
|
||||||
|
| **Observability** | Structured logs, Prometheus metrics, OpenTelemetry traces | You can monitor each module individually. |
|
||||||
|
| **DevOps Boilerplate** | CI pipelines, Dockerfiles, Semantic‑release, Docs | Makes the framework production‑ready out‑of‑the‑box. |
|
||||||
|
| **Sample Feature Module** | (e.g., Blog) to show how to add routes, permissions, DB entities | Provides a reference implementation for future developers. |
|
||||||
|
|
||||||
|
When you scaffold those pieces **once**, any downstream team can drop a new folder that follows the `module.yaml` contract, implement the initializer, add its own tables & APIs, and instantly get:
|
||||||
|
|
||||||
|
* secure authentication,
|
||||||
|
* role‑based authorization,
|
||||||
|
* logging/metrics,
|
||||||
|
* unified config,
|
||||||
|
* CI‑ready testing,
|
||||||
|
* optional multi‑tenant isolation.
|
||||||
|
|
||||||
|
That’s the foundation of a **robust, future‑proof platform boilerplate**. Happy building! 🚀
|
||||||
62
stories/COMPLETE_TASK_LIST.md
Normal file
62
stories/COMPLETE_TASK_LIST.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# Complete Task List
|
||||||
|
|
||||||
|
This document provides a comprehensive list of all tasks across all phases. Each task has a corresponding detailed file in the phase-specific directories.
|
||||||
|
|
||||||
|
## Task Organization
|
||||||
|
|
||||||
|
Tasks are organized by phase and section. Each task file follows the naming convention: `{section}.{subtask}-{description}.md`
|
||||||
|
|
||||||
|
## Phase 0: Project Setup & Foundation
|
||||||
|
|
||||||
|
### 0.1 Repository Bootstrap
|
||||||
|
- [0.1.1 - Initialize Go Module](./phase0/0.1.1-initialize-go-module.md)
|
||||||
|
- [0.1.2 - Create Directory Structure](./phase0/0.1.2-create-directory-structure.md)
|
||||||
|
- [0.1.3 - Add Gitignore](./phase0/0.1.3-add-gitignore.md)
|
||||||
|
- [0.1.4 - Create Initial README](./phase0/0.1.4-create-initial-readme.md)
|
||||||
|
|
||||||
|
### 0.2 Configuration System
|
||||||
|
- [0.2.1 - Install Configuration Dependencies](./phase0/0.2.1-install-config-dependencies.md)
|
||||||
|
- [0.2.2 - Create Config Interface](./phase0/0.2.2-create-config-interface.md)
|
||||||
|
- [0.2.3 - Implement Config Loader](./phase0/0.2.3-implement-config-loader.md)
|
||||||
|
- [0.2.4 - Create Configuration Files](./phase0/0.2.4-create-configuration-files.md)
|
||||||
|
|
||||||
|
### 0.3 Logging Foundation
|
||||||
|
- [0.3.1 - Install Logging Dependencies](./phase0/0.3.1-install-logging-dependencies.md)
|
||||||
|
- See [Phase 0 README](./phase0/README.md) for remaining tasks
|
||||||
|
|
||||||
|
### 0.4 Basic CI/CD Pipeline
|
||||||
|
- See [Phase 0 README](./phase0/README.md) for tasks
|
||||||
|
|
||||||
|
### 0.5 Dependency Injection Setup
|
||||||
|
- See [Phase 0 README](./phase0/README.md) for tasks
|
||||||
|
|
||||||
|
## Phase 1-8 Tasks
|
||||||
|
|
||||||
|
Detailed task files for Phases 1-8 are being created. See individual phase README files:
|
||||||
|
- [Phase 1 README](./phase1/README.md) - Core Kernel & Infrastructure
|
||||||
|
- [Phase 2 README](./phase2/README.md) - Authentication & Authorization
|
||||||
|
- [Phase 3 README](./phase3/README.md) - Module Framework
|
||||||
|
- [Phase 4 README](./phase4/README.md) - Sample Feature Module (Blog)
|
||||||
|
- [Phase 5 README](./phase5/README.md) - Infrastructure Adapters
|
||||||
|
- [Phase 6 README](./phase6/README.md) - Observability & Production Readiness
|
||||||
|
- [Phase 7 README](./phase7/README.md) - Testing, Documentation & CI/CD
|
||||||
|
- [Phase 8 README](./phase8/README.md) - Advanced Features & Polish
|
||||||
|
|
||||||
|
## Task Status Tracking
|
||||||
|
|
||||||
|
To track task completion:
|
||||||
|
1. Update the Status field in each task file
|
||||||
|
2. Update checkboxes in the main plan.md
|
||||||
|
3. Reference task IDs in commit messages: `[0.1.1] Initialize Go module`
|
||||||
|
4. Link GitHub issues to tasks if using issue tracking
|
||||||
|
|
||||||
|
## Generating Missing Task Files
|
||||||
|
|
||||||
|
A script is available to generate task files from plan.md:
|
||||||
|
```bash
|
||||||
|
cd docs/tasks
|
||||||
|
python3 generate_tasks.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: Manually review and refine generated task files as needed.
|
||||||
|
|
||||||
63
stories/README.md
Normal file
63
stories/README.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# Implementation Tasks
|
||||||
|
|
||||||
|
This directory contains detailed task definitions for each phase of the Go Platform implementation.
|
||||||
|
|
||||||
|
## Task Organization
|
||||||
|
|
||||||
|
Tasks are organized by phase, with each major task section having its own detailed file:
|
||||||
|
|
||||||
|
### Phase 0: Project Setup & Foundation
|
||||||
|
- [Phase 0 Tasks](./phase0/README.md) - All Phase 0 tasks
|
||||||
|
|
||||||
|
### Phase 1: Core Kernel & Infrastructure
|
||||||
|
- [Phase 1 Tasks](./phase1/README.md) - All Phase 1 tasks
|
||||||
|
|
||||||
|
### Phase 2: Authentication & Authorization
|
||||||
|
- [Phase 2 Tasks](./phase2/README.md) - All Phase 2 tasks
|
||||||
|
|
||||||
|
### Phase 3: Module Framework
|
||||||
|
- [Phase 3 Tasks](./phase3/README.md) - All Phase 3 tasks
|
||||||
|
|
||||||
|
### Phase 4: Sample Feature Module (Blog)
|
||||||
|
- [Phase 4 Tasks](./phase4/README.md) - All Phase 4 tasks
|
||||||
|
|
||||||
|
### Phase 5: Infrastructure Adapters
|
||||||
|
- [Phase 5 Tasks](./phase5/README.md) - All Phase 5 tasks
|
||||||
|
|
||||||
|
### Phase 6: Observability & Production Readiness
|
||||||
|
- [Phase 6 Tasks](./phase6/README.md) - All Phase 6 tasks
|
||||||
|
|
||||||
|
### Phase 7: Testing, Documentation & CI/CD
|
||||||
|
- [Phase 7 Tasks](./phase7/README.md) - All Phase 7 tasks
|
||||||
|
|
||||||
|
### Phase 8: Advanced Features & Polish (Optional)
|
||||||
|
- [Phase 8 Tasks](./phase8/README.md) - All Phase 8 tasks
|
||||||
|
|
||||||
|
## Task Status
|
||||||
|
|
||||||
|
Each task file includes:
|
||||||
|
- **Task ID**: Unique identifier (e.g., `0.1.1`)
|
||||||
|
- **Title**: Descriptive task name
|
||||||
|
- **Phase**: Implementation phase
|
||||||
|
- **Status**: Pending | In Progress | Completed | Blocked
|
||||||
|
- **Priority**: High | Medium | Low
|
||||||
|
- **Dependencies**: Tasks that must complete first
|
||||||
|
- **Description**: Detailed requirements
|
||||||
|
- **Acceptance Criteria**: How to verify completion
|
||||||
|
- **Implementation Notes**: Technical details and references
|
||||||
|
- **Related ADRs**: Links to relevant architecture decisions
|
||||||
|
|
||||||
|
## Task Tracking
|
||||||
|
|
||||||
|
Tasks can be tracked using:
|
||||||
|
- GitHub Issues (linked from tasks)
|
||||||
|
- Project boards
|
||||||
|
- Task management tools
|
||||||
|
- Direct commit messages referencing task IDs
|
||||||
|
|
||||||
|
## Task Naming Convention
|
||||||
|
|
||||||
|
Tasks follow the format: `{phase}.{section}.{subtask}`
|
||||||
|
|
||||||
|
Example: `0.1.1` = Phase 0, Section 1 (Repository Bootstrap), Subtask 1
|
||||||
|
|
||||||
54
stories/TASK_TEMPLATE.md
Normal file
54
stories/TASK_TEMPLATE.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Task Template
|
||||||
|
|
||||||
|
Use this template for creating new task files.
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: {phase}.{section}.{subtask}
|
||||||
|
- **Title**: {Descriptive Task Name}
|
||||||
|
- **Phase**: {Phase Number} - {Phase Name}
|
||||||
|
- **Section**: {Section Number}.{Section Name}
|
||||||
|
- **Status**: Pending | In Progress | Completed | Blocked
|
||||||
|
- **Priority**: High | Medium | Low
|
||||||
|
- **Estimated Time**: {time estimate}
|
||||||
|
- **Dependencies**: {task IDs that must complete first}
|
||||||
|
|
||||||
|
## Description
|
||||||
|
{Clear description of what needs to be done}
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- {Requirement 1}
|
||||||
|
- {Requirement 2}
|
||||||
|
- {Requirement 3}
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. {Step 1}
|
||||||
|
2. {Step 2}
|
||||||
|
3. {Step 3}
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] {Criterion 1}
|
||||||
|
- [ ] {Criterion 2}
|
||||||
|
- [ ] {Criterion 3}
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-XXXX: {ADR Title}](../../adr/XXXX-adr-title.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- {Note 1}
|
||||||
|
- {Note 2}
|
||||||
|
- {Note 3}
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# Test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Files to Create/Modify
|
||||||
|
- `path/to/file.go` - {Description}
|
||||||
|
- `path/to/file_test.go` - {Description}
|
||||||
|
|
||||||
|
## References
|
||||||
|
- {Link to relevant documentation}
|
||||||
|
- {Link to example code}
|
||||||
|
|
||||||
219
stories/generate_tasks.py
Normal file
219
stories/generate_tasks.py
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Generate task files from plan.md
|
||||||
|
This script parses the plan.md file and creates detailed task files for each task.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def parse_plan(plan_path):
|
||||||
|
"""Parse plan.md and extract tasks"""
|
||||||
|
with open(plan_path, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
tasks = []
|
||||||
|
current_phase = None
|
||||||
|
current_section = None
|
||||||
|
subtask_num = 1
|
||||||
|
|
||||||
|
lines = content.split('\n')
|
||||||
|
i = 0
|
||||||
|
while i < len(lines):
|
||||||
|
line = lines[i].rstrip()
|
||||||
|
|
||||||
|
# Phase header
|
||||||
|
phase_match = re.match(r'^## Phase (\d+):', line)
|
||||||
|
if phase_match:
|
||||||
|
current_phase = int(phase_match.group(1))
|
||||||
|
subtask_num = 1 # Reset subtask counter for new phase
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Section header (e.g., "#### 0.1 Repository Bootstrap")
|
||||||
|
section_match = re.match(r'^#### (\d+\.\d+)', line)
|
||||||
|
if section_match:
|
||||||
|
current_section = section_match.group(1)
|
||||||
|
subtask_num = 1 # Reset subtask counter for new section
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Task item (checkbox) - must match exactly
|
||||||
|
task_match = re.match(r'^- \[ \] (.+)', line)
|
||||||
|
if task_match and current_phase is not None and current_section is not None:
|
||||||
|
task_desc = task_match.group(1).strip()
|
||||||
|
|
||||||
|
# Handle tasks that end with colon (might have code block or list following)
|
||||||
|
code_block = ""
|
||||||
|
# Skip empty lines and code blocks
|
||||||
|
if i + 1 < len(lines):
|
||||||
|
next_line = lines[i + 1].strip()
|
||||||
|
if next_line.startswith('```'):
|
||||||
|
# Extract code block
|
||||||
|
j = i + 2
|
||||||
|
while j < len(lines) and not lines[j].strip().startswith('```'):
|
||||||
|
code_block += lines[j] + '\n'
|
||||||
|
j += 1
|
||||||
|
i = j + 1
|
||||||
|
elif next_line.startswith('- [ ]') or next_line.startswith('```'):
|
||||||
|
# Next task or code block, don't skip
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# Only add if we have valid phase and section
|
||||||
|
if current_phase is not None and current_section is not None:
|
||||||
|
tasks.append({
|
||||||
|
'phase': current_phase,
|
||||||
|
'section': current_section,
|
||||||
|
'subtask': subtask_num,
|
||||||
|
'description': task_desc,
|
||||||
|
'code': code_block.strip()
|
||||||
|
})
|
||||||
|
subtask_num += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
return tasks
|
||||||
|
|
||||||
|
def create_task_file(task, output_dir):
|
||||||
|
"""Create a task markdown file"""
|
||||||
|
phase_dir = output_dir / f"phase{task['phase']}"
|
||||||
|
phase_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
task_id = f"{task['section']}.{task['subtask']}"
|
||||||
|
# Create safe filename
|
||||||
|
safe_desc = re.sub(r'[^\w\s-]', '', task['description'])[:50].strip().replace(' ', '-').lower()
|
||||||
|
filename = f"{task_id}-{safe_desc}.md"
|
||||||
|
filepath = phase_dir / filename
|
||||||
|
|
||||||
|
# Generate content
|
||||||
|
content = f"""# Task {task_id}: {task['description']}
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: {task_id}
|
||||||
|
- **Title**: {task['description']}
|
||||||
|
- **Phase**: {task['phase']} - {get_phase_name(task['phase'])}
|
||||||
|
- **Section**: {task['section']}
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
{task['description']}
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- {task['description']}
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task {task_id} is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if task['code']:
|
||||||
|
content += f"\n## Code Reference\n\n```go\n{task['code']}\n```\n"
|
||||||
|
|
||||||
|
with open(filepath, 'w') as f:
|
||||||
|
f.write(content)
|
||||||
|
|
||||||
|
return filepath
|
||||||
|
|
||||||
|
def get_phase_name(phase_num):
|
||||||
|
"""Get phase name from number"""
|
||||||
|
phases = {
|
||||||
|
0: "Project Setup & Foundation",
|
||||||
|
1: "Core Kernel & Infrastructure",
|
||||||
|
2: "Authentication & Authorization",
|
||||||
|
3: "Module Framework",
|
||||||
|
4: "Sample Feature Module (Blog)",
|
||||||
|
5: "Infrastructure Adapters",
|
||||||
|
6: "Observability & Production Readiness",
|
||||||
|
7: "Testing, Documentation & CI/CD",
|
||||||
|
8: "Advanced Features & Polish"
|
||||||
|
}
|
||||||
|
return phases.get(phase_num, "Unknown")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
script_dir = Path(__file__).parent
|
||||||
|
plan_path = script_dir.parent / "plan.md"
|
||||||
|
output_dir = script_dir
|
||||||
|
|
||||||
|
if not plan_path.exists():
|
||||||
|
print(f"Error: {plan_path} not found")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"Parsing {plan_path}...")
|
||||||
|
try:
|
||||||
|
tasks = parse_plan(plan_path)
|
||||||
|
print(f"Found {len(tasks)} tasks")
|
||||||
|
|
||||||
|
if len(tasks) == 0:
|
||||||
|
print("Warning: No tasks found. Check the plan.md format.")
|
||||||
|
return
|
||||||
|
|
||||||
|
created = 0
|
||||||
|
skipped = 0
|
||||||
|
for task in tasks:
|
||||||
|
try:
|
||||||
|
task_id = f"{task['section']}.{task['subtask']}"
|
||||||
|
|
||||||
|
# Determine filepath before creating
|
||||||
|
phase_dir = output_dir / f"phase{task['phase']}"
|
||||||
|
phase_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
# Create safe filename
|
||||||
|
safe_desc = re.sub(r'[^\w\s-]', '', task['description'])[:50].strip().replace(' ', '-').lower()
|
||||||
|
filename = f"{task_id}-{safe_desc}.md"
|
||||||
|
filepath = phase_dir / filename
|
||||||
|
|
||||||
|
# Check if file already exists (skip if so)
|
||||||
|
if filepath.exists() and filepath.stat().st_size > 100:
|
||||||
|
skipped += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Create the file
|
||||||
|
create_task_file(task, output_dir)
|
||||||
|
created += 1
|
||||||
|
if created % 10 == 0:
|
||||||
|
print(f"Created {created} task files...")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error creating task {task.get('section', '?')}.{task.get('subtask', '?')}: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
print(f"\nCreated {created} new task files")
|
||||||
|
if skipped > 0:
|
||||||
|
print(f"Skipped {skipped} existing task files")
|
||||||
|
print(f"Total tasks processed: {len(tasks)}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# Task 0.1.1: Initialize Go Module
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.1.1
|
||||||
|
- **Title**: Initialize Go Module
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.1 Repository Bootstrap
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 5 minutes
|
||||||
|
- **Dependencies**: None
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Initialize the Go module with the correct module path for the platform.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Use module path: `git.dcentral.systems/toolz/goplt`
|
||||||
|
- Go version: 1.24.3
|
||||||
|
- Ensure `go.mod` file is created correctly
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Run `go mod init git.dcentral.systems/toolz/goplt` in the project root
|
||||||
|
2. Verify `go.mod` file is created with correct module path
|
||||||
|
3. Set Go version in `go.mod`: `go 1.24`
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `go.mod` file exists in project root
|
||||||
|
- [ ] Module path is `git.dcentral.systems/toolz/goplt`
|
||||||
|
- [ ] Go version is set to `1.24`
|
||||||
|
- [ ] `go mod verify` passes
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0001: Go Module Path](../../adr/0001-go-module-path.md)
|
||||||
|
- [ADR-0002: Go Version](../../adr/0002-go-version.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Ensure the module path matches the organization's Git hosting structure
|
||||||
|
- The module path will be used for all internal imports
|
||||||
|
- Update any documentation that references placeholder module paths
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# Verify module initialization
|
||||||
|
go mod verify
|
||||||
|
go mod tidy
|
||||||
|
```
|
||||||
|
|
||||||
47
stories/phase0/0.1.1-initialize-go-module.md
Normal file
47
stories/phase0/0.1.1-initialize-go-module.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Task 0.1.1: Initialize Go Module
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.1.1
|
||||||
|
- **Title**: Initialize Go Module
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.1 Repository Bootstrap
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 5 minutes
|
||||||
|
- **Dependencies**: None
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Initialize the Go module with the correct module path for the platform.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Use module path: `git.dcentral.systems/toolz/goplt`
|
||||||
|
- Go version: 1.24.3
|
||||||
|
- Ensure `go.mod` file is created correctly
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Run `go mod init git.dcentral.systems/toolz/goplt` in the project root
|
||||||
|
2. Verify `go.mod` file is created with correct module path
|
||||||
|
3. Set Go version in `go.mod`: `go 1.24`
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `go.mod` file exists in project root
|
||||||
|
- [ ] Module path is `git.dcentral.systems/toolz/goplt`
|
||||||
|
- [ ] Go version is set to `1.24`
|
||||||
|
- [ ] `go mod verify` passes
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0001: Go Module Path](../../adr/0001-go-module-path.md)
|
||||||
|
- [ADR-0002: Go Version](../../adr/0002-go-version.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Ensure the module path matches the organization's Git hosting structure
|
||||||
|
- The module path will be used for all internal imports
|
||||||
|
- Update any documentation that references placeholder module paths
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# Verify module initialization
|
||||||
|
go mod verify
|
||||||
|
go mod tidy
|
||||||
|
```
|
||||||
|
|
||||||
77
stories/phase0/0.1.2-create-directory-structure.md
Normal file
77
stories/phase0/0.1.2-create-directory-structure.md
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
# Task 0.1.2: Create directory structure:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.1.2
|
||||||
|
- **Title**: Create directory structure:
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.1
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create directory structure:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create directory structure:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 0.1.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Code Reference
|
||||||
|
|
||||||
|
```go
|
||||||
|
platform/
|
||||||
|
├── cmd/
|
||||||
|
│ └── platform/ # Main entry point
|
||||||
|
├── internal/ # Private implementation code
|
||||||
|
│ ├── di/ # Dependency injection container
|
||||||
|
│ ├── registry/ # Module registry
|
||||||
|
│ ├── pluginloader/ # Plugin loader (optional)
|
||||||
|
│ └── infra/ # Infrastructure adapters
|
||||||
|
├── pkg/ # Public interfaces (exported)
|
||||||
|
│ ├── config/ # ConfigProvider interface
|
||||||
|
│ ├── logger/ # Logger interface
|
||||||
|
│ ├── module/ # IModule interface
|
||||||
|
│ ├── auth/ # Auth interfaces
|
||||||
|
│ ├── perm/ # Permission DSL
|
||||||
|
│ └── infra/ # Infrastructure interfaces
|
||||||
|
├── modules/ # Feature modules
|
||||||
|
│ └── blog/ # Sample Blog module (Phase 4)
|
||||||
|
├── config/ # Configuration files
|
||||||
|
│ ├── default.yaml
|
||||||
|
│ ├── development.yaml
|
||||||
|
│ └── production.yaml
|
||||||
|
├── api/ # OpenAPI specs
|
||||||
|
├── scripts/ # Build/test scripts
|
||||||
|
├── docs/ # Documentation
|
||||||
|
├── ops/ # Operations (Grafana dashboards, etc.)
|
||||||
|
├── .github/
|
||||||
|
│ └── workflows/
|
||||||
|
│ └── ci.yml
|
||||||
|
├── Dockerfile
|
||||||
|
├── docker-compose.yml
|
||||||
|
├── docker-compose.test.yml
|
||||||
|
└── go.mod
|
||||||
|
```
|
||||||
56
stories/phase0/0.1.3-add-gitignore-for-go-projects.md
Normal file
56
stories/phase0/0.1.3-add-gitignore-for-go-projects.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# Task 0.1.3: Add Gitignore
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.1.3
|
||||||
|
- **Title**: Add Gitignore
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.1 Repository Bootstrap
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: Medium
|
||||||
|
- **Estimated Time**: 5 minutes
|
||||||
|
- **Dependencies**: 0.1.1
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create a comprehensive `.gitignore` file for Go projects that excludes build artifacts, dependencies, IDE files, and sensitive data.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Ignore Go build artifacts
|
||||||
|
- Ignore dependency caches
|
||||||
|
- Ignore IDE-specific files
|
||||||
|
- Ignore environment-specific files
|
||||||
|
- Ignore secrets and sensitive data
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Create `.gitignore` in project root
|
||||||
|
2. Add standard Go ignores:
|
||||||
|
- `*.exe`, `*.exe~`, `*.dll`, `*.so`, `*.dylib`
|
||||||
|
- `*.test`, `*.out`
|
||||||
|
- `go.work`, `go.work.sum`
|
||||||
|
3. Add IDE ignores:
|
||||||
|
- `.vscode/`, `.idea/`, `*.swp`, `*.swo`
|
||||||
|
4. Add environment ignores:
|
||||||
|
- `.env`, `.env.local`, `config/secrets/`
|
||||||
|
5. Add OS ignores:
|
||||||
|
- `.DS_Store`, `Thumbs.db`
|
||||||
|
6. Add build artifacts:
|
||||||
|
- `bin/`, `dist/`, `tmp/`
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `.gitignore` file exists
|
||||||
|
- [ ] Common Go artifacts are ignored
|
||||||
|
- [ ] IDE files are ignored
|
||||||
|
- [ ] Sensitive files are ignored
|
||||||
|
- [ ] Test with `git status` to verify
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Use standard Go `.gitignore` templates
|
||||||
|
- Ensure `config/secrets/` is ignored (for secret files)
|
||||||
|
- Consider adding `*.log` for log files
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# Verify gitignore works
|
||||||
|
git status
|
||||||
|
# Should not show build artifacts or IDE files
|
||||||
|
```
|
||||||
|
|
||||||
56
stories/phase0/0.1.3-add-gitignore.md
Normal file
56
stories/phase0/0.1.3-add-gitignore.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# Task 0.1.3: Add Gitignore
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.1.3
|
||||||
|
- **Title**: Add Gitignore
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.1 Repository Bootstrap
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: Medium
|
||||||
|
- **Estimated Time**: 5 minutes
|
||||||
|
- **Dependencies**: 0.1.1
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create a comprehensive `.gitignore` file for Go projects that excludes build artifacts, dependencies, IDE files, and sensitive data.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Ignore Go build artifacts
|
||||||
|
- Ignore dependency caches
|
||||||
|
- Ignore IDE-specific files
|
||||||
|
- Ignore environment-specific files
|
||||||
|
- Ignore secrets and sensitive data
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Create `.gitignore` in project root
|
||||||
|
2. Add standard Go ignores:
|
||||||
|
- `*.exe`, `*.exe~`, `*.dll`, `*.so`, `*.dylib`
|
||||||
|
- `*.test`, `*.out`
|
||||||
|
- `go.work`, `go.work.sum`
|
||||||
|
3. Add IDE ignores:
|
||||||
|
- `.vscode/`, `.idea/`, `*.swp`, `*.swo`
|
||||||
|
4. Add environment ignores:
|
||||||
|
- `.env`, `.env.local`, `config/secrets/`
|
||||||
|
5. Add OS ignores:
|
||||||
|
- `.DS_Store`, `Thumbs.db`
|
||||||
|
6. Add build artifacts:
|
||||||
|
- `bin/`, `dist/`, `tmp/`
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `.gitignore` file exists
|
||||||
|
- [ ] Common Go artifacts are ignored
|
||||||
|
- [ ] IDE files are ignored
|
||||||
|
- [ ] Sensitive files are ignored
|
||||||
|
- [ ] Test with `git status` to verify
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Use standard Go `.gitignore` templates
|
||||||
|
- Ensure `config/secrets/` is ignored (for secret files)
|
||||||
|
- Consider adding `*.log` for log files
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# Verify gitignore works
|
||||||
|
git status
|
||||||
|
# Should not show build artifacts or IDE files
|
||||||
|
```
|
||||||
|
|
||||||
63
stories/phase0/0.1.4-create-initial-readme.md
Normal file
63
stories/phase0/0.1.4-create-initial-readme.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# Task 0.1.4: Create Initial README
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.1.4
|
||||||
|
- **Title**: Create Initial README
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.1 Repository Bootstrap
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: Medium
|
||||||
|
- **Estimated Time**: 20 minutes
|
||||||
|
- **Dependencies**: 0.1.1
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create an initial `README.md` file that provides an overview of the project, its purpose, architecture, and quick start instructions.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Project overview and description
|
||||||
|
- Architecture overview
|
||||||
|
- Quick start guide
|
||||||
|
- Links to documentation
|
||||||
|
- Build and run instructions
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Create `README.md` in project root
|
||||||
|
2. Add project title and description
|
||||||
|
3. Add architecture overview section
|
||||||
|
4. Add quick start instructions
|
||||||
|
5. Add links to documentation (`docs/`)
|
||||||
|
6. Add build and run commands
|
||||||
|
7. Add contribution guidelines (placeholder)
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `README.md` exists
|
||||||
|
- [ ] Project overview is clear
|
||||||
|
- [ ] Quick start instructions are present
|
||||||
|
- [ ] Links to documentation work
|
||||||
|
- [ ] Build instructions are accurate
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Keep README concise but informative
|
||||||
|
- Update as project evolves
|
||||||
|
- Include badges (build status, etc.) later
|
||||||
|
- Reference ADRs for architecture decisions
|
||||||
|
|
||||||
|
## Content Structure
|
||||||
|
```markdown
|
||||||
|
# Go Platform (goplt)
|
||||||
|
|
||||||
|
[Description]
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
[Overview]
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
[Instructions]
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
[Links]
|
||||||
|
|
||||||
|
## Development
|
||||||
|
[Setup instructions]
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Task 0.1.4: Create Initial README
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.1.4
|
||||||
|
- **Title**: Create Initial README
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.1 Repository Bootstrap
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: Medium
|
||||||
|
- **Estimated Time**: 20 minutes
|
||||||
|
- **Dependencies**: 0.1.1
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create an initial `README.md` file that provides an overview of the project, its purpose, architecture, and quick start instructions.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Project overview and description
|
||||||
|
- Architecture overview
|
||||||
|
- Quick start guide
|
||||||
|
- Links to documentation
|
||||||
|
- Build and run instructions
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Create `README.md` in project root
|
||||||
|
2. Add project title and description
|
||||||
|
3. Add architecture overview section
|
||||||
|
4. Add quick start instructions
|
||||||
|
5. Add links to documentation (`docs/`)
|
||||||
|
6. Add build and run commands
|
||||||
|
7. Add contribution guidelines (placeholder)
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `README.md` exists
|
||||||
|
- [ ] Project overview is clear
|
||||||
|
- [ ] Quick start instructions are present
|
||||||
|
- [ ] Links to documentation work
|
||||||
|
- [ ] Build instructions are accurate
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Keep README concise but informative
|
||||||
|
- Update as project evolves
|
||||||
|
- Include badges (build status, etc.) later
|
||||||
|
- Reference ADRs for architecture decisions
|
||||||
|
|
||||||
|
## Content Structure
|
||||||
|
```markdown
|
||||||
|
# Go Platform (goplt)
|
||||||
|
|
||||||
|
[Description]
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
[Overview]
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
[Instructions]
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
[Links]
|
||||||
|
|
||||||
|
## Development
|
||||||
|
[Setup instructions]
|
||||||
|
```
|
||||||
|
|
||||||
47
stories/phase0/0.2.1-install-config-dependencies.md
Normal file
47
stories/phase0/0.2.1-install-config-dependencies.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Task 0.2.1: Install Configuration Dependencies
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.2.1
|
||||||
|
- **Title**: Install Configuration Dependencies
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.2 Configuration System
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 5 minutes
|
||||||
|
- **Dependencies**: 0.1.1
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install Viper and Cobra packages for configuration management and CLI support.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install `github.com/spf13/viper` v1.18.0+
|
||||||
|
- Install `github.com/spf13/cobra` v1.8.0+
|
||||||
|
- Add to `go.mod` with proper version constraints
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Run `go get github.com/spf13/viper@v1.18.0`
|
||||||
|
2. Run `go get github.com/spf13/cobra@v1.8.0`
|
||||||
|
3. Run `go mod tidy` to update dependencies
|
||||||
|
4. Verify packages in `go.mod`
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Viper is listed in `go.mod`
|
||||||
|
- [ ] Cobra is listed in `go.mod`
|
||||||
|
- [ ] `go mod verify` passes
|
||||||
|
- [ ] Dependencies are properly versioned
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0004: Configuration Management](../../adr/0004-configuration-management.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Use specific versions for reproducibility
|
||||||
|
- Consider using `go get -u` for latest patch versions
|
||||||
|
- Document version choices in ADR
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
go mod verify
|
||||||
|
go list -m github.com/spf13/viper
|
||||||
|
go list -m github.com/spf13/cobra
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# Task 0.2.1: Install Configuration Dependencies
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.2.1
|
||||||
|
- **Title**: Install Configuration Dependencies
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.2 Configuration System
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 5 minutes
|
||||||
|
- **Dependencies**: 0.1.1
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install Viper and Cobra packages for configuration management and CLI support.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install `github.com/spf13/viper` v1.18.0+
|
||||||
|
- Install `github.com/spf13/cobra` v1.8.0+
|
||||||
|
- Add to `go.mod` with proper version constraints
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Run `go get github.com/spf13/viper@v1.18.0`
|
||||||
|
2. Run `go get github.com/spf13/cobra@v1.8.0`
|
||||||
|
3. Run `go mod tidy` to update dependencies
|
||||||
|
4. Verify packages in `go.mod`
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Viper is listed in `go.mod`
|
||||||
|
- [ ] Cobra is listed in `go.mod`
|
||||||
|
- [ ] `go mod verify` passes
|
||||||
|
- [ ] Dependencies are properly versioned
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0004: Configuration Management](../../adr/0004-configuration-management.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Use specific versions for reproducibility
|
||||||
|
- Consider using `go get -u` for latest patch versions
|
||||||
|
- Document version choices in ADR
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
go mod verify
|
||||||
|
go list -m github.com/spf13/viper
|
||||||
|
go list -m github.com/spf13/cobra
|
||||||
|
```
|
||||||
|
|
||||||
59
stories/phase0/0.2.2-create-config-interface.md
Normal file
59
stories/phase0/0.2.2-create-config-interface.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Task 0.2.2: Create Config Interface
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.2.2
|
||||||
|
- **Title**: Create Config Interface
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.2 Configuration System
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 15 minutes
|
||||||
|
- **Dependencies**: 0.2.1
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create the `ConfigProvider` interface in `pkg/config/` to abstract configuration access. This interface will be used by all modules and services.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Define interface in `pkg/config/config.go`
|
||||||
|
- Include methods for type-safe access
|
||||||
|
- Support nested configuration keys
|
||||||
|
- Support unmarshaling into structs
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Create `pkg/config/config.go`
|
||||||
|
2. Define `ConfigProvider` interface:
|
||||||
|
```go
|
||||||
|
type ConfigProvider interface {
|
||||||
|
Get(key string) any
|
||||||
|
Unmarshal(v any) error
|
||||||
|
GetString(key string) string
|
||||||
|
GetInt(key string) int
|
||||||
|
GetBool(key string) bool
|
||||||
|
GetStringSlice(key string) []string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
3. Add package documentation
|
||||||
|
4. Export interface for use by modules
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `pkg/config/config.go` exists
|
||||||
|
- [ ] `ConfigProvider` interface is defined
|
||||||
|
- [ ] Interface methods match requirements
|
||||||
|
- [ ] Package documentation is present
|
||||||
|
- [ ] Interface compiles without errors
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0004: Configuration Management](../../adr/0004-configuration-management.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Interface should be minimal and focused
|
||||||
|
- Additional methods can be added later if needed
|
||||||
|
- Consider adding `GetDuration()` for time.Duration values
|
||||||
|
- Consider adding `IsSet(key string) bool` to check if key exists
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
go build ./pkg/config
|
||||||
|
go vet ./pkg/config
|
||||||
|
```
|
||||||
|
|
||||||
59
stories/phase0/0.2.2-create-pkgconfigconfiggo-interface.md
Normal file
59
stories/phase0/0.2.2-create-pkgconfigconfiggo-interface.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Task 0.2.2: Create Config Interface
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.2.2
|
||||||
|
- **Title**: Create Config Interface
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.2 Configuration System
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 15 minutes
|
||||||
|
- **Dependencies**: 0.2.1
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create the `ConfigProvider` interface in `pkg/config/` to abstract configuration access. This interface will be used by all modules and services.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Define interface in `pkg/config/config.go`
|
||||||
|
- Include methods for type-safe access
|
||||||
|
- Support nested configuration keys
|
||||||
|
- Support unmarshaling into structs
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Create `pkg/config/config.go`
|
||||||
|
2. Define `ConfigProvider` interface:
|
||||||
|
```go
|
||||||
|
type ConfigProvider interface {
|
||||||
|
Get(key string) any
|
||||||
|
Unmarshal(v any) error
|
||||||
|
GetString(key string) string
|
||||||
|
GetInt(key string) int
|
||||||
|
GetBool(key string) bool
|
||||||
|
GetStringSlice(key string) []string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
3. Add package documentation
|
||||||
|
4. Export interface for use by modules
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `pkg/config/config.go` exists
|
||||||
|
- [ ] `ConfigProvider` interface is defined
|
||||||
|
- [ ] Interface methods match requirements
|
||||||
|
- [ ] Package documentation is present
|
||||||
|
- [ ] Interface compiles without errors
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0004: Configuration Management](../../adr/0004-configuration-management.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Interface should be minimal and focused
|
||||||
|
- Additional methods can be added later if needed
|
||||||
|
- Consider adding `GetDuration()` for time.Duration values
|
||||||
|
- Consider adding `IsSet(key string) bool` to check if key exists
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
go build ./pkg/config
|
||||||
|
go vet ./pkg/config
|
||||||
|
```
|
||||||
|
|
||||||
60
stories/phase0/0.2.3-implement-config-loader.md
Normal file
60
stories/phase0/0.2.3-implement-config-loader.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# Task 0.2.3: Implement Config Loader
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.2.3
|
||||||
|
- **Title**: Implement Config Loader
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.2 Configuration System
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 30 minutes
|
||||||
|
- **Dependencies**: 0.2.1, 0.2.2
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Implement the Viper-based configuration loader in `internal/config/` that implements the `ConfigProvider` interface. This loader will handle hierarchical configuration loading from files and environment variables.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Implement `ConfigProvider` interface using Viper
|
||||||
|
- Load configuration in order: defaults → environment-specific → env vars
|
||||||
|
- Support YAML configuration files
|
||||||
|
- Support environment variable overrides
|
||||||
|
- Provide placeholder for secret manager integration (Phase 6)
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Create `internal/config/config.go`:
|
||||||
|
- Implement `ConfigProvider` interface
|
||||||
|
- Wrap Viper instance
|
||||||
|
- Implement all interface methods
|
||||||
|
2. Create `internal/config/loader.go`:
|
||||||
|
- `LoadConfig()` function
|
||||||
|
- Load `config/default.yaml` as baseline
|
||||||
|
- Merge environment-specific YAML (development/production)
|
||||||
|
- Apply environment variable overrides
|
||||||
|
- Set up automatic environment variable binding
|
||||||
|
3. Add error handling for missing config files
|
||||||
|
4. Add logging for configuration loading
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `internal/config/config.go` implements `ConfigProvider`
|
||||||
|
- [ ] `internal/config/loader.go` has `LoadConfig()` function
|
||||||
|
- [ ] Configuration loads from `config/default.yaml`
|
||||||
|
- [ ] Environment-specific configs are merged correctly
|
||||||
|
- [ ] Environment variables override file values
|
||||||
|
- [ ] Errors are handled gracefully
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0004: Configuration Management](../../adr/0004-configuration-management.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Use Viper's `SetConfigName()` and `AddConfigPath()`
|
||||||
|
- Use `MergeInConfig()` for environment-specific files
|
||||||
|
- Use `AutomaticEnv()` for environment variable binding
|
||||||
|
- Set environment variable prefix (e.g., `GOPLT_`)
|
||||||
|
- Use `SetEnvKeyReplacer()` to replace dots with underscores
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# Test config loading
|
||||||
|
go test ./internal/config -v
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# Task 0.2.3: Implement Config Loader
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.2.3
|
||||||
|
- **Title**: Implement Config Loader
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.2 Configuration System
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 30 minutes
|
||||||
|
- **Dependencies**: 0.2.1, 0.2.2
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Implement the Viper-based configuration loader in `internal/config/` that implements the `ConfigProvider` interface. This loader will handle hierarchical configuration loading from files and environment variables.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Implement `ConfigProvider` interface using Viper
|
||||||
|
- Load configuration in order: defaults → environment-specific → env vars
|
||||||
|
- Support YAML configuration files
|
||||||
|
- Support environment variable overrides
|
||||||
|
- Provide placeholder for secret manager integration (Phase 6)
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Create `internal/config/config.go`:
|
||||||
|
- Implement `ConfigProvider` interface
|
||||||
|
- Wrap Viper instance
|
||||||
|
- Implement all interface methods
|
||||||
|
2. Create `internal/config/loader.go`:
|
||||||
|
- `LoadConfig()` function
|
||||||
|
- Load `config/default.yaml` as baseline
|
||||||
|
- Merge environment-specific YAML (development/production)
|
||||||
|
- Apply environment variable overrides
|
||||||
|
- Set up automatic environment variable binding
|
||||||
|
3. Add error handling for missing config files
|
||||||
|
4. Add logging for configuration loading
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `internal/config/config.go` implements `ConfigProvider`
|
||||||
|
- [ ] `internal/config/loader.go` has `LoadConfig()` function
|
||||||
|
- [ ] Configuration loads from `config/default.yaml`
|
||||||
|
- [ ] Environment-specific configs are merged correctly
|
||||||
|
- [ ] Environment variables override file values
|
||||||
|
- [ ] Errors are handled gracefully
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0004: Configuration Management](../../adr/0004-configuration-management.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Use Viper's `SetConfigName()` and `AddConfigPath()`
|
||||||
|
- Use `MergeInConfig()` for environment-specific files
|
||||||
|
- Use `AutomaticEnv()` for environment variable binding
|
||||||
|
- Set environment variable prefix (e.g., `GOPLT_`)
|
||||||
|
- Use `SetEnvKeyReplacer()` to replace dots with underscores
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# Test config loading
|
||||||
|
go test ./internal/config -v
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# Task 0.2.4: Create Configuration Files
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.2.4
|
||||||
|
- **Title**: Create Configuration Files
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.2 Configuration System
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 15 minutes
|
||||||
|
- **Dependencies**: 0.1.2
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create the baseline configuration YAML files that define the default configuration structure for the platform.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `config/default.yaml` with baseline values
|
||||||
|
- Create `config/development.yaml` with development overrides
|
||||||
|
- Create `config/production.yaml` with production overrides
|
||||||
|
- Define configuration schema for all core services
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Create `config/default.yaml`:
|
||||||
|
```yaml
|
||||||
|
environment: development
|
||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
host: "0.0.0.0"
|
||||||
|
database:
|
||||||
|
driver: "postgres"
|
||||||
|
dsn: ""
|
||||||
|
logging:
|
||||||
|
level: "info"
|
||||||
|
format: "json"
|
||||||
|
```
|
||||||
|
2. Create `config/development.yaml`:
|
||||||
|
- Override logging level to "debug"
|
||||||
|
- Add development-specific settings
|
||||||
|
3. Create `config/production.yaml`:
|
||||||
|
- Override logging level to "warn"
|
||||||
|
- Add production-specific settings
|
||||||
|
4. Document configuration options
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `config/default.yaml` exists with complete structure
|
||||||
|
- [ ] `config/development.yaml` exists
|
||||||
|
- [ ] `config/production.yaml` exists
|
||||||
|
- [ ] All configuration files are valid YAML
|
||||||
|
- [ ] Configuration structure is documented
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0004: Configuration Management](../../adr/0004-configuration-management.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Use consistent indentation (2 spaces)
|
||||||
|
- Add comments for unclear configuration options
|
||||||
|
- Use environment variables for sensitive values (DSN, secrets)
|
||||||
|
- Consider adding validation schema later
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# Validate YAML syntax
|
||||||
|
yamllint config/*.yaml
|
||||||
|
# or
|
||||||
|
python3 -c "import yaml; yaml.safe_load(open('config/default.yaml'))"
|
||||||
|
```
|
||||||
|
|
||||||
67
stories/phase0/0.2.4-create-configuration-files.md
Normal file
67
stories/phase0/0.2.4-create-configuration-files.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# Task 0.2.4: Create Configuration Files
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.2.4
|
||||||
|
- **Title**: Create Configuration Files
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.2 Configuration System
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 15 minutes
|
||||||
|
- **Dependencies**: 0.1.2
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create the baseline configuration YAML files that define the default configuration structure for the platform.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `config/default.yaml` with baseline values
|
||||||
|
- Create `config/development.yaml` with development overrides
|
||||||
|
- Create `config/production.yaml` with production overrides
|
||||||
|
- Define configuration schema for all core services
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Create `config/default.yaml`:
|
||||||
|
```yaml
|
||||||
|
environment: development
|
||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
host: "0.0.0.0"
|
||||||
|
database:
|
||||||
|
driver: "postgres"
|
||||||
|
dsn: ""
|
||||||
|
logging:
|
||||||
|
level: "info"
|
||||||
|
format: "json"
|
||||||
|
```
|
||||||
|
2. Create `config/development.yaml`:
|
||||||
|
- Override logging level to "debug"
|
||||||
|
- Add development-specific settings
|
||||||
|
3. Create `config/production.yaml`:
|
||||||
|
- Override logging level to "warn"
|
||||||
|
- Add production-specific settings
|
||||||
|
4. Document configuration options
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] `config/default.yaml` exists with complete structure
|
||||||
|
- [ ] `config/development.yaml` exists
|
||||||
|
- [ ] `config/production.yaml` exists
|
||||||
|
- [ ] All configuration files are valid YAML
|
||||||
|
- [ ] Configuration structure is documented
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0004: Configuration Management](../../adr/0004-configuration-management.md)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Use consistent indentation (2 spaces)
|
||||||
|
- Add comments for unclear configuration options
|
||||||
|
- Use environment variables for sensitive values (DSN, secrets)
|
||||||
|
- Consider adding validation schema later
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# Validate YAML syntax
|
||||||
|
yamllint config/*.yaml
|
||||||
|
# or
|
||||||
|
python3 -c "import yaml; yaml.safe_load(open('config/default.yaml'))"
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 0.2.5: Add `internal/config/loader.go` with `LoadConfig()` function
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.2.5
|
||||||
|
- **Title**: Add `internal/config/loader.go` with `LoadConfig()` function
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.2
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add `internal/config/loader.go` with `LoadConfig()` function
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add `internal/config/loader.go` with `LoadConfig()` function
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 0.2.5 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
33
stories/phase0/0.3.1-install-gouberorgzap.md
Normal file
33
stories/phase0/0.3.1-install-gouberorgzap.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Task 0.3.1: Install Logging Dependencies
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.3.1
|
||||||
|
- **Title**: Install Logging Dependencies
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.3 Logging Foundation
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 5 minutes
|
||||||
|
- **Dependencies**: 0.1.1
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install the Zap logging library for structured logging.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install `go.uber.org/zap` v1.26.0+
|
||||||
|
- Add to `go.mod` with proper version constraints
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Run `go get go.uber.org/zap@v1.26.0`
|
||||||
|
2. Run `go mod tidy`
|
||||||
|
3. Verify package in `go.mod`
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Zap is listed in `go.mod`
|
||||||
|
- [ ] Version is v1.26.0 or later
|
||||||
|
- [ ] `go mod verify` passes
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0005: Logging Framework](../../adr/0005-logging-framework.md)
|
||||||
|
- [ADR-0012: Logger Interface Design](../../adr/0012-logger-interface-design.md)
|
||||||
|
|
||||||
33
stories/phase0/0.3.1-install-logging-dependencies.md
Normal file
33
stories/phase0/0.3.1-install-logging-dependencies.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Task 0.3.1: Install Logging Dependencies
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.3.1
|
||||||
|
- **Title**: Install Logging Dependencies
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.3 Logging Foundation
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: 5 minutes
|
||||||
|
- **Dependencies**: 0.1.1
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install the Zap logging library for structured logging.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install `go.uber.org/zap` v1.26.0+
|
||||||
|
- Add to `go.mod` with proper version constraints
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. Run `go get go.uber.org/zap@v1.26.0`
|
||||||
|
2. Run `go mod tidy`
|
||||||
|
3. Verify package in `go.mod`
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Zap is listed in `go.mod`
|
||||||
|
- [ ] Version is v1.26.0 or later
|
||||||
|
- [ ] `go mod verify` passes
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- [ADR-0005: Logging Framework](../../adr/0005-logging-framework.md)
|
||||||
|
- [ADR-0012: Logger Interface Design](../../adr/0012-logger-interface-design.md)
|
||||||
|
|
||||||
52
stories/phase0/0.3.2-create-pkgloggerloggergo-interface.md
Normal file
52
stories/phase0/0.3.2-create-pkgloggerloggergo-interface.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Task 0.3.2: Create `pkg/logger/logger.go` interface:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.3.2
|
||||||
|
- **Title**: Create `pkg/logger/logger.go` interface:
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.3
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `pkg/logger/logger.go` interface:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `pkg/logger/logger.go` interface:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 0.3.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Code Reference
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Logger interface {
|
||||||
|
Debug(msg string, fields ...Field)
|
||||||
|
Info(msg string, fields ...Field)
|
||||||
|
Warn(msg string, fields ...Field)
|
||||||
|
Error(msg string, fields ...Field)
|
||||||
|
With(fields ...Field) Logger
|
||||||
|
}
|
||||||
|
```
|
||||||
40
stories/phase0/0.3.3-implement-internalloggerzap_loggergo.md
Normal file
40
stories/phase0/0.3.3-implement-internalloggerzap_loggergo.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 0.3.3: Implement `internal/logger/zap_logger.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.3.3
|
||||||
|
- **Title**: Implement `internal/logger/zap_logger.go`:
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.3
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Implement `internal/logger/zap_logger.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Implement `internal/logger/zap_logger.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 0.3.3 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 0.3.4: Add request ID middleware helper (Gin middleware)
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.3.4
|
||||||
|
- **Title**: Add request ID middleware helper (Gin middleware)
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.3
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add request ID middleware helper (Gin middleware)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add request ID middleware helper (Gin middleware)
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 0.3.4 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase0/0.4.1-create-githubworkflowsciyml.md
Normal file
40
stories/phase0/0.4.1-create-githubworkflowsciyml.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 0.4.1: Create `.github/workflows/ci.yml`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.4.1
|
||||||
|
- **Title**: Create `.github/workflows/ci.yml`:
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.4
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `.github/workflows/ci.yml`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `.github/workflows/ci.yml`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 0.4.1 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase0/0.4.2-add-makefile-with-common-commands.md
Normal file
40
stories/phase0/0.4.2-add-makefile-with-common-commands.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 0.4.2: Add `Makefile` with common commands:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.4.2
|
||||||
|
- **Title**: Add `Makefile` with common commands:
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.4
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add `Makefile` with common commands:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add `Makefile` with common commands:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 0.4.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase0/0.5.1-install-gouberorgfx.md
Normal file
40
stories/phase0/0.5.1-install-gouberorgfx.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 0.5.1: Install `go.uber.org/fx`
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.5.1
|
||||||
|
- **Title**: Install `go.uber.org/fx`
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.5
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install `go.uber.org/fx`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install `go.uber.org/fx`
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 0.5.1 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase0/0.5.2-create-internaldicontainergo.md
Normal file
40
stories/phase0/0.5.2-create-internaldicontainergo.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 0.5.2: Create `internal/di/container.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.5.2
|
||||||
|
- **Title**: Create `internal/di/container.go`:
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.5
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `internal/di/container.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `internal/di/container.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 0.5.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase0/0.5.3-create-cmdplatformmaingo-skeleton.md
Normal file
40
stories/phase0/0.5.3-create-cmdplatformmaingo-skeleton.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 0.5.3: Create `cmd/platform/main.go` skeleton:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 0.5.3
|
||||||
|
- **Title**: Create `cmd/platform/main.go` skeleton:
|
||||||
|
- **Phase**: 0 - Project Setup & Foundation
|
||||||
|
- **Section**: 0.5
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `cmd/platform/main.go` skeleton:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `cmd/platform/main.go` skeleton:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 0.5.3 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
47
stories/phase0/README.md
Normal file
47
stories/phase0/README.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Phase 0: Project Setup & Foundation
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Initialize repository structure, set up Go modules and basic tooling, create configuration management foundation, and establish CI/CD skeleton.
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
### 0.1 Repository Bootstrap
|
||||||
|
- [0.1.1 - Initialize Go Module](./0.1.1-initialize-go-module.md)
|
||||||
|
- [0.1.2 - Create Directory Structure](./0.1.2-create-directory-structure.md)
|
||||||
|
- [0.1.3 - Add Gitignore](./0.1.3-add-gitignore.md)
|
||||||
|
- [0.1.4 - Create Initial README](./0.1.4-create-initial-readme.md)
|
||||||
|
|
||||||
|
### 0.2 Configuration System
|
||||||
|
- [0.2.1 - Install Configuration Dependencies](./0.2.1-install-config-dependencies.md)
|
||||||
|
- [0.2.2 - Create Config Interface](./0.2.2-create-config-interface.md)
|
||||||
|
- [0.2.3 - Implement Config Loader](./0.2.3-implement-config-loader.md)
|
||||||
|
- [0.2.4 - Create Configuration Files](./0.2.4-create-configuration-files.md)
|
||||||
|
|
||||||
|
### 0.3 Logging Foundation
|
||||||
|
- [0.3.1 - Install Logging Dependencies](./0.3.1-install-logging-dependencies.md)
|
||||||
|
- [0.3.2 - Create Logger Interface](./0.3.2-create-logger-interface.md) - Create `pkg/logger/logger.go` interface
|
||||||
|
- [0.3.3 - Implement Zap Logger](./0.3.3-implement-zap-logger.md) - Implement `internal/logger/zap_logger.go`
|
||||||
|
- [0.3.4 - Add Request ID Middleware](./0.3.4-add-request-id-middleware.md) - Create Gin middleware for request IDs
|
||||||
|
|
||||||
|
### 0.4 Basic CI/CD Pipeline
|
||||||
|
- [0.4.1 - Create GitHub Actions Workflow](./0.4.1-create-github-actions-workflow.md)
|
||||||
|
- [0.4.2 - Create Makefile](./0.4.2-create-makefile.md)
|
||||||
|
|
||||||
|
### 0.5 Dependency Injection Setup
|
||||||
|
- [0.5.1 - Install FX Dependency](./0.5.1-install-fx-dependency.md)
|
||||||
|
- [0.5.2 - Create DI Container](./0.5.2-create-di-container.md)
|
||||||
|
- [0.5.3 - Create Main Entry Point](./0.5.3-create-main-entry-point.md)
|
||||||
|
|
||||||
|
## Deliverables Checklist
|
||||||
|
- [ ] Repository structure in place
|
||||||
|
- [ ] Configuration system loads YAML files and env vars
|
||||||
|
- [ ] Structured logging works
|
||||||
|
- [ ] CI pipeline runs linting and builds binary
|
||||||
|
- [ ] Basic DI container initialized
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- `go build ./cmd/platform` succeeds
|
||||||
|
- `go test ./...` runs (even if tests are empty)
|
||||||
|
- CI pipeline passes on empty commit
|
||||||
|
- Config loads from `config/default.yaml`
|
||||||
|
|
||||||
40
stories/phase1/1.1.1-extend-internaldicontainergo.md
Normal file
40
stories/phase1/1.1.1-extend-internaldicontainergo.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.1.1: Extend `internal/di/container.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.1.1
|
||||||
|
- **Title**: Extend `internal/di/container.go`:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.1
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Extend `internal/di/container.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Extend `internal/di/container.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.1.1 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.1.2-create-internaldiprovidersgo.md
Normal file
40
stories/phase1/1.1.2-create-internaldiprovidersgo.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.1.2: Create `internal/di/providers.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.1.2
|
||||||
|
- **Title**: Create `internal/di/providers.go`:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.1
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `internal/di/providers.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `internal/di/providers.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.1.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.1.3-add-internaldicore_modulego.md
Normal file
40
stories/phase1/1.1.3-add-internaldicore_modulego.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.1.3: Add `internal/di/core_module.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.1.3
|
||||||
|
- **Title**: Add `internal/di/core_module.go`:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.1
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add `internal/di/core_module.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add `internal/di/core_module.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.1.3 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.2.1-install-entgoioentcmdent.md
Normal file
40
stories/phase1/1.2.1-install-entgoioentcmdent.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.2.1: Install `entgo.io/ent/cmd/ent`
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.2.1
|
||||||
|
- **Title**: Install `entgo.io/ent/cmd/ent`
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.2
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install `entgo.io/ent/cmd/ent`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install `entgo.io/ent/cmd/ent`
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.2.1 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
46
stories/phase1/1.2.2-initialize-ent-schema.md
Normal file
46
stories/phase1/1.2.2-initialize-ent-schema.md
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Task 1.2.2: Initialize Ent schema:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.2.2
|
||||||
|
- **Title**: Initialize Ent schema:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.2
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Initialize Ent schema:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Initialize Ent schema:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.2.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Code Reference
|
||||||
|
|
||||||
|
```go
|
||||||
|
go run entgo.io/ent/cmd/ent init User Role Permission AuditLog
|
||||||
|
```
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.2.3: Define core entities in `internal/ent/schema/`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.2.3
|
||||||
|
- **Title**: Define core entities in `internal/ent/schema/`:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.2
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Define core entities in `internal/ent/schema/`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Define core entities in `internal/ent/schema/`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.2.3 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.2.4: Generate Ent code: `go generate ./internal/ent`
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.2.4
|
||||||
|
- **Title**: Generate Ent code: `go generate ./internal/ent`
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.2
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Generate Ent code: `go generate ./internal/ent`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Generate Ent code: `go generate ./internal/ent`
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.2.4 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.2.5-create-internalinfradatabaseclientgo.md
Normal file
40
stories/phase1/1.2.5-create-internalinfradatabaseclientgo.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.2.5: Create `internal/infra/database/client.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.2.5
|
||||||
|
- **Title**: Create `internal/infra/database/client.go`:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.2
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `internal/infra/database/client.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `internal/infra/database/client.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.2.5 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.2.6: Add database config to `config/default.yaml`
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.2.6
|
||||||
|
- **Title**: Add database config to `config/default.yaml`
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.2
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add database config to `config/default.yaml`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add database config to `config/default.yaml`
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.2.6 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.3.1: Install `github.com/prometheus/client_golang/prometheus`
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.3.1
|
||||||
|
- **Title**: Install `github.com/prometheus/client_golang/prometheus`
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.3
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install `github.com/prometheus/client_golang/prometheus`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install `github.com/prometheus/client_golang/prometheus`
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.3.1 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.3.2: Install `github.com/heptiolabs/healthcheck` (optional, or custom)
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.3.2
|
||||||
|
- **Title**: Install `github.com/heptiolabs/healthcheck` (optional, or custom)
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.3
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install `github.com/heptiolabs/healthcheck` (optional, or custom)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install `github.com/heptiolabs/healthcheck` (optional, or custom)
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.3.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
48
stories/phase1/1.3.3-create-pkghealthhealthgo-interface.md
Normal file
48
stories/phase1/1.3.3-create-pkghealthhealthgo-interface.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Task 1.3.3: Create `pkg/health/health.go` interface:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.3.3
|
||||||
|
- **Title**: Create `pkg/health/health.go` interface:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.3
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `pkg/health/health.go` interface:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `pkg/health/health.go` interface:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.3.3 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Code Reference
|
||||||
|
|
||||||
|
```go
|
||||||
|
type HealthChecker interface {
|
||||||
|
Check(ctx context.Context) error
|
||||||
|
}
|
||||||
|
```
|
||||||
40
stories/phase1/1.3.4-implement-internalhealthregistrygo.md
Normal file
40
stories/phase1/1.3.4-implement-internalhealthregistrygo.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.3.4: Implement `internal/health/registry.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.3.4
|
||||||
|
- **Title**: Implement `internal/health/registry.go`:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.3
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Implement `internal/health/registry.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Implement `internal/health/registry.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.3.4 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.3.5-create-internalmetricsmetricsgo.md
Normal file
40
stories/phase1/1.3.5-create-internalmetricsmetricsgo.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.3.5: Create `internal/metrics/metrics.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.3.5
|
||||||
|
- **Title**: Create `internal/metrics/metrics.go`:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.3
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `internal/metrics/metrics.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `internal/metrics/metrics.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.3.5 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.3.6: Add `/metrics` endpoint (Prometheus format)
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.3.6
|
||||||
|
- **Title**: Add `/metrics` endpoint (Prometheus format)
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.3
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add `/metrics` endpoint (Prometheus format)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add `/metrics` endpoint (Prometheus format)
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.3.6 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.3.7: Register endpoints in main HTTP router
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.3.7
|
||||||
|
- **Title**: Register endpoints in main HTTP router
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.3
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Register endpoints in main HTTP router
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Register endpoints in main HTTP router
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.3.7 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# Task 1.4.1: Create `pkg/errorbus/errorbus.go` interface:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.4.1
|
||||||
|
- **Title**: Create `pkg/errorbus/errorbus.go` interface:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.4
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `pkg/errorbus/errorbus.go` interface:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `pkg/errorbus/errorbus.go` interface:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.4.1 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Code Reference
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ErrorPublisher interface {
|
||||||
|
Publish(err error)
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.4.2: Implement `internal/errorbus/channel_bus.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.4.2
|
||||||
|
- **Title**: Implement `internal/errorbus/channel_bus.go`:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.4
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Implement `internal/errorbus/channel_bus.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Implement `internal/errorbus/channel_bus.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.4.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.4.3: Add panic recovery middleware that publishes to error bus
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.4.3
|
||||||
|
- **Title**: Add panic recovery middleware that publishes to error bus
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.4
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add panic recovery middleware that publishes to error bus
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add panic recovery middleware that publishes to error bus
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.4.3 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.4.4-register-error-bus-in-di-container.md
Normal file
40
stories/phase1/1.4.4-register-error-bus-in-di-container.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.4.4: Register error bus in DI container
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.4.4
|
||||||
|
- **Title**: Register error bus in DI container
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.4
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Register error bus in DI container
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Register error bus in DI container
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.4.4 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.5.1-install-githubcomgin-gonicgin.md
Normal file
40
stories/phase1/1.5.1-install-githubcomgin-gonicgin.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.5.1: Install `github.com/gin-gonic/gin`
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.5.1
|
||||||
|
- **Title**: Install `github.com/gin-gonic/gin`
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.5
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install `github.com/gin-gonic/gin`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install `github.com/gin-gonic/gin`
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.5.1 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.5.2-create-internalserverservergo.md
Normal file
40
stories/phase1/1.5.2-create-internalserverservergo.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.5.2: Create `internal/server/server.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.5.2
|
||||||
|
- **Title**: Create `internal/server/server.go`:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.5
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `internal/server/server.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `internal/server/server.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.5.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.5.3-wire-http-server-into-fx-lifecycle.md
Normal file
40
stories/phase1/1.5.3-wire-http-server-into-fx-lifecycle.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.5.3: Wire HTTP server into fx lifecycle:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.5.3
|
||||||
|
- **Title**: Wire HTTP server into fx lifecycle:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.5
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Wire HTTP server into fx lifecycle:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Wire HTTP server into fx lifecycle:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.5.3 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.5.4: Update `cmd/platform/main.go` to use fx lifecycle
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.5.4
|
||||||
|
- **Title**: Update `cmd/platform/main.go` to use fx lifecycle
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.5
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Update `cmd/platform/main.go` to use fx lifecycle
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Update `cmd/platform/main.go` to use fx lifecycle
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.5.4 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.6.1-install-opentelemetry-packages.md
Normal file
40
stories/phase1/1.6.1-install-opentelemetry-packages.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.6.1: Install OpenTelemetry packages:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.6.1
|
||||||
|
- **Title**: Install OpenTelemetry packages:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.6
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install OpenTelemetry packages:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install OpenTelemetry packages:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.6.1 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.6.2-create-internalobservabilitytracergo.md
Normal file
40
stories/phase1/1.6.2-create-internalobservabilitytracergo.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.6.2: Create `internal/observability/tracer.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.6.2
|
||||||
|
- **Title**: Create `internal/observability/tracer.go`:
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.6
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `internal/observability/tracer.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `internal/observability/tracer.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.6.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase1/1.6.3-add-http-instrumentation-middleware.md
Normal file
40
stories/phase1/1.6.3-add-http-instrumentation-middleware.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.6.3: Add HTTP instrumentation middleware
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.6.3
|
||||||
|
- **Title**: Add HTTP instrumentation middleware
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.6
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add HTTP instrumentation middleware
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add HTTP instrumentation middleware
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.6.3 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 1.6.4: Add trace context propagation to requests
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 1.6.4
|
||||||
|
- **Title**: Add trace context propagation to requests
|
||||||
|
- **Phase**: 1 - Core Kernel & Infrastructure
|
||||||
|
- **Section**: 1.6
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add trace context propagation to requests
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add trace context propagation to requests
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 1.6.4 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase2/2.1.1-install-githubcomgolang-jwtjwtv5.md
Normal file
40
stories/phase2/2.1.1-install-githubcomgolang-jwtjwtv5.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 2.1.1: Install `github.com/golang-jwt/jwt/v5`
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 2.1.1
|
||||||
|
- **Title**: Install `github.com/golang-jwt/jwt/v5`
|
||||||
|
- **Phase**: 2 - Authentication & Authorization
|
||||||
|
- **Section**: 2.1
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Install `github.com/golang-jwt/jwt/v5`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Install `github.com/golang-jwt/jwt/v5`
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 2.1.1 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
56
stories/phase2/2.1.2-create-pkgauthauthgo-interfaces.md
Normal file
56
stories/phase2/2.1.2-create-pkgauthauthgo-interfaces.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# Task 2.1.2: Create `pkg/auth/auth.go` interfaces:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 2.1.2
|
||||||
|
- **Title**: Create `pkg/auth/auth.go` interfaces:
|
||||||
|
- **Phase**: 2 - Authentication & Authorization
|
||||||
|
- **Section**: 2.1
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `pkg/auth/auth.go` interfaces:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `pkg/auth/auth.go` interfaces:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 2.1.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Code Reference
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Authenticator interface {
|
||||||
|
GenerateToken(userID string, roles []string, tenantID string) (string, error)
|
||||||
|
VerifyToken(token string) (*TokenClaims, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type TokenClaims struct {
|
||||||
|
UserID string
|
||||||
|
Roles []string
|
||||||
|
TenantID string
|
||||||
|
ExpiresAt time.Time
|
||||||
|
}
|
||||||
|
```
|
||||||
40
stories/phase2/2.1.3-implement-internalauthjwt_authgo.md
Normal file
40
stories/phase2/2.1.3-implement-internalauthjwt_authgo.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 2.1.3: Implement `internal/auth/jwt_auth.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 2.1.3
|
||||||
|
- **Title**: Implement `internal/auth/jwt_auth.go`:
|
||||||
|
- **Phase**: 2 - Authentication & Authorization
|
||||||
|
- **Section**: 2.1
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Implement `internal/auth/jwt_auth.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Implement `internal/auth/jwt_auth.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 2.1.3 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
40
stories/phase2/2.1.4-create-internalauthmiddlewarego.md
Normal file
40
stories/phase2/2.1.4-create-internalauthmiddlewarego.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 2.1.4: Create `internal/auth/middleware.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 2.1.4
|
||||||
|
- **Title**: Create `internal/auth/middleware.go`:
|
||||||
|
- **Phase**: 2 - Authentication & Authorization
|
||||||
|
- **Section**: 2.1
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `internal/auth/middleware.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `internal/auth/middleware.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 2.1.4 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 2.1.5: Add login endpoint: `POST /api/v1/auth/login`
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 2.1.5
|
||||||
|
- **Title**: Add login endpoint: `POST /api/v1/auth/login`
|
||||||
|
- **Phase**: 2 - Authentication & Authorization
|
||||||
|
- **Section**: 2.1
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add login endpoint: `POST /api/v1/auth/login`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add login endpoint: `POST /api/v1/auth/login`
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 2.1.5 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 2.1.6: Add refresh endpoint: `POST /api/v1/auth/refresh`
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 2.1.6
|
||||||
|
- **Title**: Add refresh endpoint: `POST /api/v1/auth/refresh`
|
||||||
|
- **Phase**: 2 - Authentication & Authorization
|
||||||
|
- **Section**: 2.1
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Add refresh endpoint: `POST /api/v1/auth/refresh`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Add refresh endpoint: `POST /api/v1/auth/refresh`
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 2.1.6 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# Task 2.2.1: Create `pkg/identity/identity.go` interfaces:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 2.2.1
|
||||||
|
- **Title**: Create `pkg/identity/identity.go` interfaces:
|
||||||
|
- **Phase**: 2 - Authentication & Authorization
|
||||||
|
- **Section**: 2.2
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Create `pkg/identity/identity.go` interfaces:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Create `pkg/identity/identity.go` interfaces:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 2.2.1 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Code Reference
|
||||||
|
|
||||||
|
```go
|
||||||
|
type UserRepository interface {
|
||||||
|
FindByID(ctx context.Context, id string) (*User, error)
|
||||||
|
FindByEmail(ctx context.Context, email string) (*User, error)
|
||||||
|
Create(ctx context.Context, u *User) error
|
||||||
|
Update(ctx context.Context, u *User) error
|
||||||
|
Delete(ctx context.Context, id string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserService interface {
|
||||||
|
Register(ctx context.Context, email, password string) (*User, error)
|
||||||
|
VerifyEmail(ctx context.Context, token string) error
|
||||||
|
ResetPassword(ctx context.Context, email string) error
|
||||||
|
ChangePassword(ctx context.Context, userID, oldPassword, newPassword string) error
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 2.2.2: Implement `internal/identity/user_repo.go` using Ent:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 2.2.2
|
||||||
|
- **Title**: Implement `internal/identity/user_repo.go` using Ent:
|
||||||
|
- **Phase**: 2 - Authentication & Authorization
|
||||||
|
- **Section**: 2.2
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Implement `internal/identity/user_repo.go` using Ent:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Implement `internal/identity/user_repo.go` using Ent:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 2.2.2 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Task 2.2.3: Implement `internal/identity/user_service.go`:
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- **Task ID**: 2.2.3
|
||||||
|
- **Title**: Implement `internal/identity/user_service.go`:
|
||||||
|
- **Phase**: 2 - Authentication & Authorization
|
||||||
|
- **Section**: 2.2
|
||||||
|
- **Status**: Pending
|
||||||
|
- **Priority**: High
|
||||||
|
- **Estimated Time**: TBD
|
||||||
|
- **Dependencies**: TBD
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Implement `internal/identity/user_service.go`:
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Implement `internal/identity/user_service.go`:
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
1. TODO: Add implementation steps
|
||||||
|
2. TODO: Add implementation steps
|
||||||
|
3. TODO: Add implementation steps
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- [ ] Task 2.2.3 is completed
|
||||||
|
- [ ] All requirements are met
|
||||||
|
- [ ] Code compiles and tests pass
|
||||||
|
|
||||||
|
## Related ADRs
|
||||||
|
- See relevant ADRs in `docs/adr/`
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- TODO: Add implementation notes
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
```bash
|
||||||
|
# TODO: Add test commands
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user