This commit is contained in:
2026-07-17 20:03:41 +03:00
parent 4512eb6e5c
commit 4fd66e0106
7 changed files with 71 additions and 64 deletions

View File

@@ -1,8 +1,8 @@
from logging.config import fileConfig from logging.config import fileConfig
from src.models.database_models.model import engine, Model from src.models.database_models import Model
import src.models.database_models.model as models from src.models.database_models.model import engine
from sqlalchemy import engine_from_config from sqlalchemy import engine_from_config
from sqlalchemy import pool from sqlalchemy import pool

View File

@@ -1,8 +1,8 @@
"""empty message """empty message
Revision ID: 83b4c2ae88d3 Revision ID: 5e60c8fbc553
Revises: Revises:
Create Date: 2026-07-17 15:00:15.263996 Create Date: 2026-07-17 20:02:01.237457
""" """
from typing import Sequence, Union from typing import Sequence, Union
@@ -11,9 +11,8 @@ from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.sql import text from sqlalchemy.sql import text
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision: str = '83b4c2ae88d3' revision: str = '5e60c8fbc553'
down_revision: Union[str, Sequence[str], None] = None down_revision: Union[str, Sequence[str], None] = None
branch_labels: Union[str, Sequence[str], None] = None branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None
@@ -41,6 +40,16 @@ def upgrade() -> None:
batch_op.create_index(batch_op.f('ix_permissions_id'), ['id'], unique=False) batch_op.create_index(batch_op.f('ix_permissions_id'), ['id'], unique=False)
op.execute(text("INSERT INTO permissions (permission) VALUES ('admin');")) op.execute(text("INSERT INTO permissions (permission) VALUES ('admin');"))
op.create_table('reports',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('filename', sa.String(length=255), nullable=False),
sa.Column('created_at', sa.TIMESTAMP(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_reports'))
)
with op.batch_alter_table('reports', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_reports_filename'), ['filename'], unique=False)
batch_op.create_index(batch_op.f('ix_reports_id'), ['id'], unique=False)
op.create_table('users', op.create_table('users',
sa.Column('id', sa.Uuid(), nullable=False), sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('first_name', sa.String(length=64), nullable=False), sa.Column('first_name', sa.String(length=64), nullable=False),
@@ -64,6 +73,25 @@ def upgrade() -> None:
sa.ForeignKeyConstraint(['permission_id'], ['permissions.id'], name=op.f('fk_group_permission_permission_id_permissions')), sa.ForeignKeyConstraint(['permission_id'], ['permissions.id'], name=op.f('fk_group_permission_permission_id_permissions')),
sa.PrimaryKeyConstraint('group_id', 'permission_id', name=op.f('pk_group_permission')) sa.PrimaryKeyConstraint('group_id', 'permission_id', name=op.f('pk_group_permission'))
) )
op.create_table('refresh_tokens',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Uuid(), nullable=False),
sa.Column('token_hash', sa.String(length=255), nullable=False),
sa.Column('device_info', sa.String(length=255), nullable=False),
sa.Column('ip_address', sa.String(length=45), nullable=False),
sa.Column('is_revoked', sa.Boolean(), nullable=False),
sa.Column('expires_at', sa.TIMESTAMP(), nullable=False),
sa.Column('created_at', sa.TIMESTAMP(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.Column('replaced_by', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['replaced_by'], ['refresh_tokens.id'], name=op.f('fk_refresh_tokens_replaced_by_refresh_tokens')),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_refresh_tokens_user_id_users'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id', name=op.f('pk_refresh_tokens')),
sa.UniqueConstraint('token_hash', name=op.f('uq_refresh_tokens_token_hash'))
)
with op.batch_alter_table('refresh_tokens', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_refresh_tokens_id'), ['id'], unique=False)
batch_op.create_index(batch_op.f('ix_refresh_tokens_user_id'), ['user_id'], unique=False)
op.create_table('user_direct_permissions', op.create_table('user_direct_permissions',
sa.Column('user_id', sa.Uuid(), nullable=False), sa.Column('user_id', sa.Uuid(), nullable=False),
sa.Column('permission_id', sa.Integer(), nullable=False), sa.Column('permission_id', sa.Integer(), nullable=False),
@@ -78,7 +106,6 @@ def upgrade() -> None:
sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_user_group_user_id_users')), sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_user_group_user_id_users')),
sa.PrimaryKeyConstraint('user_id', 'permission_group_id', name=op.f('pk_user_group')) sa.PrimaryKeyConstraint('user_id', 'permission_group_id', name=op.f('pk_user_group'))
) )
# ### end Alembic commands ### # ### end Alembic commands ###
@@ -87,6 +114,11 @@ def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ### # ### commands auto generated by Alembic - please adjust! ###
op.drop_table('user_group') op.drop_table('user_group')
op.drop_table('user_direct_permissions') op.drop_table('user_direct_permissions')
with op.batch_alter_table('refresh_tokens', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_refresh_tokens_user_id'))
batch_op.drop_index(batch_op.f('ix_refresh_tokens_id'))
op.drop_table('refresh_tokens')
op.drop_table('group_permission') op.drop_table('group_permission')
with op.batch_alter_table('users', schema=None) as batch_op: with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_users_middle_name')) batch_op.drop_index(batch_op.f('ix_users_middle_name'))
@@ -95,6 +127,11 @@ def downgrade() -> None:
batch_op.drop_index(batch_op.f('ix_users_email')) batch_op.drop_index(batch_op.f('ix_users_email'))
op.drop_table('users') op.drop_table('users')
with op.batch_alter_table('reports', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_reports_id'))
batch_op.drop_index(batch_op.f('ix_reports_filename'))
op.drop_table('reports')
with op.batch_alter_table('permissions', schema=None) as batch_op: with op.batch_alter_table('permissions', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_permissions_id')) batch_op.drop_index(batch_op.f('ix_permissions_id'))

View File

@@ -1,54 +0,0 @@
"""empty message
Revision ID: 9b30685906fb
Revises: 83b4c2ae88d3
Create Date: 2026-07-17 17:40:07.269967
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '9b30685906fb'
down_revision: Union[str, Sequence[str], None] = '83b4c2ae88d3'
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('refresh_tokens',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Uuid(), nullable=False),
sa.Column('token_hash', sa.String(length=255), nullable=False),
sa.Column('device_info', sa.String(length=255), nullable=False),
sa.Column('ip_address', sa.String(length=45), nullable=False),
sa.Column('is_revoked', sa.Boolean(), nullable=False),
sa.Column('expires_at', sa.TIMESTAMP(), nullable=False),
sa.Column('created_at', sa.TIMESTAMP(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
sa.Column('replaced_by', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['replaced_by'], ['refresh_tokens.id'], name=op.f('fk_refresh_tokens_replaced_by_refresh_tokens')),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_refresh_tokens_user_id_users'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id', name=op.f('pk_refresh_tokens')),
sa.UniqueConstraint('token_hash', name=op.f('uq_refresh_tokens_token_hash'))
)
with op.batch_alter_table('refresh_tokens', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_refresh_tokens_id'), ['id'], unique=False)
batch_op.create_index(batch_op.f('ix_refresh_tokens_user_id'), ['user_id'], unique=False)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('refresh_tokens', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_refresh_tokens_user_id'))
batch_op.drop_index(batch_op.f('ix_refresh_tokens_id'))
op.drop_table('refresh_tokens')
# ### end Alembic commands ###

View File

@@ -0,0 +1,2 @@
from .files import Stored
from .model import Model, User, RefreshTokens, PermissionsGroups, Permissions

View File

@@ -0,0 +1,14 @@
from datetime import datetime
from sqlalchemy import TIMESTAMP, String, func
from sqlalchemy.orm import Mapped, mapped_column
from src.models.database_models.model import Model
class Stored(Model):
__tablename__="reports"
id:Mapped[int]=mapped_column(primary_key=True, index=True)
filename:Mapped[str]=mapped_column(String(255), index=True)
created_at:Mapped[datetime]=mapped_column(TIMESTAMP, server_default=func.now())
def __repr__(self) -> str:
return f'ID: {self.id}, Filename: {self.filename}'

View File

@@ -1,4 +1,3 @@
from dataclasses import replace
from datetime import datetime from datetime import datetime
from typing import Annotated from typing import Annotated
from pydantic import BaseModel, EmailStr, Field from pydantic import BaseModel, EmailStr, Field
@@ -61,7 +60,7 @@ class PermissionsGroupsOut(Base):
class RefreshTokens(Base): class RefreshTokens(Base):
id:int
user_id:Annotated[UUID, Field(..., description="foreign key for the user")] user_id:Annotated[UUID, Field(..., description="foreign key for the user")]
token_hash:Annotated[str, Field(..., description="token hash")] token_hash:Annotated[str, Field(..., description="token hash")]
device_info:Annotated[str, Field(..., description="User device info")] device_info:Annotated[str, Field(..., description="User device info")]
@@ -69,4 +68,12 @@ class RefreshTokens(Base):
is_revoked:Annotated[bool|None, Field(None, description="revoke token if logout was made")] is_revoked:Annotated[bool|None, Field(None, description="revoke token if logout was made")]
expires_at:Annotated[datetime, Field(..., description="when token is going to be expired")] expires_at:Annotated[datetime, Field(..., description="when token is going to be expired")]
class RefreshTokensOut(Base):
id:int
user_id:Annotated[UUID, Field(..., description="foreign key for the user")]
token_hash:Annotated[str, Field(..., description="token hash")]
device_info:Annotated[str, Field(..., description="User device info")]
ip_address:Annotated[str, Field(..., description="ip v4/v6 of the user")]
is_revoked:Annotated[bool|None, Field(None, description="revoke token if logout was made")]
expires_at:Annotated[datetime, Field(..., description="when token is going to be expired")]

1
src/service/__init__.py Normal file
View File

@@ -0,0 +1 @@
'''business logic'''