Skip to content

[EPIC-4-3] Add YAML configuration system for sync-service#24

Merged
deserat merged 2 commits into
developfrom
feature/EPIC-4-3-sync-config-yaml
Jan 24, 2026
Merged

[EPIC-4-3] Add YAML configuration system for sync-service#24
deserat merged 2 commits into
developfrom
feature/EPIC-4-3-sync-config-yaml

Conversation

@deserat

@deserat deserat commented Jan 23, 2026

Copy link
Copy Markdown
Owner

Summary

Implements YAML-based configuration system for sync-service with four sections: vault (file watching), api (HTTP client), sync (behavior), and logging. Enables flexible deployment configuration without code changes.

Related Issue

Closes #23 (EPIC-4-3)

Changes

  • Added src/config.rs - Configuration module with 4 sub-structs
  • Added config.example.yaml - Comprehensive YAML template with inline docs
  • Added .gitignore - Excludes user-specific config.yaml
  • Added README.md - 545 lines covering all configuration options
  • Added tests/config_test.rs - Integration tests for config loading
  • Modified Cargo.toml - Added shellexpand dependency for ~ path expansion
  • Modified src/lib.rs - Exposed config module
  • Fixed doctest bug in vault/lock.rs (from Issue Vault Directory Structure and Markdown Utilities #12)

Configuration Sections

  1. vault: File watching settings (path, watch_recursive, debounce_ms)
  2. api: HTTP client settings (base_url, timeout_ms, retry_attempts, retry_delay_ms)
  3. sync: Sync behavior (batch_size, sync_interval_ms, ignore_patterns)
  4. logging: Logging settings (level, format, file, max_size_mb, max_backups)

Testing

  • Unit tests pass (4 tests in src/config.rs)
  • Integration tests pass (3 tests in tests/config_test.rs)
  • Coverage >= 80% (config.rs: 98.92%, overall: 84.57%)
  • Manual testing completed (config.example.yaml loads successfully)
  • All quality checks pass (cargo fmt, clippy, check)

Documentation

  • README.md: Comprehensive guide with all options, ranges, defaults
  • config.example.yaml: Development-oriented defaults with inline comments
  • Inline documentation: Doctests for Config::load() and Config::vault_path()
  • Implementation plan: docs/dev/plans/EPIC-4-3-sync-config-yaml.md

Verification Steps

cd sync-service

# Verify config loads successfully
cargo run --example load_config  # (if example exists)
# Or use in tests
cargo test test_load_example_config

# Check coverage
cargo llvm-cov --all-features --workspace --summary-only

# Expected output:
# - config.rs: 98.92% coverage
# - All tests pass

Checklist

  • Code follows sync-service conventions (Rust patterns)
  • sync-service/AGENTS.md reviewed for context
  • Documentation updated (README.md, config.example.yaml)
  • No secrets or sensitive data committed
  • .gitignore excludes user-specific config.yaml
  • shellexpand dependency added for path expansion

- What: Created YAML-based configuration with 4 sections (vault, api, sync, logging)
- Why: Enables flexible deployment configuration without code changes (Issue #23)
- How: serde_yaml for deserialization, shellexpand for ~ path expansion

Acceptance criteria addressed:
- [x] Config struct with VaultConfig, ApiConfig, SyncConfig, LoggingConfig
- [x] Config::load() method reads and parses YAML files
- [x] Config::vault_path() expands ~ to home directory
- [x] config.example.yaml template with inline documentation
- [x] .gitignore excludes user-specific config.yaml
- [x] README.md with comprehensive configuration guide
- [x] Dependencies: serde_yaml (existing), shellexpand 3.1.1 (new)

Testing:
- Unit tests for config deserialization (4 tests in src/config.rs)
- Integration tests for file loading (3 tests in tests/config_test.rs)
- Coverage: config.rs 98.92%, overall 84.57% (target: 80%+)

Documentation:
- README.md: 545 lines covering all config options, ranges, defaults
- config.example.yaml: 207 lines with development-oriented defaults
- Inline docs: doctests for Config::load() and Config::vault_path()

Additional fixes:
- Fixed doctest bug in vault/lock.rs (Issue #12 code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@github-actions github-actions Bot added service/sync-service File watching Rust service service/docs Documentation only labels Jan 23, 2026
@deserat

deserat commented Jan 24, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive YAML-based configuration system for the sync-service, which is a great step towards flexible deployment. The changes include the configuration module itself, an example configuration file, extensive documentation in the README, and thorough unit and integration tests.

My review has identified a couple of areas for improvement:

  • In src/config.rs, using enums for logging level and format would improve type safety and configuration validation.
  • The .gitignore file should be updated to exclude generated code coverage reports like lcov.info.

Overall, this is a very well-executed feature with excellent documentation and testing. The implementation plan is also very detailed. Great work!

Comment thread sync-service/.gitignore

# Local environment variables
.env
.env.local

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Code coverage reports like lcov.info are generated artifacts and should not be committed to version control. It's a good practice to add a section for them in .gitignore to keep the repository clean.

.env.local

# Coverage reports
lcov.info
*.lcov
/target/llvm-cov/

Comment thread sync-service/src/config.rs Outdated
Comment on lines +59 to +61
pub level: String,
/// Log format: text (human-readable) or json (structured)
pub format: String,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using String for level and format is flexible but error-prone. A typo in config.yaml (e.g., "inf" instead of "info") would not be caught at deserialization time and could lead to unexpected logging behavior.

To improve robustness and provide immediate feedback on invalid configuration, I recommend using enums for these fields. This allows serde to validate the values when parsing the YAML file.

You can define the enums like this, for example above the LoggingConfig struct:

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum LogLevel {
    Trace,
    Debug,
    Info,
    Warn,
    Error,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum LogFormat {
    Text,
    Json,
}

Then, you can update LoggingConfig to use them.

Suggested change
pub level: String,
/// Log format: text (human-readable) or json (structured)
pub format: String,
pub level: LogLevel,
/// Log format: text (human-readable) or json (structured)
pub format: LogFormat,

- Add LogLevel and LogFormat enums for type-safe config (addresses @gemini-code-assist comment)
  * Validates log level/format at deserialization time
  * Prevents typos in config.yaml (e.g., 'inf' instead of 'info')
  * Uses serde(rename_all = lowercase) for YAML compatibility

- Add coverage reports to .gitignore (addresses @gemini-code-assist comment)
  * Exclude lcov.info and *.lcov files
  * Exclude /target/llvm-cov/ directory
  * Remove lcov.info from git tracking

Testing:
- Added test_invalid_log_level() - verifies invalid level rejected
- Added test_invalid_log_format() - verifies invalid format rejected
- Updated all tests to use enum variants (LogLevel::Info, LogFormat::Text)
- All 42 tests pass (40 unit + 2 integration)
- Coverage maintained: config.rs still at 98%+

Quality checks:
- cargo fmt: ✓ passed
- cargo clippy: ✓ passed (no warnings)
- cargo check: ✓ passed

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@deserat

deserat commented Jan 24, 2026

Copy link
Copy Markdown
Owner Author

Review Comments Addressed

Thank you @gemini-code-assist for the thorough review! I've addressed both comments:

✅ Comment 1: Coverage Reports in .gitignore

Fixed: Added coverage section to .gitignore

# Coverage reports
lcov.info
*.lcov
/target/llvm-cov/
  • Removed lcov.info from git tracking
  • Coverage artifacts now properly excluded

✅ Comment 2: Type-Safe Enums for LoggingConfig

Fixed: Replaced String types with enums for level and format

New enums:

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum LogLevel {
    Trace,
    Debug,
    Info,
    Warn,
    Error,
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum LogFormat {
    Text,
    Json,
}

Benefits:

  • ✅ Invalid values (e.g., "inf" instead of "info") now caught at deserialization time
  • ✅ Type safety prevents runtime errors
  • ✅ IDE autocomplete for valid values
  • ✅ Clear error messages when config is invalid

Testing:

  • Added test_invalid_log_level() - verifies typos are rejected
  • Added test_invalid_log_format() - verifies invalid formats are rejected
  • Updated all existing tests to use enum variants
  • All 42 tests passing ✓

Quality Checks:

  • cargo fmt: ✓ Passed
  • cargo clippy: ✓ Passed (no warnings)
  • cargo check: ✓ Passed
  • Coverage maintained: config.rs still 98%+

Commit: a043ba1
Branch: feature/EPIC-4-3-sync-config-yaml

Ready for re-review! 🚀

@gemini-code-assist

Copy link
Copy Markdown

Thank you, @deserat, for the detailed update and for addressing the feedback from the previous review! I appreciate you taking the time to implement these changes.

I'm particularly pleased to see the implementation of type-safe enums (LogLevel and LogFormat) for the LoggingConfig. This is a significant improvement for correctness and maintainability, as it prevents invalid values at deserialization time and enhances clarity, as you've rightly pointed out. The addition of tests for invalid log levels and formats is also excellent.

I've noted the update to the .gitignore as well, which correctly excludes coverage reports.

I will now proceed with a re-review of the pull request to verify these changes and ensure everything is in order. Great work! 🚀

@deserat deserat merged commit 0a10060 into develop Jan 24, 2026
1 check passed
@deserat deserat deleted the feature/EPIC-4-3-sync-config-yaml branch January 24, 2026 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

service/docs Documentation only service/sync-service File watching Rust service

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant