feat: add boards and tasks management endpoints

This commit is contained in:
Abhimanyu Saharan
2026-02-04 02:28:51 +05:30
parent 23faa0865b
commit 1abc8f68f3
170 changed files with 6860 additions and 10706 deletions

View File

@@ -1,37 +0,0 @@
# DB reset + seed (dev-machine)
This repo uses Alembic migrations as schema source-of-truth.
## Reset to the current seed
```bash
cd backend
./scripts/reset_db.sh
```
Environment variables (optional):
- `DB_NAME` (default `openclaw_agency`)
- `DB_USER` (default `postgres`)
- `DB_HOST` (default `127.0.0.1`)
- `DB_PORT` (default `5432`)
- `DB_PASSWORD` (default `postgres`)
## Updating the seed
The seed is a **data-only** dump (not schema). Regenerate it from the current DB state:
```bash
cd backend
PGPASSWORD=postgres pg_dump \
--data-only \
--column-inserts \
--disable-triggers \
--no-owner \
--no-privileges \
-U postgres -h 127.0.0.1 -d openclaw_agency \
> scripts/seed_data.sql
# IMPORTANT: do not include alembic_version in the seed (migrations already set it)
# (our committed seed already has this removed)
```

View File

@@ -1,9 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")/.."
. .venv/bin/activate
python -m black .
python -m isort .
python -m flake8 .

View File

@@ -1,55 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
DB_NAME=${DB_NAME:-openclaw_agency}
DB_USER=${DB_USER:-postgres}
DB_HOST=${DB_HOST:-127.0.0.1}
DB_PORT=${DB_PORT:-5432}
# Never hardcode passwords in git. Prefer:
# - DB_PASSWORD env var, or
# - infer from backend/.env DATABASE_URL
DB_PASSWORD=${DB_PASSWORD:-}
cd "$(dirname "$0")/.."
if [[ -z "${DB_PASSWORD}" ]] && [[ -f .env ]]; then
DB_PASSWORD=$(python3 - <<'PY'
import os
from pathlib import Path
from urllib.parse import urlparse
def parse_database_url(url: str) -> str:
# supports postgresql+psycopg://user:pass@host:port/db
u = urlparse(url)
return u.password or ""
for line in Path('.env').read_text().splitlines():
if line.startswith('DATABASE_URL='):
print(parse_database_url(line.split('=',1)[1].strip()))
break
PY
)
fi
if [[ -z "${DB_PASSWORD}" ]]; then
echo "ERROR: DB_PASSWORD not set and could not infer it from backend/.env DATABASE_URL" >&2
echo "Set DB_PASSWORD=... or create backend/.env with DATABASE_URL" >&2
exit 2
fi
export PGPASSWORD="$DB_PASSWORD"
# 1) wipe schema
psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -v ON_ERROR_STOP=1 \
-c 'DROP SCHEMA public CASCADE; CREATE SCHEMA public;'
# 2) migrate
. .venv/bin/activate
alembic upgrade head
# 3) seed
psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -v ON_ERROR_STOP=1 \
-f scripts/seed_data.sql
echo "Reset complete: $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME"

View File

@@ -1,50 +0,0 @@
-- Mission Control seed data (minimal)
-- Keep this data-only seed small and deterministic.
-- NOTE: Do NOT include alembic_version here; migrations manage it.
SET client_min_messages = warning;
SET row_security = off;
-- Disable triggers to avoid FK ordering issues during seed.
ALTER TABLE public.employees DISABLE TRIGGER ALL;
ALTER TABLE public.departments DISABLE TRIGGER ALL;
ALTER TABLE public.teams DISABLE TRIGGER ALL;
ALTER TABLE public.projects DISABLE TRIGGER ALL;
ALTER TABLE public.tasks DISABLE TRIGGER ALL;
ALTER TABLE public.task_comments DISABLE TRIGGER ALL;
ALTER TABLE public.project_members DISABLE TRIGGER ALL;
ALTER TABLE public.activities DISABLE TRIGGER ALL;
-- Employees (keep only Abhimanyu)
INSERT INTO public.employees (id, name, employee_type, department_id, manager_id, title, status, openclaw_session_key, notify_enabled, team_id)
VALUES
(1, 'Abhimanyu', 'human', NULL, NULL, 'CEO', 'active', NULL, false, NULL)
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
employee_type = EXCLUDED.employee_type,
department_id = EXCLUDED.department_id,
manager_id = EXCLUDED.manager_id,
title = EXCLUDED.title,
status = EXCLUDED.status,
openclaw_session_key = EXCLUDED.openclaw_session_key,
notify_enabled = EXCLUDED.notify_enabled,
team_id = EXCLUDED.team_id;
-- Fix sequences (avoid PK reuse after explicit ids)
SELECT setval('employees_id_seq', (SELECT COALESCE(max(id), 1) FROM public.employees));
SELECT setval('departments_id_seq', (SELECT COALESCE(max(id), 1) FROM public.departments));
SELECT setval('teams_id_seq', (SELECT COALESCE(max(id), 1) FROM public.teams));
SELECT setval('projects_id_seq', (SELECT COALESCE(max(id), 1) FROM public.projects));
SELECT setval('tasks_id_seq', (SELECT COALESCE(max(id), 1) FROM public.tasks));
SELECT setval('task_comments_id_seq', (SELECT COALESCE(max(id), 1) FROM public.task_comments));
SELECT setval('project_members_id_seq', (SELECT COALESCE(max(id), 1) FROM public.project_members));
SELECT setval('activities_id_seq', (SELECT COALESCE(max(id), 1) FROM public.activities));
ALTER TABLE public.employees ENABLE TRIGGER ALL;
ALTER TABLE public.departments ENABLE TRIGGER ALL;
ALTER TABLE public.teams ENABLE TRIGGER ALL;
ALTER TABLE public.projects ENABLE TRIGGER ALL;
ALTER TABLE public.tasks ENABLE TRIGGER ALL;
ALTER TABLE public.task_comments ENABLE TRIGGER ALL;
ALTER TABLE public.project_members ENABLE TRIGGER ALL;
ALTER TABLE public.activities ENABLE TRIGGER ALL;

View File

@@ -0,0 +1,46 @@
from __future__ import annotations
from uuid import uuid4
from sqlmodel import Session
from app.db.session import engine
from app.models.orgs import Org, Workspace
from app.models.users import Membership, User
def run() -> None:
with Session(engine) as session:
org = Org(name="Demo Org", slug="demo-org")
session.add(org)
session.commit()
session.refresh(org)
workspace = Workspace(org_id=org.id, name="Demo Workspace", slug="demo-workspace")
session.add(workspace)
session.commit()
session.refresh(workspace)
user = User(
clerk_user_id=f"demo-{uuid4()}",
email="demo@example.com",
name="Demo Admin",
is_super_admin=True,
)
session.add(user)
session.commit()
session.refresh(user)
membership = Membership(
org_id=org.id,
workspace_id=workspace.id,
user_id=user.id,
role="admin",
)
session.add(membership)
session.commit()
if __name__ == "__main__":
run()