Permission Catalog

This page is the canonical catalog of Reply Pilot application permissions. The permission code is the string used by backend and Flask authorization checks. Keep this page in sync with public.app_permission, AppPermissionCodes, backend authorization checks, Flask permission gates, and seeded role grants.

Permission List

Code Definition Scope and important behavior
company.view_assigned User can view companies assigned to them. Assigned company means party_organization.default_email_sales_user_id = app_user.id. Companies without an assigned default email sales user are not visible through this permission alone. Task search reuses this scope: tasks without linked party and tasks linked to non-company parties are visible; company-linked tasks are visible when the linked company is assigned to the user. Exact-task reads also include any active Jira task assigned to the current local user or Jira-account profile. Company delegation remains limited to active assigned Reply Pilot Task items. Normalized Done tasks never delegate access.
company.view_all User can view all companies. Bypasses the assigned-company read scope for backend read model and search proxy, including task search. No separate task.* or ticket.* permission exists.
company.write User can perform global company write operations. Accepted for creating self-assigned companies, creating company-linked Reply Pilot Task issues, and existing-company and linked-task mutations, where backend still checks company visibility.
company.write_assigned User can create self-assigned companies and write existing companies and linked tasks within their company visibility scope. New companies are assigned to the current user as default_email_sales_user_id. For users without company.view_all, existing writes remain limited to companies where the user is the default email communication owner; this also covers creating company-linked Reply Pilot Task issues for visible assigned companies.
company.merge User can merge duplicate companies. Merge endpoints still require access to the affected company records.
security.manage_roles User can manage role assignments. Required for listing all roles, reading another user's assigned role IDs, and replacing user roles. Backend prevents removing the last role manager.
security.impersonate_user User can start a controlled impersonation session for another user. Kept separate from admin. Cannot impersonate self, users with security.manage_roles, or users with security.impersonate_user. Starts are recorded in app_user_impersonation_audit.

Delegated task read exception: backend read-model company endpoints may also expose the company linked to an active Reply Pilot Task when the current app user is its local assignee or the cached Jira assignee matches the user's Jira profile. This includes the company's notes and activities. Exact-task reads use the same active-assignee rule for all Jira work types. The assignee may also trigger POST /api/tasks/{taskId}/refresh-from-jira as read-side cache synchronization; the backend always uses the Jira key stored on that task and ignores any client supplied key. Delegation does not expose unrelated companies or unrelated tasks at the same company and excludes unassigned or normalized Done tasks.

Delegated company collaboration exception: an active assigned Reply Pilot Task allows its assignee to add company notes, create/update/remove company contact methods, create a new person linked to the company, and remove a person-company relationship. A related person's profile, notes, and contacts may be edited only when the user can collaborate with every active, unmerged company linked through CONTACT_FOR; a standalone person requires global company.write. Delegation does not allow company fields, visibility, identifiers, requirements, ownership, merge, task creation, task-company relinking, or email-thread relinking.

Delegated task mutation exception: assignment to any active Jira task permits the existing operations for that exact task type, including Supplier Onboarding edit/reply, Email Reply edit/status/reassignment/send/forward, and Reply Pilot resolve/reassignment. Reply Pilot close remains requester-only. Jira keys and work types are loaded and validated server-side; legacy client jira_key fields are ignored. Changing an Email Reply task's company still requires normal write access to the source and destination companies. Reassignment or a transition to normalized Done immediately removes assignment-derived access. No separate permission code is introduced by these exceptions.

Seeded System Roles

Role Permissions Notes
admin company.view_assigned, company.view_all, company.write, company.write_assigned, company.merge, security.manage_roles Full normal administration. security.impersonate_user is intentionally not included.
sales company.view_assigned, company.write_assigned Can create self-assigned companies and view/mutate assigned companies and their linked tasks. Cannot view unassigned/all companies.
sales_manager company.view_assigned, company.view_all, company.write, company.write_assigned, company.merge Can view and mutate all companies and merge companies.
support_impersonator security.impersonate_user Dedicated support role for impersonation.

Maintenance Rules

  • When adding, renaming, deleting, or changing the meaning of a permission, update this page in the same change.
  • When changing seeded role grants, update the role table above in the same change.
  • When changing authorization behavior without changing the database grant, update the scope and important behavior column.
  • Keep permission labels and descriptions aligned with Liquibase seed data.