diff --git a/alembic/versions/2026-06-22_model_mixins.py b/alembic/versions/2026-06-22_model_mixins.py new file mode 100644 index 0000000..db030e1 --- /dev/null +++ b/alembic/versions/2026-06-22_model_mixins.py @@ -0,0 +1,44 @@ +"""model mixins + +Revision ID: 661202797ecd +Revises: 869d48618a1c +Create Date: 2026-06-22 13:29:39.689067 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = '661202797ecd' +down_revision: Union[str, Sequence[str], None] = '869d48618a1c' +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.add_column('organisation', sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now())) + op.add_column('organisation', sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now())) + op.add_column('organisation', sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True)) + op.add_column('user', sa.Column('active', sa.Boolean(), nullable=False, server_default=sa.false())) + op.add_column('user', sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now())) + op.add_column('user', sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now())) + op.add_column('user', sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True)) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('user', 'deleted_at') + op.drop_column('user', 'updated_at') + op.drop_column('user', 'created_at') + op.drop_column('user', 'active') + op.drop_column('organisation', 'deleted_at') + op.drop_column('organisation', 'updated_at') + op.drop_column('organisation', 'created_at') + # ### end Alembic commands ### diff --git a/src/contact/models.py b/src/contact/models.py index ca359cd..37665e5 100644 --- a/src/contact/models.py +++ b/src/contact/models.py @@ -6,16 +6,17 @@ Models: street_address, street_address_line_2, post_office_box_number, address_locality, country_code, address_region, postal_code """ +from src.models import IdMixin + from sqlalchemy import ForeignKey from sqlalchemy.orm import mapped_column, Mapped from src.models import CustomBase -class Contact(CustomBase): +class Contact(CustomBase, IdMixin): __tablename__ = "contact" - id: Mapped[int] = mapped_column(primary_key=True) email: Mapped[str] = mapped_column(default=None, nullable=True) first_name: Mapped[str] = mapped_column(default=None, nullable=True) last_name: Mapped[str] = mapped_column(default=None, nullable=True) diff --git a/src/iam/models.py b/src/iam/models.py index 1f6d9ba..7fdb7c7 100644 --- a/src/iam/models.py +++ b/src/iam/models.py @@ -21,13 +21,12 @@ Models: from sqlalchemy import ForeignKey, UniqueConstraint from sqlalchemy.orm import relationship, mapped_column, Mapped -from src.models import CustomBase +from src.models import CustomBase, IdMixin -class Permission(CustomBase): +class Permission(CustomBase, IdMixin): __tablename__ = "permission" - id: Mapped[int] = mapped_column(primary_key=True) resource: Mapped[str] action: Mapped[str] @@ -61,9 +60,9 @@ class Permission(CustomBase): return self.service_rel.name -class Group(CustomBase): +class Group(CustomBase, IdMixin): __tablename__ = "group" - id: Mapped[int] = mapped_column(primary_key=True) + name: Mapped[str] org_id: Mapped[int] = mapped_column(ForeignKey("organisation.id", ondelete="CASCADE")) diff --git a/src/organisation/models.py b/src/organisation/models.py index e6f5acf..97d1247 100644 --- a/src/organisation/models.py +++ b/src/organisation/models.py @@ -14,18 +14,19 @@ Models: - OrgUsers: org_id[FK][PK], user_id[FK][PK] """ +from src.models import IdMixin, DeletedTimestampMixin + from typing import Any from sqlalchemy import ForeignKey from sqlalchemy.orm import relationship, Mapped, mapped_column -from src.models import CustomBase +from src.models import CustomBase, TimestampMixin -class Organisation(CustomBase): +class Organisation(CustomBase, IdMixin, TimestampMixin, DeletedTimestampMixin): __tablename__ = "organisation" - id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] status: Mapped[str] = mapped_column(default="partial") intake_questionnaire: Mapped[dict[str, Any] | None] diff --git a/src/service/models.py b/src/service/models.py index 63719a6..de6dcd6 100644 --- a/src/service/models.py +++ b/src/service/models.py @@ -8,13 +8,12 @@ Models: from sqlalchemy.orm import relationship, mapped_column, Mapped -from src.models import CustomBase +from src.models import CustomBase, IdMixin -class Service(CustomBase): +class Service(CustomBase, IdMixin): __tablename__ = "service" - id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(unique=True) api_key: Mapped[str] diff --git a/src/user/models.py b/src/user/models.py index 5f603ee..4803d54 100644 --- a/src/user/models.py +++ b/src/user/models.py @@ -10,6 +10,8 @@ Models: - groups: Calc property dict of {group_rel.org_rel.name: group_rel.name} """ +from src.models import IdMixin, ActivatedMixin, TimestampMixin, DeletedTimestampMixin + from collections import defaultdict from sqlalchemy.orm import relationship, mapped_column, Mapped @@ -17,10 +19,9 @@ from sqlalchemy.orm import relationship, mapped_column, Mapped from src.models import CustomBase -class User(CustomBase): +class User(CustomBase, IdMixin, ActivatedMixin, TimestampMixin, DeletedTimestampMixin): __tablename__ = "user" - id: Mapped[int] = mapped_column(primary_key=True) email: Mapped[str] first_name: Mapped[str] last_name: Mapped[str]