|
|
|
|
@@ -0,0 +1,872 @@
|
|
|
|
|
"""Initial baseline
|
|
|
|
|
|
|
|
|
|
Revision ID: 8905071fdd15
|
|
|
|
|
Revises:
|
|
|
|
|
Create Date: 2026-01-09 09:29:05.123731
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
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 = '8905071fdd15'
|
|
|
|
|
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:
|
|
|
|
|
# ### commands auto generated by Alembic - please adjust! ###
|
|
|
|
|
op.drop_table('role_permissions')
|
|
|
|
|
op.drop_table('user_activity_logs')
|
|
|
|
|
op.drop_index('idx_support_details_file_id', table_name='support_details')
|
|
|
|
|
op.drop_index('idx_support_details_material_id', table_name='support_details')
|
|
|
|
|
op.drop_table('support_details')
|
|
|
|
|
op.drop_table('material_purchase_tracking')
|
|
|
|
|
op.drop_index('idx_purchase_confirmations_job_revision', table_name='purchase_confirmations')
|
|
|
|
|
op.drop_table('purchase_confirmations')
|
|
|
|
|
op.drop_table('valve_details')
|
|
|
|
|
op.drop_table('purchase_items')
|
|
|
|
|
op.drop_index('idx_revision_sessions_job_no', table_name='revision_sessions')
|
|
|
|
|
op.drop_index('idx_revision_sessions_status', table_name='revision_sessions')
|
|
|
|
|
op.drop_table('revision_sessions')
|
|
|
|
|
op.drop_table('instrument_details')
|
|
|
|
|
op.drop_table('fitting_details')
|
|
|
|
|
op.drop_table('flange_details')
|
|
|
|
|
op.drop_index('idx_special_material_details_file_id', table_name='special_material_details')
|
|
|
|
|
op.drop_index('idx_special_material_details_material_id', table_name='special_material_details')
|
|
|
|
|
op.drop_table('special_material_details')
|
|
|
|
|
op.drop_table('pipe_end_preparations')
|
|
|
|
|
op.drop_table('user_sessions')
|
|
|
|
|
op.drop_table('login_logs')
|
|
|
|
|
op.drop_table('material_revisions_comparison')
|
|
|
|
|
op.drop_index('idx_purchase_request_items_category', table_name='purchase_request_items')
|
|
|
|
|
op.drop_index('idx_purchase_request_items_material_id', table_name='purchase_request_items')
|
|
|
|
|
op.drop_index('idx_purchase_request_items_request_id', table_name='purchase_request_items')
|
|
|
|
|
op.drop_table('purchase_request_items')
|
|
|
|
|
op.drop_table('material_comparison_details')
|
|
|
|
|
op.drop_index('idx_confirmed_purchase_items_category', table_name='confirmed_purchase_items')
|
|
|
|
|
op.drop_index('idx_confirmed_purchase_items_confirmation', table_name='confirmed_purchase_items')
|
|
|
|
|
op.drop_table('confirmed_purchase_items')
|
|
|
|
|
op.drop_table('material_purchase_mapping')
|
|
|
|
|
op.drop_table('bolt_details')
|
|
|
|
|
op.drop_table('permissions')
|
|
|
|
|
op.drop_index('idx_purchase_requests_job_no', table_name='purchase_requests')
|
|
|
|
|
op.drop_index('idx_purchase_requests_requested_by', table_name='purchase_requests')
|
|
|
|
|
op.drop_index('idx_purchase_requests_status', table_name='purchase_requests')
|
|
|
|
|
op.drop_table('purchase_requests')
|
|
|
|
|
op.drop_table('gasket_details')
|
|
|
|
|
op.drop_index('idx_revision_changes_action', table_name='revision_material_changes')
|
|
|
|
|
op.drop_index('idx_revision_changes_session', table_name='revision_material_changes')
|
|
|
|
|
op.drop_index('idx_revision_changes_status', table_name='revision_material_changes')
|
|
|
|
|
op.drop_table('revision_material_changes')
|
|
|
|
|
op.drop_index('idx_revision_logs_date', table_name='revision_action_logs')
|
|
|
|
|
op.drop_index('idx_revision_logs_session', table_name='revision_action_logs')
|
|
|
|
|
op.drop_index('idx_revision_logs_type', table_name='revision_action_logs')
|
|
|
|
|
op.drop_table('revision_action_logs')
|
|
|
|
|
op.drop_index('idx_inventory_transfers_date', table_name='inventory_transfers')
|
|
|
|
|
op.drop_index('idx_inventory_transfers_material', table_name='inventory_transfers')
|
|
|
|
|
op.drop_table('inventory_transfers')
|
|
|
|
|
op.drop_table('users')
|
|
|
|
|
op.drop_table('jobs')
|
|
|
|
|
op.drop_index('idx_files_active', table_name='files')
|
|
|
|
|
op.drop_index('idx_files_project', table_name='files')
|
|
|
|
|
op.drop_index('idx_files_purchase_confirmed', table_name='files')
|
|
|
|
|
op.drop_index('idx_files_uploaded_by', table_name='files')
|
|
|
|
|
op.create_index(op.f('ix_files_id'), 'files', ['id'], unique=False)
|
|
|
|
|
op.drop_constraint('files_project_id_fkey', 'files', type_='foreignkey')
|
|
|
|
|
op.create_foreign_key(None, 'files', 'projects', ['project_id'], ['id'])
|
|
|
|
|
op.drop_column('files', 'description')
|
|
|
|
|
op.drop_column('files', 'classification_completed')
|
|
|
|
|
op.drop_column('files', 'purchase_confirmed')
|
|
|
|
|
op.drop_column('files', 'bom_name')
|
|
|
|
|
op.drop_column('files', 'confirmed_at')
|
|
|
|
|
op.drop_column('files', 'confirmed_by')
|
|
|
|
|
op.drop_column('files', 'job_no')
|
|
|
|
|
op.drop_column('files', 'parsed_count')
|
|
|
|
|
op.create_index(op.f('ix_material_categories_id'), 'material_categories', ['id'], unique=False)
|
|
|
|
|
op.create_index(op.f('ix_material_grades_id'), 'material_grades', ['id'], unique=False)
|
|
|
|
|
op.create_index(op.f('ix_material_patterns_id'), 'material_patterns', ['id'], unique=False)
|
|
|
|
|
op.create_index(op.f('ix_material_specifications_id'), 'material_specifications', ['id'], unique=False)
|
|
|
|
|
op.drop_constraint('material_standards_standard_code_key', 'material_standards', type_='unique')
|
|
|
|
|
op.create_index(op.f('ix_material_standards_id'), 'material_standards', ['id'], unique=False)
|
|
|
|
|
op.create_index(op.f('ix_material_standards_standard_code'), 'material_standards', ['standard_code'], unique=True)
|
|
|
|
|
op.create_index(op.f('ix_material_tubing_mapping_id'), 'material_tubing_mapping', ['id'], unique=False)
|
|
|
|
|
op.alter_column('materials', 'verified_by',
|
|
|
|
|
existing_type=sa.VARCHAR(length=100),
|
|
|
|
|
type_=sa.String(length=50),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.alter_column('materials', 'material_hash',
|
|
|
|
|
existing_type=sa.VARCHAR(length=64),
|
|
|
|
|
type_=sa.String(length=100),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.alter_column('materials', 'full_material_grade',
|
|
|
|
|
existing_type=sa.TEXT(),
|
|
|
|
|
type_=sa.String(length=100),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.drop_index('idx_materials_category', table_name='materials')
|
|
|
|
|
op.drop_index('idx_materials_classification_details', table_name='materials', postgresql_using='gin')
|
|
|
|
|
op.drop_index('idx_materials_file', table_name='materials')
|
|
|
|
|
op.drop_index('idx_materials_material_size', table_name='materials')
|
|
|
|
|
op.create_index(op.f('ix_materials_id'), 'materials', ['id'], unique=False)
|
|
|
|
|
op.drop_constraint('materials_file_id_fkey', 'materials', type_='foreignkey')
|
|
|
|
|
op.create_foreign_key(None, 'materials', 'files', ['file_id'], ['id'])
|
|
|
|
|
op.drop_column('materials', 'classification_details')
|
|
|
|
|
op.add_column('pipe_details', sa.Column('material_standard', sa.String(length=50), nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('material_grade', sa.String(length=50), nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('material_type', sa.String(length=50), nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('wall_thickness', sa.String(length=50), nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('nominal_size', sa.String(length=50), nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('material_confidence', sa.Numeric(precision=3, scale=2), nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('manufacturing_confidence', sa.Numeric(precision=3, scale=2), nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('end_prep_confidence', sa.Numeric(precision=3, scale=2), nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('schedule_confidence', sa.Numeric(precision=3, scale=2), nullable=True))
|
|
|
|
|
op.alter_column('pipe_details', 'file_id',
|
|
|
|
|
existing_type=sa.INTEGER(),
|
|
|
|
|
nullable=False)
|
|
|
|
|
op.create_index(op.f('ix_pipe_details_id'), 'pipe_details', ['id'], unique=False)
|
|
|
|
|
op.drop_constraint('pipe_details_material_id_fkey', 'pipe_details', type_='foreignkey')
|
|
|
|
|
op.drop_constraint('pipe_details_file_id_fkey', 'pipe_details', type_='foreignkey')
|
|
|
|
|
op.create_foreign_key(None, 'pipe_details', 'files', ['file_id'], ['id'])
|
|
|
|
|
op.drop_column('pipe_details', 'outer_diameter')
|
|
|
|
|
op.drop_column('pipe_details', 'additional_info')
|
|
|
|
|
op.drop_column('pipe_details', 'classification_confidence')
|
|
|
|
|
op.drop_column('pipe_details', 'material_id')
|
|
|
|
|
op.drop_column('pipe_details', 'material_spec')
|
|
|
|
|
op.drop_index('idx_projects_design_code', table_name='projects')
|
|
|
|
|
op.drop_index('idx_projects_official_code', table_name='projects')
|
|
|
|
|
op.drop_constraint('projects_official_project_code_key', 'projects', type_='unique')
|
|
|
|
|
op.create_index(op.f('ix_projects_id'), 'projects', ['id'], unique=False)
|
|
|
|
|
op.create_index(op.f('ix_projects_official_project_code'), 'projects', ['official_project_code'], unique=True)
|
|
|
|
|
op.create_index(op.f('ix_requirement_types_id'), 'requirement_types', ['id'], unique=False)
|
|
|
|
|
op.create_index(op.f('ix_special_material_grades_id'), 'special_material_grades', ['id'], unique=False)
|
|
|
|
|
op.create_index(op.f('ix_special_material_patterns_id'), 'special_material_patterns', ['id'], unique=False)
|
|
|
|
|
op.create_index(op.f('ix_special_materials_id'), 'special_materials', ['id'], unique=False)
|
|
|
|
|
op.create_index(op.f('ix_tubing_categories_id'), 'tubing_categories', ['id'], unique=False)
|
|
|
|
|
op.alter_column('tubing_manufacturers', 'contact_info',
|
|
|
|
|
existing_type=postgresql.JSONB(astext_type=sa.Text()),
|
|
|
|
|
type_=sa.JSON(),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.alter_column('tubing_manufacturers', 'quality_certs',
|
|
|
|
|
existing_type=postgresql.JSONB(astext_type=sa.Text()),
|
|
|
|
|
type_=sa.JSON(),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.create_index(op.f('ix_tubing_manufacturers_id'), 'tubing_manufacturers', ['id'], unique=False)
|
|
|
|
|
op.alter_column('tubing_products', 'last_price_update',
|
|
|
|
|
existing_type=sa.DATE(),
|
|
|
|
|
type_=sa.DateTime(),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.drop_constraint('tubing_products_specification_id_manufacturer_id_manufactur_key', 'tubing_products', type_='unique')
|
|
|
|
|
op.create_index(op.f('ix_tubing_products_id'), 'tubing_products', ['id'], unique=False)
|
|
|
|
|
op.create_index(op.f('ix_tubing_specifications_id'), 'tubing_specifications', ['id'], unique=False)
|
|
|
|
|
op.alter_column('user_requirements', 'due_date',
|
|
|
|
|
existing_type=sa.DATE(),
|
|
|
|
|
type_=sa.DateTime(),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.create_index(op.f('ix_user_requirements_id'), 'user_requirements', ['id'], unique=False)
|
|
|
|
|
op.drop_constraint('user_requirements_material_id_fkey', 'user_requirements', type_='foreignkey')
|
|
|
|
|
op.drop_constraint('user_requirements_file_id_fkey', 'user_requirements', type_='foreignkey')
|
|
|
|
|
op.create_foreign_key(None, 'user_requirements', 'materials', ['material_id'], ['id'])
|
|
|
|
|
op.create_foreign_key(None, 'user_requirements', 'files', ['file_id'], ['id'])
|
|
|
|
|
# ### end Alembic commands ###
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def downgrade() -> None:
|
|
|
|
|
# ### commands auto generated by Alembic - please adjust! ###
|
|
|
|
|
op.drop_constraint(None, 'user_requirements', type_='foreignkey')
|
|
|
|
|
op.drop_constraint(None, 'user_requirements', type_='foreignkey')
|
|
|
|
|
op.create_foreign_key('user_requirements_file_id_fkey', 'user_requirements', 'files', ['file_id'], ['id'], ondelete='CASCADE')
|
|
|
|
|
op.create_foreign_key('user_requirements_material_id_fkey', 'user_requirements', 'materials', ['material_id'], ['id'], ondelete='CASCADE')
|
|
|
|
|
op.drop_index(op.f('ix_user_requirements_id'), table_name='user_requirements')
|
|
|
|
|
op.alter_column('user_requirements', 'due_date',
|
|
|
|
|
existing_type=sa.DateTime(),
|
|
|
|
|
type_=sa.DATE(),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.drop_index(op.f('ix_tubing_specifications_id'), table_name='tubing_specifications')
|
|
|
|
|
op.drop_index(op.f('ix_tubing_products_id'), table_name='tubing_products')
|
|
|
|
|
op.create_unique_constraint('tubing_products_specification_id_manufacturer_id_manufactur_key', 'tubing_products', ['specification_id', 'manufacturer_id', 'manufacturer_part_number'])
|
|
|
|
|
op.alter_column('tubing_products', 'last_price_update',
|
|
|
|
|
existing_type=sa.DateTime(),
|
|
|
|
|
type_=sa.DATE(),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.drop_index(op.f('ix_tubing_manufacturers_id'), table_name='tubing_manufacturers')
|
|
|
|
|
op.alter_column('tubing_manufacturers', 'quality_certs',
|
|
|
|
|
existing_type=sa.JSON(),
|
|
|
|
|
type_=postgresql.JSONB(astext_type=sa.Text()),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.alter_column('tubing_manufacturers', 'contact_info',
|
|
|
|
|
existing_type=sa.JSON(),
|
|
|
|
|
type_=postgresql.JSONB(astext_type=sa.Text()),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.drop_index(op.f('ix_tubing_categories_id'), table_name='tubing_categories')
|
|
|
|
|
op.drop_index(op.f('ix_special_materials_id'), table_name='special_materials')
|
|
|
|
|
op.drop_index(op.f('ix_special_material_patterns_id'), table_name='special_material_patterns')
|
|
|
|
|
op.drop_index(op.f('ix_special_material_grades_id'), table_name='special_material_grades')
|
|
|
|
|
op.drop_index(op.f('ix_requirement_types_id'), table_name='requirement_types')
|
|
|
|
|
op.drop_index(op.f('ix_projects_official_project_code'), table_name='projects')
|
|
|
|
|
op.drop_index(op.f('ix_projects_id'), table_name='projects')
|
|
|
|
|
op.create_unique_constraint('projects_official_project_code_key', 'projects', ['official_project_code'])
|
|
|
|
|
op.create_index('idx_projects_official_code', 'projects', ['official_project_code'], unique=False)
|
|
|
|
|
op.create_index('idx_projects_design_code', 'projects', ['design_project_code'], unique=False)
|
|
|
|
|
op.add_column('pipe_details', sa.Column('material_spec', sa.VARCHAR(length=100), autoincrement=False, nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('classification_confidence', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('additional_info', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True))
|
|
|
|
|
op.add_column('pipe_details', sa.Column('outer_diameter', sa.VARCHAR(length=50), autoincrement=False, nullable=True))
|
|
|
|
|
op.drop_constraint(None, 'pipe_details', type_='foreignkey')
|
|
|
|
|
op.create_foreign_key('pipe_details_file_id_fkey', 'pipe_details', 'files', ['file_id'], ['id'], ondelete='CASCADE')
|
|
|
|
|
op.create_foreign_key('pipe_details_material_id_fkey', 'pipe_details', 'materials', ['material_id'], ['id'], ondelete='CASCADE')
|
|
|
|
|
op.drop_index(op.f('ix_pipe_details_id'), table_name='pipe_details')
|
|
|
|
|
op.alter_column('pipe_details', 'file_id',
|
|
|
|
|
existing_type=sa.INTEGER(),
|
|
|
|
|
nullable=True)
|
|
|
|
|
op.drop_column('pipe_details', 'schedule_confidence')
|
|
|
|
|
op.drop_column('pipe_details', 'end_prep_confidence')
|
|
|
|
|
op.drop_column('pipe_details', 'manufacturing_confidence')
|
|
|
|
|
op.drop_column('pipe_details', 'material_confidence')
|
|
|
|
|
op.drop_column('pipe_details', 'nominal_size')
|
|
|
|
|
op.drop_column('pipe_details', 'wall_thickness')
|
|
|
|
|
op.drop_column('pipe_details', 'material_type')
|
|
|
|
|
op.drop_column('pipe_details', 'material_grade')
|
|
|
|
|
op.drop_column('pipe_details', 'material_standard')
|
|
|
|
|
op.add_column('materials', sa.Column('classification_details', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True))
|
|
|
|
|
op.drop_constraint(None, 'materials', type_='foreignkey')
|
|
|
|
|
op.create_foreign_key('materials_file_id_fkey', 'materials', 'files', ['file_id'], ['id'], ondelete='CASCADE')
|
|
|
|
|
op.drop_index(op.f('ix_materials_id'), table_name='materials')
|
|
|
|
|
op.create_index('idx_materials_material_size', 'materials', ['material_grade', 'size_spec'], unique=False)
|
|
|
|
|
op.create_index('idx_materials_file', 'materials', ['file_id'], unique=False)
|
|
|
|
|
op.create_index('idx_materials_classification_details', 'materials', ['classification_details'], unique=False, postgresql_using='gin')
|
|
|
|
|
op.create_index('idx_materials_category', 'materials', ['classified_category', 'classified_subcategory'], unique=False)
|
|
|
|
|
op.alter_column('materials', 'full_material_grade',
|
|
|
|
|
existing_type=sa.String(length=100),
|
|
|
|
|
type_=sa.TEXT(),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.alter_column('materials', 'material_hash',
|
|
|
|
|
existing_type=sa.String(length=100),
|
|
|
|
|
type_=sa.VARCHAR(length=64),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.alter_column('materials', 'verified_by',
|
|
|
|
|
existing_type=sa.String(length=50),
|
|
|
|
|
type_=sa.VARCHAR(length=100),
|
|
|
|
|
existing_nullable=True)
|
|
|
|
|
op.drop_index(op.f('ix_material_tubing_mapping_id'), table_name='material_tubing_mapping')
|
|
|
|
|
op.drop_index(op.f('ix_material_standards_standard_code'), table_name='material_standards')
|
|
|
|
|
op.drop_index(op.f('ix_material_standards_id'), table_name='material_standards')
|
|
|
|
|
op.create_unique_constraint('material_standards_standard_code_key', 'material_standards', ['standard_code'])
|
|
|
|
|
op.drop_index(op.f('ix_material_specifications_id'), table_name='material_specifications')
|
|
|
|
|
op.drop_index(op.f('ix_material_patterns_id'), table_name='material_patterns')
|
|
|
|
|
op.drop_index(op.f('ix_material_grades_id'), table_name='material_grades')
|
|
|
|
|
op.drop_index(op.f('ix_material_categories_id'), table_name='material_categories')
|
|
|
|
|
op.add_column('files', sa.Column('parsed_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True))
|
|
|
|
|
op.add_column('files', sa.Column('job_no', sa.VARCHAR(length=50), autoincrement=False, nullable=True))
|
|
|
|
|
op.add_column('files', sa.Column('confirmed_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True, comment='구매 수량 확정자'))
|
|
|
|
|
op.add_column('files', sa.Column('confirmed_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True, comment='구매 수량 확정 시간'))
|
|
|
|
|
op.add_column('files', sa.Column('bom_name', sa.VARCHAR(length=255), autoincrement=False, nullable=True))
|
|
|
|
|
op.add_column('files', sa.Column('purchase_confirmed', sa.BOOLEAN(), server_default=sa.text('false'), autoincrement=False, nullable=True, comment='구매 수량 확정 여부'))
|
|
|
|
|
op.add_column('files', sa.Column('classification_completed', sa.BOOLEAN(), server_default=sa.text('false'), autoincrement=False, nullable=True))
|
|
|
|
|
op.add_column('files', sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True))
|
|
|
|
|
op.drop_constraint(None, 'files', type_='foreignkey')
|
|
|
|
|
op.create_foreign_key('files_project_id_fkey', 'files', 'projects', ['project_id'], ['id'], ondelete='CASCADE')
|
|
|
|
|
op.drop_index(op.f('ix_files_id'), table_name='files')
|
|
|
|
|
op.create_index('idx_files_uploaded_by', 'files', ['uploaded_by'], unique=False)
|
|
|
|
|
op.create_index('idx_files_purchase_confirmed', 'files', ['purchase_confirmed'], unique=False)
|
|
|
|
|
op.create_index('idx_files_project', 'files', ['project_id'], unique=False)
|
|
|
|
|
op.create_index('idx_files_active', 'files', ['is_active'], unique=False)
|
|
|
|
|
op.create_table('jobs',
|
|
|
|
|
sa.Column('job_no', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('job_name', sa.VARCHAR(length=200), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('client_name', sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('end_user', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('epc_company', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('project_site', sa.VARCHAR(length=200), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('contract_date', sa.DATE(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('delivery_date', sa.DATE(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('delivery_terms', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('status', sa.VARCHAR(length=20), server_default=sa.text("'진행중'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('delivery_completed_date', sa.DATE(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('project_closed_date', sa.DATE(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_by', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('is_active', sa.BOOLEAN(), server_default=sa.text('true'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('assigned_to', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('project_type', sa.VARCHAR(length=50), server_default=sa.text("'냉동기'::character varying"), autoincrement=False, nullable=False),
|
|
|
|
|
sa.PrimaryKeyConstraint('job_no', name='jobs_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('users',
|
|
|
|
|
sa.Column('user_id', sa.INTEGER(), server_default=sa.text("nextval('users_user_id_seq'::regclass)"), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('username', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('password', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('name', sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('email', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('role', sa.VARCHAR(length=20), server_default=sa.text("'user'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('access_level', sa.VARCHAR(length=20), server_default=sa.text("'worker'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('is_active', sa.BOOLEAN(), server_default=sa.text('true'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('failed_login_attempts', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('locked_until', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('department', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('position', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('phone', sa.VARCHAR(length=20), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('last_login_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('status', sa.VARCHAR(length=20), server_default=sa.text("'active'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.CheckConstraint("access_level::text = ANY (ARRAY['admin'::character varying, 'system'::character varying, 'group_leader'::character varying, 'support_team'::character varying, 'worker'::character varying]::text[])", name='users_access_level_check'),
|
|
|
|
|
sa.CheckConstraint("role::text = ANY (ARRAY['admin'::character varying, 'system'::character varying, 'leader'::character varying, 'support'::character varying, 'user'::character varying]::text[])", name='users_role_check'),
|
|
|
|
|
sa.PrimaryKeyConstraint('user_id', name='users_pkey'),
|
|
|
|
|
sa.UniqueConstraint('username', name='users_username_key'),
|
|
|
|
|
postgresql_ignore_search_path=False
|
|
|
|
|
)
|
|
|
|
|
op.create_table('inventory_transfers',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('revision_change_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_description', sa.TEXT(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('category', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('quantity', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('unit', sa.VARCHAR(length=10), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('inventory_location', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('storage_notes', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('transferred_by', sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('transferred_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('status', sa.VARCHAR(length=20), server_default=sa.text("'transferred'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['revision_change_id'], ['revision_material_changes.id'], name='inventory_transfers_revision_change_id_fkey'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='inventory_transfers_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_index('idx_inventory_transfers_material', 'inventory_transfers', ['material_description'], unique=False)
|
|
|
|
|
op.create_index('idx_inventory_transfers_date', 'inventory_transfers', ['transferred_at'], unique=False)
|
|
|
|
|
op.create_table('revision_action_logs',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('session_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('revision_change_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('action_type', sa.VARCHAR(length=30), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('action_description', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('executed_by', sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('executed_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('result', sa.VARCHAR(length=20), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('result_message', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('result_data', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['revision_change_id'], ['revision_material_changes.id'], name='revision_action_logs_revision_change_id_fkey'),
|
|
|
|
|
sa.ForeignKeyConstraint(['session_id'], ['revision_sessions.id'], name='revision_action_logs_session_id_fkey'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='revision_action_logs_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_index('idx_revision_logs_type', 'revision_action_logs', ['action_type'], unique=False)
|
|
|
|
|
op.create_index('idx_revision_logs_session', 'revision_action_logs', ['session_id'], unique=False)
|
|
|
|
|
op.create_index('idx_revision_logs_date', 'revision_action_logs', ['executed_at'], unique=False)
|
|
|
|
|
op.create_table('revision_material_changes',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('session_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('previous_material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_description', sa.TEXT(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('category', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('change_type', sa.VARCHAR(length=20), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('previous_quantity', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('current_quantity', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('quantity_difference', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('purchase_status', sa.VARCHAR(length=20), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('purchase_confirmed_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('revision_action', sa.VARCHAR(length=30), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('action_status', sa.VARCHAR(length=20), server_default=sa.text("'pending'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('processed_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('processed_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('processing_notes', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='revision_material_changes_material_id_fkey'),
|
|
|
|
|
sa.ForeignKeyConstraint(['session_id'], ['revision_sessions.id'], name='revision_material_changes_session_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='revision_material_changes_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_index('idx_revision_changes_status', 'revision_material_changes', ['action_status'], unique=False)
|
|
|
|
|
op.create_index('idx_revision_changes_session', 'revision_material_changes', ['session_id'], unique=False)
|
|
|
|
|
op.create_index('idx_revision_changes_action', 'revision_material_changes', ['revision_action'], unique=False)
|
|
|
|
|
op.create_table('gasket_details',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('gasket_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('gasket_subtype', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_type', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('filler_material', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('size_inches', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('pressure_rating', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('thickness', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('temperature_range', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('fire_safe', sa.BOOLEAN(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('classification_confidence', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('additional_info', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='gasket_details_file_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='gasket_details_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='gasket_details_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('purchase_requests',
|
|
|
|
|
sa.Column('request_id', sa.INTEGER(), server_default=sa.text("nextval('purchase_requests_request_id_seq'::regclass)"), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('request_no', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('job_no', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('category', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('excel_file_path', sa.VARCHAR(length=500), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('project_name', sa.VARCHAR(length=200), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('requested_by', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('requested_by_username', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('request_date', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('status', sa.VARCHAR(length=20), server_default=sa.text("'pending'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('total_items', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('notes', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('approved_by', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('approved_by_username', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('approved_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['approved_by'], ['users.user_id'], name='purchase_requests_approved_by_fkey'),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='purchase_requests_file_id_fkey'),
|
|
|
|
|
sa.ForeignKeyConstraint(['requested_by'], ['users.user_id'], name='purchase_requests_requested_by_fkey'),
|
|
|
|
|
sa.PrimaryKeyConstraint('request_id', name='purchase_requests_pkey'),
|
|
|
|
|
sa.UniqueConstraint('request_no', name='purchase_requests_request_no_key'),
|
|
|
|
|
postgresql_ignore_search_path=False
|
|
|
|
|
)
|
|
|
|
|
op.create_index('idx_purchase_requests_status', 'purchase_requests', ['status'], unique=False)
|
|
|
|
|
op.create_index('idx_purchase_requests_requested_by', 'purchase_requests', ['requested_by'], unique=False)
|
|
|
|
|
op.create_index('idx_purchase_requests_job_no', 'purchase_requests', ['job_no'], unique=False)
|
|
|
|
|
op.create_table('permissions',
|
|
|
|
|
sa.Column('permission_id', sa.INTEGER(), server_default=sa.text("nextval('permissions_permission_id_seq'::regclass)"), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('permission_name', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('module', sa.VARCHAR(length=30), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.PrimaryKeyConstraint('permission_id', name='permissions_pkey'),
|
|
|
|
|
sa.UniqueConstraint('permission_name', name='permissions_permission_name_key'),
|
|
|
|
|
postgresql_ignore_search_path=False
|
|
|
|
|
)
|
|
|
|
|
op.create_table('bolt_details',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('bolt_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('thread_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('diameter', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('length', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_standard', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_grade', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('coating_type', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('pressure_rating', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('includes_nut', sa.BOOLEAN(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('includes_washer', sa.BOOLEAN(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('nut_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('washer_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('classification_confidence', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('additional_info', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='bolt_details_file_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='bolt_details_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='bolt_details_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('material_purchase_mapping',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('purchase_item_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('quantity_ratio', sa.NUMERIC(precision=5, scale=2), server_default=sa.text('1.0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='material_purchase_mapping_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['purchase_item_id'], ['purchase_items.id'], name='material_purchase_mapping_purchase_item_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='material_purchase_mapping_pkey'),
|
|
|
|
|
sa.UniqueConstraint('material_id', 'purchase_item_id', name='material_purchase_mapping_material_id_purchase_item_id_key')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('confirmed_purchase_items',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('confirmation_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('item_code', sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('category', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('specification', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('size', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('bom_quantity', sa.NUMERIC(precision=15, scale=3), server_default=sa.text('0'), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('calculated_qty', sa.NUMERIC(precision=15, scale=3), server_default=sa.text('0'), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('unit', sa.VARCHAR(length=20), server_default=sa.text("'EA'::character varying"), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('safety_factor', sa.NUMERIC(precision=5, scale=3), server_default=sa.text('1.0'), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['confirmation_id'], ['purchase_confirmations.id'], name='confirmed_purchase_items_confirmation_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='confirmed_purchase_items_pkey'),
|
|
|
|
|
comment='확정된 구매 품목 상세 테이블'
|
|
|
|
|
)
|
|
|
|
|
op.create_index('idx_confirmed_purchase_items_confirmation', 'confirmed_purchase_items', ['confirmation_id'], unique=False)
|
|
|
|
|
op.create_index('idx_confirmed_purchase_items_category', 'confirmed_purchase_items', ['category'], unique=False)
|
|
|
|
|
op.create_table('material_comparison_details',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('comparison_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('material_hash', sa.VARCHAR(length=32), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('change_type', sa.VARCHAR(length=20), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('description', sa.TEXT(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('size_spec', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_grade', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('previous_quantity', sa.NUMERIC(precision=10, scale=3), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('current_quantity', sa.NUMERIC(precision=10, scale=3), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('quantity_diff', sa.NUMERIC(precision=10, scale=3), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('additional_purchase_needed', sa.NUMERIC(precision=10, scale=3), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('classified_category', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('classification_confidence', sa.NUMERIC(precision=3, scale=2), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['comparison_id'], ['material_revisions_comparison.id'], name='material_comparison_details_comparison_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='material_comparison_details_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('purchase_request_items',
|
|
|
|
|
sa.Column('item_id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('request_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('description', sa.TEXT(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('category', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('subcategory', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_grade', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('size_spec', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('quantity', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('unit', sa.VARCHAR(length=10), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('drawing_name', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('notes', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('user_requirement', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('is_ordered', sa.BOOLEAN(), server_default=sa.text('false'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('is_received', sa.BOOLEAN(), server_default=sa.text('false'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='purchase_request_items_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['request_id'], ['purchase_requests.request_id'], name='purchase_request_items_request_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('item_id', name='purchase_request_items_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_index('idx_purchase_request_items_request_id', 'purchase_request_items', ['request_id'], unique=False)
|
|
|
|
|
op.create_index('idx_purchase_request_items_material_id', 'purchase_request_items', ['material_id'], unique=False)
|
|
|
|
|
op.create_index('idx_purchase_request_items_category', 'purchase_request_items', ['category'], unique=False)
|
|
|
|
|
op.create_table('material_revisions_comparison',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('job_no', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('current_revision', sa.VARCHAR(length=20), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('previous_revision', sa.VARCHAR(length=20), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('current_file_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('previous_file_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('total_current_items', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('total_previous_items', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('new_items_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('modified_items_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('removed_items_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('unchanged_items_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('comparison_details', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['current_file_id'], ['files.id'], name='material_revisions_comparison_current_file_id_fkey'),
|
|
|
|
|
sa.ForeignKeyConstraint(['previous_file_id'], ['files.id'], name='material_revisions_comparison_previous_file_id_fkey'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='material_revisions_comparison_pkey'),
|
|
|
|
|
sa.UniqueConstraint('job_no', 'current_revision', 'previous_revision', name='material_revisions_comparison_job_no_current_revision_previ_key')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('login_logs',
|
|
|
|
|
sa.Column('log_id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('user_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('login_time', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('ip_address', sa.VARCHAR(length=45), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('user_agent', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('login_status', sa.VARCHAR(length=20), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('failure_reason', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('session_duration', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.CheckConstraint("login_status::text = ANY (ARRAY['success'::character varying, 'failed'::character varying]::text[])", name='login_logs_login_status_check'),
|
|
|
|
|
sa.ForeignKeyConstraint(['user_id'], ['users.user_id'], name='login_logs_user_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('log_id', name='login_logs_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('user_sessions',
|
|
|
|
|
sa.Column('session_id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('user_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('refresh_token', sa.VARCHAR(length=500), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('expires_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('ip_address', sa.VARCHAR(length=45), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('user_agent', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('is_active', sa.BOOLEAN(), server_default=sa.text('true'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['user_id'], ['users.user_id'], name='user_sessions_user_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('session_id', name='user_sessions_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('pipe_end_preparations',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('end_preparation_type', sa.VARCHAR(length=50), server_default=sa.text("'PBE'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('end_preparation_code', sa.VARCHAR(length=20), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('machining_required', sa.BOOLEAN(), server_default=sa.text('false'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('cutting_note', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('original_description', sa.TEXT(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('clean_description', sa.TEXT(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('confidence', sa.DOUBLE_PRECISION(precision=53), server_default=sa.text('0.0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('matched_pattern', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='pipe_end_preparations_file_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='pipe_end_preparations_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='pipe_end_preparations_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('special_material_details',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('special_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('special_subtype', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_standard', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_grade', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('specifications', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('dimensions', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('weight_kg', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('classification_confidence', sa.NUMERIC(precision=3, scale=2), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='special_material_details_file_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='special_material_details_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='special_material_details_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_index('idx_special_material_details_material_id', 'special_material_details', ['material_id'], unique=False)
|
|
|
|
|
op.create_index('idx_special_material_details_file_id', 'special_material_details', ['file_id'], unique=False)
|
|
|
|
|
op.create_table('flange_details',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('flange_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('facing_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('pressure_rating', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_standard', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_grade', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('size_inches', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('bolt_hole_count', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('bolt_hole_size', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('classification_confidence', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('additional_info', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='flange_details_file_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='flange_details_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='flange_details_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('fitting_details',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('fitting_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('fitting_subtype', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('connection_method', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('connection_code', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('pressure_rating', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('max_pressure', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('manufacturing_method', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_standard', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_grade', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('main_size', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('reduced_size', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('length_mm', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('schedule', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('classification_confidence', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('additional_info', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='fitting_details_file_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='fitting_details_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='fitting_details_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('instrument_details',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('instrument_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('instrument_subtype', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('measurement_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('measurement_range', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('accuracy', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('connection_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('connection_size', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('body_material', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('wetted_parts_material', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('electrical_rating', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('output_signal', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('classification_confidence', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('additional_info', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='instrument_details_file_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='instrument_details_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='instrument_details_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('revision_sessions',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('job_no', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('current_file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('previous_file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('current_revision', sa.VARCHAR(length=20), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('previous_revision', sa.VARCHAR(length=20), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('status', sa.VARCHAR(length=20), server_default=sa.text("'processing'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('total_materials', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('processed_materials', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('added_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('removed_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('changed_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('unchanged_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('purchase_cancel_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('inventory_transfer_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('additional_purchase_count', sa.INTEGER(), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('completed_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['current_file_id'], ['files.id'], name='revision_sessions_current_file_id_fkey'),
|
|
|
|
|
sa.ForeignKeyConstraint(['previous_file_id'], ['files.id'], name='revision_sessions_previous_file_id_fkey'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='revision_sessions_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_index('idx_revision_sessions_status', 'revision_sessions', ['status'], unique=False)
|
|
|
|
|
op.create_index('idx_revision_sessions_job_no', 'revision_sessions', ['job_no'], unique=False)
|
|
|
|
|
op.create_table('purchase_items',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('item_code', sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('category', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('specification', sa.TEXT(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('material_spec', sa.VARCHAR(length=200), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('size_spec', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('unit', sa.VARCHAR(length=10), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('bom_quantity', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('safety_factor', sa.NUMERIC(precision=3, scale=2), server_default=sa.text('1.10'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('minimum_order_qty', sa.NUMERIC(precision=10, scale=3), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('order_unit_qty', sa.NUMERIC(precision=10, scale=3), server_default=sa.text('1'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('calculated_qty', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('cutting_loss', sa.NUMERIC(precision=10, scale=3), server_default=sa.text('0'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('standard_length', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('pipes_count', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('waste_length', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('detailed_spec', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('preferred_supplier', sa.VARCHAR(length=200), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('last_unit_price', sa.NUMERIC(precision=10, scale=2), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('currency', sa.VARCHAR(length=10), server_default=sa.text("'KRW'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('lead_time_days', sa.INTEGER(), server_default=sa.text('30'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('job_no', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('revision', sa.VARCHAR(length=20), server_default=sa.text("'Rev.0'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('is_active', sa.BOOLEAN(), server_default=sa.text('true'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('approved_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('approved_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='purchase_items_file_id_fkey', ondelete='SET NULL'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='purchase_items_pkey'),
|
|
|
|
|
sa.UniqueConstraint('item_code', name='purchase_items_item_code_key')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('valve_details',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('valve_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('valve_subtype', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('actuator_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('connection_method', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('pressure_rating', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('pressure_class', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('body_material', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('trim_material', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('size_inches', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('fire_safe', sa.BOOLEAN(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('low_temp_service', sa.BOOLEAN(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('special_features', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('classification_confidence', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('additional_info', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='valve_details_file_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='valve_details_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='valve_details_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('purchase_confirmations',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('job_no', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('bom_name', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('revision', sa.VARCHAR(length=50), server_default=sa.text("'Rev.0'::character varying"), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('confirmed_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('confirmed_by', sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('is_active', sa.BOOLEAN(), server_default=sa.text('true'), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='purchase_confirmations_file_id_fkey'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='purchase_confirmations_pkey'),
|
|
|
|
|
comment='구매 수량 확정 마스터 테이블'
|
|
|
|
|
)
|
|
|
|
|
op.create_index('idx_purchase_confirmations_job_revision', 'purchase_confirmations', ['job_no', 'revision', 'is_active'], unique=False)
|
|
|
|
|
op.create_table('material_purchase_tracking',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_hash', sa.VARCHAR(length=64), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('original_description', sa.TEXT(), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('size_spec', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_grade', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('bom_quantity', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('confirmed_quantity', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('purchase_quantity', sa.NUMERIC(precision=10, scale=3), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('status', sa.VARCHAR(length=20), server_default=sa.text("'pending'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('confirmed_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('confirmed_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('ordered_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('ordered_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('approved_by', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('approved_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('job_no', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('revision', sa.VARCHAR(length=20), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('purchase_status', sa.VARCHAR(length=20), server_default=sa.text("'pending'::character varying"), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='material_purchase_tracking_file_id_fkey', ondelete='SET NULL'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='material_purchase_tracking_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('support_details',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('material_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('file_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('support_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('support_subtype', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('load_rating', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('load_capacity', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_standard', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('material_grade', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('pipe_size', sa.VARCHAR(length=20), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('length_mm', sa.NUMERIC(precision=10, scale=2), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('width_mm', sa.NUMERIC(precision=10, scale=2), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('height_mm', sa.NUMERIC(precision=10, scale=2), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('classification_confidence', sa.NUMERIC(precision=3, scale=2), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('updated_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['file_id'], ['files.id'], name='support_details_file_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.ForeignKeyConstraint(['material_id'], ['materials.id'], name='support_details_material_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='support_details_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_index('idx_support_details_material_id', 'support_details', ['material_id'], unique=False)
|
|
|
|
|
op.create_index('idx_support_details_file_id', 'support_details', ['file_id'], unique=False)
|
|
|
|
|
op.create_table('user_activity_logs',
|
|
|
|
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('user_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('username', sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('activity_type', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('activity_description', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('target_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('target_type', sa.VARCHAR(length=50), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('ip_address', sa.VARCHAR(length=45), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('user_agent', sa.TEXT(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('metadata', postgresql.JSONB(astext_type=sa.Text()), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.PrimaryKeyConstraint('id', name='user_activity_logs_pkey')
|
|
|
|
|
)
|
|
|
|
|
op.create_table('role_permissions',
|
|
|
|
|
sa.Column('role_permission_id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
|
|
|
sa.Column('role', sa.VARCHAR(length=20), autoincrement=False, nullable=False),
|
|
|
|
|
sa.Column('permission_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
|
|
|
sa.Column('created_at', postgresql.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), autoincrement=False, nullable=True),
|
|
|
|
|
sa.ForeignKeyConstraint(['permission_id'], ['permissions.permission_id'], name='role_permissions_permission_id_fkey', ondelete='CASCADE'),
|
|
|
|
|
sa.PrimaryKeyConstraint('role_permission_id', name='role_permissions_pkey'),
|
|
|
|
|
sa.UniqueConstraint('role', 'permission_id', name='role_permissions_role_permission_id_key')
|
|
|
|
|
)
|
|
|
|
|
# ### end Alembic commands ###
|