fix(db): linearize Alembic migration chain to resolve branch conflicts
This commit is contained in:
parent
f8f885a499
commit
7cc9e86de1
|
|
@ -510,14 +510,32 @@ async def get_runtime_usage(
|
||||||
"""
|
"""
|
||||||
now = utcnow()
|
now = utcnow()
|
||||||
|
|
||||||
cost_raw, status_raw = await asyncio.gather(
|
cost_raw, status_raw, sessions_raw = await asyncio.gather(
|
||||||
_safe_call("usage.cost", config),
|
_safe_call("usage.cost", config),
|
||||||
_safe_call("usage.status", config),
|
_safe_call("usage.status", config),
|
||||||
|
_safe_call("sessions.list", config),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Extract sessions from sessions.list response (primary source)
|
||||||
|
# Fallback to usage.cost if sessions.list fails
|
||||||
|
if isinstance(sessions_raw, dict):
|
||||||
|
raw_sessions = sessions_raw.get("sessions") or []
|
||||||
|
elif isinstance(sessions_raw, list):
|
||||||
|
raw_sessions = sessions_raw
|
||||||
|
else:
|
||||||
|
raw_sessions = []
|
||||||
|
|
||||||
|
# Filter to dicts and merge with usage.cost data if available
|
||||||
|
sessions: list[dict[str, Any]] = []
|
||||||
|
if raw_sessions:
|
||||||
|
sessions = [s for s in raw_sessions if isinstance(s, dict)]
|
||||||
|
else:
|
||||||
|
# Fallback: parse from usage.cost response
|
||||||
|
sessions = _parse_sessions(cost_raw)
|
||||||
|
|
||||||
# Merge both payloads — some gateways return everything in one response
|
# Merge both payloads — some gateways return everything in one response
|
||||||
merged_status = {**cost_raw, **status_raw}
|
merged_status = {**cost_raw, **status_raw}
|
||||||
|
|
||||||
sessions = _parse_sessions(cost_raw)
|
|
||||||
per_model = aggregate_per_model(sessions, account_key=account_key)
|
per_model = aggregate_per_model(sessions, account_key=account_key)
|
||||||
window = _build_window(merged_status, now)
|
window = _build_window(merged_status, now)
|
||||||
current = _build_current(per_model, merged_status)
|
current = _build_current(per_model, merged_status)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
"""Add board_webhooks table.
|
||||||
|
|
||||||
|
Revision ID: a1b2c3d4e5f5
|
||||||
|
Revises: 658dca8f4a11
|
||||||
|
Create Date: 2026-03-03 00:00:00.000000
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
import sqlmodel
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "a1b2c3d4e5f5"
|
||||||
|
down_revision = "4c1f5e2a7b9d"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
"""Create board_webhooks table."""
|
||||||
|
op.create_table(
|
||||||
|
"board_webhooks",
|
||||||
|
sa.Column("id", sa.Uuid(), nullable=False),
|
||||||
|
sa.Column("board_id", sa.Uuid(), nullable=False),
|
||||||
|
sa.Column("agent_id", sa.Uuid(), nullable=True),
|
||||||
|
sa.Column("description", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||||
|
sa.Column("enabled", sa.Boolean(), nullable=False),
|
||||||
|
sa.Column("secret", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||||
|
sa.Column("signature_header", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||||
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
||||||
|
sa.Column("updated_at", sa.DateTime(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["board_id"],
|
||||||
|
["boards.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["agent_id"],
|
||||||
|
["agents.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_board_webhooks_board_id"),
|
||||||
|
"board_webhooks",
|
||||||
|
["board_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_board_webhooks_agent_id"),
|
||||||
|
"board_webhooks",
|
||||||
|
["agent_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_board_webhooks_enabled"),
|
||||||
|
"board_webhooks",
|
||||||
|
["enabled"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
"""Drop board_webhooks table."""
|
||||||
|
op.drop_index(op.f("ix_board_webhooks_enabled"), table_name="board_webhooks")
|
||||||
|
op.drop_index(op.f("ix_board_webhooks_agent_id"), table_name="board_webhooks")
|
||||||
|
op.drop_index(op.f("ix_board_webhooks_board_id"), table_name="board_webhooks")
|
||||||
|
op.drop_table("board_webhooks")
|
||||||
|
|
@ -13,7 +13,7 @@ from alembic import op
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = "a1b2c3d4e5f6"
|
revision = "a1b2c3d4e5f6"
|
||||||
down_revision = "f1b2c3d4e5a6"
|
down_revision = "a1b2c3d4e5f5"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ from alembic import op
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = "a2f6c9d4b7e8"
|
revision = "a2f6c9d4b7e8"
|
||||||
down_revision = "4c1f5e2a7b9d"
|
down_revision = "d1e2f3a4b5c6"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ from alembic import op
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = "b7a1d9c3e4f5"
|
revision = "b7a1d9c3e4f5"
|
||||||
down_revision = "a2f6c9d4b7e8"
|
down_revision = "a9b1c2d3e4f7"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ from alembic import op
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = "c5d1a2b3e4f6"
|
revision = "c5d1a2b3e4f6"
|
||||||
down_revision = "b7a1d9c3e4f5"
|
down_revision = "c1d2e3f4a5b6"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import sqlalchemy as sa
|
||||||
from alembic import op
|
from alembic import op
|
||||||
|
|
||||||
revision = "d1e2f3a4b5c6"
|
revision = "d1e2f3a4b5c6"
|
||||||
down_revision = "c1d2e3f4a5b6"
|
down_revision = "f1b2c3d4e5a6"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ from alembic import op
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = "f5a2b3c4d5e6"
|
revision = "f5a2b3c4d5e6"
|
||||||
down_revision = "a9b1c2d3e4f7"
|
down_revision = "b7a1d9c3e4f5"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,15 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# docker-test.sh — Rebuild and redeploy Pipeline locally from scratch.
|
# docker-test.sh — Rebuild and redeploy Pipeline locally from scratch.
|
||||||
# Clears all Docker cache before building to ensure a clean slate.
|
# Cleans only Pipeline Docker resources before building.
|
||||||
|
# IMPORTANT: Do not add global Docker cleanup here (for example `docker system prune`).
|
||||||
|
# This script must only stop/remove resources for the Pipeline compose project.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
cd "$(git rev-parse --show-toplevel)"
|
cd "$(git rev-parse --show-toplevel)"
|
||||||
|
|
||||||
echo "=== Stopping and removing existing containers, images, volumes ==="
|
echo "=== Stopping and removing Pipeline containers, images, volumes ==="
|
||||||
docker compose down --rmi all --volumes --remove-orphans 2>/dev/null || true
|
docker compose down --rmi all --volumes --remove-orphans 2>/dev/null || true
|
||||||
|
|
||||||
echo "=== Pruning all dangling Docker resources ==="
|
|
||||||
docker system prune -a --volumes -f
|
|
||||||
|
|
||||||
echo "=== Removing Pipeline build cache ==="
|
|
||||||
docker builder prune -f 2>/dev/null || true
|
|
||||||
|
|
||||||
echo "=== Building and starting all containers ==="
|
echo "=== Building and starting all containers ==="
|
||||||
docker compose up --build -d
|
docker compose up --build -d
|
||||||
|
|
||||||
|
|
@ -25,5 +21,5 @@ docker compose ps
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== Deploy complete ==="
|
echo "=== Deploy complete ==="
|
||||||
echo "Frontend: http://localhost:3030"
|
echo 'Frontend: http://localhost:3030'
|
||||||
echo "Backend: http://localhost:8001"
|
echo 'Backend: http://localhost:8001'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue