Coverage for src/prosemark/freewriting/ports/node_service.py: 100%
16 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-09-24 18:08 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-09-24 18:08 +0000
1"""Node service port interface for freewriting feature.
3This module defines the port interface for node management operations
4specific to the freewriting functionality.
5"""
7from __future__ import annotations
9from abc import ABC, abstractmethod
12class NodeServicePort(ABC):
13 """Port interface for node management operations.
15 This port defines the contract for operations on prosemark nodes,
16 including creation, existence checking, and content appending.
17 """
19 @abstractmethod
20 def node_exists(self, node_uuid: str) -> bool:
21 """Check if a node file exists.
23 Args:
24 node_uuid: UUID of the node to check.
26 Returns:
27 True if node exists, False otherwise.
29 """
31 @abstractmethod
32 def create_node(self, node_uuid: str, title: str | None = None) -> str:
33 """Create a new node file and add to binder.
35 Creates a new prosemark node file with the given UUID and optionally
36 adds it to the project binder for organization.
38 Args:
39 node_uuid: UUID for the new node.
40 title: Optional title for the node.
42 Returns:
43 Path to created node file.
45 Raises:
46 ValidationError: If UUID is invalid.
47 FileSystemError: If creation fails.
48 NodeError: If node creation fails.
50 """
52 @abstractmethod
53 def append_to_node(self, node_uuid: str, content: list[str], session_metadata: dict[str, str]) -> None:
54 """Append freewriting content to existing node.
56 Appends the given content lines to the specified node, adding
57 session metadata to provide context about when and how the
58 content was added.
60 Args:
61 node_uuid: Target node UUID.
62 content: Lines of content to append.
63 session_metadata: Session info for context (timestamp, word count, etc.).
65 Raises:
66 FileSystemError: If write fails.
67 ValidationError: If node doesn't exist.
68 NodeError: If node operations fail.
70 """
72 @abstractmethod
73 def get_node_path(self, node_uuid: str) -> str:
74 """Get file path for a node UUID.
76 Args:
77 node_uuid: UUID of the node.
79 Returns:
80 Absolute path to the node file.
82 Raises:
83 ValidationError: If UUID format is invalid.
85 """
87 @staticmethod
88 @abstractmethod
89 def validate_node_uuid(node_uuid: str) -> bool:
90 """Validate that a node UUID is properly formatted.
92 Args:
93 node_uuid: UUID string to validate.
95 Returns:
96 True if valid UUID format, False otherwise.
98 """
100 @abstractmethod
101 def add_to_binder(self, node_uuid: str, title: str | None = None) -> None:
102 """Add node to the project binder.
104 Args:
105 node_uuid: UUID of the node to add.
106 title: Optional title for the binder entry.
108 Raises:
109 FileSystemError: If binder update fails.
110 NodeError: If node addition fails.
112 """