Initial SFERA platform baseline

This commit is contained in:
2026-05-16 19:03:49 +03:00
commit 3b845c8fce
282 changed files with 55045 additions and 0 deletions
@@ -0,0 +1,196 @@
from __future__ import annotations
from datetime import datetime, timezone
from enum import Enum
from pydantic import BaseModel, Field
class TaskStatus(str, Enum):
OPEN = "OPEN"
IN_PROGRESS = "IN_PROGRESS"
DONE = "DONE"
CANCELED = "CANCELED"
class User(BaseModel):
user_id: str
display_name: str
email: str | None = None
class Workspace(BaseModel):
workspace_id: str
name: str
owner_user_id: str | None = None
class Project(BaseModel):
project_id: str
workspace_id: str
name: str
class Task(BaseModel):
task_id: str
project_id: str
title: str
status: TaskStatus = TaskStatus.OPEN
assignee_user_id: str | None = None
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
class ChangeSession(BaseModel):
session_id: str
task_id: str
user_id: str
started_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
finished_at: datetime | None = None
class Comment(BaseModel):
comment_id: str
project_id: str
target_id: str
user_id: str
body: str
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
class ActivityEvent(BaseModel):
event_id: str
project_id: str
actor_user_id: str
verb: str
target_id: str
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
attributes: dict = Field(default_factory=dict)
class Ownership(BaseModel):
owner_user_id: str
project_id: str
target_id: str
role: str = "OWNER"
assigned_by: str | None = None
assigned_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
attributes: dict = Field(default_factory=dict)
class InMemoryCollaborationStore:
def __init__(self) -> None:
self.users: dict[str, User] = {}
self.workspaces: dict[str, Workspace] = {}
self.projects: dict[str, Project] = {}
self.tasks: dict[str, Task] = {}
self.sessions: dict[str, ChangeSession] = {}
self.comments: dict[str, Comment] = {}
self.activities: list[ActivityEvent] = []
self.ownership: dict[str, Ownership] = {}
def upsert_user(self, user: User) -> User:
self.users[user.user_id] = user
return user
def upsert_workspace(self, workspace: Workspace) -> Workspace:
self.workspaces[workspace.workspace_id] = workspace
return workspace
def upsert_project(self, project: Project) -> Project:
self.projects[project.project_id] = project
return project
def upsert_task(self, task: Task) -> Task:
self.tasks[task.task_id] = task
return task
def start_session(self, session: ChangeSession) -> ChangeSession:
if session.task_id not in self.tasks:
raise KeyError(f"Unknown task: {session.task_id}")
if session.user_id not in self.users:
raise KeyError(f"Unknown user: {session.user_id}")
self.sessions[session.session_id] = session
return session
def finish_session(self, session_id: str) -> ChangeSession:
session = self.sessions.get(session_id)
if session is None:
raise KeyError(f"Unknown session: {session_id}")
if session.finished_at is None:
session = session.model_copy(update={"finished_at": datetime.now(timezone.utc)})
self.sessions[session_id] = session
return session
def add_comment(self, comment: Comment) -> Comment:
if comment.user_id not in self.users:
raise KeyError(f"Unknown user: {comment.user_id}")
self.comments[comment.comment_id] = comment
return comment
def comments_for_project(self, project_id: str) -> list[Comment]:
return sorted(
[
comment
for comment in self.comments.values()
if comment.project_id == project_id
],
key=lambda item: item.created_at,
)
def comments_for_target(self, project_id: str, target_id: str) -> list[Comment]:
return [
comment
for comment in self.comments_for_project(project_id)
if comment.target_id == target_id
]
def add_activity(self, event: ActivityEvent) -> ActivityEvent:
self.activities.append(event)
return event
def assign_owner(self, ownership: Ownership) -> Ownership:
if ownership.owner_user_id not in self.users:
raise KeyError(f"Unknown user: {ownership.owner_user_id}")
self.ownership[self._ownership_key(ownership)] = ownership
return ownership
def owners_for_project(self, project_id: str) -> list[Ownership]:
return sorted(
[
ownership
for ownership in self.ownership.values()
if ownership.project_id == project_id
],
key=lambda item: (item.target_id, item.role, item.owner_user_id),
)
def owners_for_target(self, project_id: str, target_id: str) -> list[Ownership]:
return [
ownership
for ownership in self.owners_for_project(project_id)
if ownership.target_id == target_id
]
def activity_feed(self, project_id: str) -> list[ActivityEvent]:
return [
event
for event in sorted(self.activities, key=lambda item: item.created_at, reverse=True)
if event.project_id == project_id
]
def _ownership_key(self, ownership: Ownership) -> str:
return f"{ownership.project_id}:{ownership.target_id}:{ownership.role}:{ownership.owner_user_id}"
__all__ = [
"ActivityEvent",
"ChangeSession",
"Comment",
"InMemoryCollaborationStore",
"Ownership",
"Project",
"Task",
"TaskStatus",
"User",
"Workspace",
]