feat: implement Active Pointer + Smart Deletion Pattern for accounts
- Consolidate migrations: merge 002/003 into 001_initial with UNIQUE did constraint - Add foreign key: active_identity.activeDid REFERENCES accounts.did ON DELETE RESTRICT - Replace empty string defaults with NULL for proper empty state handling - Implement atomic smart deletion with auto-switch logic in IdentitySwitcherView - Add DAL methods: $getAllAccountDids, $getActiveDid, $setActiveDid, $pickNextAccountDid - Add migration bootstrapping to auto-select first account if none selected - Block deletion of last remaining account with user notification Refs: doc/active-pointer-smart-deletion-pattern.md
This commit is contained in:
@@ -272,15 +272,48 @@ export default class IdentitySwitcherView extends Vue {
|
||||
this.notify.confirm(
|
||||
NOTIFY_DELETE_IDENTITY_CONFIRM.text,
|
||||
async () => {
|
||||
await this.$exec(`DELETE FROM accounts WHERE id = ?`, [id]);
|
||||
this.otherIdentities = this.otherIdentities.filter(
|
||||
(ident) => ident.id !== id,
|
||||
);
|
||||
await this.smartDeleteAccount(id);
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Smart deletion with atomic transaction and last account protection
|
||||
* Follows the Active Pointer + Smart Deletion Pattern
|
||||
*/
|
||||
async smartDeleteAccount(id: string) {
|
||||
await this.$withTransaction(async () => {
|
||||
const total = await this.$countAccounts();
|
||||
if (total <= 1) {
|
||||
this.notify.warning(
|
||||
"Cannot delete the last account. Keep at least one.",
|
||||
);
|
||||
throw new Error("blocked:last-item");
|
||||
}
|
||||
|
||||
const accountDid = await this.$getAccountDidById(parseInt(id));
|
||||
const activeDid = await this.$getActiveDid();
|
||||
|
||||
if (activeDid === accountDid) {
|
||||
const allDids = await this.$getAllAccountDids();
|
||||
const nextDid = this.$pickNextAccountDid(
|
||||
allDids.filter((d) => d !== accountDid),
|
||||
accountDid,
|
||||
);
|
||||
await this.$setActiveDid(nextDid);
|
||||
this.notify.success(`Switched active to ${nextDid} before deletion.`);
|
||||
}
|
||||
|
||||
await this.$exec("DELETE FROM accounts WHERE id = ?", [id]);
|
||||
});
|
||||
|
||||
// Update UI
|
||||
this.otherIdentities = this.otherIdentities.filter(
|
||||
(ident) => ident.id !== id,
|
||||
);
|
||||
}
|
||||
|
||||
notifyCannotDelete() {
|
||||
this.notify.warning(
|
||||
NOTIFY_CANNOT_DELETE_ACTIVE_IDENTITY.message,
|
||||
|
||||
Reference in New Issue
Block a user