356 lines
19 KiB
Python
356 lines
19 KiB
Python
"""initial schema
|
|
|
|
Revision ID: initial_schema
|
|
Revises:
|
|
Create Date: 2024-12-03 12:00:00.000000
|
|
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
from sqlalchemy.dialects import postgresql
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = 'initial_schema'
|
|
down_revision: Union[str, None] = None
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
# Create categories table
|
|
op.create_table('categories',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('name', sa.String(), nullable=True),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('thumbnail', sa.String(), nullable=True),
|
|
sa.Column('count_mapset', sa.Integer(), server_default='0', nullable=True),
|
|
sa.Column('is_active', sa.Boolean(), nullable=True),
|
|
sa.Column('order', sa.Integer(), server_default='0', nullable=False),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_categories_id', 'categories', ['id'])
|
|
|
|
# Create classifications table
|
|
op.create_table('classifications',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('name', sa.String(length=20), nullable=False),
|
|
sa.Column('is_open', sa.Boolean(), nullable=True),
|
|
sa.Column('is_limited', sa.Boolean(), nullable=True),
|
|
sa.Column('is_secret', sa.Boolean(), nullable=True),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_classifications_id', 'classifications', ['id'])
|
|
|
|
# Create map_projection_systems table
|
|
op.create_table('map_projection_systems',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('name', sa.String(length=50), nullable=False),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_map_projection_systems_id', 'map_projection_systems', ['id'])
|
|
|
|
# Create news table
|
|
op.create_table('news',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('name', sa.String(), nullable=True),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('thumbnail', sa.String(), nullable=True),
|
|
sa.Column('is_active', sa.Boolean(), nullable=True),
|
|
sa.Column('is_deleted', sa.Boolean(), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_news_id', 'news', ['id'])
|
|
|
|
# Create organizations table
|
|
op.create_table('organizations',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('name', sa.String(length=100), nullable=False),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('thumbnail', sa.String(length=255), nullable=True),
|
|
sa.Column('address', sa.String(length=255), nullable=True),
|
|
sa.Column('phone_number', sa.String(length=15), nullable=True),
|
|
sa.Column('email', sa.String(length=100), nullable=True),
|
|
sa.Column('website', sa.String(length=255), nullable=True),
|
|
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=True),
|
|
sa.Column('is_deleted', sa.Boolean(), server_default='false', nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
|
|
sa.Column('modified_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_organizations_id', 'organizations', ['id'])
|
|
|
|
# Create regionals table
|
|
op.create_table('regionals',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('code', sa.String(length=10), nullable=False),
|
|
sa.Column('name', sa.String(length=50), nullable=False),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('thumbnail', sa.String(length=255), nullable=True),
|
|
sa.Column('is_active', sa.Boolean(), nullable=False),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_regionals_id', 'regionals', ['id'])
|
|
|
|
# Create roles table
|
|
op.create_table('roles',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('name', sa.String(length=20), nullable=False),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('is_active', sa.Boolean(), nullable=False),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_roles_id', 'roles', ['id'])
|
|
|
|
# Create users table (depends on roles and organizations)
|
|
op.create_table('users',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('name', sa.String(), nullable=False),
|
|
sa.Column('email', sa.String(), nullable=False),
|
|
sa.Column('profile_picture', sa.String(), nullable=True),
|
|
sa.Column('username', sa.String(), nullable=False),
|
|
sa.Column('password', sa.String(), nullable=False),
|
|
sa.Column('position', sa.String(), nullable=True),
|
|
sa.Column('role_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('employee_id', sa.String(), nullable=True),
|
|
sa.Column('organization_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('is_active', sa.Boolean(), nullable=True),
|
|
sa.Column('is_deleted', sa.Boolean(), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('modified_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ),
|
|
sa.ForeignKeyConstraint(['role_id'], ['roles.id'], ),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.UniqueConstraint('email'),
|
|
sa.UniqueConstraint('username')
|
|
)
|
|
op.create_index('ix_users_id', 'users', ['id'])
|
|
|
|
# Create credentials table (depends on users)
|
|
op.create_table('credentials',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('name', sa.String(), nullable=True),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('encrypted_data', sa.Text(), nullable=False),
|
|
sa.Column('encryption_iv', sa.String(length=255), nullable=False),
|
|
sa.Column('credential_type', sa.String(length=50), nullable=False),
|
|
sa.Column('credential_metadata', postgresql.JSON(astext_type=sa.Text()), nullable=True),
|
|
sa.Column('created_by', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('updated_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('last_used_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('last_used_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('is_default', sa.Boolean(), nullable=True),
|
|
sa.Column('is_active', sa.Boolean(), nullable=True),
|
|
sa.Column('is_deleted', sa.Boolean(), nullable=True),
|
|
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
|
|
sa.ForeignKeyConstraint(['last_used_by'], ['users.id'], ),
|
|
sa.ForeignKeyConstraint(['updated_by'], ['users.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_credentials_id', 'credentials', ['id'])
|
|
|
|
# Create files table (depends on users)
|
|
op.create_table('files',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('filename', sa.String(length=255), nullable=False),
|
|
sa.Column('object_name', sa.String(length=512), nullable=False),
|
|
sa.Column('content_type', sa.String(length=100), nullable=False),
|
|
sa.Column('size', sa.Integer(), nullable=False),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('url', sa.String(length=1024), nullable=False),
|
|
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('modified_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.UniqueConstraint('object_name')
|
|
)
|
|
op.create_index('ix_files_filename', 'files', ['filename'])
|
|
op.create_index('ix_files_id', 'files', ['id'])
|
|
|
|
# Create refresh_tokens table (depends on users)
|
|
op.create_table('refresh_tokens',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('token', sa.String(length=255), nullable=False),
|
|
sa.Column('expires_at', sa.DateTime(timezone=True), nullable=False),
|
|
sa.Column('revoked', sa.Boolean(), server_default='false', nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_refresh_tokens_id', 'refresh_tokens', ['id'])
|
|
op.create_index('ix_refresh_tokens_token', 'refresh_tokens', ['token'])
|
|
op.create_index('ix_refresh_tokens_user_id', 'refresh_tokens', ['user_id'])
|
|
|
|
# Create map_sources table (depends on credentials)
|
|
op.create_table('map_sources',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('name', sa.String(length=50), nullable=False),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('credential_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('is_active', sa.Boolean(), nullable=True),
|
|
sa.Column('is_deleted', sa.Boolean(), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('url', sa.Text(), nullable=True),
|
|
sa.ForeignKeyConstraint(['credential_id'], ['credentials.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_map_sources_id', 'map_sources', ['id'])
|
|
|
|
# Create mapsets table (depends on multiple tables)
|
|
op.create_table('mapsets',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('name', sa.String(length=255), nullable=False),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('scale', sa.String(length=29), nullable=False),
|
|
sa.Column('layer_url', sa.Text(), nullable=True),
|
|
sa.Column('metadata_url', sa.Text(), nullable=True),
|
|
sa.Column('category_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('classification_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('regional_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('projection_system_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('producer_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('status_validation', sa.String(length=20), nullable=True),
|
|
sa.Column('data_status', sa.String(length=20), nullable=False),
|
|
sa.Column('data_update_period', sa.String(length=20), nullable=False),
|
|
sa.Column('data_version', sa.String(length=20), nullable=False),
|
|
sa.Column('coverage_level', sa.String(length=20), nullable=True),
|
|
sa.Column('coverage_area', sa.String(length=20), nullable=True),
|
|
sa.Column('is_popular', sa.Boolean(), nullable=True),
|
|
sa.Column('is_active', sa.Boolean(), nullable=True),
|
|
sa.Column('is_deleted', sa.Boolean(), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('created_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('updated_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('layer_type', sa.String(length=20), nullable=True),
|
|
sa.Column('view_count', sa.Integer(), server_default='0', nullable=False),
|
|
sa.Column('download_count', sa.Integer(), server_default='0', nullable=False),
|
|
sa.Column('order', sa.Integer(), server_default='0', nullable=False),
|
|
sa.ForeignKeyConstraint(['category_id'], ['categories.id'], ),
|
|
sa.ForeignKeyConstraint(['classification_id'], ['classifications.id'], ),
|
|
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
|
|
sa.ForeignKeyConstraint(['producer_id'], ['organizations.id'], ),
|
|
sa.ForeignKeyConstraint(['projection_system_id'], ['map_projection_systems.id'], ),
|
|
sa.ForeignKeyConstraint(['regional_id'], ['regionals.id'], ),
|
|
sa.ForeignKeyConstraint(['updated_by'], ['users.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_mapsets_id', 'mapsets', ['id'])
|
|
|
|
# Create mapset_access table (depends on mapsets, users, and organizations)
|
|
op.create_table('mapset_access',
|
|
sa.Column('id', sa.String(), nullable=False),
|
|
sa.Column('mapset_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('organization_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('granted_by', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('can_read', sa.Boolean(), nullable=True),
|
|
sa.Column('can_write', sa.Boolean(), nullable=True),
|
|
sa.Column('can_delete', sa.Boolean(), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.ForeignKeyConstraint(['granted_by'], ['users.id'], ),
|
|
sa.ForeignKeyConstraint(['mapset_id'], ['mapsets.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
|
|
# Create mapset_histories table (depends on mapsets and users)
|
|
op.create_table('mapset_histories',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('mapset_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('validation_type', sa.String(length=50), nullable=False),
|
|
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('notes', sa.Text(), nullable=True),
|
|
sa.Column('timestamp', sa.DateTime(timezone=True), nullable=True),
|
|
sa.ForeignKeyConstraint(['mapset_id'], ['mapsets.id'], ),
|
|
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_mapset_histories_id', 'mapset_histories', ['id'])
|
|
op.create_index('ix_mapset_histories_mapset_id', 'mapset_histories', ['mapset_id'])
|
|
|
|
# Create source_usages table (depends on map_sources and mapsets)
|
|
op.create_table('source_usages',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('source_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('mapset_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.ForeignKeyConstraint(['mapset_id'], ['mapsets.id'], ),
|
|
sa.ForeignKeyConstraint(['source_id'], ['map_sources.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('ix_source_usages_id', 'source_usages', ['id'])
|
|
|
|
# Create feedback table (independent)
|
|
op.create_table('feedback',
|
|
sa.Column('id', sa.Integer(), nullable=False, autoincrement=True),
|
|
sa.Column('datetime', sa.DateTime(), nullable=True),
|
|
sa.Column('score', sa.Integer(), nullable=True),
|
|
sa.Column('tujuan_tercapai', sa.Boolean(), nullable=True),
|
|
sa.Column('tujuan_ditemukan', sa.Boolean(), nullable=True),
|
|
sa.Column('tujuan', sa.String(length=255), nullable=True),
|
|
sa.Column('sektor', sa.String(length=255), nullable=True),
|
|
sa.Column('email', sa.String(length=255), nullable=True),
|
|
sa.Column('saran', sa.Text(), nullable=True),
|
|
sa.Column('source_url', sa.String(length=255), nullable=True),
|
|
sa.Column('source_access', sa.String(length=255), nullable=True),
|
|
sa.Column('notes', sa.Text(), nullable=True),
|
|
sa.Column('gender', sa.Integer(), nullable=True),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
# Drop tables in reverse order to respect foreign key constraints
|
|
op.drop_table('feedback')
|
|
op.drop_index('ix_source_usages_id', table_name='source_usages')
|
|
op.drop_table('source_usages')
|
|
op.drop_index('ix_mapset_histories_mapset_id', table_name='mapset_histories')
|
|
op.drop_index('ix_mapset_histories_id', table_name='mapset_histories')
|
|
op.drop_table('mapset_histories')
|
|
op.drop_table('mapset_access')
|
|
op.drop_index('ix_mapsets_id', table_name='mapsets')
|
|
op.drop_table('mapsets')
|
|
op.drop_index('ix_map_sources_id', table_name='map_sources')
|
|
op.drop_table('map_sources')
|
|
op.drop_index('ix_refresh_tokens_user_id', table_name='refresh_tokens')
|
|
op.drop_index('ix_refresh_tokens_token', table_name='refresh_tokens')
|
|
op.drop_index('ix_refresh_tokens_id', table_name='refresh_tokens')
|
|
op.drop_table('refresh_tokens')
|
|
op.drop_index('ix_files_id', table_name='files')
|
|
op.drop_index('ix_files_filename', table_name='files')
|
|
op.drop_table('files')
|
|
op.drop_index('ix_credentials_id', table_name='credentials')
|
|
op.drop_table('credentials')
|
|
op.drop_index('ix_users_id', table_name='users')
|
|
op.drop_table('users')
|
|
op.drop_index('ix_roles_id', table_name='roles')
|
|
op.drop_table('roles')
|
|
op.drop_index('ix_regionals_id', table_name='regionals')
|
|
op.drop_table('regionals')
|
|
op.drop_index('ix_organizations_id', table_name='organizations')
|
|
op.drop_table('organizations')
|
|
op.drop_index('ix_news_id', table_name='news')
|
|
op.drop_table('news')
|
|
op.drop_index('ix_map_projection_systems_id', table_name='map_projection_systems')
|
|
op.drop_table('map_projection_systems')
|
|
op.drop_index('ix_classifications_id', table_name='classifications')
|
|
op.drop_table('classifications')
|
|
op.drop_index('ix_categories_id', table_name='categories')
|
|
op.drop_table('categories')
|