airs_memspec/models/
workspace.rs

1//! Workspace domain models and functionality
2//!
3//! This module contains data structures and operations related to workspace-level
4//! configuration, shared patterns, context management, and historical snapshots.
5
6use std::collections::HashMap;
7use std::path::PathBuf;
8
9use chrono::{DateTime, Utc};
10use serde::{Deserialize, Serialize};
11
12use super::sub_project::SubProject;
13
14/// Root workspace configuration and metadata
15///
16/// Represents the top-level workspace containing multiple sub-projects,
17/// shared patterns, and workspace-wide configuration.
18#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
19pub struct Workspace {
20    /// Workspace metadata and configuration
21    pub metadata: WorkspaceMetadata,
22
23    /// Shared patterns and architectural decisions
24    pub shared_patterns: SharedPatterns,
25
26    /// Current active context tracking
27    pub current_context: CurrentContext,
28
29    /// Map of sub-project name to sub-project data
30    pub sub_projects: HashMap<String, SubProject>,
31
32    /// Historical context snapshots
33    pub snapshots: Vec<ContextSnapshot>,
34}
35
36/// Workspace-level metadata and configuration
37#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
38pub struct WorkspaceMetadata {
39    /// Workspace name/identifier
40    pub name: String,
41
42    /// Brief description of the workspace purpose
43    pub description: Option<String>,
44
45    /// Workspace creation timestamp
46    pub created_at: DateTime<Utc>,
47
48    /// Last modification timestamp
49    pub updated_at: DateTime<Utc>,
50
51    /// Workspace version for compatibility tracking
52    pub version: String,
53
54    /// Root directory path
55    pub root_path: PathBuf,
56
57    /// Additional metadata fields
58    pub metadata: HashMap<String, String>,
59}
60
61/// Shared patterns and architectural decisions across the workspace
62#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
63pub struct SharedPatterns {
64    /// Core implementation patterns
65    pub implementation_patterns: Vec<Pattern>,
66
67    /// Architecture and design patterns  
68    pub architecture_patterns: Vec<Pattern>,
69
70    /// Methodology and workflow patterns
71    pub methodology_patterns: Vec<Pattern>,
72
73    /// Cross-cutting concerns and shared utilities
74    pub shared_utilities: Vec<SharedUtility>,
75}
76
77/// A documented pattern or practice
78#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
79pub struct Pattern {
80    /// Pattern name/identifier
81    pub name: String,
82
83    /// Detailed pattern description
84    pub description: String,
85
86    /// When to apply this pattern
87    pub usage_context: String,
88
89    /// Code examples or templates
90    pub examples: Vec<String>,
91
92    /// Related patterns or references
93    pub references: Vec<String>,
94
95    /// Pattern category/tags
96    pub tags: Vec<String>,
97}
98
99/// Shared utility or cross-cutting concern
100#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
101pub struct SharedUtility {
102    /// Utility name
103    pub name: String,
104
105    /// Purpose and functionality
106    pub description: String,
107
108    /// Location/path to the utility
109    pub location: String,
110
111    /// API or usage documentation
112    pub usage: String,
113
114    /// Dependencies and requirements
115    pub dependencies: Vec<String>,
116}
117
118/// Current context tracking for active sub-project
119#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
120pub struct CurrentContext {
121    /// Currently active sub-project
122    pub active_sub_project: String,
123
124    /// When context was last switched
125    pub switched_on: DateTime<Utc>,
126
127    /// Who/what triggered the context switch
128    pub switched_by: String,
129
130    /// Current status/phase description
131    pub status: String,
132
133    /// Additional context metadata
134    pub metadata: HashMap<String, String>,
135}
136
137/// Historical context snapshot for restoration and analysis
138#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
139pub struct ContextSnapshot {
140    /// Snapshot creation timestamp
141    pub timestamp: DateTime<Utc>,
142
143    /// Human-readable description
144    pub description: String,
145
146    /// Active sub-project at snapshot time
147    pub active_sub_project: String,
148
149    /// Workspace state at snapshot time
150    pub workspace_state: WorkspaceMetadata,
151
152    /// Sub-project states at snapshot time
153    pub sub_project_states: HashMap<String, SubProject>,
154}
155
156impl Workspace {
157    /// Create a new workspace with default configuration
158    pub fn new(name: String, root_path: PathBuf) -> Self {
159        let now = Utc::now();
160
161        Self {
162            metadata: WorkspaceMetadata {
163                name: name.clone(),
164                description: None,
165                created_at: now,
166                updated_at: now,
167                version: "1.0.0".to_string(),
168                root_path,
169                metadata: HashMap::new(),
170            },
171            shared_patterns: SharedPatterns {
172                implementation_patterns: Vec::new(),
173                architecture_patterns: Vec::new(),
174                methodology_patterns: Vec::new(),
175                shared_utilities: Vec::new(),
176            },
177            current_context: CurrentContext {
178                active_sub_project: String::new(),
179                switched_on: now,
180                switched_by: "system".to_string(),
181                status: "initialized".to_string(),
182                metadata: HashMap::new(),
183            },
184            sub_projects: HashMap::new(),
185            snapshots: Vec::new(),
186        }
187    }
188
189    /// Add a new sub-project to the workspace
190    pub fn add_sub_project(&mut self, name: String, sub_project: SubProject) {
191        self.sub_projects.insert(name, sub_project);
192        self.metadata.updated_at = Utc::now();
193    }
194
195    /// Switch active context to a different sub-project
196    pub fn switch_context(
197        &mut self,
198        sub_project: String,
199        switched_by: String,
200    ) -> Result<(), String> {
201        if !self.sub_projects.contains_key(&sub_project) {
202            return Err(format!("Sub-project '{sub_project}' not found"));
203        }
204
205        self.current_context = CurrentContext {
206            active_sub_project: sub_project,
207            switched_on: Utc::now(),
208            switched_by,
209            status: "active".to_string(),
210            metadata: HashMap::new(),
211        };
212
213        self.metadata.updated_at = Utc::now();
214        Ok(())
215    }
216
217    /// Get the currently active sub-project
218    pub fn get_active_sub_project(&self) -> Option<&SubProject> {
219        if self.current_context.active_sub_project.is_empty() {
220            return None;
221        }
222        self.sub_projects
223            .get(&self.current_context.active_sub_project)
224    }
225
226    /// Create a context snapshot for historical tracking
227    pub fn create_snapshot(&mut self, description: String) {
228        let snapshot = ContextSnapshot {
229            timestamp: Utc::now(),
230            description,
231            active_sub_project: self.current_context.active_sub_project.clone(),
232            workspace_state: self.metadata.clone(),
233            sub_project_states: self.sub_projects.clone(),
234        };
235
236        self.snapshots.push(snapshot);
237        self.metadata.updated_at = Utc::now();
238    }
239}