Skip to main content

backbone_bucket/domain/entity/
file_comment.ext.rs

1//! The extension of `file_comment.rs` (hand-written; ADR-0031).
2
3#[allow(unused_imports)]
4use super::*;
5
6impl FileComment {
7
8    // ==========================================================
9    // DDD Entity Methods
10    // ==========================================================
11
12    /// Check if this is a reply to another comment
13    pub fn is_reply(&self) -> bool {
14        self.parent_id.is_some()
15    }
16
17    /// Check if comment has region annotations
18    pub fn has_annotations(&self) -> bool {
19        self.annotation_region
20            .as_ref()
21            .map(|v| !v.is_null() && v != &serde_json::Value::Object(serde_json::Map::new()))
22            .unwrap_or(false)
23    }
24
25    /// Get reply comments (aggregate pattern - replies loaded separately via repository)
26    pub fn get_replies(&self) -> Vec<FileComment> {
27        Vec::new()
28    }
29
30    /// Mark comment as resolved
31    pub fn resolve(&mut self, by_user_id: Uuid) -> Result<(), CommentError> {
32        if self.resolved {
33            return Err(CommentError::Conflict("Comment is already resolved".to_string()));
34        }
35        self.resolved = true;
36        self.resolved_by = Some(by_user_id);
37        self.resolved_at = Some(Utc::now());
38        self.metadata.touch();
39        Ok(())
40    }
41
42    /// Mark comment as unresolved
43    pub fn unresolve(&mut self) -> Result<(), CommentError> {
44        if !self.resolved {
45            return Err(CommentError::Conflict("Comment is not resolved".to_string()));
46        }
47        self.resolved = false;
48        self.resolved_by = None;
49        self.resolved_at = None;
50        self.metadata.touch();
51        Ok(())
52    }
53
54    /// Count mentioned users
55    pub fn mention_count(&self) -> i32 {
56        self.mentions.len() as i32
57    }
58
59    /// Check all business invariants
60    pub fn check_invariants(&self) -> Result<(), Vec<&'static str>> {
61        let mut errors = Vec::new();
62        if self.content.len() > 10000 {
63            errors.push("content must not exceed 10000 characters");
64        }
65        if self.parent_id == Some(self.id) {
66            errors.push("parent_id must not reference self");
67        }
68        if errors.is_empty() { Ok(()) } else { Err(errors) }
69    }
70}