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.
- issues_fs/issues/Issue__Path__Config.py +25 -0
- issues_fs/issues/__init__.py +3 -0
- issues_fs/issues/graph_services/Comments__Service.py +235 -0
- issues_fs/issues/graph_services/Graph__Repository.py +307 -0
- issues_fs/issues/graph_services/Graph__Repository__Factory.py +106 -0
- issues_fs/issues/graph_services/Link__Service.py +227 -0
- issues_fs/issues/graph_services/Node__Service.py +392 -0
- issues_fs/issues/graph_services/Type__Service.py +209 -0
- issues_fs/issues/graph_services/__init__.py +3 -0
- issues_fs/issues/phase_1/Issue__Children__Service.py +340 -0
- issues_fs/issues/phase_1/Root__Issue__Service.py +137 -0
- issues_fs/issues/phase_1/Root__Selection__Service.py +310 -0
- issues_fs/issues/phase_1/__init__.py +3 -0
- issues_fs/issues/status/Git__Status__Service.py +115 -0
- issues_fs/issues/status/Index__Status__Service.py +131 -0
- issues_fs/issues/status/Server__Status__Service.py +113 -0
- issues_fs/issues/status/Storage__Status__Service.py +75 -0
- issues_fs/issues/status/Types__Status__Service.py +75 -0
- issues_fs/issues/status/__init__.py +3 -0
- issues_fs/issues/storage/Path__Handler__Graph_Node.py +185 -0
- issues_fs/issues/storage/Path__Handler__Issues.py +57 -0
- issues_fs/issues/storage/__init__.py +3 -0
- issues_fs/schemas/__init__.py +0 -0
- issues_fs/schemas/enums/Enum__Comment__Author.py +10 -0
- issues_fs/schemas/enums/Enum__Graph__Storage__Backend.py +8 -0
- issues_fs/schemas/enums/Enum__Issue__Status.py +13 -0
- issues_fs/schemas/enums/__init__.py +3 -0
- issues_fs/schemas/graph/Safe_Str__Graph_Types.py +63 -0
- issues_fs/schemas/graph/Schema__Global__Index.py +16 -0
- issues_fs/schemas/graph/Schema__Graph__Link.py +8 -0
- issues_fs/schemas/graph/Schema__Graph__Node.py +10 -0
- issues_fs/schemas/graph/Schema__Graph__Response.py +21 -0
- issues_fs/schemas/graph/Schema__Link__Create__Request.py +12 -0
- issues_fs/schemas/graph/Schema__Link__Create__Response.py +15 -0
- issues_fs/schemas/graph/Schema__Link__Delete__Response.py +16 -0
- issues_fs/schemas/graph/Schema__Link__List__Response.py +15 -0
- issues_fs/schemas/graph/Schema__Link__Type.py +20 -0
- issues_fs/schemas/graph/Schema__Node.py +43 -0
- issues_fs/schemas/graph/Schema__Node__Create__Request.py +19 -0
- issues_fs/schemas/graph/Schema__Node__Create__Response.py +14 -0
- issues_fs/schemas/graph/Schema__Node__Delete__Response.py +15 -0
- issues_fs/schemas/graph/Schema__Node__Link.py +17 -0
- issues_fs/schemas/graph/Schema__Node__List__Response.py +16 -0
- issues_fs/schemas/graph/Schema__Node__Summary.py +15 -0
- issues_fs/schemas/graph/Schema__Node__Type.py +28 -0
- issues_fs/schemas/graph/Schema__Node__Update__Request.py +18 -0
- issues_fs/schemas/graph/Schema__Node__Update__Response.py +14 -0
- issues_fs/schemas/graph/Schema__Property__Definition.py +27 -0
- issues_fs/schemas/graph/Schema__Type__Index.py +16 -0
- issues_fs/schemas/graph/Schema__Type__Summary.py +13 -0
- issues_fs/schemas/graph/__init__.py +0 -0
- issues_fs/schemas/identifiers/Comment_Id.py +5 -0
- issues_fs/schemas/identifiers/Issue_Id.py +13 -0
- issues_fs/schemas/identifiers/__init__.py +0 -0
- issues_fs/schemas/issues/Schema__Comment.py +61 -0
- issues_fs/schemas/issues/__init__.py +0 -0
- issues_fs/schemas/issues/phase_1/Schema__Issue__Children.py +85 -0
- issues_fs/schemas/issues/phase_1/Schema__Root.py +60 -0
- issues_fs/schemas/issues/phase_1/__init__.py +0 -0
- issues_fs/schemas/safe_str/Safe_Str__Hex_Color.py +10 -0
- issues_fs/schemas/safe_str/Safe_Str__Issue_Id.py +14 -0
- issues_fs/schemas/safe_str/Safe_Str__Issue__Node__Description.py +15 -0
- issues_fs/schemas/safe_str/Safe_Str__Label_Name.py +9 -0
- issues_fs/schemas/safe_str/__init__.py +0 -0
- issues_fs/schemas/status/Schema__API__Info.py +15 -0
- issues_fs/schemas/status/Schema__Git__Status.py +21 -0
- issues_fs/schemas/status/Schema__Index__Status.py +22 -0
- issues_fs/schemas/status/Schema__Server__Status.py +28 -0
- issues_fs/schemas/status/Schema__Storage__Status.py +23 -0
- issues_fs/schemas/status/Schema__Types__Status.py +30 -0
- issues_fs/schemas/status/__init__.py +0 -0
- issues_fs/version +1 -1
- {issues_fs-0.3.0.dist-info → issues_fs-0.4.0.dist-info}/METADATA +2 -1
- issues_fs-0.4.0.dist-info/RECORD +79 -0
- issues_fs-0.3.0.dist-info/RECORD +0 -8
- {issues_fs-0.3.0.dist-info → issues_fs-0.4.0.dist-info}/LICENSE +0 -0
- {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,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
|