diff --git a/api/api/db/alembic/env.py b/api/api/db/alembic/env.py index 35709fa..190c21d 100644 --- a/api/api/db/alembic/env.py +++ b/api/api/db/alembic/env.py @@ -7,7 +7,7 @@ from sqlalchemy import pool from alembic import context -from api.db import metadata +from api.db import metadata, tables # this is the Alembic Config object, which provides # access to the values within the .ini file in use. diff --git a/api/api/db/sql_types.py b/api/api/db/sql_types.py new file mode 100644 index 0000000..f988d5a --- /dev/null +++ b/api/api/db/sql_types.py @@ -0,0 +1,18 @@ +__all__ = ["BigIntegerPK", "SAEnum", "UnsignedInt"] + +from typing import Any + +from sqlalchemy import BigInteger, Enum, Integer +from sqlalchemy.dialects import mysql + + +# class SAEnum(Enum): +# def __init__(self, *enums: object, **kw: Any): +# validate_strings = kw.pop("validate_strings", True) +# super().__init__(*enums, **kw, validate_strings=validate_strings) + + +# # https://docs.sqlalchemy.org/en/20/dialects/sqlite.html#allowing-autoincrement-behavior-sqlalchemy-types-other-than-integer-integer + +# BigIntegerPK = BigInteger().with_variant(Integer, "sqlite") +UnsignedInt = Integer().with_variant(mysql.INTEGER(unsigned=True), "mysql") diff --git a/api/api/db/tables/account.py b/api/api/db/tables/account.py index 07ffe3f..46b5e71 100644 --- a/api/api/db/tables/account.py +++ b/api/api/db/tables/account.py @@ -1,6 +1,12 @@ -from sqlalchemy import Table, Column, Integer, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index, MetaData +from sqlalchemy import Table, Column, Integer, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index from sqlalchemy.sql import func + +from datetime import datetime, timedelta + from enum import Enum, auto + +from api.db.sql_types import UnsignedInt + from api.db import metadata @@ -20,14 +26,14 @@ class AccountStatus(str,Enum): account_table = Table( 'account', metadata, - Column('id', Integer, primary_key=True, autoincrement=True), + Column('id', UnsignedInt, primary_key=True, autoincrement=True), Column('name', String(100), nullable=False), Column('login', String(100), nullable=False), Column('email', String(100), nullable=True), Column('bind_tenant_id', String(40), nullable=True), Column('role', SQLAEnum(AccountRole), nullable=False), Column('meta', JSON, default={}), - Column('creator_id', Integer, ForeignKey('account.id'), nullable=True), + Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=True), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('status', SQLAEnum(AccountStatus), nullable=False), @@ -48,10 +54,20 @@ class KeyStatus(str,Enum): account_keyring_table = Table( 'account_keyring', metadata, - Column('owner_id', Integer, ForeignKey('account.id'), primary_key=True, nullable=False), + Column('owner_id', UnsignedInt, ForeignKey('account.id'), primary_key=True, nullable=False), Column('key_type', SQLAEnum(KeyType), primary_key=True, nullable=False), Column('key_id', String(40), default=None), Column('key_value', String(64), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('expiry', DateTime(timezone=True), nullable=True), Column('status', SQLAEnum(KeyStatus), nullable=False), ) + + +def set_expiry_for_key_type(key_type: KeyType) -> datetime: + match key_type: + case KeyType.ACCESS_TOKEN: + return datetime.now() + timedelta(hours=1) # 1 hour + case KeyType.REFRESH_TOKEN: + return datetime.now() + timedelta(days=365) # 1 year + case KeyType.API_KEY: + return datetime.max # max datetime diff --git a/api/api/db/tables/events.py b/api/api/db/tables/events.py index 51179cf..cc33c06 100644 --- a/api/api/db/tables/events.py +++ b/api/api/db/tables/events.py @@ -1,6 +1,9 @@ from sqlalchemy import Table, Column, Integer, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index from sqlalchemy.sql import func from enum import Enum, auto + +from api.db.sql_types import UnsignedInt + from api.db import metadata class EventState(str, Enum): @@ -15,10 +18,10 @@ class EventStatus(str, Enum): list_events_table = Table( 'list_events', metadata, - Column('id', Integer, primary_key=True, autoincrement=True), + Column('id', UnsignedInt, primary_key=True, autoincrement=True), Column('name', String(40, collation='latin1_bin'), nullable=False), Column('title', String(64), nullable=False), - Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('schema', JSON, default={}), Column('state', SQLAEnum(EventState), nullable=False), diff --git a/api/api/db/tables/process.py b/api/api/db/tables/process.py index 0d98353..16bdef3 100644 --- a/api/api/db/tables/process.py +++ b/api/api/db/tables/process.py @@ -1,6 +1,9 @@ from sqlalchemy import Table, Column, Integer, String, Text, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index, PrimaryKeyConstraint from sqlalchemy.sql import func from enum import Enum, auto + +from api.db.sql_types import UnsignedInt + from api.db import metadata @@ -14,11 +17,11 @@ class ProcessStatus(str, Enum): # Определение таблицы process_schema process_schema_table = Table( 'process_schema', metadata, - Column('id', Integer, primary_key=True, autoincrement=True), + Column('id', UnsignedInt, primary_key=True, autoincrement=True), Column('title', String(100), nullable=False), Column('description', Text, nullable=False), - Column('owner_id', Integer, ForeignKey('account.id'), nullable=False), - Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('owner_id', UnsignedInt, ForeignKey('account.id'), nullable=False), + Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('settings', JSON, default={}), Column('status', SQLAEnum(ProcessStatus), nullable=False), @@ -28,12 +31,13 @@ process_schema_table = Table( process_version_archive_table = Table( 'process_version_archive', metadata, - Column('id', Integer, autoincrement=True, nullable=False), - Column('version', Integer, default=1, nullable=False), + Column('id', UnsignedInt, autoincrement=True, nullable=False), + Column('ps_id', UnsignedInt, ForeignKey('process_schema.id'), nullable=False), + Column('version', UnsignedInt, default=1, nullable=False), Column('snapshot', JSON, default={}), - Column('owner_id', Integer, ForeignKey('account.id'), nullable=False), + Column('owner_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), - Column('is_last', Integer, default=0), + Column('is_last', UnsignedInt, default=0), PrimaryKeyConstraint('id', 'version') ) class NodeStatus(str, Enum): @@ -48,11 +52,11 @@ class NodeType(Enum): ps_node_table = Table( 'ps_node', metadata, - Column('id', Integer, autoincrement=True, primary_key=True, nullable=False), - Column('ps_id', Integer, ForeignKey('process_schema.id'), nullable=False), + Column('id', UnsignedInt, autoincrement=True, primary_key=True, nullable=False), + Column('ps_id', UnsignedInt, ForeignKey('process_schema.id'), nullable=False), Column('node_type', SQLAEnum(NodeType), nullable=False), Column('settings', JSON, default={}), - Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('status', SQLAEnum(NodeStatus), nullable=False), @@ -67,12 +71,12 @@ class NodeLinkStatus(str, Enum): node_link_table = Table( 'node_link', metadata, - Column('id', Integer, autoincrement=True, primary_key=True, nullable=False), + Column('id', UnsignedInt, autoincrement=True, primary_key=True, nullable=False), Column('link_name', String(20), nullable=False), - Column('node_id', Integer, ForeignKey('ps_node.id'), nullable=False), - Column('next_node_id', Integer, ForeignKey('ps_node.id'), nullable=False), + Column('node_id', UnsignedInt, ForeignKey('ps_node.id'), nullable=False), + Column('next_node_id', UnsignedInt, ForeignKey('ps_node.id'), nullable=False), Column('settings', JSON, default={}), - Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('status', SQLAEnum(NodeLinkStatus),nullable=False),