logicspike/docs

Settings

Workspace Settings & Profile Polish - Technical Specification

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 slug or tenantId. This is to prevent breaking existing API links, integrations, or custom domains that rely on the slug.
  • Permissions:
    • Only role_owner or role_admin can rename a workspace.
    • If a role_member or role_viewer hits the endpoint, it must return 403 Forbidden.
  • UI/UX Flow:
    • Located at /dashboard/settings.
    • The "Workspace Name" input switches from disabled to 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.

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 lacks role_owner or role_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_owner can delete a workspace. No exceptions.
  • 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.
  • Cascading Database Deletions:
    • Using Drizzle ORM, we must perform a db.transaction.
    • Step 1: Delete all tenantServices for the tenantId.
    • Step 2: Delete all memberships for the tenantId.
    • (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.
  • 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.

Backend API Specification

  • Endpoint: DELETE /manager/tenants
  • Headers: Authorization: Bearer <jwt>, x-tenant-id: <string>
  • Error Responses:
    • 403 Forbidden: User is not role_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_owner can initiate a transfer.
  • Role Swapping:
    • When ownership is successfully transferred, the previous owner is automatically demoted to role_admin to prevent orphaned high-privilege accounts, while the new owner is assigned role_owner.
  • 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.

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 to role_owner.

4. Implementation Steps Checklist

Backend Updates

  1. Update apps/manager/src/routes/tenants.ts to include PATCH / logic.
  2. Update apps/manager/src/routes/tenants.ts to include DELETE / logic with a full db.transaction() cascade. Enforce isOwner === true by checking the database.
  3. Update apps/manager/src/routes/tenants.ts to include POST /transfer logic.

Frontend Updates

  1. Enhance apps/seller-dashboard/src/app/dashboard/settings/page.tsx:
    • Workspace Name field is editable with "Save Changes" hooked to PATCH.
  2. 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.
  3. 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-themes on the frontend, optionally synced to the users table 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:
      1. Delete the workspace first.
      2. Transfer ownership of the workspace to another member.
    • Once confirmed, all memberships for this user are dropped, their users row is stripped (or hard deleted), and auth provider links are severed.
Settings