feat: wire relay API with dependency injection

- split settings module into per-struct files
- add DatabaseSettings with default in-memory SQLite path
- implement RelayApi struct with GET /relays and POST
  /relays/{id}/toggle
- wire create_relay_controller and create_label_repository into
  Application::build() with mock/real selection via cfg!(test) || CI
- register RelayApi in OpenApiService alongside existing APIs
This commit is contained in:
2026-03-04 12:47:21 +01:00
parent fd00d1925b
commit 2eebc52f17
30 changed files with 1170 additions and 670 deletions
@@ -12,11 +12,13 @@
#[cfg(test)]
mod relay_label_repository_contract_tests {
use crate::{domain::relay::{
repository::RelayLabelRepository,
types::{RelayId, RelayLabel},
}, infrastructure::persistence::label_repository::MockRelayLabelRepository};
use crate::{
domain::relay::{
repository::RelayLabelRepository,
types::{RelayId, RelayLabel},
},
infrastructure::persistence::label_repository::MockRelayLabelRepository,
};
#[tokio::test]
pub async fn test_get_label_returns_none_for_non_existent_relay() {
@@ -75,7 +77,6 @@ mod relay_label_repository_contract_tests {
);
}
#[tokio::test]
pub async fn test_save_label_succeeds() {
let repo = MockRelayLabelRepository::new();
@@ -179,7 +180,6 @@ mod relay_label_repository_contract_tests {
assert_eq!(retrieved.unwrap().as_str(), "X", "Label should match");
}
#[tokio::test]
pub async fn test_delete_label_succeeds_for_existing_label() {
let repo = MockRelayLabelRepository::new();
@@ -265,7 +265,6 @@ mod relay_label_repository_contract_tests {
);
}
#[tokio::test]
pub async fn test_get_all_labels_returns_empty_when_no_labels() {
let repo = MockRelayLabelRepository::new();