""" ThinkStorm Data Models & Enums Defines lifecycle states, operational entities, and schema types. """ from enum import Enum from dataclasses import dataclass, field from typing import Optional, List, Dict, Any from datetime import datetime class LifecycleState(str, Enum): SUBMITTED = "SUBMITTED" AVAILABLE = "AVAILABLE" CLAIMED = "CLAIMED" ACTIVE = "ACTIVE" COMPLETED = "COMPLETED" ABANDONED = "ABANDONED" RETIRED = "RETIRED" QUARANTINED = "QUARANTINED" REJECTED = "REJECTED" DUPLICATE = "DUPLICATE" TRASHED = "TRASHED" class ProcessingState(str, Enum): IDLE = "IDLE" QUEUED = "QUEUED" PROCESSING = "PROCESSING" PARTIAL = "PARTIAL" ERROR = "ERROR" class URLSafetyState(str, Enum): PENDING = "PENDING" CHECKING = "CHECKING" SAFE = "SAFE" SUSPICIOUS = "SUSPICIOUS" MALICIOUS = "MALICIOUS" UNKNOWN = "UNKNOWN" ERROR = "ERROR" class AutomationPolicy(str, Enum): APPROVED = "APPROVED" BLOCKED = "BLOCKED" REQUIRES_REVIEW = "REQUIRES_REVIEW" class WorkTrackState(str, Enum): PLANNED = "PLANNED" ACTIVE = "ACTIVE" PAUSED = "PAUSED" COMPLETED = "COMPLETED" ABANDONED = "ABANDONED" RETIRED = "RETIRED" class UserRole(str, Enum): ANONYMOUS = "ANONYMOUS" USER = "USER" ADMIN = "ADMIN" class ProcessorStatus(str, Enum): PENDING = "PENDING" RUNNING = "RUNNING" COMPLETED = "COMPLETED" FAILED = "FAILED" CANCELLED = "CANCELLED" @dataclass class User: id: int username: str password_hash: str role: UserRole = UserRole.USER created_at: str = "" @dataclass class IdeaURL: id: Optional[int] idea_id: str url: str safety_state: URLSafetyState = URLSafetyState.PENDING automation_policy: AutomationPolicy = AutomationPolicy.REQUIRES_REVIEW virustotal_data: Dict[str, Any] = field(default_factory=dict) admin_review_required: bool = False reviewed_by: Optional[str] = None reviewed_at: Optional[str] = None decision: Optional[str] = None @dataclass class Idea: id: str # e.g. TS-0001 original_text: str submitted_at: str title: str = "" summary: str = "" categories: List[str] = field(default_factory=list) tags: List[str] = field(default_factory=list) lifecycle_state: LifecycleState = LifecycleState.SUBMITTED processing_state: ProcessingState = ProcessingState.IDLE enrichment_level: int = 0 claimed_by: Optional[str] = None claimed_at: Optional[str] = None released_at: Optional[str] = None previous_lifecycle_state: Optional[str] = None trashed_at: Optional[str] = None profile_id: Optional[str] = None profile_version: int = 1 opengist_id: Optional[str] = None opengist_url: Optional[str] = None gitea_repo_name: Optional[str] = None gitea_repo_url: Optional[str] = None created_at: str = "" updated_at: str = "" urls: List[IdeaURL] = field(default_factory=list) relationships: List[Dict[str, Any]] = field(default_factory=list) @dataclass class WorkTrackOutput: id: Optional[int] work_track_id: str name: str artifact_path: str content: str version: int = 1 is_current: bool = True model_used: Optional[str] = None opengist_file: Optional[str] = None created_at: str = "" updated_at: str = "" @dataclass class WorkTrack: id: str # e.g. WT-0001 idea_id: str work_type_id: str # ARTICLE, BLOG_ENTRY, CODING_PROJECT name: str state: WorkTrackState = WorkTrackState.PLANNED workflow_id: str = "" model_override: Optional[str] = None created_at: str = "" started_at: Optional[str] = None completed_at: Optional[str] = None outputs: List[WorkTrackOutput] = field(default_factory=list) external_resources: List[Dict[str, Any]] = field(default_factory=list) @dataclass class PromptVersion: id: Optional[int] prompt_definition_id: str version: int system_prompt: str user_prompt_template: str applies_to: Dict[str, Any] = field(default_factory=dict) model_policy: str = "reasoning" expected_outputs: List[str] = field(default_factory=list) prompt_hash: str = "" created_by: str = "system" created_at: str = "" @dataclass class PromptDefinition: id: str # e.g. prior-art-software name: str stage: str description: str current_version: int = 1 enabled: bool = True created_at: str = "" versions: List[PromptVersion] = field(default_factory=list) @dataclass class PromptProfile: id: str # e.g. software-idea-v1 name: str description: str prompt_assignments: Dict[str, str] = field(default_factory=dict) # stage -> prompt_id@version is_default: bool = False created_at: str = "" @dataclass class ProcessorRun: id: str # e.g. RUN-0001 idea_id: str work_track_id: Optional[str] processor_name: str stage: str prompt_id: Optional[str] prompt_version: Optional[int] prompt_hash: Optional[str] model_policy: str resolved_provider: str resolved_model: str input_tokens: int = 0 output_tokens: int = 0 total_tokens: int = 0 started_at: str = "" completed_at: Optional[str] = None duration_ms: int = 0 output_artifact: Optional[str] = None output_data: Dict[str, Any] = field(default_factory=dict) error_message: Optional[str] = None status: ProcessorStatus = ProcessorStatus.PENDING @dataclass class ServiceConfig: id: str name: str endpoint: str api_key_masked: str enabled: bool config_json: Dict[str, Any] = field(default_factory=dict) last_tested_at: Optional[str] = None health_status: str = "UNKNOWN" last_error: Optional[str] = None @dataclass class AuditEvent: id: Optional[int] user_id: str action: str entity_type: str entity_id: str details: Dict[str, Any] created_at: str = ""