Skip to content
41 changes: 41 additions & 0 deletions alembic/versions/20260218_add_simulation_filter_columns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""add filter_field and filter_value to simulations

Revision ID: add_sim_filters
Revises: merge_001
Create Date: 2026-02-18

The Simulation model already has filter_field and filter_value fields
(used for regional economy simulations), but no migration added them
to the database. This brings the schema in line with the model.
"""

from typing import Sequence, Union

import sqlmodel.sql.sqltypes

from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision: str = "add_sim_filters"
down_revision: Union[str, Sequence[str], None] = "merge_001"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Add filter_field and filter_value columns to simulations table."""
op.add_column(
"simulations",
sa.Column("filter_field", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
)
op.add_column(
"simulations",
sa.Column("filter_value", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
)


def downgrade() -> None:
"""Remove filter_field and filter_value columns from simulations table."""
op.drop_column("simulations", "filter_value")
op.drop_column("simulations", "filter_field")
43 changes: 43 additions & 0 deletions alembic/versions/20260218_drop_parent_report_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""drop parent_report_id from reports

Revision ID: drop_parent_report
Revises: add_sim_filters
Create Date: 2026-02-18

Remove the unused self-referential parent_report_id foreign key from
the reports table. No code reads or writes this column.
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision: str = "drop_parent_report"
down_revision: Union[str, Sequence[str], None] = "add_sim_filters"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Drop parent_report_id column and its FK constraint."""
op.drop_constraint(
"reports_parent_report_id_fkey", "reports", type_="foreignkey"
)
op.drop_column("reports", "parent_report_id")


def downgrade() -> None:
"""Re-add parent_report_id column and FK constraint."""
op.add_column(
"reports",
sa.Column("parent_report_id", sa.Uuid(), nullable=True),
)
op.create_foreign_key(
"reports_parent_report_id_fkey",
"reports",
"reports",
["parent_report_id"],
["id"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""merge user_policies and household_support branches

Revision ID: merge_001
Revises: 0002_user_policies, a1b2c3d4e5f6
Create Date: 2026-02-18

Merge the two migration branches that diverged from the initial schema:
- 0002_user_policies: added user_policies table + policy.tax_benefit_model_id
- f419b5f4acba → a1b2c3d4e5f6: added household support + regions table

No schema changes — both branches modify independent tables.
"""

from typing import Sequence, Union

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "merge_001"
down_revision: tuple[str, str] = ("0002_user_policies", "a1b2c3d4e5f6")
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""No schema changes — merge only."""
pass


def downgrade() -> None:
"""No schema changes — merge only."""
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""add user_simulation_associations table

Revision ID: 621977f3b1aa
Revises: drop_parent_report
Create Date: 2026-02-19 00:37:43.378088

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
import sqlmodel.sql.sqltypes


# revision identifiers, used by Alembic.
revision: str = '621977f3b1aa'
down_revision: Union[str, Sequence[str], None] = 'drop_parent_report'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('user_simulation_associations',
sa.Column('user_id', sa.Uuid(), nullable=False),
sa.Column('simulation_id', sa.Uuid(), nullable=False),
sa.Column('country_id', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column('label', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['simulation_id'], ['simulations.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_user_simulation_associations_simulation_id'), 'user_simulation_associations', ['simulation_id'], unique=False)
op.create_index(op.f('ix_user_simulation_associations_user_id'), 'user_simulation_associations', ['user_id'], unique=False)
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_user_simulation_associations_user_id'), table_name='user_simulation_associations')
op.drop_index(op.f('ix_user_simulation_associations_simulation_id'), table_name='user_simulation_associations')
op.drop_table('user_simulation_associations')
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""add user_report_associations table

Revision ID: 9daa015274dd
Revises: 621977f3b1aa
Create Date: 2026-02-19 16:58:03.157551

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
import sqlmodel.sql.sqltypes


# revision identifiers, used by Alembic.
revision: str = '9daa015274dd'
down_revision: Union[str, Sequence[str], None] = '621977f3b1aa'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('user_report_associations',
sa.Column('user_id', sa.Uuid(), nullable=False),
sa.Column('report_id', sa.Uuid(), nullable=False),
sa.Column('country_id', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column('label', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
sa.Column('last_run_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['report_id'], ['reports.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_user_report_associations_report_id'), 'user_report_associations', ['report_id'], unique=False)
op.create_index(op.f('ix_user_report_associations_user_id'), 'user_report_associations', ['user_id'], unique=False)
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_user_report_associations_user_id'), table_name='user_report_associations')
op.drop_index(op.f('ix_user_report_associations_report_id'), table_name='user_report_associations')
op.drop_table('user_report_associations')
# ### end Alembic commands ###
4 changes: 4 additions & 0 deletions src/policyengine_api/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
tax_benefit_models,
user_household_associations,
user_policies,
user_report_associations,
user_simulation_associations,
variables,
)

Expand All @@ -45,5 +47,7 @@
api_router.include_router(agent.router)
api_router.include_router(user_household_associations.router)
api_router.include_router(user_policies.router)
api_router.include_router(user_simulation_associations.router)
api_router.include_router(user_report_associations.router)

__all__ = ["api_router"]
Loading