generated from coulomb/repo-seed
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>
This commit is contained in:
88
src/activity_core/seed.py
Normal file
88
src/activity_core/seed.py
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
"""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))
|
||||||
@@ -52,7 +52,7 @@ tasks:
|
|||||||
state_hub_task_id: 491a6903-8189-43bb-958f-4d16abc84f8e
|
state_hub_task_id: 491a6903-8189-43bb-958f-4d16abc84f8e
|
||||||
- id: T12
|
- id: T12
|
||||||
title: Seed one example ActivityDefinition
|
title: Seed one example ActivityDefinition
|
||||||
status: todo
|
status: done
|
||||||
state_hub_task_id: f24662ff-4a26-48bd-b997-57e7586c7f11
|
state_hub_task_id: f24662ff-4a26-48bd-b997-57e7586c7f11
|
||||||
- id: T13
|
- id: T13
|
||||||
title: Scaffold Python worker project
|
title: Scaffold Python worker project
|
||||||
|
|||||||
Reference in New Issue
Block a user