mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-28 08:49:42 +02:00
feat: agent versioning and model configurations override (#227)
* feat: add tests and migrations * feat: workflow versioning among published and draft * feat: add a new settings page to simplify workflow detail page * fix: fix tsclient generation
This commit is contained in:
parent
f5fa9ce717
commit
38d1d928b7
62 changed files with 10158 additions and 3131 deletions
|
|
@ -0,0 +1,132 @@
|
|||
"""add versioning in workflow definitions
|
||||
|
||||
Revision ID: a399b39479fe
|
||||
Revises: c71db647d354
|
||||
Create Date: 2026-04-07 14:43:50.042973
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "a399b39479fe"
|
||||
down_revision: Union[str, None] = "c71db647d354"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index(op.f("ix_api_keys_key_hash"), table_name="api_keys")
|
||||
op.create_index(op.f("ix_api_keys_key_hash"), "api_keys", ["key_hash"], unique=True)
|
||||
op.add_column(
|
||||
"workflow_definitions",
|
||||
sa.Column(
|
||||
"status", sa.String(), server_default=sa.text("'published'"), nullable=False
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"workflow_definitions", sa.Column("version_number", sa.Integer(), nullable=True)
|
||||
)
|
||||
op.add_column(
|
||||
"workflow_definitions",
|
||||
sa.Column("published_at", sa.DateTime(timezone=True), nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"workflow_definitions",
|
||||
sa.Column(
|
||||
"workflow_configurations",
|
||||
sa.JSON(),
|
||||
server_default=sa.text("'{}'::json"),
|
||||
nullable=False,
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"workflow_definitions",
|
||||
sa.Column(
|
||||
"template_context_variables",
|
||||
sa.JSON(),
|
||||
server_default=sa.text("'{}'::json"),
|
||||
nullable=False,
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"workflow_definitions",
|
||||
sa.Column(
|
||||
"call_disposition_codes",
|
||||
sa.JSON(),
|
||||
server_default=sa.text("'{}'::json"),
|
||||
nullable=False,
|
||||
),
|
||||
)
|
||||
op.alter_column(
|
||||
"workflow_definitions",
|
||||
"workflow_hash",
|
||||
existing_type=sa.VARCHAR(),
|
||||
nullable=True,
|
||||
)
|
||||
op.drop_index(
|
||||
op.f("ix_workflow_hash_workflow_id"), table_name="workflow_definitions"
|
||||
)
|
||||
op.drop_constraint(
|
||||
op.f("uq_workflow_hash_workflow_id"), "workflow_definitions", type_="unique"
|
||||
)
|
||||
op.create_index(
|
||||
"ix_workflow_definitions_workflow_status",
|
||||
"workflow_definitions",
|
||||
["workflow_id", "status"],
|
||||
unique=False,
|
||||
)
|
||||
op.add_column(
|
||||
"workflows", sa.Column("released_definition_id", sa.Integer(), nullable=True)
|
||||
)
|
||||
op.create_foreign_key(
|
||||
None,
|
||||
"workflows",
|
||||
"workflow_definitions",
|
||||
["released_definition_id"],
|
||||
["id"],
|
||||
use_alter=True,
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint(None, "workflows", type_="foreignkey")
|
||||
op.drop_column("workflows", "released_definition_id")
|
||||
op.drop_index(
|
||||
"ix_workflow_definitions_workflow_status", table_name="workflow_definitions"
|
||||
)
|
||||
op.create_unique_constraint(
|
||||
op.f("uq_workflow_hash_workflow_id"),
|
||||
"workflow_definitions",
|
||||
["workflow_hash", "workflow_id"],
|
||||
postgresql_nulls_not_distinct=False,
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_workflow_hash_workflow_id"),
|
||||
"workflow_definitions",
|
||||
["workflow_hash", "workflow_id"],
|
||||
unique=False,
|
||||
)
|
||||
op.alter_column(
|
||||
"workflow_definitions",
|
||||
"workflow_hash",
|
||||
existing_type=sa.VARCHAR(),
|
||||
nullable=False,
|
||||
)
|
||||
op.drop_column("workflow_definitions", "call_disposition_codes")
|
||||
op.drop_column("workflow_definitions", "template_context_variables")
|
||||
op.drop_column("workflow_definitions", "workflow_configurations")
|
||||
op.drop_column("workflow_definitions", "published_at")
|
||||
op.drop_column("workflow_definitions", "version_number")
|
||||
op.drop_column("workflow_definitions", "status")
|
||||
op.drop_index(op.f("ix_api_keys_key_hash"), table_name="api_keys")
|
||||
op.create_index(
|
||||
op.f("ix_api_keys_key_hash"), "api_keys", ["key_hash"], unique=False
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
"""backfill workflow definition versioning
|
||||
|
||||
Copy workflow_configurations, template_context_variables, call_disposition_codes
|
||||
from the workflows table into the is_current=True definition for each workflow.
|
||||
Set that definition as status='published', version_number=1.
|
||||
Set all other definitions to status='archived'.
|
||||
Point workflows.released_definition_id to the published definition.
|
||||
|
||||
Revision ID: d688d0da1123
|
||||
Revises: a399b39479fe
|
||||
Create Date: 2026-04-07 15:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "d688d0da1123"
|
||||
down_revision: Union[str, None] = "a399b39479fe"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
conn = op.get_bind()
|
||||
|
||||
# Step 1: For each workflow's is_current=True definition, copy configs from
|
||||
# the workflow table and mark as published with version_number=1.
|
||||
conn.execute(
|
||||
sa.text("""
|
||||
UPDATE workflow_definitions wd
|
||||
SET
|
||||
workflow_configurations = w.workflow_configurations,
|
||||
template_context_variables = w.template_context_variables,
|
||||
status = 'published',
|
||||
version_number = 1,
|
||||
published_at = wd.created_at
|
||||
FROM workflows w
|
||||
WHERE wd.workflow_id = w.id
|
||||
AND wd.is_current = true
|
||||
""")
|
||||
)
|
||||
|
||||
# Step 2: Mark all pre-versioning non-current definitions as legacy.
|
||||
conn.execute(
|
||||
sa.text("""
|
||||
UPDATE workflow_definitions
|
||||
SET status = 'legacy'
|
||||
WHERE is_current = false
|
||||
""")
|
||||
)
|
||||
|
||||
# Step 3: Set released_definition_id on workflows to their published definition.
|
||||
conn.execute(
|
||||
sa.text("""
|
||||
UPDATE workflows w
|
||||
SET released_definition_id = wd.id
|
||||
FROM workflow_definitions wd
|
||||
WHERE wd.workflow_id = w.id
|
||||
AND wd.is_current = true
|
||||
""")
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
conn = op.get_bind()
|
||||
|
||||
# Clear the released pointer
|
||||
conn.execute(
|
||||
sa.text("""
|
||||
UPDATE workflows SET released_definition_id = NULL
|
||||
""")
|
||||
)
|
||||
|
||||
# Reset all definitions back to server defaults
|
||||
conn.execute(
|
||||
sa.text("""
|
||||
UPDATE workflow_definitions
|
||||
SET
|
||||
status = 'published',
|
||||
version_number = NULL,
|
||||
published_at = NULL,
|
||||
workflow_configurations = '{}',
|
||||
template_context_variables = '{}'
|
||||
""")
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue