Overview
CRUD store for managing Linear workspace registrations, user associations, and conversation records, provided by the OpenHands enterprise storage layer.
Description
LinearIntegrationStore provides the persistence layer for the Linear project management integration. It follows the same API pattern established by the Jira integration stores, managing three entity types: workspaces (representing a connected Linear organization), workspace-user links (mapping OpenHands users to Linear workspaces), and conversations (tying OpenHands conversations to specific Linear issues).
The distinguishing identifier for Linear workspaces is linear_org_id (the Linear organization identifier), as opposed to jira_cloud_id or jira_dc_base_url used by the Jira variants. All other operations -- workspace lifecycle, user link management, and conversation tracking -- follow the same patterns and method signatures.
This consistent API across integration stores allows higher-level code to interact with different integrations through a uniform interface, simplifying the implementation of multi-integration features.
Usage
Use LinearIntegrationStore when building or maintaining Linear integration endpoints. It is used during the Linear OAuth flow to register workspaces, in issue sidebar endpoints to resolve user links, and in conversation creation to persist the Linear issue association.
Code Reference
Source Location
Signature
class LinearIntegrationStore:
def __init__(self, session: Session):
...
def create_workspace(self, linear_org_id: str, **kwargs) -> LinearWorkspace:
...
def update_workspace(self, workspace_id: str, **kwargs) -> LinearWorkspace:
...
def create_workspace_link(self, workspace_id: str, user_id: str, **kwargs) -> LinearWorkspaceLink:
...
def get_workspace_by_id(self, workspace_id: str) -> Optional[LinearWorkspace]:
...
def get_active_user(self, workspace_id: str, user_id: str) -> Optional[LinearWorkspaceLink]:
...
def deactivate_workspace(self, workspace_id: str) -> None:
...
def create_conversation(self, workspace_id: str, issue_id: str, conversation_id: str) -> LinearConversation:
...
def get_user_conversations_by_issue_id(self, workspace_id: str, user_id: str, issue_id: str) -> List[LinearConversation]:
...
Import
from enterprise.storage.linear_integration_store import LinearIntegrationStore
I/O Contract
Inputs
Constructor
| Name |
Type |
Required |
Description
|
| session |
Session |
Yes |
SQLAlchemy database session for executing queries
|
create_workspace()
| Name |
Type |
Required |
Description
|
| linear_org_id |
str |
Yes |
Linear organization identifier (primary workspace identifier)
|
| **kwargs |
dict |
No |
Additional workspace attributes (e.g., access_token, org_name)
|
create_workspace_link()
| Name |
Type |
Required |
Description
|
| workspace_id |
str |
Yes |
The workspace to link the user to
|
| user_id |
str |
Yes |
The OpenHands user ID to associate with the workspace
|
| **kwargs |
dict |
No |
Additional link attributes (e.g., linear_user_id)
|
get_user_conversations_by_issue_id()
| Name |
Type |
Required |
Description
|
| workspace_id |
str |
Yes |
The workspace scope for the query
|
| user_id |
str |
Yes |
The user whose conversations to retrieve
|
| issue_id |
str |
Yes |
The Linear issue ID to filter conversations by
|
Outputs
| Method |
Return Type |
Description
|
| create_workspace() |
LinearWorkspace |
The newly created workspace ORM object
|
| update_workspace() |
LinearWorkspace |
The updated workspace ORM object
|
| create_workspace_link() |
LinearWorkspaceLink |
The newly created user-workspace link
|
| get_workspace_by_id() |
Optional[LinearWorkspace] |
The workspace if found, None otherwise
|
| get_active_user() |
Optional[LinearWorkspaceLink] |
The active link if found, None otherwise
|
| deactivate_workspace() |
None |
Marks workspace as inactive (soft delete)
|
| create_conversation() |
LinearConversation |
The newly created conversation record
|
| get_user_conversations_by_issue_id() |
List[LinearConversation] |
All conversations for the user on the given issue
|
Usage Examples
Registering a Linear Organization
from enterprise.storage.linear_integration_store import LinearIntegrationStore
store = LinearIntegrationStore(session=db_session)
# Register a new Linear organization after OAuth
workspace = store.create_workspace(
linear_org_id="lin-org-abc123",
access_token="lin-oauth-token",
org_name="Acme Engineering"
)
# Link the installing user
link = store.create_workspace_link(
workspace_id=workspace.id,
user_id="user-456",
linear_user_id="lin-user-789"
)
Conversation Lifecycle
# Create a conversation for a Linear issue
conversation = store.create_conversation(
workspace_id=workspace.id,
issue_id="LIN-42",
conversation_id="conv-new-001"
)
# Query conversations for a specific issue
conversations = store.get_user_conversations_by_issue_id(
workspace_id=workspace.id,
user_id="user-456",
issue_id="LIN-42"
)
Related Pages
Related Implementations
Environment