//! Groups: a GitLab-like, single-parent org tree ABOVE apps (Phase 2). //! //! Groups are a pure org / RBAC / UI container — they own no resources //! (scripts/secrets stay app-owned). A `group_admin` on any ancestor is //! implicitly app_admin on every app/subgroup beneath it; resolution //! takes the highest effective role across the app's own membership and //! all ancestor group memberships. //! //! See docs/design/groups-and-project-tool.md §5. use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use crate::GroupId; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Group { pub id: GroupId, /// `None` for a root node. Single-parent keeps the tree acyclic. pub parent_id: Option, /// Instance-global identifier, frozen at creation (a rename/reparent /// never rewrites it — the deployment key stays stable). pub slug: String, pub name: String, pub description: Option, /// Per-subtree structure version, bumped on every structural mutation /// (reparent/rename/delete). Not an authz input. pub structure_version: i64, pub created_at: DateTime, pub updated_at: DateTime, }