diff --git a/database/migrations/2026_06_17_000000_create_gdpr_requests_table.php b/database/migrations/2026_06_17_000000_create_gdpr_requests_table.php new file mode 100644 index 000000000..3d1982e84 --- /dev/null +++ b/database/migrations/2026_06_17_000000_create_gdpr_requests_table.php @@ -0,0 +1,43 @@ +id(); + $table->unsignedBigInteger('user_id')->nullable(); + $table->string('requester_username')->nullable(); + $table->string('requester_email')->nullable(); + $table->string('type', 32); + $table->string('status', 32)->default('pending'); + $table->json('request_payload')->nullable(); + $table->json('response_payload')->nullable(); + $table->text('notes')->nullable(); + $table->text('admin_notes')->nullable(); + $table->string('export_disk')->nullable(); + $table->string('export_path')->nullable(); + $table->timestamp('export_expires_at')->nullable(); + $table->unsignedBigInteger('processed_by')->nullable(); + $table->timestamp('completed_at')->nullable(); + $table->timestamps(); + + $table->index(['user_id', 'type', 'status'], 'ix_gdpr_requests_user_type_status'); + $table->index(['status', 'created_at'], 'ix_gdpr_requests_status_created'); + $table->index(['type', 'created_at'], 'ix_gdpr_requests_type_created'); + }); + } + + public function down(): void + { + Schema::dropIfExists('gdpr_requests'); + } +}; diff --git a/database/migrations/2026_06_17_000001_create_gdpr_consents_table.php b/database/migrations/2026_06_17_000001_create_gdpr_consents_table.php new file mode 100644 index 000000000..87c70f71f --- /dev/null +++ b/database/migrations/2026_06_17_000001_create_gdpr_consents_table.php @@ -0,0 +1,37 @@ +id(); + $table->unsignedBigInteger('user_id')->nullable(); + $table->string('consent_type', 64); + $table->string('status', 32)->default('granted'); + $table->string('policy_version', 64)->nullable(); + $table->timestamp('consented_at')->nullable(); + $table->timestamp('withdrawn_at')->nullable(); + $table->string('ip_address', 45)->nullable(); + $table->string('user_agent_hash', 64)->nullable(); + $table->json('metadata')->nullable(); + $table->timestamps(); + + $table->index(['user_id', 'consent_type'], 'ix_gdpr_consents_user_type'); + $table->index(['consent_type', 'status'], 'ix_gdpr_consents_type_status'); + }); + } + + public function down(): void + { + Schema::dropIfExists('gdpr_consents'); + } +}; diff --git a/database/migrations/2026_06_17_000002_create_gdpr_audit_logs_table.php b/database/migrations/2026_06_17_000002_create_gdpr_audit_logs_table.php new file mode 100644 index 000000000..792d64a44 --- /dev/null +++ b/database/migrations/2026_06_17_000002_create_gdpr_audit_logs_table.php @@ -0,0 +1,35 @@ +id(); + $table->unsignedBigInteger('gdpr_request_id')->nullable(); + $table->unsignedBigInteger('user_id')->nullable(); + $table->unsignedBigInteger('actor_id')->nullable(); + $table->string('event', 64); + $table->text('description'); + $table->json('metadata')->nullable(); + $table->timestamp('created_at')->useCurrent(); + + $table->index(['gdpr_request_id', 'created_at'], 'ix_gdpr_audit_request_created'); + $table->index(['user_id', 'created_at'], 'ix_gdpr_audit_user_created'); + $table->index(['event', 'created_at'], 'ix_gdpr_audit_event_created'); + }); + } + + public function down(): void + { + Schema::dropIfExists('gdpr_audit_logs'); + } +};