""" Idea Lifecycle & Workflow State Machine Tests PRD Section 10, 11, 28, 30, 31, 34: - Separation of Lifecycle State and Processing State - Claiming (AVAILABLE -> CLAIMED) - Activation (CLAIMED -> ACTIVE) - Work tracks & outputs """ import pytest import asyncio from thinkstorm.database import init_db, get_db, next_sequence, get_utc_now from thinkstorm.processors.pipeline import execute_intake_pipeline, execute_work_track_workflow from thinkstorm.models import LifecycleState, ProcessingState @pytest.mark.asyncio async def test_full_idea_intake_and_claim_lifecycle(): init_db() idea_id = next_sequence("idea") raw_text = f"Quantum biological sensor interface for monitoring mitochondrial ATP flux oscillations in real-time {idea_id} https://example.com/sensor" now = get_utc_now() # 1. Anonymous submission with get_db() as conn: conn.execute( """ INSERT INTO ideas (id, original_text, submitted_at, title, summary, lifecycle_state, processing_state, enrichment_level, created_at, updated_at) VALUES (?, ?, ?, 'Pending', 'Pending', 'SUBMITTED', 'QUEUED', 0, ?, ?) """, (idea_id, raw_text, now, now, now) ) # 2. Run intake pipeline await execute_intake_pipeline(idea_id) # 3. Verify Idea reached AVAILABLE with get_db() as conn: idea = conn.execute("SELECT * FROM ideas WHERE id = ?", (idea_id,)).fetchone() assert idea["lifecycle_state"] == LifecycleState.AVAILABLE.value assert idea["processing_state"] == ProcessingState.IDLE.value assert idea["enrichment_level"] >= 4 assert len(idea["title"]) > 0 assert idea["opengist_id"] is not None # Verify raw original text was NEVER mutated assert idea["original_text"] == raw_text # Verify runs were recorded runs = conn.execute("SELECT * FROM processor_runs WHERE idea_id = ?", (idea_id,)).fetchall() assert len(runs) >= 4 total_tokens = sum(r["total_tokens"] for r in runs) assert total_tokens > 0 # 4. Claim Idea (AVAILABLE -> CLAIMED) claim_time = get_utc_now() with get_db() as conn: conn.execute( "UPDATE ideas SET lifecycle_state = 'CLAIMED', claimed_by = 'researcher', claimed_at = ? WHERE id = ?", (claim_time, idea_id) ) claimed_idea = conn.execute("SELECT * FROM ideas WHERE id = ?", (idea_id,)).fetchone() assert claimed_idea["lifecycle_state"] == LifecycleState.CLAIMED.value assert claimed_idea["claimed_by"] == "researcher" # 5. Activate Idea (CLAIMED -> ACTIVE) with get_db() as conn: conn.execute( "UPDATE ideas SET lifecycle_state = 'ACTIVE' WHERE id = ?", (idea_id,) ) active_idea = conn.execute("SELECT * FROM ideas WHERE id = ?", (idea_id,)).fetchone() assert active_idea["lifecycle_state"] == LifecycleState.ACTIVE.value # 6. Add Work Track track_id = next_sequence("work_track") with get_db() as conn: conn.execute( """ INSERT INTO work_tracks (id, idea_id, work_type_id, name, state, created_at) VALUES (?, ?, 'CODING_PROJECT', 'Core Architecture Blueprint', 'PLANNED', ?) """, (track_id, idea_id, get_utc_now()) ) # 7. Execute Work Track Workflow await execute_work_track_workflow(track_id) # 8. Verify Work Track completed and outputs produced with get_db() as conn: track = conn.execute("SELECT * FROM work_tracks WHERE id = ?", (track_id,)).fetchone() assert track["state"] == "COMPLETED" outputs = conn.execute("SELECT * FROM work_track_outputs WHERE work_track_id = ?", (track_id,)).fetchall() assert len(outputs) >= 2