feat: applied model mixins
All checks were successful
ci / ruff (push) Successful in 3s
ci / ty (push) Successful in 4s
ci / tests (push) Successful in 16s

IdMixin used on every table with an ID index (no changes needed to db)

Timestamp and Deleted mixins applied to org and user tables.

ActivatedMixin added to users.
This commit is contained in:
Chris Milne 2026-06-22 13:45:37 +01:00
parent 7e1ab6c6ee
commit c28b4dc37b
6 changed files with 60 additions and 15 deletions

View file

@ -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 ###

View file

@ -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)

View file

@ -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"))

View file

@ -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]

View file

@ -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]

View file

@ -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]