diff --git a/alembic/versions/a4ec4f8f6e9f_add_month_lifecycle_state.py b/alembic/versions/a4ec4f8f6e9f_add_month_lifecycle_state.py new file mode 100644 index 0000000..fd89b7c --- /dev/null +++ b/alembic/versions/a4ec4f8f6e9f_add_month_lifecycle_state.py @@ -0,0 +1,40 @@ +"""add month lifecycle state + +Revision ID: a4ec4f8f6e9f +Revises: ec804bdf366d +Create Date: 2026-04-17 12:59:25.811354 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = 'a4ec4f8f6e9f' +down_revision: Union[str, Sequence[str], None] = 'ec804bdf366d' +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! ### + with op.batch_alter_table('month', schema=None) as batch_op: + batch_op.add_column(sa.Column('state', sa.Enum('planning', 'active', 'closed', name='monthstate', native_enum=False, length=16), server_default='planning', nullable=False)) + batch_op.add_column(sa.Column('activated_at', sa.DateTime(timezone=True), nullable=True)) + batch_op.add_column(sa.Column('closed_at', sa.DateTime(timezone=True), nullable=True)) + + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('month', schema=None) as batch_op: + batch_op.drop_column('closed_at') + batch_op.drop_column('activated_at') + batch_op.drop_column('state') + + # ### end Alembic commands ### diff --git a/src/quartermaster/models.py b/src/quartermaster/models.py index c2edacb..6d8f25a 100644 --- a/src/quartermaster/models.py +++ b/src/quartermaster/models.py @@ -27,6 +27,12 @@ class Section(str, enum.Enum): sinking_fund = "sinking_fund" +class MonthState(str, enum.Enum): + planning = "planning" + active = "active" + closed = "closed" + + SECTION_LABELS: dict[Section, str] = { Section.income: "Incomes", Section.fixed_bill: "Fixed Amount Bills", @@ -86,6 +92,18 @@ class Month(Base): id: Mapped[int] = mapped_column(primary_key=True) year_month: Mapped[str] = mapped_column(String(7), nullable=False, unique=True) + state: Mapped[MonthState] = mapped_column( + Enum(MonthState, native_enum=False, length=16), + nullable=False, + default=MonthState.planning, + server_default=MonthState.planning.value, + ) + activated_at: Mapped[datetime | None] = mapped_column( + DateTime(timezone=True), nullable=True + ) + closed_at: Mapped[datetime | None] = mapped_column( + DateTime(timezone=True), nullable=True + ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False )