"""Dev seed script — inserts fixture data for local development. Usage: ACTCORE_DB_URL=postgresql+asyncpg://actcore:actcore@localhost:5433/actcore \ python -m activity_core.seed Safe to re-run: skips rows that already exist (matched by name). Never run against production. """ import asyncio import os import sys import uuid from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker from activity_core.db import make_engine from activity_core.orm import ActivityDefinition # noqa: F401 — registers metadata SEED_DEFINITIONS = [ { "id": uuid.UUID("00000000-0000-0000-0000-000000000001"), "name": "example-heartbeat", "enabled": True, "trigger_type": "cron", "trigger_config": { "trigger_type": "cron", "cron_expression": "* * * * *", # every minute "timezone": "UTC", "jitter_seconds": 0, "misfire_policy": "skip", }, "context_sources": [ { "name": "stub", "type": "static", "config": {"value": {"ping": "pong"}}, } ], "task_templates": [ { "task_type": "log_message", "condition": None, "params_template": {"message": "heartbeat from {context.stub.ping}"}, } ], "dedupe_key_strategy": "skip", "version": 1, }, ] async def seed(db_url: str | None = None) -> None: engine = make_engine(db_url) Session = async_sessionmaker(engine, expire_on_commit=False) async with Session() as session: async with session.begin(): for defn in SEED_DEFINITIONS: existing = await session.scalar( select(ActivityDefinition).where( ActivityDefinition.name == defn["name"] ) ) if existing: print(f" skip {defn['name']!r} (already exists, id={existing.id})") continue session.add(ActivityDefinition(**defn)) print(f" insert {defn['name']!r} (id={defn['id']})") await engine.dispose() print("done.") if __name__ == "__main__": url = os.environ.get("ACTCORE_DB_URL") if not url: print( "error: set ACTCORE_DB_URL before running this script\n" " e.g. ACTCORE_DB_URL=postgresql+asyncpg://actcore:actcore@localhost:5433/actcore", file=sys.stderr, ) sys.exit(1) asyncio.run(seed(url))