lab_resource_manager/
lib.rs

1//! # lab-resource-manager
2//!
3//! GPU and room resource management system with Google Calendar and Slack integration.
4//!
5//! This crate provides a resource management system designed for research labs,
6//! tracking GPU servers and meeting room reservations through Google Calendar
7//! and sending notifications via Slack.
8//!
9//! ## Architecture
10//!
11//! Built with Clean Architecture (DDD + Hexagonal Architecture):
12//!
13//! - **Domain Layer**: Core business logic, aggregates, and value objects
14//! - **Application Layer**: Use cases that orchestrate domain logic
15//! - **Infrastructure Layer**: External system integrations (Google Calendar, Slack)
16//!
17//! ## Usage as a Binary
18//!
19//! The primary use case is running the watcher service:
20//!
21//! ```bash
22//! # Run with Google Calendar and Slack
23//! cargo run --bin watcher
24//!
25//! # Run with mock implementations for testing
26//! cargo run --bin watcher --notifier mock --repository mock
27//!
28//! # Customize polling interval (default: 60 seconds)
29//! cargo run --bin watcher --interval 30
30//! ```
31//!
32//! ## Usage as a Library
33//!
34//! You can also use this crate as a library to build custom resource management systems:
35//!
36//! ```rust,no_run
37//! use lab_resource_manager::{
38//!     NotifyResourceUsageChangesUseCase,
39//!     GoogleCalendarUsageRepository,
40//!     NotificationRouter,
41//!     JsonFileIdentityLinkRepository,
42//!     load_config,
43//! };
44//! use std::sync::Arc;
45//!
46//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
47//! // Load configuration
48//! let config = load_config("config/resources.toml")?;
49//!
50//! // Create repository and notifier
51//! let repository = GoogleCalendarUsageRepository::new(
52//!     "secrets/service-account.json",
53//!     config.clone(),
54//! ).await?;
55//! // Create identity link repository for Slack user mapping
56//! let identity_repo = Arc::new(JsonFileIdentityLinkRepository::new("data/identity_links.json".into()));
57//! // NotificationRouter automatically supports all configured notification types
58//! // (Slack, Mock, etc.) based on config/resources.toml
59//! let notifier = NotificationRouter::new(config, identity_repo);
60//!
61//! // Create and run use case
62//! let usecase = NotifyResourceUsageChangesUseCase::new(repository, notifier).await?;
63//! usecase.poll_once().await?;
64//! # Ok(())
65//! # }
66//! ```
67//!
68//! ## Device Specification Format
69//!
70//! Calendar event titles support flexible device specification:
71//!
72//! - Single: `0` → Device 0
73//! - Range: `0-2` → Devices 0, 1, 2
74//! - Multiple: `0,2,5` → Devices 0, 2, 5
75//! - Mixed: `0-1,6-7` → Devices 0, 1, 6, 7
76//!
77//! ## Features
78//!
79//! - Google Calendar integration for resource reservations
80//! - Slack notifications for create/update/delete events
81//! - DDD Factory Pattern for device specification parsing
82//! - Mock implementations for testing
83//! - CLI arguments for flexible deployment
84//!
85//! ## Setup
86//!
87//! See the [README](https://github.com/kano-lab/lab-resource-manager) for detailed setup instructions.
88
89// Module declarations
90pub mod application;
91pub mod domain;
92pub mod infrastructure;
93pub mod interface;
94
95/// Commonly used types for building resource management systems
96///
97/// This prelude re-exports the most frequently used types and traits,
98/// allowing users to import everything they need with a single use statement:
99///
100/// ```rust
101/// use lab_resource_manager::prelude::*;
102/// ```
103pub mod prelude {
104    // Use cases
105    pub use crate::application::usecases::NotifyResourceUsageChangesUseCase;
106
107    // Application errors
108    pub use crate::application::error::ApplicationError;
109
110    // Domain types
111    pub use crate::domain::aggregates::resource_usage::{
112        entity::ResourceUsage,
113        errors::ResourceUsageError,
114        factory::{ResourceFactory, ResourceFactoryError},
115        value_objects::{Gpu, Resource, TimePeriod, UsageId},
116    };
117
118    // Ports (traits)
119    pub use crate::domain::ports::{
120        notifier::{NotificationError, NotificationEvent, Notifier},
121        repositories::{RepositoryError, ResourceUsageRepository},
122    };
123
124    // Infrastructure implementations
125    pub use crate::infrastructure::{
126        config::{DeviceConfig, ResourceConfig, RoomConfig, ServerConfig, load_config},
127        notifier::{
128            router::NotificationRouter,
129            senders::{MockSender, SlackSender},
130        },
131        repositories::{
132            identity_link::JsonFileIdentityLinkRepository,
133            resource_usage::{
134                google_calendar::GoogleCalendarUsageRepository, mock::MockUsageRepository,
135            },
136        },
137    };
138}
139
140// Convenience re-exports at crate root
141pub use application::{error::ApplicationError, usecases::NotifyResourceUsageChangesUseCase};
142pub use domain::ports::{
143    notifier::{NotificationError, NotificationEvent, Notifier},
144    repositories::{RepositoryError, ResourceUsageRepository},
145};
146pub use infrastructure::{
147    config::load_config,
148    notifier::{
149        router::NotificationRouter,
150        senders::{MockSender, SlackSender},
151    },
152    repositories::{
153        identity_link::JsonFileIdentityLinkRepository,
154        resource_usage::{
155            google_calendar::GoogleCalendarUsageRepository, mock::MockUsageRepository,
156        },
157    },
158};