-- Repositorio de credenciales privado por usuario ("Contraseñas"). Idempotente. -- password_enc/notes_enc guardan el resultado de encrypt() (AES-256-GCM, backend/src/utils/crypto.js), -- nunca texto plano. Privado por usuario -- nadie mas lo ve, ni siquiera un superadmin. CREATE TABLE IF NOT EXISTS vault_entries ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, title VARCHAR(160) NOT NULL, url VARCHAR(500) NULL, username VARCHAR(160) NULL, password_enc TEXT NULL, notes_enc TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT fk_vault_entries_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE INDEX IF NOT EXISTS idx_vault_entries_user ON vault_entries(user_id); -- PIN de acceso al modulo (candado, NO participa del cifrado -- 4 digitos seria debil para eso). -- Independiente del password_hash de login: cambiarlo/resetearlo nunca toca vault_entries. ALTER TABLE users ADD COLUMN IF NOT EXISTS vault_pin_hash VARCHAR(255) NULL, ADD COLUMN IF NOT EXISTS vault_pin_reset_token VARCHAR(128) NULL, ADD COLUMN IF NOT EXISTS vault_pin_reset_token_expires DATETIME NULL; CREATE INDEX IF NOT EXISTS idx_users_vault_pin_reset_token ON users(vault_pin_reset_token);