# Story 1.2: Database Layer with Ent ORM ## Metadata - **Story ID**: 1.2 - **Title**: Database Layer with Ent ORM - **Epic**: 1 - Core Kernel & Infrastructure - **Status**: Completed - **Priority**: High - **Estimated Time**: 6-8 hours - **Dependencies**: 1.1 ## Goal Set up a complete database layer using Ent ORM with core domain entities, migrations, and connection management. ## Description This story implements the complete database layer using Ent ORM. It includes defining core domain entities (User, Role, Permission, AuditLog), setting up migrations, configuring connection pooling, and creating a database client that integrates with the DI container. ## Deliverables ### 1. Ent Schema Initialization - Initialize Ent schema in `internal/ent/` - Set up code generation ### 2. Core Domain Entities (`internal/ent/schema/`) Define core entities: - **User** (`user.go`): ID, email, password_hash, verified, created_at, updated_at - **Role** (`role.go`): ID, name, description, created_at - **Permission** (`permission.go`): ID, name (format: "module.resource.action") - **AuditLog** (`audit_log.go`): ID, actor_id, action, target_id, metadata (JSON), timestamp - **Relationships**: - `role_permissions.go` - Many-to-many between Role and Permission - `user_roles.go` - Many-to-many between User and Role ### 3. Generated Ent Code - Run `go generate ./internal/ent` - Verify generated code compiles - Type-safe database operations ### 4. Database Client (`internal/infra/database/client.go`) - `NewEntClient(dsn string) (*ent.Client, error)` function - Connection pooling configuration: - Max connections - Max idle connections - Connection lifetime - Idle timeout - Migration runner wrapper - Database health check integration - Graceful connection closing ### 5. Database Configuration - Add database config to `config/default.yaml`: - Connection string (DSN) - Connection pool settings - Migration settings - Driver configuration ### 6. DI Integration - Provider function for database client - Register in DI container - Lifecycle management (close on shutdown) ## Implementation Steps 1. **Install Ent** ```bash go get entgo.io/ent/cmd/ent ``` 2. **Initialize Ent Schema** ```bash go run entgo.io/ent/cmd/ent init User Role Permission AuditLog ``` 3. **Define Core Entities** - Create schema files for each entity - Define fields and relationships - Add indexes where needed 4. **Generate Ent Code** ```bash go generate ./internal/ent ``` 5. **Create Database Client** - Create `internal/infra/database/client.go` - Implement connection management - Add migration runner - Add health check 6. **Add Configuration** - Update `config/default.yaml` - Add database configuration section 7. **Integrate with DI** - Create provider function - Register in container - Test connection ## Acceptance Criteria - [x] Ent schema compiles and generates code successfully - [x] Database client connects to PostgreSQL - [x] Core entities can be created and queried - [x] Migrations run successfully on startup - [x] Connection pooling is configured correctly - [x] Database health check works - [x] All entities have proper indexes and relationships - [x] Database client is injectable via DI - [x] Connections are closed gracefully on shutdown ## Related ADRs - [ADR-0013: Database ORM](../../adr/0013-database-orm.md) ## Implementation Notes - Use Ent for type-safe database operations - Configure connection pooling appropriately - Run migrations on application startup - Add proper indexes for performance - Handle database connection errors gracefully - Support for database migrations in future epics ## Testing ```bash # Test Ent schema generation go generate ./internal/ent go build ./internal/ent # Test database connection go test ./internal/infra/database/... # Test migrations go run cmd/platform/main.go ``` ## Files to Create/Modify - `internal/ent/schema/user.go` - User entity - `internal/ent/schema/role.go` - Role entity - `internal/ent/schema/permission.go` - Permission entity - `internal/ent/schema/audit_log.go` - AuditLog entity - `internal/ent/schema/role_permissions.go` - Relationship - `internal/ent/schema/user_roles.go` - Relationship - `internal/infra/database/client.go` - Database client - `internal/di/providers.go` - Add database provider - `config/default.yaml` - Add database config