Skip to content

Commit 6b865d6

Browse files
committed
⚗ trigger migration
1 parent 3a95cc4 commit 6b865d6

File tree

3 files changed

+91
-4
lines changed

3 files changed

+91
-4
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""Create chatbot triggers
2+
3+
Revision ID: e2a71c5767b1
4+
Revises: 2e8dc6b4f10c
5+
Create Date: 2025-06-15 22:26:27.946492
6+
7+
"""
8+
9+
import sqlalchemy as sa
10+
from alembic_utils.pg_extension import PGExtension
11+
from alembic_utils.pg_function import PGFunction
12+
from alembic_utils.pg_trigger import PGTrigger
13+
from sqlalchemy import text as sql_text
14+
from sqlalchemy.dialects import postgresql
15+
16+
from alembic import op
17+
18+
# revision identifiers, used by Alembic.
19+
revision = "e2a71c5767b1"
20+
down_revision = "2e8dc6b4f10c"
21+
branch_labels = None
22+
depends_on = None
23+
24+
25+
def upgrade():
26+
# ### commands auto generated by Alembic - please adjust! ###
27+
public_notify_flow_event = PGFunction(
28+
schema="public",
29+
signature="notify_flow_event()",
30+
definition="returns trigger LANGUAGE plpgsql\n AS $function$\n BEGIN\n -- Notify on session state changes with comprehensive event data\n IF TG_OP = 'INSERT' THEN\n PERFORM pg_notify(\n 'flow_events',\n json_build_object(\n 'event_type', 'session_started',\n 'session_id', NEW.id,\n 'flow_id', NEW.flow_id,\n 'user_id', NEW.user_id,\n 'current_node', NEW.current_node_id,\n 'status', NEW.status,\n 'revision', NEW.revision,\n 'timestamp', extract(epoch from NEW.created_at)\n )::text\n );\n RETURN NEW;\n ELSIF TG_OP = 'UPDATE' THEN\n -- Only notify on significant state changes\n IF OLD.current_node_id != NEW.current_node_id \n OR OLD.status != NEW.status \n OR OLD.revision != NEW.revision THEN\n PERFORM pg_notify(\n 'flow_events',\n json_build_object(\n 'event_type', CASE \n WHEN OLD.status != NEW.status THEN 'session_status_changed'\n WHEN OLD.current_node_id != NEW.current_node_id THEN 'node_changed'\n ELSE 'session_updated'\n END,\n 'session_id', NEW.id,\n 'flow_id', NEW.flow_id,\n 'user_id', NEW.user_id,\n 'current_node', NEW.current_node_id,\n 'previous_node', OLD.current_node_id,\n 'status', NEW.status,\n 'previous_status', OLD.status,\n 'revision', NEW.revision,\n 'previous_revision', OLD.revision,\n 'timestamp', extract(epoch from NEW.updated_at)\n )::text\n );\n END IF;\n RETURN NEW;\n ELSIF TG_OP = 'DELETE' THEN\n PERFORM pg_notify(\n 'flow_events',\n json_build_object(\n 'event_type', 'session_deleted',\n 'session_id', OLD.id,\n 'flow_id', OLD.flow_id,\n 'user_id', OLD.user_id,\n 'timestamp', extract(epoch from NOW())\n )::text\n );\n RETURN OLD;\n END IF;\n RETURN NULL;\n END;\n $function$",
31+
)
32+
op.create_entity(public_notify_flow_event)
33+
34+
public_conversation_sessions_conversation_sessions_notify_flow_event_trigger = PGTrigger(
35+
schema="public",
36+
signature="conversation_sessions_notify_flow_event_trigger",
37+
on_entity="public.conversation_sessions",
38+
is_constraint=False,
39+
definition="AFTER INSERT OR UPDATE OR DELETE ON public.conversation_sessions \n FOR EACH ROW EXECUTE FUNCTION notify_flow_event()",
40+
)
41+
op.create_entity(
42+
public_conversation_sessions_conversation_sessions_notify_flow_event_trigger
43+
)
44+
45+
public_collection_items_update_collections_trigger = PGTrigger(
46+
schema="public",
47+
signature="update_collections_trigger",
48+
on_entity="public.collection_items",
49+
is_constraint=False,
50+
definition="AFTER INSERT OR UPDATE ON public.collection_items FOR EACH ROW EXECUTE FUNCTION update_collections_function()",
51+
)
52+
op.drop_entity(public_collection_items_update_collections_trigger)
53+
54+
# ### end Alembic commands ###
55+
56+
57+
def downgrade():
58+
# ### commands auto generated by Alembic - please adjust! ###
59+
60+
public_collection_items_update_collections_trigger = PGTrigger(
61+
schema="public",
62+
signature="update_collections_trigger",
63+
on_entity="public.collection_items",
64+
is_constraint=False,
65+
definition="AFTER INSERT OR UPDATE ON public.collection_items FOR EACH ROW EXECUTE FUNCTION update_collections_function()",
66+
)
67+
op.create_entity(public_collection_items_update_collections_trigger)
68+
69+
public_conversation_sessions_conversation_sessions_notify_flow_event_trigger = PGTrigger(
70+
schema="public",
71+
signature="conversation_sessions_notify_flow_event_trigger",
72+
on_entity="public.conversation_sessions",
73+
is_constraint=False,
74+
definition="AFTER INSERT OR UPDATE OR DELETE ON public.conversation_sessions \n FOR EACH ROW EXECUTE FUNCTION notify_flow_event()",
75+
)
76+
op.drop_entity(
77+
public_conversation_sessions_conversation_sessions_notify_flow_event_trigger
78+
)
79+
80+
public_notify_flow_event = PGFunction(
81+
schema="public",
82+
signature="notify_flow_event()",
83+
definition="returns trigger LANGUAGE plpgsql\n AS $function$\n BEGIN\n -- Notify on session state changes with comprehensive event data\n IF TG_OP = 'INSERT' THEN\n PERFORM pg_notify(\n 'flow_events',\n json_build_object(\n 'event_type', 'session_started',\n 'session_id', NEW.id,\n 'flow_id', NEW.flow_id,\n 'user_id', NEW.user_id,\n 'current_node', NEW.current_node_id,\n 'status', NEW.status,\n 'revision', NEW.revision,\n 'timestamp', extract(epoch from NEW.created_at)\n )::text\n );\n RETURN NEW;\n ELSIF TG_OP = 'UPDATE' THEN\n -- Only notify on significant state changes\n IF OLD.current_node_id != NEW.current_node_id \n OR OLD.status != NEW.status \n OR OLD.revision != NEW.revision THEN\n PERFORM pg_notify(\n 'flow_events',\n json_build_object(\n 'event_type', CASE \n WHEN OLD.status != NEW.status THEN 'session_status_changed'\n WHEN OLD.current_node_id != NEW.current_node_id THEN 'node_changed'\n ELSE 'session_updated'\n END,\n 'session_id', NEW.id,\n 'flow_id', NEW.flow_id,\n 'user_id', NEW.user_id,\n 'current_node', NEW.current_node_id,\n 'previous_node', OLD.current_node_id,\n 'status', NEW.status,\n 'previous_status', OLD.status,\n 'revision', NEW.revision,\n 'previous_revision', OLD.revision,\n 'timestamp', extract(epoch from NEW.updated_at)\n )::text\n );\n END IF;\n RETURN NEW;\n ELSIF TG_OP = 'DELETE' THEN\n PERFORM pg_notify(\n 'flow_events',\n json_build_object(\n 'event_type', 'session_deleted',\n 'session_id', OLD.id,\n 'flow_id', OLD.flow_id,\n 'user_id', OLD.user_id,\n 'timestamp', extract(epoch from NOW())\n )::text\n );\n RETURN OLD;\n END IF;\n RETURN NULL;\n END;\n $function$",
84+
)
85+
op.drop_entity(public_notify_flow_event)
86+
87+
# ### end Alembic commands ###

app/crud/collection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ def _update_item_in_collection(
229229
logger.warning("Skipping update of info for missing item in collection")
230230
return
231231
info_dict = dict(item_orm_object.info)
232-
info_update_dict = item_update.info.dict(exclude_unset=True)
232+
info_update_dict = item_update.info.model_dump(exclude_unset=True)
233233

234234
if image_data := info_update_dict.get("cover_image"):
235235
logger.debug(
@@ -352,7 +352,7 @@ def add_item_to_collection(
352352

353353
info_dict = {}
354354
if item.info is not None:
355-
info_dict = item.info.dict(exclude_unset=True)
355+
info_dict = item.info.model_dump(exclude_unset=True)
356356

357357
if cover_image_data := info_dict.get("cover_image"):
358358
logger.debug("Processing cover image for new collection item")

app/tests/integration/test_editions_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def test_update_edition_work(client, backend_service_account_headers, works_list
1616

1717
update_response = client.patch(
1818
f"v1/edition/{test_edition.isbn}",
19-
json=edition_update_with_new_work.dict(exclude_unset=True),
19+
json=edition_update_with_new_work.model_dump(exclude_unset=True),
2020
headers=backend_service_account_headers,
2121
)
2222
update_response.raise_for_status()
@@ -28,7 +28,7 @@ def test_update_edition_work(client, backend_service_account_headers, works_list
2828

2929
revert_response = client.patch(
3030
f"v1/edition/{test_edition.isbn}",
31-
json=edition_update_with_og_work.dict(exclude_unset=True),
31+
json=edition_update_with_og_work.model_dump(exclude_unset=True),
3232
headers=backend_service_account_headers,
3333
)
3434
revert_response.raise_for_status()

0 commit comments

Comments
 (0)