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//! NotifyFutureResourceUsageChangesUseCase,
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 = Arc::new(
52//! GoogleCalendarUsageRepository::new(
53//! "secrets/service-account.json",
54//! config.clone(),
55//! "data/google_calendar_mappings.json".into(),
56//! )
57//! .await?,
58//! );
59//! // Create identity link repository for Slack user mapping
60//! let identity_repo = Arc::new(JsonFileIdentityLinkRepository::new("data/identity_links.json".into()));
61//! // NotificationRouter automatically supports all configured notification types
62//! // (Slack, Mock, etc.) based on config/resources.toml
63//! let notifier = NotificationRouter::new(config, identity_repo);
64//!
65//! // Create and run use case
66//! let usecase = NotifyFutureResourceUsageChangesUseCase::new(repository, notifier).await?;
67//! usecase.poll_once().await?;
68//! # Ok(())
69//! # }
70//! ```
71//!
72//! ## Device Specification Format
73//!
74//! Calendar event titles support flexible device specification:
75//!
76//! - Single: `0` → Device 0
77//! - Range: `0-2` → Devices 0, 1, 2
78//! - Multiple: `0,2,5` → Devices 0, 2, 5
79//! - Mixed: `0-1,6-7` → Devices 0, 1, 6, 7
80//!
81//! ## Features
82//!
83//! - Google Calendar integration for resource reservations
84//! - Slack notifications for create/update/delete events
85//! - DDD Factory Pattern for device specification parsing
86//! - Mock implementations for testing
87//! - CLI arguments for flexible deployment
88//!
89//! ## Setup
90//!
91//! See the [README](https://github.com/kano-lab/lab-resource-manager) for detailed setup instructions.
92
93// Module declarations
94pub mod application;
95pub mod domain;
96pub mod infrastructure;
97pub mod interface;
98
99/// Commonly used types for building resource management systems
100///
101/// This prelude re-exports the most frequently used types and traits,
102/// allowing users to import everything they need with a single use statement:
103///
104/// ```rust
105/// use lab_resource_manager::prelude::*;
106/// ```
107pub mod prelude {
108 // Use cases
109 pub use crate::application::usecases::NotifyFutureResourceUsageChangesUseCase;
110
111 // Application errors
112 pub use crate::application::error::ApplicationError;
113
114 // Domain types
115 pub use crate::domain::aggregates::resource_usage::{
116 entity::ResourceUsage,
117 errors::ResourceUsageError,
118 factory::{ResourceFactory, ResourceFactoryError},
119 value_objects::{Gpu, Resource, TimePeriod, UsageId},
120 };
121
122 // Ports (traits)
123 pub use crate::domain::ports::{
124 notifier::{NotificationError, NotificationEvent, Notifier},
125 repositories::{RepositoryError, ResourceUsageRepository},
126 };
127
128 // Infrastructure implementations
129 pub use crate::infrastructure::{
130 config::{DeviceConfig, ResourceConfig, RoomConfig, ServerConfig, load_config},
131 notifier::{
132 router::NotificationRouter,
133 senders::{MockSender, SlackSender},
134 },
135 repositories::{
136 identity_link::JsonFileIdentityLinkRepository,
137 resource_usage::{
138 google_calendar::GoogleCalendarUsageRepository, mock::MockUsageRepository,
139 },
140 },
141 };
142}
143
144// Convenience re-exports at crate root
145pub use application::{error::ApplicationError, usecases::NotifyFutureResourceUsageChangesUseCase};
146pub use domain::ports::{
147 notifier::{NotificationError, NotificationEvent, Notifier},
148 repositories::{RepositoryError, ResourceUsageRepository},
149};
150pub use infrastructure::{
151 config::load_config,
152 notifier::{
153 router::NotificationRouter,
154 senders::{MockSender, SlackSender},
155 },
156 repositories::{
157 identity_link::JsonFileIdentityLinkRepository,
158 resource_usage::{
159 google_calendar::GoogleCalendarUsageRepository, mock::MockUsageRepository,
160 },
161 },
162};