Capture ThinkStorm project: codebase state, workflows, and access control policies
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
"""
|
||||
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
|
||||
Reference in New Issue
Block a user