Account deletion
How a traveller's or a partner's account is deleted, and what the office does with a deletion request. Since 1 Oct 2026 nobody erases their own account: every traveller and partner who asks files a request, and the office approves or declines it within 30 days. Rules: AUD-025, AUD-026, AUD-027. Screens: the app (native app), the website (portals) and, for the office, Account deletions.
What the person does
In the app: Me → Request account deletion (a partner: More → Request account deletion).
On the website: My Profile → Request account deletion (a partner: /me). They read what is
erased and what is kept, type DELETE and their password.
- Always → a request comes to the office, even when nothing is open. They read "Your request has been sent. The office will review your account and contact you." Nothing is erased and they stay signed in.
- Anything the office must settle first is listed for them in plain words — a trip, a balance, money the company holds for them ("We hold ₹5000.00 for you on booking BK-4 — the office will settle it with you first."), a payment or request still open.
- A business partner's request says "Business partner — the office decides".
- When the office approves, they get one email, "Your Alhuda Travels account has been deleted", at the address the account had, and the login stops working.
A staff login cannot do this. A member of staff who leaves is closed by HR (deactivate on the employee record).
Handling a request (the office)
People → Account deletions (/people/account-deletions). Travellers' requests need
customers.edit; partners' need partners.edit.
- Open Waiting. Each request shows its answer-by date (30 days after the request — answer before then; nothing escalates by itself) and lists what is still in the way, worked out afresh each time the page loads. A request with nothing in the way still waits for you: review it, then approve or decline.
- Call the person. Settle each item the normal way:
- The trip has not finished — if they want to cancel, cancel the booking (the cancellation policy applies; a refund goes the usual way). If they will travel, tell them to ask again after the trip, and Decline with a note saying so.
- A balance is still to be paid — record the payment, or agree it; a write-off is a finance decision, made the usual way. Amounts read in rupees as ₹40000.00, and in the currency's code for anything else (SAR 1500.00) — the same on every line.
- A payment you reported is waiting for the office — finance verifies or rejects it.
The line names the booking (Booking BK-…) or, for a partner who reported a payment
against a group invoice, the invoice (Invoice GI-…). Until migration
20261006140000a partner's claim on a group invoice was missed and did not block. - A request is still open — close or answer it.
- An unpaid invoice — as a balance.
- We hold money for them on a booking (an overpayment, or a cancelled traveller's refund not paid out) — finance refunds it the usual way (request, then approve — the approval pays it out). The line goes once the refund is paid.
- A refund is waiting for the office — finance approves (pays) or rejects it.
- We hold money for them on an invoice — refund the overpayment on the group invoice.
- An advance not yet used — allocate it to a booking or refund it.
- Business partner — review the agency first: its bookings, invoices, commission and ledger; settle anything open with the partner.
- Tour leader of a departure — appoint someone else, or wait for the return.
- The office has paused this account — resolve the reason, resume or leave paused, then decide.
- When the list is empty, Complete deletion — this is the approval. Add a note if useful (it stays on the record, never shown to the person). The system erases the details, sends the goodbye email, moves the Drive files to the trash and deletes the login.
- To refuse, Decline with a note. Write it for the person — they read it in the app and on the website (REQ-001, REQ-002). They may ask again later.
Complete deletion stays greyed out while anything is in the way; the database refuses it as well.
Checking the follow-up
Deleted shows each deletion with: login deleted or not, Drive files in the trash
(n/total), goodbye email sent or not.
- Login NOT yet deleted — the auth service refused; the login was banned instead and the user row is inactive, so nobody can sign in. Press Finish to try again.
- Drive files not all in the trash — the Drive was not connected or refused. Press Finish
when the Drive is back (Google Drive). If a file still will not move, open the
Shared Drive as an administrator, find the file by its id (the database keeps it in
AccountDeletion."driveFileIds") and move it to the trash by hand, then press Finish. - Email not sent — email was not configured (
RESEND_API_KEY) or refused. It is not sent again: the address is gone. Nothing else to do.
A trashed file is removed from the Shared Drive's trash after 30 days.
What is erased and what is kept
See AUD-026. In short: the login and personal details go; bookings, payments, receipts, invoices, tickets, the ledger, travellers' names on them, the customer code, PAN, GSTIN and state stay; a partner's business record stays; the audit trail is never changed.
A request by email or phone from someone without an account, or from someone who cannot sign in, is not handled by these screens. Record it as a customer request and ask IT; access and correction requests, and erasure for people without an account, are still open under AUD-022.
Deploying (IT)
The migration 20261004090000_a_person_deletes_their_account.sql goes with the normal release
(Deploy runbook). The edge function is new:
scripts/deno-check-functions.sh account-delete
supabase functions deploy account-delete --project-ref yzpfwdxpwalmfuodkxni
In Dashboard → Edge Functions → account-delete, Verify JWT must be off (as in
supabase/config.toml). It uses the secrets already set for other functions:
SUPABASE_ANON_KEY (the password check), SUPABASE_SERVICE_ROLE_KEY, RESEND_API_KEY /
RESEND_FROM (the goodbye email) and the Google Drive secrets (the trash). No new secret.
The change of 1 Oct 2026 (always a request; money held blocks) is the migration
20261005090000_an_account_is_deleted_only_on_request.sql and a redeploy of account-delete
(its wording). Deploy them together; until the function is redeployed the old function still
works — the database files the request either way.
To try it after the deploy, create a test traveller with invented details on a departure that has already returned, sign in to the app, and request deletion. Check the app says the request has been sent and the traveller is still signed in, then Complete deletion on Account deletions → Waiting and check Deleted shows the login deleted and the email sent.