updates
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
"""add_anonymous_gdpr_support
|
||||
|
||||
Revision ID: 6f7f8689fc98
|
||||
Revises: 7a899ef55e3b
|
||||
Create Date: 2025-12-01 04:15:00.000000
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '6f7f8689fc98'
|
||||
down_revision = '7a899ef55e3b'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Update gdpr_requests table to support anonymous users
|
||||
op.alter_column('gdpr_requests', 'user_id',
|
||||
existing_type=sa.Integer(),
|
||||
nullable=True)
|
||||
op.add_column('gdpr_requests', sa.Column('is_anonymous', sa.Boolean(), nullable=False, server_default='0'))
|
||||
op.create_index(op.f('ix_gdpr_requests_is_anonymous'), 'gdpr_requests', ['is_anonymous'], unique=False)
|
||||
|
||||
# Update consents table to support anonymous users
|
||||
op.alter_column('consents', 'user_id',
|
||||
existing_type=sa.Integer(),
|
||||
nullable=True)
|
||||
op.add_column('consents', sa.Column('user_email', sa.String(length=255), nullable=True))
|
||||
op.add_column('consents', sa.Column('is_anonymous', sa.Boolean(), nullable=False, server_default='0'))
|
||||
op.create_index(op.f('ix_consents_user_email'), 'consents', ['user_email'], unique=False)
|
||||
op.create_index(op.f('ix_consents_is_anonymous'), 'consents', ['is_anonymous'], unique=False)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index(op.f('ix_consents_is_anonymous'), table_name='consents')
|
||||
op.drop_index(op.f('ix_consents_user_email'), table_name='consents')
|
||||
op.drop_column('consents', 'is_anonymous')
|
||||
op.drop_column('consents', 'user_email')
|
||||
op.alter_column('consents', 'user_id',
|
||||
existing_type=sa.Integer(),
|
||||
nullable=False)
|
||||
|
||||
op.drop_index(op.f('ix_gdpr_requests_is_anonymous'), table_name='gdpr_requests')
|
||||
op.drop_column('gdpr_requests', 'is_anonymous')
|
||||
op.alter_column('gdpr_requests', 'user_id',
|
||||
existing_type=sa.Integer(),
|
||||
nullable=False)
|
||||
@@ -0,0 +1,173 @@
|
||||
"""add_comprehensive_gdpr_tables
|
||||
|
||||
Revision ID: 7a899ef55e3b
|
||||
Revises: dbafe747c931
|
||||
Create Date: 2025-12-01 04:10:25.699589
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import mysql
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '7a899ef55e3b'
|
||||
down_revision = 'dbafe747c931'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Consent table
|
||||
op.create_table(
|
||||
'consents',
|
||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||
sa.Column('consent_type', sa.Enum('marketing', 'analytics', 'necessary', 'preferences', 'third_party_sharing', 'profiling', 'automated_decision_making', name='consenttype'), nullable=False),
|
||||
sa.Column('status', sa.Enum('granted', 'withdrawn', 'pending', 'expired', name='consentstatus'), nullable=False),
|
||||
sa.Column('granted_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('withdrawn_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('expires_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('legal_basis', sa.String(length=100), nullable=True),
|
||||
sa.Column('consent_method', sa.String(length=50), nullable=True),
|
||||
sa.Column('consent_version', sa.String(length=20), nullable=True),
|
||||
sa.Column('ip_address', sa.String(length=45), nullable=True),
|
||||
sa.Column('user_agent', sa.String(length=255), nullable=True),
|
||||
sa.Column('source', sa.String(length=100), nullable=True),
|
||||
sa.Column('extra_metadata', sa.JSON(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=False),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_consents_id'), 'consents', ['id'], unique=False)
|
||||
op.create_index(op.f('ix_consents_user_id'), 'consents', ['user_id'], unique=False)
|
||||
op.create_index(op.f('ix_consents_consent_type'), 'consents', ['consent_type'], unique=False)
|
||||
op.create_index(op.f('ix_consents_status'), 'consents', ['status'], unique=False)
|
||||
op.create_index(op.f('ix_consents_created_at'), 'consents', ['created_at'], unique=False)
|
||||
|
||||
# Data processing records table
|
||||
op.create_table(
|
||||
'data_processing_records',
|
||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
||||
sa.Column('processing_category', sa.Enum('collection', 'storage', 'usage', 'sharing', 'deletion', 'anonymization', 'transfer', name='processingcategory'), nullable=False),
|
||||
sa.Column('legal_basis', sa.Enum('consent', 'contract', 'legal_obligation', 'vital_interests', 'public_task', 'legitimate_interests', name='legalbasis'), nullable=False),
|
||||
sa.Column('purpose', sa.Text(), nullable=False),
|
||||
sa.Column('data_categories', sa.JSON(), nullable=True),
|
||||
sa.Column('data_subjects', sa.JSON(), nullable=True),
|
||||
sa.Column('recipients', sa.JSON(), nullable=True),
|
||||
sa.Column('third_parties', sa.JSON(), nullable=True),
|
||||
sa.Column('transfers_to_third_countries', sa.Boolean(), nullable=False),
|
||||
sa.Column('transfer_countries', sa.JSON(), nullable=True),
|
||||
sa.Column('safeguards', sa.Text(), nullable=True),
|
||||
sa.Column('retention_period', sa.String(length=100), nullable=True),
|
||||
sa.Column('retention_criteria', sa.Text(), nullable=True),
|
||||
sa.Column('security_measures', sa.Text(), nullable=True),
|
||||
sa.Column('user_id', sa.Integer(), nullable=True),
|
||||
sa.Column('related_booking_id', sa.Integer(), nullable=True),
|
||||
sa.Column('related_payment_id', sa.Integer(), nullable=True),
|
||||
sa.Column('processed_by', sa.Integer(), nullable=True),
|
||||
sa.Column('processing_timestamp', sa.DateTime(), nullable=False),
|
||||
sa.Column('extra_metadata', sa.JSON(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=False),
|
||||
sa.ForeignKeyConstraint(['processed_by'], ['users.id'], ),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_data_processing_records_id'), 'data_processing_records', ['id'], unique=False)
|
||||
op.create_index(op.f('ix_data_processing_records_processing_category'), 'data_processing_records', ['processing_category'], unique=False)
|
||||
op.create_index(op.f('ix_data_processing_records_legal_basis'), 'data_processing_records', ['legal_basis'], unique=False)
|
||||
op.create_index(op.f('ix_data_processing_records_user_id'), 'data_processing_records', ['user_id'], unique=False)
|
||||
op.create_index(op.f('ix_data_processing_records_processing_timestamp'), 'data_processing_records', ['processing_timestamp'], unique=False)
|
||||
op.create_index(op.f('ix_data_processing_records_created_at'), 'data_processing_records', ['created_at'], unique=False)
|
||||
|
||||
# Data breaches table
|
||||
op.create_table(
|
||||
'data_breaches',
|
||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
||||
sa.Column('breach_type', sa.Enum('confidentiality', 'integrity', 'availability', name='breachtype'), nullable=False),
|
||||
sa.Column('status', sa.Enum('detected', 'investigating', 'contained', 'reported_to_authority', 'notified_data_subjects', 'resolved', name='breachstatus'), nullable=False),
|
||||
sa.Column('description', sa.Text(), nullable=False),
|
||||
sa.Column('affected_data_categories', sa.JSON(), nullable=True),
|
||||
sa.Column('affected_data_subjects', sa.JSON(), nullable=True),
|
||||
sa.Column('detected_at', sa.DateTime(), nullable=False),
|
||||
sa.Column('occurred_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('contained_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('reported_to_authority_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('authority_reference', sa.String(length=255), nullable=True),
|
||||
sa.Column('notified_data_subjects_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('notification_method', sa.String(length=100), nullable=True),
|
||||
sa.Column('likely_consequences', sa.Text(), nullable=True),
|
||||
sa.Column('measures_proposed', sa.Text(), nullable=True),
|
||||
sa.Column('risk_level', sa.String(length=20), nullable=True),
|
||||
sa.Column('reported_by', sa.Integer(), nullable=False),
|
||||
sa.Column('investigated_by', sa.Integer(), nullable=True),
|
||||
sa.Column('extra_metadata', sa.JSON(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=False),
|
||||
sa.ForeignKeyConstraint(['investigated_by'], ['users.id'], ),
|
||||
sa.ForeignKeyConstraint(['reported_by'], ['users.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_data_breaches_id'), 'data_breaches', ['id'], unique=False)
|
||||
op.create_index(op.f('ix_data_breaches_breach_type'), 'data_breaches', ['breach_type'], unique=False)
|
||||
op.create_index(op.f('ix_data_breaches_status'), 'data_breaches', ['status'], unique=False)
|
||||
op.create_index(op.f('ix_data_breaches_detected_at'), 'data_breaches', ['detected_at'], unique=False)
|
||||
|
||||
# Retention rules table
|
||||
op.create_table(
|
||||
'retention_rules',
|
||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
||||
sa.Column('data_category', sa.String(length=100), nullable=False),
|
||||
sa.Column('retention_period_days', sa.Integer(), nullable=False),
|
||||
sa.Column('retention_period_months', sa.Integer(), nullable=True),
|
||||
sa.Column('retention_period_years', sa.Integer(), nullable=True),
|
||||
sa.Column('legal_basis', sa.Text(), nullable=True),
|
||||
sa.Column('legal_requirement', sa.Text(), nullable=True),
|
||||
sa.Column('action_after_retention', sa.String(length=50), nullable=False),
|
||||
sa.Column('conditions', sa.JSON(), nullable=True),
|
||||
sa.Column('is_active', sa.Boolean(), nullable=False),
|
||||
sa.Column('description', sa.Text(), nullable=True),
|
||||
sa.Column('created_by', sa.Integer(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=False),
|
||||
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('data_category')
|
||||
)
|
||||
op.create_index(op.f('ix_retention_rules_id'), 'retention_rules', ['id'], unique=False)
|
||||
op.create_index(op.f('ix_retention_rules_data_category'), 'retention_rules', ['data_category'], unique=True)
|
||||
op.create_index(op.f('ix_retention_rules_is_active'), 'retention_rules', ['is_active'], unique=False)
|
||||
|
||||
# Data retention logs table
|
||||
op.create_table(
|
||||
'data_retention_logs',
|
||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
||||
sa.Column('retention_rule_id', sa.Integer(), nullable=False),
|
||||
sa.Column('data_category', sa.String(length=100), nullable=False),
|
||||
sa.Column('action_taken', sa.String(length=50), nullable=False),
|
||||
sa.Column('records_affected', sa.Integer(), nullable=False),
|
||||
sa.Column('affected_ids', sa.JSON(), nullable=True),
|
||||
sa.Column('executed_by', sa.Integer(), nullable=True),
|
||||
sa.Column('executed_at', sa.DateTime(), nullable=False),
|
||||
sa.Column('success', sa.Boolean(), nullable=False),
|
||||
sa.Column('error_message', sa.Text(), nullable=True),
|
||||
sa.Column('extra_metadata', sa.JSON(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['executed_by'], ['users.id'], ),
|
||||
sa.ForeignKeyConstraint(['retention_rule_id'], ['retention_rules.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_data_retention_logs_id'), 'data_retention_logs', ['id'], unique=False)
|
||||
op.create_index(op.f('ix_data_retention_logs_retention_rule_id'), 'data_retention_logs', ['retention_rule_id'], unique=False)
|
||||
op.create_index(op.f('ix_data_retention_logs_data_category'), 'data_retention_logs', ['data_category'], unique=False)
|
||||
op.create_index(op.f('ix_data_retention_logs_executed_at'), 'data_retention_logs', ['executed_at'], unique=False)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# Drop foreign keys first, then indexes, then tables
|
||||
op.drop_table('data_retention_logs')
|
||||
|
||||
op.drop_table('retention_rules')
|
||||
op.drop_table('data_breaches')
|
||||
op.drop_table('data_processing_records')
|
||||
op.drop_table('consents')
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user