issues-fs 0.3.0__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. issues_fs/issues/Issue__Path__Config.py +25 -0
  2. issues_fs/issues/__init__.py +3 -0
  3. issues_fs/issues/graph_services/Comments__Service.py +235 -0
  4. issues_fs/issues/graph_services/Graph__Repository.py +307 -0
  5. issues_fs/issues/graph_services/Graph__Repository__Factory.py +106 -0
  6. issues_fs/issues/graph_services/Link__Service.py +227 -0
  7. issues_fs/issues/graph_services/Node__Service.py +392 -0
  8. issues_fs/issues/graph_services/Type__Service.py +209 -0
  9. issues_fs/issues/graph_services/__init__.py +3 -0
  10. issues_fs/issues/phase_1/Issue__Children__Service.py +340 -0
  11. issues_fs/issues/phase_1/Root__Issue__Service.py +137 -0
  12. issues_fs/issues/phase_1/Root__Selection__Service.py +310 -0
  13. issues_fs/issues/phase_1/__init__.py +3 -0
  14. issues_fs/issues/status/Git__Status__Service.py +115 -0
  15. issues_fs/issues/status/Index__Status__Service.py +131 -0
  16. issues_fs/issues/status/Server__Status__Service.py +113 -0
  17. issues_fs/issues/status/Storage__Status__Service.py +75 -0
  18. issues_fs/issues/status/Types__Status__Service.py +75 -0
  19. issues_fs/issues/status/__init__.py +3 -0
  20. issues_fs/issues/storage/Path__Handler__Graph_Node.py +185 -0
  21. issues_fs/issues/storage/Path__Handler__Issues.py +57 -0
  22. issues_fs/issues/storage/__init__.py +3 -0
  23. issues_fs/schemas/__init__.py +0 -0
  24. issues_fs/schemas/enums/Enum__Comment__Author.py +10 -0
  25. issues_fs/schemas/enums/Enum__Graph__Storage__Backend.py +8 -0
  26. issues_fs/schemas/enums/Enum__Issue__Status.py +13 -0
  27. issues_fs/schemas/enums/__init__.py +3 -0
  28. issues_fs/schemas/graph/Safe_Str__Graph_Types.py +63 -0
  29. issues_fs/schemas/graph/Schema__Global__Index.py +16 -0
  30. issues_fs/schemas/graph/Schema__Graph__Link.py +8 -0
  31. issues_fs/schemas/graph/Schema__Graph__Node.py +10 -0
  32. issues_fs/schemas/graph/Schema__Graph__Response.py +21 -0
  33. issues_fs/schemas/graph/Schema__Link__Create__Request.py +12 -0
  34. issues_fs/schemas/graph/Schema__Link__Create__Response.py +15 -0
  35. issues_fs/schemas/graph/Schema__Link__Delete__Response.py +16 -0
  36. issues_fs/schemas/graph/Schema__Link__List__Response.py +15 -0
  37. issues_fs/schemas/graph/Schema__Link__Type.py +20 -0
  38. issues_fs/schemas/graph/Schema__Node.py +43 -0
  39. issues_fs/schemas/graph/Schema__Node__Create__Request.py +19 -0
  40. issues_fs/schemas/graph/Schema__Node__Create__Response.py +14 -0
  41. issues_fs/schemas/graph/Schema__Node__Delete__Response.py +15 -0
  42. issues_fs/schemas/graph/Schema__Node__Link.py +17 -0
  43. issues_fs/schemas/graph/Schema__Node__List__Response.py +16 -0
  44. issues_fs/schemas/graph/Schema__Node__Summary.py +15 -0
  45. issues_fs/schemas/graph/Schema__Node__Type.py +28 -0
  46. issues_fs/schemas/graph/Schema__Node__Update__Request.py +18 -0
  47. issues_fs/schemas/graph/Schema__Node__Update__Response.py +14 -0
  48. issues_fs/schemas/graph/Schema__Property__Definition.py +27 -0
  49. issues_fs/schemas/graph/Schema__Type__Index.py +16 -0
  50. issues_fs/schemas/graph/Schema__Type__Summary.py +13 -0
  51. issues_fs/schemas/graph/__init__.py +0 -0
  52. issues_fs/schemas/identifiers/Comment_Id.py +5 -0
  53. issues_fs/schemas/identifiers/Issue_Id.py +13 -0
  54. issues_fs/schemas/identifiers/__init__.py +0 -0
  55. issues_fs/schemas/issues/Schema__Comment.py +61 -0
  56. issues_fs/schemas/issues/__init__.py +0 -0
  57. issues_fs/schemas/issues/phase_1/Schema__Issue__Children.py +85 -0
  58. issues_fs/schemas/issues/phase_1/Schema__Root.py +60 -0
  59. issues_fs/schemas/issues/phase_1/__init__.py +0 -0
  60. issues_fs/schemas/safe_str/Safe_Str__Hex_Color.py +10 -0
  61. issues_fs/schemas/safe_str/Safe_Str__Issue_Id.py +14 -0
  62. issues_fs/schemas/safe_str/Safe_Str__Issue__Node__Description.py +15 -0
  63. issues_fs/schemas/safe_str/Safe_Str__Label_Name.py +9 -0
  64. issues_fs/schemas/safe_str/__init__.py +0 -0
  65. issues_fs/schemas/status/Schema__API__Info.py +15 -0
  66. issues_fs/schemas/status/Schema__Git__Status.py +21 -0
  67. issues_fs/schemas/status/Schema__Index__Status.py +22 -0
  68. issues_fs/schemas/status/Schema__Server__Status.py +28 -0
  69. issues_fs/schemas/status/Schema__Storage__Status.py +23 -0
  70. issues_fs/schemas/status/Schema__Types__Status.py +30 -0
  71. issues_fs/schemas/status/__init__.py +0 -0
  72. issues_fs/version +1 -1
  73. {issues_fs-0.3.0.dist-info → issues_fs-0.4.0.dist-info}/METADATA +2 -1
  74. issues_fs-0.4.0.dist-info/RECORD +79 -0
  75. issues_fs-0.3.0.dist-info/RECORD +0 -8
  76. {issues_fs-0.3.0.dist-info → issues_fs-0.4.0.dist-info}/LICENSE +0 -0
  77. {issues_fs-0.3.0.dist-info → issues_fs-0.4.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,16 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Global__Index - Global index for entire graph
3
+ # Stored at .issues/_index.json - tracks total nodes and per-type counts
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from typing import List
7
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
8
+ from osbot_utils.type_safe.primitives.core.Safe_UInt import Safe_UInt
9
+ from osbot_utils.type_safe.primitives.domains.identifiers.safe_int.Timestamp_Now import Timestamp_Now
10
+ from issues_fs.schemas.graph.Schema__Type__Summary import Schema__Type__Summary
11
+
12
+
13
+ class Schema__Global__Index(Type_Safe): # Global index file (.issues/_index.json)
14
+ total_nodes : Safe_UInt = Safe_UInt(0) # Total nodes across all types
15
+ last_updated : Timestamp_Now = None # ISO timestamp of last update
16
+ type_counts : List[Schema__Type__Summary] # Count per type
@@ -0,0 +1,8 @@
1
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
2
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Label, Safe_Str__Link_Verb
3
+
4
+ # todo, see if we shouldn't call 'link_type' 'link_verb'
5
+ class Schema__Graph__Link(Type_Safe): # Link for graph response
6
+ source : Safe_Str__Node_Label
7
+ target : Safe_Str__Node_Label
8
+ link_type : Safe_Str__Link_Verb # verb like "has-task", "blocks"
@@ -0,0 +1,10 @@
1
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
2
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
3
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Type, Safe_Str__Node_Label, Safe_Str__Status
4
+
5
+
6
+ class Schema__Graph__Node(Type_Safe): # Node summary for graph response
7
+ label : Safe_Str__Node_Label
8
+ title : Safe_Str__Text
9
+ node_type : Safe_Str__Node_Type
10
+ status : Safe_Str__Status
@@ -0,0 +1,21 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Graph__Response - Response types for graph traversal API
3
+ # Used by GET /nodes/api/nodes/{type}/{label}/graph endpoint
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+ from typing import List
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.core.Safe_UInt import Safe_UInt
8
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
9
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Label
10
+ from issues_fs.schemas.graph.Schema__Graph__Link import Schema__Graph__Link
11
+ from issues_fs.schemas.graph.Schema__Graph__Node import Schema__Graph__Node
12
+
13
+
14
+
15
+ class Schema__Graph__Response(Type_Safe): # Full graph traversal response
16
+ success : bool = False
17
+ root : Safe_Str__Node_Label = None
18
+ nodes : List[Schema__Graph__Node] = None
19
+ links : List[Schema__Graph__Link] = None
20
+ depth : Safe_UInt = 0
21
+ message : Safe_Str__Text = ''
@@ -0,0 +1,12 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Link__Create__Request - Request body for creating a link between nodes
3
+ # POST /api/nodes/{label}/links
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Link_Verb, Safe_Str__Node_Label
8
+
9
+
10
+ class Schema__Link__Create__Request(Type_Safe): # Create link request
11
+ verb : Safe_Str__Link_Verb # Required: "blocks", "has-task"
12
+ target_label : Safe_Str__Node_Label # Required: target node label
@@ -0,0 +1,15 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Link__Create__Response - Response body after creating a link
3
+ # Contains both the forward and inverse links created
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
8
+ from issues_fs.schemas.graph.Schema__Node__Link import Schema__Node__Link
9
+
10
+
11
+ class Schema__Link__Create__Response(Type_Safe): # Create link response
12
+ success : bool = False # Operation success
13
+ source_link : Schema__Node__Link = None # Link added to source node
14
+ target_link : Schema__Node__Link = None # Inverse link added to target
15
+ message : Safe_Str__Text = '' # Error message if failed
@@ -0,0 +1,16 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Link__Delete__Response - Response body after deleting a link
3
+ # DELETE /api/nodes/{label}/links/{target_label}
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
8
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Label
9
+
10
+
11
+ class Schema__Link__Delete__Response(Type_Safe): # Delete link response
12
+ success : bool = False # Operation success
13
+ deleted : bool = False # Whether link was deleted
14
+ source_label : Safe_Str__Node_Label = '' # Source node label
15
+ target_label : Safe_Str__Node_Label = '' # Target node label
16
+ message : Safe_Str__Text = '' # Error message if failed
@@ -0,0 +1,15 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Link__List__Response - Response body for listing links from a node
3
+ # GET /api/nodes/{label}/links
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from typing import List
7
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
8
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
9
+ from issues_fs.schemas.graph.Schema__Node__Link import Schema__Node__Link
10
+
11
+
12
+ class Schema__Link__List__Response(Type_Safe): # List links response
13
+ success : bool = False # Operation success
14
+ links : List[Schema__Node__Link] # Links from node
15
+ message : Safe_Str__Text = '' # Error message if failed
@@ -0,0 +1,20 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Link__Type - Definition of a relationship type (blocks, has-task, etc.)
3
+ # Link types define the semantics of relationships between nodes
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from typing import List
7
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
8
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
9
+ from osbot_utils.type_safe.primitives.domains.identifiers.Obj_Id import Obj_Id
10
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Link_Verb, Safe_Str__Node_Type
11
+
12
+ # todo: set link_type_id to Issue__Link_Type__Id (or Issue__Link__Type__Id)
13
+ class Schema__Link__Type(Type_Safe): # Link type definition
14
+ link_type_id : Obj_Id # Unique identifier
15
+ verb : Safe_Str__Link_Verb # "blocks", "has-task"
16
+ inverse_verb : Safe_Str__Link_Verb # "blocked-by", "task-of"
17
+ description : Safe_Str__Text # What this relationship means
18
+
19
+ source_types : List[Safe_Str__Node_Type] # Valid source node types
20
+ target_types : List[Safe_Str__Node_Type] # Valid target node types
@@ -0,0 +1,43 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Node - Base node structure for graph-based issue tracking
3
+ # All entities (bugs, tasks, features, people) are nodes with typed relationships
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from typing import List, Dict, Any
7
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
8
+ from osbot_utils.type_safe.primitives.core.Safe_UInt import Safe_UInt
9
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
10
+ from osbot_utils.type_safe.primitives.domains.identifiers.Node_Id import Node_Id
11
+ from osbot_utils.type_safe.primitives.domains.identifiers.Obj_Id import Obj_Id
12
+ from osbot_utils.type_safe.primitives.domains.identifiers.safe_int.Timestamp_Now import Timestamp_Now
13
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Type, Safe_Str__Node_Label, Safe_Str__Status
14
+ from issues_fs.schemas.graph.Schema__Node__Link import Schema__Node__Link
15
+ from issues_fs.schemas.safe_str.Safe_Str__Issue__Node__Description import Safe_Str__Issue__Node__Description
16
+
17
+
18
+ # todo: refactor all these classes to use 'Issue' since that is the generic name for this
19
+ # for example this class should be called 'Schema__Issue__Node'
20
+ class Schema__Node(Type_Safe): # Base node structure for all entities
21
+ node_id : Node_Id # Random 10-char GUID for machine use
22
+ node_type : Safe_Str__Node_Type # Classification: bug, task, feature, person
23
+ node_index : Safe_UInt # Per-type sequential number
24
+ label : Safe_Str__Node_Label # Human-readable: "Bug-27", "Task-15"
25
+
26
+ # todo: create Safe_Str__Issue__Node__Title to use here
27
+ title : Safe_Str__Text # Display title
28
+ description : Safe_Str__Issue__Node__Description # Detailed description
29
+ status : Safe_Str__Status # Current status (type-specific)
30
+
31
+ created_at : Timestamp_Now # ISO timestamp created
32
+ updated_at : Timestamp_Now # ISO timestamp updated
33
+ # todo: see what is the best class to use here (Persona_Id , Creator_Id)
34
+ # : this should be an id created_by__id and the created_by should be name
35
+ created_by : Obj_Id # Person/agent node_id who created
36
+
37
+ # todo: refactor these to use Type_Safe collections, and this should be Safe_Str__Issue__Tag
38
+ tags : List[Safe_Str__Text] # Tags/categories (renamed from labels to avoid confusion)
39
+ # todo: rename to Schema__Issue__Node__Link
40
+ links : List[Schema__Node__Link] # Relationships to other nodes
41
+
42
+ # todo: this should be an Type_Safe collection and we shouldn't be using raw primitives like str, Any
43
+ properties : Dict[str, Any] # Type-specific properties (severity, browser, etc.)
@@ -0,0 +1,19 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Node__Create__Request - Request body for creating a new node
3
+ # POST /api/nodes
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from typing import List, Dict, Any
7
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
8
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
9
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Type, Safe_Str__Status
10
+ from issues_fs.schemas.safe_str.Safe_Str__Issue__Node__Description import Safe_Str__Issue__Node__Description
11
+
12
+
13
+ class Schema__Node__Create__Request(Type_Safe): # Create node request
14
+ node_type : Safe_Str__Node_Type # Required: "bug", "task", etc.
15
+ title : Safe_Str__Text # Required: display title
16
+ description : Safe_Str__Issue__Node__Description # Optional description
17
+ status : Safe_Str__Status = None # Optional: defaults to type's default
18
+ tags : List[Safe_Str__Text] # Optional tags
19
+ properties : Dict[str, Any] # Type-specific properties
@@ -0,0 +1,14 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Node__Create__Response - Response body after creating a node
3
+ # POST /api/nodes
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
8
+ from issues_fs.schemas.graph.Schema__Node import Schema__Node
9
+
10
+
11
+ class Schema__Node__Create__Response(Type_Safe): # Create node response
12
+ success : bool = False # Operation success
13
+ node : Schema__Node = None # Created node data
14
+ message : Safe_Str__Text = '' # Error message if failed
@@ -0,0 +1,15 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Node__Delete__Response - Response body after deleting a node
3
+ # DELETE /api/nodes/{label}
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
8
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Label
9
+
10
+
11
+ class Schema__Node__Delete__Response(Type_Safe): # Delete node response
12
+ success : bool = False # Operation success
13
+ deleted : bool = False # Whether node was deleted
14
+ label : Safe_Str__Node_Label = '' # Deleted node label
15
+ message : Safe_Str__Text = '' # Error message if failed
@@ -0,0 +1,17 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Node__Link - Relationship edge between nodes
3
+ # Links are bidirectional and denormalized (stored on both ends)
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.domains.identifiers.Obj_Id import Obj_Id
8
+ from osbot_utils.type_safe.primitives.domains.identifiers.safe_int.Timestamp_Now import Timestamp_Now
9
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Link_Verb, Safe_Str__Node_Label
10
+
11
+
12
+ class Schema__Node__Link(Type_Safe): # Relationship to another node
13
+ link_type_id : Obj_Id # Reference to link type definition
14
+ verb : Safe_Str__Link_Verb # "blocks", "has-task", "assigned-to"
15
+ target_id : Obj_Id # Target node's node_id
16
+ target_label : Safe_Str__Node_Label # Denormalized: "Task-15" for display
17
+ created_at : Timestamp_Now # When link was created
@@ -0,0 +1,16 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Node__List__Response - Response body for listing nodes
3
+ # GET /api/nodes or GET /api/nodes/type/{node_type}
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from typing import List
7
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
8
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
9
+ from issues_fs.schemas.graph.Schema__Node__Summary import Schema__Node__Summary
10
+
11
+
12
+ class Schema__Node__List__Response(Type_Safe): # List nodes response
13
+ success : bool = False # Operation success
14
+ nodes : List[Schema__Node__Summary] # Node summaries
15
+ total : int = 0 # Total count
16
+ message : Safe_Str__Text = '' # Error message if failed
@@ -0,0 +1,15 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Node__Summary - Lightweight node summary for list responses
3
+ # Contains only essential fields for display in lists
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
8
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Label, Safe_Str__Node_Type, Safe_Str__Status
9
+
10
+
11
+ class Schema__Node__Summary(Type_Safe): # Node summary for listings
12
+ label : Safe_Str__Node_Label # "Bug-27"
13
+ node_type : Safe_Str__Node_Type # "bug"
14
+ title : Safe_Str__Text # Display title
15
+ status : Safe_Str__Status # Current status
@@ -0,0 +1,28 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Node__Type - Definition of a node type (bug, task, feature, etc.)
3
+ # Each type has its own statuses, properties, and display configuration
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from typing import List
7
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
8
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
9
+ from osbot_utils.type_safe.primitives.domains.identifiers.Obj_Id import Obj_Id
10
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Type, Safe_Str__Node_Type_Display, Safe_Str__Status
11
+ from issues_fs.schemas.graph.Schema__Property__Definition import Schema__Property__Definition
12
+ from issues_fs.schemas.safe_str.Safe_Str__Hex_Color import Safe_Str__Hex_Color
13
+
14
+ # todo: refactor to Schema__Issue__Node__Type
15
+ # (do the same *__Issue__* refactoring where applicable
16
+ class Schema__Node__Type(Type_Safe): # Node type definition
17
+ #todo: refactor to Issue__Node__Type_Id
18
+ type_id : Obj_Id # Unique identifier for this type
19
+ name : Safe_Str__Node_Type # "bug", "task", "feature"
20
+ display_name : Safe_Str__Node_Type_Display # "Bug", "Task", "Feature"
21
+ description : Safe_Str__Text # What this type represents
22
+ icon : Safe_Str__Text # Icon identifier (optional)
23
+ color : Safe_Str__Hex_Color # Display color like #ef4444
24
+
25
+ statuses : List[Safe_Str__Status] # Valid statuses for this type
26
+ default_status : Safe_Str__Status # Initial status for new nodes
27
+
28
+ properties : List[Schema__Property__Definition] # Type-specific field definitions
@@ -0,0 +1,18 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Node__Update__Request - Request body for updating an existing node
3
+ # PATCH /api/nodes/{label} - All fields optional (partial update)
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from typing import List, Dict, Any
7
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
8
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
9
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Status
10
+ from issues_fs.schemas.safe_str.Safe_Str__Issue__Node__Description import Safe_Str__Issue__Node__Description
11
+
12
+
13
+ class Schema__Node__Update__Request(Type_Safe): # Update node request (partial)
14
+ title : Safe_Str__Text = None # New title
15
+ description : Safe_Str__Issue__Node__Description = None # New description
16
+ status : Safe_Str__Status = None # New status
17
+ tags : List[Safe_Str__Text] = None # New tags (replaces existing)
18
+ properties : Dict[str, Any] = None # New properties (merged)
@@ -0,0 +1,14 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Node__Update__Response - Response body after updating a node
3
+ # PATCH /api/nodes/{label}
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
8
+ from issues_fs.schemas.graph.Schema__Node import Schema__Node
9
+
10
+
11
+ class Schema__Node__Update__Response(Type_Safe): # Update node response
12
+ success : bool = False # Operation success
13
+ node : Schema__Node = None # Updated node data
14
+ message : Safe_Str__Text = '' # Error message if failed
@@ -0,0 +1,27 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Property__Definition - Definition of a type-specific property field
3
+ # Properties allow each node type to have its own custom fields
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from typing import List
7
+ from enum import Enum
8
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
9
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
10
+
11
+
12
+ class Enum__Property__Type(str, Enum): # Property value types
13
+ STRING = "string" # Free text
14
+ NUMBER = "number" # Numeric value
15
+ BOOLEAN = "boolean" # True/false
16
+ ENUM = "enum" # Predefined options
17
+ DATE = "date" # ISO date string
18
+ DATETIME = "datetime" # ISO datetime string
19
+
20
+
21
+ class Schema__Property__Definition(Type_Safe): # Custom property definition
22
+ name : Safe_Str__Text # Property name like "severity"
23
+ prop_type : Enum__Property__Type = Enum__Property__Type.STRING # Value type
24
+ description : Safe_Str__Text # What this property represents
25
+ required : bool = False # Whether property is required
26
+ options : List[Safe_Str__Text] # For ENUM type: valid options
27
+ default : Safe_Str__Text = None # Default value (optional)
@@ -0,0 +1,16 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Type__Index - Per-type index tracking for node counts and next ID
3
+ # Stored at .issues/data/{node_type}/_index.json
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.core.Safe_UInt import Safe_UInt
8
+ from osbot_utils.type_safe.primitives.domains.identifiers.safe_int.Timestamp_Now import Timestamp_Now
9
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Type
10
+
11
+
12
+ class Schema__Type__Index(Type_Safe): # Per-type index file
13
+ node_type : Safe_Str__Node_Type # "bug", "task", etc.
14
+ next_index : Safe_UInt = Safe_UInt(1) # Next available index
15
+ count : Safe_UInt = Safe_UInt(0) # Total nodes of this type
16
+ last_updated : Timestamp_Now = None # ISO timestamp
@@ -0,0 +1,13 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Type__Summary - Summary of node count for a single type
3
+ # Used within Schema__Global__Index
4
+ # ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.core.Safe_UInt import Safe_UInt
8
+ from issues_fs.schemas.graph.Safe_Str__Graph_Types import Safe_Str__Node_Type
9
+
10
+
11
+ class Schema__Type__Summary(Type_Safe): # Summary for a node type
12
+ node_type : Safe_Str__Node_Type # Type name
13
+ count : Safe_UInt = Safe_UInt(0) # Node count
File without changes
@@ -0,0 +1,5 @@
1
+ from issues_fs.schemas.identifiers.Issue_Id import Issue_Id
2
+
3
+
4
+ class Comment_Id(Issue_Id):
5
+ pass
@@ -0,0 +1,13 @@
1
+ from osbot_utils.type_safe.primitives.domains.identifiers.Obj_Id import Obj_Id
2
+
3
+ # we need to refactor the code to use this
4
+ class Issue_Id(Obj_Id): # Obj_Id that allows empty values (needed for serialisation)
5
+ def __new__(cls, value=None):
6
+ if value is None or value == '':
7
+ return str.__new__(cls, '')
8
+ else:
9
+ return super().__new__(cls, value)
10
+
11
+ @classmethod
12
+ def new(cls): # helper method for the easy creation of non-empty Issue_ids
13
+ return cls(Obj_Id())
File without changes
@@ -0,0 +1,61 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Schema__Comment - Data types for comments on nodes
3
+ # ═══════════════════════════════════════════════════════════════════════════════
4
+
5
+ from typing import List, Optional
6
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
7
+ from osbot_utils.type_safe.primitives.domains.identifiers.Obj_Id import Obj_Id
8
+ from osbot_utils.type_safe.primitives.domains.identifiers.safe_int.Timestamp_Now import Timestamp_Now
9
+ from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
10
+
11
+
12
+ # ═══════════════════════════════════════════════════════════════════════════════
13
+ # Comment Schema
14
+ # ═══════════════════════════════════════════════════════════════════════════════
15
+
16
+ # todo: this should be Schema__Issue__Comment
17
+ # refactor each of these files into a separate schema file
18
+ # change id to comment_id
19
+ class Schema__Comment(Type_Safe): # Single comment on a node
20
+ id : Obj_Id # Unique comment ID
21
+ author : Safe_Str__Text # Who wrote it: 'human', 'claude-code', etc.
22
+ text : Safe_Str__Text # Comment content (supports markdown)
23
+ created_at : Timestamp_Now # When created
24
+ updated_at : Timestamp_Now # When last edited
25
+
26
+
27
+ # ═══════════════════════════════════════════════════════════════════════════════
28
+ # Request Schemas
29
+ # ═══════════════════════════════════════════════════════════════════════════════
30
+
31
+ class Schema__Comment__Create__Request(Type_Safe): # Create comment request
32
+ author : Safe_Str__Text # Who is writing
33
+ text : Safe_Str__Text # Comment content
34
+
35
+
36
+ class Schema__Comment__Update__Request(Type_Safe): # Update comment request
37
+ text : Safe_Str__Text # New comment content
38
+
39
+
40
+ # ═══════════════════════════════════════════════════════════════════════════════
41
+ # Response Schemas
42
+ # ═══════════════════════════════════════════════════════════════════════════════
43
+
44
+ class Schema__Comment__Response(Type_Safe): # Single comment response
45
+ success : bool = False
46
+ comment : Schema__Comment = None
47
+ message : str = ''
48
+
49
+
50
+ class Schema__Comment__List__Response(Type_Safe): # List comments response
51
+ success : bool = False
52
+ comments : List[Schema__Comment] = None
53
+ total : int = 0
54
+ message : str = ''
55
+
56
+
57
+ class Schema__Comment__Delete__Response(Type_Safe): # Delete comment response
58
+ success : bool = False
59
+ deleted : bool = False
60
+ comment_id : str = ''
61
+ message : str = ''
File without changes