feat(epic1): implement core infrastructure (stories 1.1-1.5)

Implemented Epic 1 core kernel and infrastructure stories:

Story 1.1: Enhanced DI Container
- Added providers for database, health, metrics, and error bus
- Extended CoreModule to include all core services

Story 1.2: Database Layer with Ent ORM
- Created Ent schema for User, Role, Permission, AuditLog entities
- Implemented many-to-many relationships (User-Role, Role-Permission)
- Created database client wrapper with connection pooling
- Added database provider to DI container with migration support

Story 1.3: Health Monitoring and Metrics System
- Implemented health check registry and interface
- Added database health checker
- Created Prometheus metrics system with HTTP instrumentation
- Added health and metrics providers to DI container

Story 1.4: Error Handling and Error Bus
- Implemented channel-based error bus
- Created ErrorPublisher interface
- Added error bus provider with lifecycle management

Story 1.5: HTTP Server Foundation
- Created HTTP server with Gin framework
- Implemented comprehensive middleware stack:
  - Request ID generation
  - Structured logging
  - Panic recovery with error bus integration
  - Prometheus metrics collection
  - CORS support
- Registered core routes: /healthz, /ready, /metrics
- Integrated with FX lifecycle for graceful shutdown

All components are integrated via DI container and ready for use.
This commit is contained in:
2025-11-05 18:11:11 +01:00
parent a38a08ca17
commit 30320304f6
77 changed files with 19409 additions and 30 deletions

View File

@@ -0,0 +1,87 @@
package database
import (
"context"
"database/sql"
"fmt"
"time"
"entgo.io/ent/dialect"
entsql "entgo.io/ent/dialect/sql"
"git.dcentral.systems/toolz/goplt/internal/ent"
_ "github.com/lib/pq" // PostgreSQL driver
)
// Client wraps the Ent client with additional functionality.
type Client struct {
*ent.Client
db *sql.DB
}
// Config holds database configuration.
type Config struct {
DSN string
MaxConnections int
MaxIdleConns int
ConnMaxLifetime time.Duration
ConnMaxIdleTime time.Duration
}
// NewClient creates a new Ent client with connection pooling.
func NewClient(cfg Config) (*Client, error) {
// Open database connection
db, err := sql.Open("postgres", cfg.DSN)
if err != nil {
return nil, fmt.Errorf("failed to open database connection: %w", err)
}
// Configure connection pool
db.SetMaxOpenConns(cfg.MaxConnections)
db.SetMaxIdleConns(cfg.MaxIdleConns)
db.SetConnMaxLifetime(cfg.ConnMaxLifetime)
db.SetConnMaxIdleTime(cfg.ConnMaxIdleTime)
// Test connection
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := db.PingContext(ctx); err != nil {
db.Close()
return nil, fmt.Errorf("failed to ping database: %w", err)
}
// Create Ent driver
drv := entsql.OpenDB(dialect.Postgres, db)
// Create Ent client
entClient := ent.NewClient(ent.Driver(drv))
return &Client{
Client: entClient,
db: db,
}, nil
}
// Close closes the database connection.
func (c *Client) Close() error {
if err := c.Client.Close(); err != nil {
return err
}
return c.db.Close()
}
// Migrate runs database migrations.
func (c *Client) Migrate(ctx context.Context) error {
return c.Client.Schema.Create(ctx)
}
// Ping checks database connectivity.
func (c *Client) Ping(ctx context.Context) error {
return c.db.PingContext(ctx)
}
// DB returns the underlying *sql.DB for advanced operations.
func (c *Client) DB() *sql.DB {
return c.db
}