diff --git a/README.md b/README.md index f926133..36f9fd0 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This document serves as the master index for the SCADA system design. The system | # | Component | Document | Description | |---|-----------|----------|-------------| -| 1 | Template Engine | [docs/requirements/Component-TemplateEngine.md](docs/requirements/Component-TemplateEngine.md) | Template modeling, inheritance, composition, path-qualified member addressing, override granularity, locking, alarms, flattening, semantic validation, revision hashing, and diff calculation. | +| 1 | Template Engine | [docs/requirements/Component-TemplateEngine.md](docs/requirements/Component-TemplateEngine.md) | Template modeling, inheritance, composition, path-qualified member addressing, override granularity, locking, alarms, flattening, semantic validation, revision hashing, diff calculation, and folder organization (nested folders, drag-drop). | | 2 | Deployment Manager | [docs/requirements/Component-DeploymentManager.md](docs/requirements/Component-DeploymentManager.md) | Central-side deployment pipeline with deployment ID/idempotency, per-instance operation lock, state transition matrix, all-or-nothing site apply, system-wide artifact deployment with per-site status. | | 3 | Site Runtime | [docs/requirements/Component-SiteRuntime.md](docs/requirements/Component-SiteRuntime.md) | Site-side actor hierarchy with explicit supervision strategies, staggered startup, script trust model (constrained APIs), Tell/Ask conventions, concurrency serialization, and site-wide Akka stream with per-subscriber backpressure. | | 4 | Data Connection Layer | [docs/requirements/Component-DataConnectionLayer.md](docs/requirements/Component-DataConnectionLayer.md) | Common data connection interface (OPC UA, custom), Become/Stash connection actor model, auto-reconnect, immediate bad quality on disconnect, transparent re-subscribe, synchronous write failures, tag path resolution retry. | diff --git a/docs/requirements/Component-CentralUI.md b/docs/requirements/Component-CentralUI.md index 469f203..6a6d872 100644 --- a/docs/requirements/Component-CentralUI.md +++ b/docs/requirements/Component-CentralUI.md @@ -37,6 +37,9 @@ Central cluster only. Sites have no user interface. ## Workflows / Pages ### Template Authoring (Design Role) +- The `/design/templates` page uses a **split-pane layout**: a folder/template tree sidebar on the left and the editor on the right. +- The tree shows nested `TemplateFolder` entities with their templates underneath; composition children render inline as leaf nodes beneath their owning template (right-click "Open composed template" reveals and selects the target). +- **Per-kind context menus** on folder, template, and composition nodes expose the relevant operations (new folder, new template, rename, move, delete, move to folder). Native HTML5 **drag-drop** reorganizes templates between folders and reparents folders, with cycle detection rejected via toast on drop. Tree expansion state persists in `sessionStorage`, and deep links (`/design/templates/{id}`) reveal and select the target node. - Create, edit, and delete templates. - **Template deletion** is blocked if any instances or child templates reference the template. The UI displays the references preventing deletion. - Manage template hierarchy (inheritance) — visual tree of parent/child relationships. diff --git a/docs/requirements/Component-ConfigurationDatabase.md b/docs/requirements/Component-ConfigurationDatabase.md index ddc16b0..dada6b0 100644 --- a/docs/requirements/Component-ConfigurationDatabase.md +++ b/docs/requirements/Component-ConfigurationDatabase.md @@ -28,7 +28,8 @@ Central cluster only. Site clusters do not access the configuration database — The configuration database stores all central system data, organized by domain area: ### Template & Modeling -- **Templates**: Template definitions (name, parent template reference, description). +- **Templates**: Template definitions (name, parent template reference, description, nullable `FolderId` FK to `TemplateFolders` — null means the template lives at the tree root). +- **TemplateFolders**: Hierarchical organizational folders for templates (`Id`, `Name`, nullable `ParentFolderId` self-reference, `SortOrder`). Unique index on `(ParentFolderId, Name)` enforces case-insensitive sibling uniqueness. Folders are UI-only — they have no effect on template resolution or flattening. - **Template Attributes**: Attribute definitions per template (name, value, data type, lock flag, description, data source reference). - **Template Alarms**: Alarm definitions per template (name, description, priority, lock flag, trigger type, trigger configuration, on-trigger script reference). - **Template Scripts**: Script definitions per template (name, lock flag, C# source code, trigger type, trigger configuration, minimum time between runs, parameter definitions, return value definitions). diff --git a/docs/requirements/Component-ManagementService.md b/docs/requirements/Component-ManagementService.md index 20f5594..a1ddffc 100644 --- a/docs/requirements/Component-ManagementService.md +++ b/docs/requirements/Component-ManagementService.md @@ -83,6 +83,15 @@ The endpoint performs LDAP authentication and role resolution server-side, colla - **ValidateTemplate**: Run on-demand pre-deployment validation (flattening, naming collisions, script compilation). - **GetTemplateDiff**: Compare deployed vs. template-derived configuration for an instance. +### Template Folders + +- **ListTemplateFolders**: List all template folders (read-only; any authenticated user). +- **CreateTemplateFolder** (`Name`, `ParentFolderId?`): Create a folder, optionally nested under a parent (Design role). +- **RenameTemplateFolder** (`FolderId`, `NewName`): Rename a folder; enforces sibling uniqueness (Design role). +- **MoveTemplateFolder** (`FolderId`, `NewParentFolderId?`): Move a folder to a new parent (or root); rejects cycles (Design role). +- **DeleteTemplateFolder** (`FolderId`): Delete a folder; blocked if the folder contains any subfolders or templates (Design role). +- **MoveTemplateToFolder** (`TemplateId`, `NewFolderId?`): Move a template into a folder, or to the root when null (Design role). + ### Template Members - **AddTemplateAttribute** / **UpdateTemplateAttribute** / **DeleteTemplateAttribute**: Manage attributes on a template. diff --git a/docs/requirements/Component-TemplateEngine.md b/docs/requirements/Component-TemplateEngine.md index 90758c7..b4d586b 100644 --- a/docs/requirements/Component-TemplateEngine.md +++ b/docs/requirements/Component-TemplateEngine.md @@ -23,6 +23,7 @@ Central cluster only. Sites receive flattened output and have no awareness of te - Perform comprehensive pre-deployment validation (see Validation section). - Provide on-demand validation for Design users during template authoring. - Enforce template deletion constraints — templates cannot be deleted if any instances or child templates reference them. +- Organize templates into nested folders (`TemplateFolder` entity) and validate folder hierarchy invariants (acyclicity, sibling uniqueness, non-empty-on-delete). ## Key Entities @@ -33,6 +34,14 @@ Central cluster only. Sites receive flattened output and have no awareness of te - Defines attributes, alarms, and scripts as first-class members. - Cannot be deleted if referenced by instances or child templates. - Concurrent editing uses **last-write-wins** — no pessimistic locking or conflict detection. +- May belong to a `TemplateFolder` via nullable `FolderId`, or live at the tree root when null. + +### TemplateFolder +- Hierarchical organizational entity with a self-referencing `ParentFolderId` (null at the root). +- Sibling folder names are unique (case-insensitive) within the same parent. +- Folders carry **no semantic meaning** for template resolution, flattening, validation, or inheritance — they exist purely for UI organization. +- Folder deletion is blocked if the folder contains any subfolders or templates. +- The folder graph is enforced acyclic on move (a folder cannot become its own descendant). ### Attribute - Name, Value, Data Type (Boolean, Integer, Float, String), Lock Flag, Description.