Files
activity-core/src/activity_core/seed.py
Bernd Worsch 027e41dbc0 feat(db): add dev seed script for ActivityDefinition — T12
src/activity_core/seed.py: inserts one example ActivityDefinition
('example-heartbeat', cron every minute, static context source,
log_message task template). Idempotent — skips by name on re-run.

Run with:
  ACTCORE_DB_URL=postgresql+asyncpg://actcore:actcore@localhost:5433/actcore \
      python -m activity_core.seed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 21:53:59 +00:00

89 lines
2.6 KiB
Python

"""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))