Skip to content

fix(database): add user soft-delete and fix audit_logs FK constraint (closes #344) - #493

Open
beulah7717108-eng wants to merge 1 commit into
XStreamRollz:mainfrom
beulah7717108-eng:fix/344-user-soft-delete
Open

fix(database): add user soft-delete and fix audit_logs FK constraint (closes #344)#493
beulah7717108-eng wants to merge 1 commit into
XStreamRollz:mainfrom
beulah7717108-eng:fix/344-user-soft-delete

Conversation

@beulah7717108-eng

Copy link
Copy Markdown

Summary

Closes #344 — users table has no soft-delete: deleted users leave orphaned foreign keys.

Changes

Database

  • Added deleted_at TIMESTAMPTZ column to the users table for GDPR-compliant soft-delete
  • Updated audit_logs.user_id FK to ON DELETE SET NULL to prevent orphaned rows when a user is deleted
  • Added idx_users_deleted_at partial index on non-null deleted_at values for efficient filtering
  • Created migration 2026082001_add_user_soft_delete with up/down rollback support
  • Updated database/schema.sql and database/audit_logs.sql to reflect the cumulative schema state

API

  • UsersRepository: Added WHERE deleted_at IS NULL filter to all read queries (findByEmail, findByUsername, findById, updateProfile, updatePasswordHash)
  • UsersRepository: Added softDelete(id) method that sets deleted_at = NOW()
  • UsersService: Added deleteUser() method with token revocation and audit logging
  • UsersController: Added DELETE /users/me endpoint (204 No Content, rate-limited)
  • AuditAction enum: Added USER_DELETE action for audit trail
  • Integration tests: Updated to verify deleted_at column exists

Testing

  • Migration pair is idempotent (uses IF EXISTS/IF NOT EXISTS guards)
  • Soft-deleted users are excluded from all repository queries
  • Token is revoked on deletion, preventing continued access
  • Audit log captures the deletion event

Migration

-- UP: 2026082001_add_user_soft_delete.up.sql
ALTER TABLE audit_logs DROP CONSTRAINT IF EXISTS audit_logs_user_id_fkey;
ALTER TABLE audit_logs ADD CONSTRAINT audit_logs_user_id_fkey
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE users ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
CREATE INDEX IF NOT EXISTS idx_users_deleted_at ON users(deleted_at)
    WHERE deleted_at IS NOT NULL;

…loses XStreamRollz#344)

- Add deleted_at TIMESTAMPTZ column to users table for GDPR-compliant soft-delete
- Update audit_logs.user_id FK to ON DELETE SET NULL to prevent orphaned rows
- Add idx_users_deleted_at partial index for efficient soft-delete filtering
- Update UsersRepository: filter WHERE deleted_at IS NULL on all read queries
- Add softDelete method to UsersRepository
- Implement DELETE /users/me endpoint in UsersController with token revocation
- Add USER_DELETE audit action to AuditAction enum
- Update integration tests to verify deleted_at column exists
- Create migration 2026082001 with up/down rollback support
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

database: users table has no soft-delete — deleted users leave orphaned foreign keys

2 participants