feat: auto-seed in dev mode on startup if DB empty
Some checks failed
Deploy Tracker / deploy (push) Failing after 4s

This commit is contained in:
markov 2026-02-25 08:41:44 +01:00
parent 7a58cf97c8
commit ce98d45712
2 changed files with 72 additions and 76 deletions

View File

@ -64,6 +64,15 @@ async def lifespan(app: FastAPI):
await conn.run_sync(Base.metadata.create_all)
logger.info("Database tables ensured.")
# Auto-seed if DB is empty (dev only)
async with async_session() as session:
result = await session.execute(select(Member).limit(1))
if not result.scalar_one_or_none():
logger.info("Empty DB detected in dev mode — running seed...")
from tracker.init_db import seed_dev_data
await seed_dev_data(session)
logger.info("Dev seed complete.")
heartbeat_task = asyncio.create_task(heartbeat_monitor())
yield
heartbeat_task.cancel()

View File

@ -1,11 +1,11 @@
"""Initialize database — drop all and create fresh tables + seed data."""
"""Initialize database — dev seed data."""
import asyncio
import hashlib
import logging
import uuid
from tracker.database import engine, async_session
from sqlalchemy.ext.asyncio import AsyncSession
from tracker.enums import AuthMethod, ChatKind, MemberRole, MemberStatus, MemberType, ProjectStatus
from tracker.models import Base, Member, Chat, Project, ProjectMember, AgentConfig
@ -16,85 +16,72 @@ def hash_password(password: str) -> str:
return hashlib.sha256(password.encode()).hexdigest()
async def init_db():
"""Drop all tables and recreate from models. Seed with admin + lobby."""
async def seed_dev_data(session: AsyncSession):
"""Seed dev data into an existing session. Expects empty DB."""
# Admin (owner)
admin = Member(
name="Admin",
slug="admin",
type=MemberType.HUMAN,
role=MemberRole.OWNER,
auth_method=AuthMethod.PASSWORD,
password_hash=hash_password("teamboard"),
status=MemberStatus.OFFLINE,
)
session.add(admin)
# Coder agent (for dev/testing)
coder = Member(
name="Coder",
slug="coder",
type=MemberType.AGENT,
role=MemberRole.MEMBER,
auth_method=AuthMethod.TOKEN,
token="tb-coder-dev-token",
status=MemberStatus.OFFLINE,
)
session.add(coder)
await session.flush()
# Team-board project
project = Project(
name="Team Board",
slug="team-board",
description="AI agent collaboration platform",
status=ProjectStatus.ACTIVE,
)
session.add(project)
await session.flush()
# Project chat
project_chat = Chat(kind=ChatKind.PROJECT, project_id=project.id)
session.add(project_chat)
# Project members
session.add(ProjectMember(project_id=project.id, member_id=admin.id, role=MemberRole.OWNER))
session.add(ProjectMember(project_id=project.id, member_id=coder.id, role=MemberRole.MEMBER))
# Lobby chat
lobby = Chat(kind=ChatKind.LOBBY, project_id=None)
session.add(lobby)
await session.commit()
logger.info("Dev seed: admin, coder, project team-board (id=%s), lobby", project.id)
async def reset_db():
"""Drop all tables, recreate, and seed. For dev use only."""
from tracker.database import engine, async_session
async with engine.begin() as conn:
logger.info("Dropping all tables...")
await conn.run_sync(Base.metadata.drop_all)
logger.info("Creating all tables...")
await conn.run_sync(Base.metadata.create_all)
logger.info("Tables recreated.")
async with async_session() as session:
# Create admin (owner)
admin = Member(
name="Admin",
slug="admin",
type=MemberType.HUMAN,
role=MemberRole.OWNER,
auth_method=AuthMethod.PASSWORD,
password_hash=hash_password("teamboard"),
status=MemberStatus.OFFLINE,
)
session.add(admin)
# Create coder agent
coder = Member(
name="Coder",
slug="coder",
type=MemberType.AGENT,
role=MemberRole.MEMBER,
auth_method=AuthMethod.TOKEN,
token="tb-coder-dev-token",
status=MemberStatus.OFFLINE,
)
session.add(coder)
# Flush to get member IDs
await session.flush()
# Create team-board project
project = Project(
name="Team Board",
slug="team-board",
description="AI agent collaboration platform",
status=ProjectStatus.ACTIVE,
)
session.add(project)
await session.flush()
# Create project chat
project_chat = Chat(
kind=ChatKind.PROJECT,
project_id=project.id,
)
session.add(project_chat)
# Create project members
admin_member = ProjectMember(
project_id=project.id,
member_id=admin.id,
role=MemberRole.OWNER,
)
session.add(admin_member)
coder_member = ProjectMember(
project_id=project.id,
member_id=coder.id,
role=MemberRole.MEMBER,
)
session.add(coder_member)
# Create lobby chat
lobby = Chat(
kind=ChatKind.LOBBY,
project_id=None,
)
session.add(lobby)
await session.commit()
logger.info("Seed data created: admin user, coder agent, team-board project (id=%s), lobby chat (id=%s)", project.id, lobby.id)
await seed_dev_data(session)
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
asyncio.run(init_db())
asyncio.run(reset_db())