Skip to content

refactor: improve database configuration type safety and module organization#240

Merged
josecelano merged 6 commits intomainfrom
refactor-database-config-types
Dec 16, 2025
Merged

refactor: improve database configuration type safety and module organization#240
josecelano merged 6 commits intomainfrom
refactor-database-config-types

Conversation

@josecelano
Copy link
Copy Markdown
Member

Summary

This PR refactors the database configuration structure across the application to improve type safety, eliminate magic strings, and enhance module organization.

Changes

1. Database Configuration Type Extraction

  • Extracted SqliteConfig and MysqlConfig from the DatabaseConfig enum
  • Converted database.rs to database/ folder module with separate driver modules
  • Improved type safety and modularity

2. Infrastructure Layer Improvements

  • Renamed MysqlConfigMysqlSetupConfig in docker_compose context (clearer naming for initialization)
  • Converted docker_compose/context.rs to directory module with submodules:
    • builder.rs - Builder pattern implementation
    • database.rs - Database configuration and constants
    • ports.rs - Port configuration
  • Renamed DockerComposeContextBuilder::with_sqlite()::new() (SQLite is the default)

3. Builder API Enhancements

  • Simplified with_mysql() to accept MysqlSetupConfig struct instead of 5 individual parameters
  • Extracted driver name constants: DRIVER_SQLITE = "sqlite3", DRIVER_MYSQL = "mysql"
  • Eliminated magic strings throughout the codebase

4. Domain Layer Consistency

  • Added driver name constants to domain/tracker/database/mod.rs
  • Updated driver_name() method to use constants
  • Ensures consistency between domain and infrastructure layers

Testing

All pre-commit checks passed:

  • ✅ 1,515 unit tests
  • ✅ 8 E2E integration tests
  • ✅ 373 doctests
  • ✅ Linting (clippy, rustfmt, shellcheck, markdown, yaml, toml, cspell)
  • ✅ E2E infrastructure lifecycle tests
  • ✅ E2E deployment workflow tests

Benefits

  • Type Safety: Stronger typing with dedicated config structs
  • Maintainability: Eliminated magic strings with constants
  • Clarity: Better module organization and clearer naming
  • Consistency: Unified approach across domain and infrastructure layers
  • Usability: Simpler builder API with struct parameters

Migration

No breaking changes for end users. Internal refactoring only.

Extracts database configuration types into standalone structs to enable
code reuse across the application.

Changes:
- Create SqliteConfig struct with database_name field
- Create MysqlConfig struct with host, port, database_name, username, password fields
- Update DatabaseConfig enum to use tuple variants with extracted structs
- Use #[serde(tag = "driver", content = "config")] for proper JSON serialization
- Update all usages across domain, application, and infrastructure layers
- Export new types through domain::tracker and domain::environment modules
- Update all tests to match new JSON structure

JSON format changed from flat to nested structure:
- Old: {"driver": "sqlite3", "database_name": "tracker.db"}
- New: {"driver": "sqlite3", "config": {"database_name": "tracker.db"}}
… modules

Restructured src/domain/tracker/database.rs into a modular folder structure:
- Created database/ directory with mod.rs, sqlite.rs, and mysql.rs
- Extracted SqliteConfig into dedicated sqlite.rs module
- Extracted MysqlConfig into dedicated mysql.rs module
- Maintained DatabaseConfig enum in mod.rs with proper re-exports
- Added module documentation explaining structure and extensibility

This modular structure makes it easier to add new database drivers in the
future by simply adding new modules (e.g., postgres.rs, mongodb.rs).

Changed:
- src/domain/tracker/database.rs → src/domain/tracker/database/mod.rs
- New: src/domain/tracker/database/sqlite.rs (SqliteConfig + tests)
- New: src/domain/tracker/database/mysql.rs (MysqlConfig + tests)
- Tests: Preserved all existing tests distributed across modules
…ntext

Renamed infrastructure::docker_compose::MysqlConfig to MysqlSetupConfig to
clearly distinguish its purpose from the domain MysqlConfig type.

Key distinction:
- Domain MysqlConfig: Used for connecting to existing MySQL database
  * Has user credentials (username, password, host)
  * No root password needed

- Infrastructure MysqlSetupConfig: Used for Docker Compose MySQL initialization
  * Has root password for database creation
  * Creates database, user, and sets permissions
  * No host field (always service name in Docker Compose)

Changes:
- Renamed MysqlConfig → MysqlSetupConfig
- Removed unused from_domain() method and DomainMysqlConfig import
- Updated documentation to explain initialization vs connection distinction
- Removed test for unused from_domain() method
- Updated all references in DatabaseConfig and builder

This makes the code more self-documenting and prevents confusion between
connecting to a database vs initializing a new one.
Renamed the private constructor method for better symmetry and clarity:
- Old: DockerComposeContextBuilder::new(ports)
- New: DockerComposeContextBuilder::with_sqlite(ports)

This provides better symmetry with the with_mysql() method and makes it
more explicit that the builder starts with SQLite configuration by default.

The builder() public method now calls with_sqlite() instead of new().
…lder improvements

- Convert context.rs to directory module (context/mod.rs, builder.rs, database.rs, ports.rs)
- Extract database driver name constants (DRIVER_SQLITE, DRIVER_MYSQL)
- Rename DockerComposeContextBuilder::with_sqlite to ::new for clarity
- Simplify with_mysql to accept MysqlSetupConfig directly instead of 5 parameters
- Add MysqlSetupConfig to public re-exports
- Update all usages across production and test code
@josecelano josecelano self-assigned this Dec 16, 2025
@josecelano
Copy link
Copy Markdown
Member Author

ACK b2bf805

@josecelano josecelano merged commit 803f078 into main Dec 16, 2025
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant