Last Updated: 2026-03-29
Overview
This document details the architectural additions and edge cases for polishing the "Settings & Profile" section of the Seller Dashboard. The primary focus is extending the Workspace settings to support Renaming and Deletion, while ensuring strict access control, data integrity, and a premium UI/UX.
1. Feature: Workspace Renaming
Description
Allows users with appropriate permissions (role_owner, role_admin) to change the display name of their active workspace.
Edge Cases & Requirements
- Validation:
- Must be between 1 and 100 characters.
- Cannot be empty or just whitespace.
- Slug Integrity:
- Renaming the workspace Display Name will NOT change the underlying
slugortenantId. This is to prevent breaking existing API links, integrations, or custom domains that rely on the slug.
- Renaming the workspace Display Name will NOT change the underlying
- Permissions:
- Only
role_ownerorrole_admincan rename a workspace. - If a
role_memberorrole_viewerhits the endpoint, it must return403 Forbidden.
- Only
- UI/UX Flow:
- Located at
/dashboard/settings. - The "Workspace Name" input switches from
disabledto actively editable for admins/owners. - On input change, a "Save Changes" button appears or activates.
- Button shows a loading spinner on submission.
- On success: Toast notification -> update React state -> update sidebar workspace list selector without needing a full page reload.
- Located at
Backend API Specification
- Endpoint:
PATCH /manager/tenants - Headers:
Authorization: Bearer <jwt>,x-tenant-id: <string> - Request Body:
{ "name": string } - Error Responses:
400 Bad Request: Validation errors (e.g., name too short).401 Unauthorized: Missing or invalid JWT.403 Forbidden: User lacksrole_ownerorrole_admin.404 Not Found: Tenant does not exist.
2. Feature: Workspace Deletion (Danger Zone)
Description
Allows the creator/owner to permanently delete the workspace, dropping all associated data, memberships, and services.
Edge Cases & Requirements
- Strict Access Control:
- ONLY
role_ownercan delete a workspace. No exceptions.
- ONLY
- Confirmation Mechanism (UI):
- Cannot be deleted with a single click.
- Requires a modal where the user must type the exact name of the workspace to enable the final "Delete Permanently" button.
- Last Workspace Handling:
- If the user deletes their only remaining workspace, they will be left without a context.
- Resolution: The frontend checks the updated workspace list. If
workspaces.length === 0, redirect the user immediately to/onboarding.
- Immediate Context Switching:
- If the user has other workspaces, the system must automatically run
switchWorkspace(otherTenantId)so they are not left on a broken context.
- If the user has other workspaces, the system must automatically run
- Cascading Database Deletions:
- Using Drizzle ORM, we must perform a
db.transaction. - Step 1: Delete all
tenantServicesfor thetenantId. - Step 2: Delete all
membershipsfor thetenantId. - (Future) Step 3: Delete billing/subscription data, API keys, etc. Let's ensure no foreign key constraints bounce the deletion.
- Step 4: Delete the row in
tenants.
- Using Drizzle ORM, we must perform a
- Re-Authentication / Session Refresh:
- The current JWT contains the deleted
tenantId. The frontend must clear this token or immediately fetch a new one by switching to another workspace.
- The current JWT contains the deleted
Backend API Specification
- Endpoint:
DELETE /manager/tenants - Headers:
Authorization: Bearer <jwt>,x-tenant-id: <string> - Error Responses:
403 Forbidden: User is notrole_owner.500 Internal Server Error: Transaction failed due to cascading constraints.
3. Feature: Transfer Workspace Ownership
Description
Allows the current Workspace Owner to transfer full ownership to another existing member of the workspace.
Edge Cases & Requirements
- Target User Validation:
- The user receiving ownership MUST already be an active member of the workspace.
- You cannot transfer ownership to someone who hasn't accepted an invite or doesn't have an account.
- Access Control:
- ONLY the current
role_ownercan initiate a transfer.
- ONLY the current
- Role Swapping:
- When ownership is successfully transferred, the previous owner is automatically demoted to
role_adminto prevent orphaned high-privilege accounts, while the new owner is assignedrole_owner.
- When ownership is successfully transferred, the previous owner is automatically demoted to
- UI/UX Flow:
- Located in the Danger Zone of
/dashboard/settings. - Dropdown selects from a list of current workspace members.
- Requires a confirmation modal (similar to deletion) to prevent accidental transfers.
- Once complete, the UI must re-fetch permissions. If the user is no longer the owner, the Danger Zone hides itself.
- Located in the Danger Zone of
Backend API Specification
- Endpoint:
POST /manager/tenants/transfer - Headers:
Authorization: Bearer <jwt>,x-tenant-id: <string> - Request Body:
{ "newOwnerId": string } - Process:
- Transaction: Demote current owner to
role_admin, promote target user torole_owner.
- Transaction: Demote current owner to
4. Implementation Steps Checklist
Backend Updates
- Update
apps/manager/src/routes/tenants.tsto includePATCH /logic. - Update
apps/manager/src/routes/tenants.tsto includeDELETE /logic with a fulldb.transaction()cascade. EnforceisOwner === trueby checking the database. - Update
apps/manager/src/routes/tenants.tsto includePOST /transferlogic.
Frontend Updates
- Enhance
apps/seller-dashboard/src/app/dashboard/settings/page.tsx:- Workspace Name field is editable with "Save Changes" hooked to
PATCH.
- Workspace Name field is editable with "Save Changes" hooked to
- Implement the "Danger Zone" in the settings page UI:
- Include a prominent red section.
- Add "Transfer Ownership" modal and logic.
- Add "Delete Workspace" modal and logic.
- Implement post-delete routing in the frontend hook (
useWorkspaces/page.tsx).
Future Considerations Noted
- Pre-deletion checks: If a workspace has an active paid subscription via Stripe, we must cancel the Stripe subscription before dropping it from the DB to avoid ghost charges. (To be scoped when Billing is implemented).
- Soft Delete vs Hard Delete: For now, we utilize Hard Delete. Later, enterprise plans might require a 30-day Soft Delete retention period.
5. Feature: User-Level Settings (Global Profile)
Description
While workspaces are isolated tenants, a User represents a global identity across the platform. The User-Level settings must dictate preferences and security that persist regardless of the active workspace context.
4.1. Global Identity & Authentication
- Edge Cases:
- Email Immutability: Emails are tied to NextAuth (OAuth providers) and primary Identity. To prevent account takeovers, users cannot change their primary email through a simple input. If required later, this must trigger a secure email verification flow to the new address before swapping, while notifying the old address.
- Avatar Management: Uploads must be validated (Max 4MB, restricted to
image/jpeg,image/png,image/webp). Processed and stored globally (e.g., in a cloud bucket).
4.2. Security (2FA & Active Sessions)
- Two-Factor Authentication (2FA):
- Flow: Provide TOTP (Authenticator App) setup. The user scans a QR code generated by the backend, inputs a 6-digit pin to verify.
- Edge Case: Must provide recovery codes during setup. If the user loses their phone and has no recovery codes, manual admin intervention is required.
- Enforcement: Workspaces can eventually enable "Require 2FA for all members". If a user doesn't have 2FA enabled globally, they are locked out of that specific workspace until they enable it.
- Active Sessions:
- Flow: Display a list of active devices/IPs where the user is logged in.
- Action: Allow the user to "Revoke All Other Sessions". This forces a JWT rotation or invalidates existing refresh tokens globally.
4.3. User Preferences (Cosmetics & UX)
- Theme: Light, Dark, or System preference. (Handled contextually via
next-themeson the frontend, optionally synced to theuserstable for multi-device sync). - Notifications:
- Granular toggles: Email vs. Push vs. In-App.
- Categories: Security alerts (cannot be disabled), Workspace invites, Billing updates, Marketing.
4.4. Global Account Deletion
- Description: "Right to be forgotten" implementation.
- Edge Cases (CRITICAL):
- A user cannot delete their global account if they are the sole Owner of an active workspace. They must either:
- Delete the workspace first.
- Transfer ownership of the workspace to another member.
- Once confirmed, all
membershipsfor this user are dropped, theirusersrow is stripped (or hard deleted), and auth provider links are severed.
- A user cannot delete their global account if they are the sole Owner of an active workspace. They must either: