From be119ab2c8b69d892b577a44b9b8216b3604deaf Mon Sep 17 00:00:00 2001 From: Mariano Fuentes Date: Thu, 5 Mar 2026 16:28:09 -0500 Subject: [PATCH 01/34] Feat/rbac v1 (#2092) * feat(rbac): extend better-auth permissions with GRC resources - Update permissions.ts to extend defaultStatements from better-auth - Add GRC resources: control, evidence, policy, risk, vendor, task, framework, audit, finding, questionnaire, integration - Add program_manager role with full GRC access but no member management - Update owner/admin roles to extend ownerAc/adminAc from better-auth - Update auditor role with read + export permissions - Keep employee/contractor roles minimal with assignment-based access - Add ROLE_HIERARCHY, RESTRICTED_ROLES, PRIVILEGED_ROLES exports - Add placeholder for dynamicAccessControl in auth.ts (Sprint 2) Part of ENG-138: Complete Permission System Co-Authored-By: Claude Opus 4.5 * feat(rbac): add PermissionGuard and @RequirePermission decorator - Create PermissionGuard that calls better-auth's hasPermission API - Add fallback role-based check when better-auth is unavailable - Create @RequirePermission decorator for route-level permission checks - Create @RequirePermissions decorator for multi-resource permissions - Export GRCResource and GRCAction types for type safety - Add program_manager to Role enum in database schema - Update AuthModule to export PermissionGuard The guard: - Validates permissions via better-auth's hasPermission endpoint - Falls back to role-based check if API unavailable - Logs warnings for API key bypass (TODO: add API key scopes) - Provides static isRestrictedRole() helper for assignment filtering Part of ENG-138: Complete Permission System Co-Authored-By: Claude Opus 4.5 * feat(rbac): sync portal permissions with app permissions - Update portal permissions.ts to match app version - Fix security issue where employee/contractor had excessive permissions - Add program_manager role to portal - Extend defaultStatements from better-auth - Add RESTRICTED_ROLES and PRIVILEGED_ROLES exports BREAKING CHANGE: Employee and contractor roles in portal now have restricted permissions matching the app. Previously they had member management and organization update permissions. Part of ENG-138: Complete Permission System Co-Authored-By: Claude Opus 4.5 * test(rbac): add PermissionGuard unit tests Add comprehensive tests for PermissionGuard covering: - Permission bypass when no permissions required - API key bypass behavior - Role-based access for privileged vs restricted roles - Fallback behavior when better-auth API unavailable - isRestrictedRole static method for all role types Co-Authored-By: Claude Opus 4.5 * feat(rbac): migrate controllers from RequireRoles to RequirePermission Migrate all API controllers to use the new better-auth permission system: - findings.controller.ts: finding create/update/delete permissions - task-management.controller.ts: task CRUD + assign permissions - people.controller.ts: member delete permission for removeHost - evidence-export.controller.ts: evidence export permission Also fix TypeScript errors in permission.guard.spec.ts for fetch mocking. Co-Authored-By: Claude Opus 4.5 * feat(rbac): add assignment-based filtering for employee/contractor roles Implement assignment filtering to restrict employees/contractors to only see resources they are assigned to: - Add memberId to AuthContext for assignment checking - Create assignment-filter utility with filter builders and access checkers - Update tasks controller/service with assignment filtering on GET endpoints - Update risks controller/service with assignment filtering on GET endpoints - Add PermissionGuard and @RequirePermission to tasks and risks endpoints Employees/contractors now only see: - Tasks where they are the assignee - Risks where they are the assignee Privileged roles (owner, admin, program_manager, auditor) see all resources. Co-Authored-By: Claude Opus 4.5 * feat(rbac): add department-based policy visibility Allow admins to control which departments can see specific policies: Schema changes: - Add PolicyVisibility enum (ALL, DEPARTMENT) - Add visibility and visibleToDepartments fields to Policy model API changes: - Add memberDepartment to AuthContext for visibility filtering - Create department-visibility utility with filter builders - Update policies controller to filter by visibility for restricted roles - Update policies service to accept visibility filter Policies can now be: - Visible to ALL (default) - everyone in the organization sees them - Visible to specific DEPARTMENTS only - only members in those departments see them Privileged roles (owner, admin, program_manager, auditor) see all policies regardless of visibility settings. Co-Authored-By: Claude Opus 4.5 * feat(auth): centralize auth on API with security hardening - Move auth server to API, app now uses proxy to forward auth requests - Remove localStorage token storage (XSS prevention) - Add rate limiting to auth proxy (60/min general, 10/min sensitive) - Add redirect URL validation to prevent open redirects - Add AUTH_SECRET validation at startup - Make all debug logging conditional on NODE_ENV - Simplify root page routing (no activeOrganizationId dependency) - Use URL-based RBAC with direct DB member lookup Co-Authored-By: Claude Opus 4.5 * feat(rbac): add shared auth package and API integration - Add @comp/auth package with centralized permissions and role definitions - Update API auth module to integrate with better-auth server - Add 403 responses to policy and risk endpoints for Swagger - Add assignment filter and department visibility utilities with tests - Sync permissions across app and portal - Update tsconfig and nest-cli for proper module resolution Co-Authored-By: Claude Opus 4.5 * feat(rbac): enable dynamic access control for custom roles - Add dynamicAccessControl config to organization plugin - Add OrganizationRole table for storing custom roles - Configure maximum 20 roles per organization - Add schema mapping for better-auth role table Resolves: ENG-145 Co-Authored-By: Claude Opus 4.5 * feat(rbac): add Custom Roles API for dynamic role management - Add roles module with CRUD endpoints for custom roles - Implement privilege escalation prevention - Add permission validation against valid resources/actions - Protect built-in roles (owner, admin, auditor, employee, contractor) - Add OrganizationRole table migration - Limit to 20 custom roles per organization - Require ac:create/read/update/delete permissions for role management Implements: ENG-146 Co-Authored-By: Claude Opus 4.5 * feat(rbac): support multiple roles for privilege escalation checks - Update roles service to accept array of roles instead of single role - Add getCombinedPermissions to merge permissions from all user roles - Update controller to pass full userRoles array - Users with multiple roles now get combined permissions for validation Co-Authored-By: Claude Opus 4.5 * fix(auth): prevent JWKS key regeneration causing session loss Add explicit jwks configuration with rotationInterval to prevent better-auth from creating new JWKS keys on each request. Without this, all existing JWTs become invalid when the API restarts because new signing keys are generated. - Set rotationInterval to 30 days for monthly key rotation - Set gracePeriod to 7 days so old keys remain valid after rotation Fixes: Session persistence across API restarts References: - https://github.com/better-auth/better-auth/issues/6215 Co-Authored-By: Claude Opus 4.5 * test(rbac): add unit tests for Custom Roles API - Add 18 tests for RolesService covering CRUD operations - Add 9 tests for RolesController - Test permission validation and privilege escalation prevention - Test multiple roles support for privilege checking - Test edge cases (duplicate names, max roles limit, reserved names) Co-Authored-By: Claude Opus 4.5 * docs: add testing guidelines for API development - Update .cursorrules with testing requirements and conventions - Add apps/api/CLAUDE.md with API-specific development guidelines - Document when to write tests, how to run them, and test patterns - Include RBAC system documentation Co-Authored-By: Claude Opus 4.5 * refactor(docs): move API testing rules to apps/api - Remove API-specific testing rules from root .cursorrules - Create apps/api/.cursorrules with API testing requirements - Keep root .cursorrules focused on commit message conventions Co-Authored-By: Claude Opus 4.5 * test(rbac): add privilege escalation test for role updates Ensures that users cannot escalate privileges when updating role permissions, not just when creating roles. Co-Authored-By: Claude Opus 4.5 * feat(rbac): implement Custom Roles UI (ENG-148) - Add roles settings pages (list, create, edit) with permission matrix - Add "Select all" feature to quickly set all permissions - Integrate custom roles into member management UI: - Role filter dropdown shows all roles dynamically - Invite modal supports custom role selection - Edit member role supports custom roles - Allow normal spelling for role names (spaces, capitalization) - Add loading skeletons with proper PageLayout wrappers - Add comprehensive tests for RolesTable, RoleForm, PermissionMatrix Co-Authored-By: Claude Opus 4.5 * chore(docs): add API endpoints for managing custom roles * chore(auth): implement cleanup of stale JWKS records on secret change * chore(permissions): implement user permissions resolution and route protection - Add functions to resolve user permissions based on roles and organization - Implement route permission checks to guard access to various app sections - Introduce new layout components for route protection across multiple pages - Update existing components to utilize the new permissions system for access control * chore(api): migrate to session-based authentication and add controls management * refactor(auth): update permission checks to include cookie header * refactor(api): update permission guard logging to include request details * refactor(api): remove unnecessary logging from getPolicy function * chore(api): handle optional chaining for user ID in various actions * refactor(app): update policy editor to check version read-only state * refactor(api): enhance version content handling and validation in policies * refactor(app): update PolicyArchiveSheet to use new design system components * feat(audit): implement audit logging interceptor and related functionality * refactor(audit): add audit log constants, resolvers, and utilities * refactor(auth): add isPlatformAdmin support in authentication and guards * chore(api): add unit tests for PeopleController and PeopleService * chore(tests): add unit tests for layout and questionnaire data queries * chore(api): implement pagination and filtering for risks retrieval * chore(api): add onboarding endpoint to retrieve organization onboarding data * refactor(vendors): migrate vendor data fetching to server API and remove obsolete queries * refactor(api): update controllers and services to use new API structure and enhance data fetching * refactor(soa): remove console logs for component initialization and debugging * refactor(auth): implement service token authentication and update guards * refactor(trust): replace server action with API call for brand settings * chore(openapi): add new endpoints for trust portal settings management * chore(trust): add endpoints for managing trust portal settings and favicon * feat(auth): add API key validation with scopes and new auth controller * refactor(auth): update resource mapping from "portal" to "trust" in permissions * feat(tasks): add bulk submit for review functionality and task approval methods * feat(audit): add comprehensive audit commands for design system, hooks, RBAC, unit tests, and production readiness * feat(auth): add apiKey resource and permissions to roles and decorators * refactor: standardize roles in packages/auth package * refactor(auth): add createdAt field to user response and update environment variables * refactor(env): add internal API token to environment configuration * fix(CompanyFormPageClient): remove orgId parameter from API call * refactor: add AWS credentials validation and integration test actions * refactor(cloud-tests): update authentication method to use session cookie * chore: add unit tests * chore(trust): enhance permission gating tests and mock localStorage * chore(db): add multiple migrations for policy visibility and role management * chore: fix stuff * feat: add audit log controller and integrate with existing modules * feat: add audit log controller and integrate with existing modules * chore: remove CODE_OF_CONDUCT and commitlint configuration files * feat(api): implement pentest billing module with Stripe integration - Add PentestBillingController and PentestBillingService for managing subscriptions and billing. - Implement endpoints for subscription status, creating checkout sessions, handling success callbacks, and managing billing portals. - Integrate role-based access control for billing actions using @RequirePermission. - Introduce tools for AI chat to fetch organization and policy data based on user permissions. - Update app.module.ts to include StripeModule and RolesModule for billing functionalities. - Ensure all new features are covered by tests and adhere to project guidelines. * feat(api): implement triggerEmail function for email notifications - Introduce triggerEmail function to replace sendEmail for sending email notifications. - Update various notifier services to utilize triggerEmail for sending emails. - Add new send-email task to handle email sending via the trigger.dev SDK. - Update package.json and bun.lock to include @react-email/render dependency. - Ensure all changes are covered by tests and adhere to project guidelines. * feat(db): add migrations for policy visibility, organization roles, role notifications, JWKS expiration, and API key scopes - Create new enum type "PolicyVisibility" and update "Policy" table to include visibility and visibleToDepartments fields. - Introduce "organization_role" table for dynamic roles with associated permissions and foreign key constraints. - Add "role_notification_setting" table to manage notification settings per role within organizations. - Extend "jwks" table to include "expiresAt" timestamp for better key management. - Change "permissions" column in "organization_role" from jsonb to text for compatibility with better-auth. * chore: update .gitignore and remove outdated audit findings document - Update .gitignore to reflect the new path for audit findings. - Remove the outdated audit findings document from the repository. * chore(deps): update ai-sdk packages and remove unused DraggableCards component - Upgrade @ai-sdk dependencies to version 3.0.0 for @ai-sdk/anthropic, @ai-sdk/groq, @ai-sdk/openai, @ai-sdk/provider, and @ai-sdk/react. - Update @ai-sdk/rsc to version 2.0.0 and @ai-sdk/provider-utils to version 4.0.19. - Remove the unused DraggableCards component from the project. - Adjust types in InviteMembersModal and other components for better type safety. * fix(api): add error handling to streaming pump in assistant chat controller Wrap the ReadableStream pump loop in try/catch/finally to handle stream read errors gracefully (e.g., client disconnects) and ensure res.end() is always called. Co-Authored-By: Claude Opus 4.6 * fix(api): validate organization exists in service token auth Service token auth now verifies the x-organization-id header references a real organization in the database, preventing operations against non-existent or arbitrary organization IDs. Co-Authored-By: Claude Opus 4.6 * fix(api): audit preflight failure no longer blocks requests + filter expired API keys 1. Wrap audit preflight in .catch() so a failure in pre-flight data collection (e.g., bad controlIds) never blocks the actual API request. The request proceeds with empty audit context instead. 2. Filter expired API keys at the DB level to reduce payload size during validation. The full-table scan design (per-key salts) is a known limitation that requires a schema migration to fully resolve. Co-Authored-By: Claude Opus 4.6 * fix(api): add keyPrefix for indexed API key lookup Store first 8 chars of the plaintext key as `keyPrefix` for O(1) indexed lookup instead of loading all active keys into memory. Backwards compatible: legacy keys without a prefix fall back to scanning only keys where keyPrefix IS NULL, and the prefix is backfilled on first successful validation so future lookups are fast. Co-Authored-By: Claude Opus 4.6 * fix(api): handle errors in @Res() streaming endpoint + set isServiceToken explicitly 1. Wrap completions endpoint in try/catch since @Res() bypasses NestJS exception filters. Errors now return proper JSON responses instead of hanging. 2. Explicitly set isServiceToken=false in API key and session auth handlers to prevent accidental fallthrough in PermissionGuard. Co-Authored-By: Claude Opus 4.6 * fix(api): validate domain format in trust portal to prevent path injection Add domain format validation in addCustomDomain and checkDnsRecords to ensure user-provided domain values can't inject path segments into Vercel API or DNS lookup URLs. Co-Authored-By: Claude Opus 4.6 * fix(api): merge duplicate permissions, skip chat audit, add maxSteps, fix control mapping descriptions 1. PermissionGuard: merge actions for duplicate resources instead of overwriting, preventing silently dropped permission checks. 2. Assistant chat completions: add @SkipAuditLog() to prevent noisy "Created app" audit entries on every chat message. 3. Assistant chat: add maxSteps=5 to streamText so the model can synthesize tool results into natural language responses. 4. Audit log resolvers: extract resource name from URL path instead of hardcoding "policy". fetchControlIds now dynamically resolves the correct Prisma model. Co-Authored-By: Claude Opus 4.6 * feat: rBAC support and major security improvements Role-Based Access Control (RBAC) system with custom roles, permission guards, and audit logging across the platform. Key changes: - Hybrid auth guard for session, API key, service token - Permission guard with better-auth and custom roles - Granular resource:action permissions - Audit log interceptor with mutation tracking - API key prefix indexing for O(1) lookups - Service token org existence validation - Domain validation to prevent SSRF - Streaming endpoint error handling - AI assistant chat with permission-gated tools BREAKING CHANGE: all API endpoints now require RBAC permissions via @RequirePermission decorators. Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.5 --- .claude/commands/audit-design-system.md | 61 + .claude/commands/audit-hooks.md | 37 + .claude/commands/audit-rbac.md | 50 + .claude/commands/audit-tests.md | 63 + .claude/commands/production-readiness.md | 43 + .cursorrules | 58 +- .gitignore | 6 +- CLAUDE.md | 150 + CODE_OF_CONDUCT.md | 128 - apps/api/.cursorrules | 45 + apps/api/.env.example | 5 +- apps/api/.gitignore | 9 +- apps/api/CLAUDE.md | 159 + apps/api/nest-cli.json | 1 + apps/api/package.json | 17 +- apps/api/src/app.module.ts | 12 + .../assistant-chat/assistant-chat-tools.ts | 112 + .../assistant-chat.controller.ts | 135 +- .../assistant-chat/assistant-chat.module.ts | 3 +- .../src/attachments/attachments.controller.ts | 12 +- .../src/attachments/attachments.service.ts | 44 + apps/api/src/audit/audit-log.constants.ts | 70 + apps/api/src/audit/audit-log.controller.ts | 77 + .../src/audit/audit-log.interceptor.spec.ts | 1382 ++ apps/api/src/audit/audit-log.interceptor.ts | 289 + apps/api/src/audit/audit-log.resolvers.ts | 161 + apps/api/src/audit/audit-log.utils.ts | 365 + apps/api/src/audit/audit.module.ts | 17 + .../api/src/audit/skip-audit-log.decorator.ts | 20 + apps/api/src/auth/api-key.guard.ts | 9 +- apps/api/src/auth/api-key.service.ts | 208 +- apps/api/src/auth/auth-context.decorator.ts | 32 +- apps/api/src/auth/auth.controller.ts | 119 + apps/api/src/auth/auth.module.ts | 29 +- apps/api/src/auth/auth.server.ts | 327 + apps/api/src/auth/hybrid-auth.guard.ts | 318 +- apps/api/src/auth/internal-token.guard.ts | 44 - apps/api/src/auth/permission.guard.spec.ts | 180 + apps/api/src/auth/permission.guard.ts | 205 + apps/api/src/auth/platform-admin.guard.ts | 137 +- apps/api/src/auth/public.decorator.ts | 4 + .../src/auth/require-permission.decorator.ts | 77 + apps/api/src/auth/service-token.config.ts | 81 + apps/api/src/auth/skip-org-check.decorator.ts | 4 + apps/api/src/auth/types.ts | 24 +- .../src/browserbase/browserbase.controller.ts | 26 +- .../src/browserbase/browserbase.service.ts | 5 +- .../cloud-security-legacy.service.ts | 234 + .../cloud-security-query.service.ts | 326 + .../cloud-security.controller.ts | 41 +- .../cloud-security/cloud-security.module.ts | 4 + .../comment-mention-notifier.service.ts | 6 +- apps/api/src/comments/comments.controller.ts | 15 +- apps/api/src/config/better-auth.config.ts | 17 +- apps/api/src/context/context.controller.ts | 33 +- apps/api/src/context/context.service.ts | 71 +- .../src/context/schemas/context-operations.ts | 10 +- apps/api/src/controls/controls.controller.ts | 87 + apps/api/src/controls/controls.module.ts | 12 + apps/api/src/controls/controls.service.ts | 216 + .../src/controls/dto/create-control.dto.ts | 63 + .../device-agent/device-agent.controller.ts | 12 +- .../schemas/device-agent-operations.ts | 4 +- apps/api/src/devices/devices.controller.ts | 16 +- apps/api/src/email/trigger-email.ts | 47 + .../evidence-forms.controller.ts | 17 +- .../evidence-forms.service.spec.ts | 4 +- .../findings/finding-notifier.service.spec.ts | 10 +- .../src/findings/finding-notifier.service.ts | 50 +- .../src/findings/findings.controller.spec.ts | 4 +- apps/api/src/findings/findings.controller.ts | 27 +- .../task-template/task-template.controller.ts | 15 +- .../src/frameworks/dto/add-frameworks.dto.ts | 14 + .../frameworks/frameworks-scores.helper.ts | 215 + .../frameworks/frameworks-upsert.helper.ts | 340 + .../frameworks/frameworks.controller.spec.ts | 83 + .../src/frameworks/frameworks.controller.ts | 109 + apps/api/src/frameworks/frameworks.module.ts | 12 + .../src/frameworks/frameworks.service.spec.ts | 92 + apps/api/src/frameworks/frameworks.service.ts | 263 + .../controllers/checks.controller.ts | 12 + .../controllers/connections.controller.ts | 72 +- .../controllers/oauth-apps.controller.ts | 40 +- .../controllers/oauth.controller.ts | 22 +- .../controllers/sync.controller.ts | 116 +- .../task-integrations.controller.ts | 44 +- .../controllers/variables.controller.ts | 13 +- .../integration-platform.module.ts | 2 + .../dto/save-manual-answer.dto.ts | 18 + .../knowledge-base.controller.spec.ts | 212 + .../knowledge-base.controller.ts | 184 +- .../knowledge-base/knowledge-base.module.ts | 2 + .../knowledge-base.service.spec.ts | 398 + .../knowledge-base/knowledge-base.service.ts | 66 + apps/api/src/main.ts | 6 +- .../notifications/check-unsubscribe.spec.ts | 427 + .../dto/update-organization.dto.ts | 1 + .../organization/organization.controller.ts | 179 +- .../src/organization/organization.service.ts | 328 + .../schemas/organization-operations.ts | 10 +- apps/api/src/people/dto/create-people.dto.ts | 5 +- .../src/people/dto/people-responses.dto.ts | 6 + .../dto/update-email-preferences.dto.ts | 37 + apps/api/src/people/dto/update-people.dto.ts | 35 +- apps/api/src/people/people-fleet.helper.ts | 174 + apps/api/src/people/people.controller.spec.ts | 305 + apps/api/src/people/people.controller.ts | 170 +- apps/api/src/people/people.service.spec.ts | 581 + apps/api/src/people/people.service.ts | 102 +- .../src/people/schemas/people-operations.ts | 16 +- apps/api/src/people/utils/member-queries.ts | 65 +- .../api/src/policies/dto/update-policy.dto.ts | 17 +- .../src/policies/dto/upload-policy-pdf.dto.ts | 19 + apps/api/src/policies/dto/version.dto.ts | 1 + apps/api/src/policies/policies.controller.ts | 508 +- apps/api/src/policies/policies.service.ts | 202 +- .../schemas/get-policy-by-id.responses.ts | 17 + .../src/policies/schemas/policy-operations.ts | 10 +- .../questionnaire.controller.spec.ts | 274 + .../questionnaire/questionnaire.controller.ts | 91 + .../src/questionnaire/questionnaire.module.ts | 3 +- .../questionnaire.service.spec.ts | 579 + .../questionnaire/questionnaire.service.ts | 64 + apps/api/src/risks/dto/get-risks-query.dto.ts | 113 + apps/api/src/risks/risks.controller.ts | 97 +- apps/api/src/risks/risks.service.ts | 126 +- .../risks/schemas/get-risk-by-id.responses.ts | 17 + apps/api/src/risks/schemas/risk-operations.ts | 10 +- apps/api/src/roles/dto/create-role.dto.ts | 31 + apps/api/src/roles/dto/update-role.dto.ts | 33 + apps/api/src/roles/roles.controller.spec.ts | 222 + apps/api/src/roles/roles.controller.ts | 263 + apps/api/src/roles/roles.module.ts | 12 + apps/api/src/roles/roles.service.spec.ts | 462 + apps/api/src/roles/roles.service.ts | 423 + apps/api/src/secrets/encryption.util.ts | 58 + apps/api/src/secrets/secrets.controller.ts | 166 + apps/api/src/secrets/secrets.module.ts | 11 + apps/api/src/secrets/secrets.service.ts | 155 + .../pentest-billing.controller.ts | 106 + .../pentest-billing.service.ts | 314 + .../security-penetration-tests.controller.ts | 19 +- .../security-penetration-tests.module.ts | 6 +- apps/api/src/soa/soa.controller.ts | 19 +- apps/api/src/stripe/stripe.module.ts | 9 + apps/api/src/stripe/stripe.service.ts | 31 + .../task-item-assignment-notifier.service.ts | 14 +- .../task-item-mention-notifier.service.ts | 6 +- .../task-management.controller.ts | 15 +- .../task-management.service.ts | 102 - .../automations/automations.controller.ts | 51 +- .../tasks/automations/automations.service.ts | 40 + .../automations/dto/update-automation.dto.ts | 18 +- .../evidence-export.controller.ts | 29 +- .../internal-task-notification.controller.ts | 210 - apps/api/src/tasks/task-notifier.service.ts | 111 +- apps/api/src/tasks/tasks.controller.ts | 311 +- apps/api/src/tasks/tasks.module.ts | 3 +- apps/api/src/tasks/tasks.service.ts | 299 +- .../dto/send-training-completion.dto.ts | 9 +- .../src/training/training-email.service.ts | 4 +- apps/api/src/training/training.controller.ts | 50 +- apps/api/src/training/training.module.ts | 2 + .../run-browser-automation.ts | 4 +- .../cloud-security/run-cloud-security-scan.ts | 1 + apps/api/src/trigger/email/send-email.ts | 73 + .../run-connection-checks.ts | 8 +- .../run-task-integration-checks.ts | 8 +- .../sync-employees-schedule.ts | 12 +- .../trigger/policies/update-policy-helpers.ts | 299 + .../trigger/policies/update-policy-prompts.ts | 83 + .../api/src/trigger/policies/update-policy.ts | 58 + apps/api/src/trust-portal/email.service.ts | 10 +- .../trust-portal/trust-access.controller.ts | 75 +- .../src/trust-portal/trust-access.service.ts | 6 +- .../trust-portal/trust-portal.controller.ts | 174 +- .../src/trust-portal/trust-portal.service.ts | 840 + apps/api/src/utils/assignment-filter.spec.ts | 254 + apps/api/src/utils/assignment-filter.ts | 175 + apps/api/src/utils/compliance-filters.ts | 114 + .../src/utils/department-visibility.spec.ts | 252 + apps/api/src/utils/department-visibility.ts | 89 + .../dto/trigger-vendor-risk-assessment.dto.ts | 10 +- .../internal-vendor-automation.controller.ts | 53 +- .../src/vendors/schemas/vendor-operations.ts | 10 +- apps/api/src/vendors/vendors.controller.ts | 49 +- apps/api/src/vendors/vendors.service.ts | 52 + apps/api/tsconfig.json | 4 +- apps/app/.env.example | 5 +- apps/app/components.json | 24 + apps/app/package.json | 39 +- apps/app/src/actions/add-comment.ts | 75 - apps/app/src/actions/change-organization.ts | 77 - .../create-context-entry-action.ts | 38 - .../delete-context-entry-action.ts | 27 - .../update-context-entry-action.ts | 38 - .../actions/controls/create-control-action.ts | 102 - apps/app/src/actions/files/upload-file.ts | 16 - apps/app/src/actions/floating.ts | 24 - .../delete-integration-connection.ts | 55 - .../retrieve-integration-session-token.ts | 25 - .../update-integration-settings-action.ts | 93 - .../add-frameworks-to-organization-action.ts | 59 - .../organization/create-api-key-action.ts | 114 - .../delete-organization-action.ts | 53 - .../actions/organization/invite-employee.ts | 2 +- .../src/actions/organization/invite-member.ts | 2 +- .../actions/organization/remove-employee.ts | 2 +- .../organization/revoke-api-key-action.ts | 55 - ...pdate-organization-advanced-mode-action.ts | 48 - .../update-organization-logo-action.ts | 112 - .../update-organization-name-action.ts | 49 - .../update-organization-website-action.ts | 49 - .../accept-requested-policy-changes.ts | 18 +- .../src/actions/policies/archive-policy.ts | 76 - .../src/actions/policies/create-new-policy.ts | 119 - .../src/actions/policies/create-version.ts | 170 - .../app/src/actions/policies/delete-policy.ts | 102 - .../src/actions/policies/delete-version.ts | 104 - .../policies/deny-requested-policy-changes.ts | 107 - .../actions/policies/discard-draft-changes.ts | 82 - .../actions/policies/get-policy-versions.ts | 61 - .../migrate-policies-to-versioning.ts | 186 - apps/app/src/actions/policies/publish-all.ts | 213 - .../src/actions/policies/publish-version.ts | 131 - .../policies/restore-version-to-draft.ts | 92 - .../actions/policies/set-active-version.ts | 82 - .../submit-policy-for-approval-action.ts | 60 - .../policies/submit-version-for-approval.ts | 96 - apps/app/src/actions/policies/update-draft.ts | 131 - .../actions/policies/update-policy-action.ts | 121 - .../policies/update-policy-form-action.ts | 101 - .../policies/update-policy-overview-action.ts | 71 - .../src/actions/risk/create-risk-action.ts | 53 - .../actions/risk/task/update-task-action.ts | 63 - .../risk/update-inherent-risk-action.ts | 51 - .../risk/update-residual-risk-action.ts | 67 - .../risk/update-residual-risk-enum-action.ts | 51 - .../src/actions/risk/update-risk-action.ts | 58 - apps/app/src/actions/safe-action.ts | 16 +- apps/app/src/actions/tasks.ts | 26 - .../src/actions/tasks/create-task-action.ts | 95 - .../actions/tasks/regenerate-task-action.ts | 66 - .../(overview)/components/AuditorView.tsx | 1 - .../(app)/[orgId]/auditor/(overview)/page.tsx | 159 +- .../src/app/(app)/[orgId]/auditor/layout.tsx | 13 + .../actions/create-trigger-token.ts | 44 - .../cloud-tests/actions/disconnect-cloud.ts | 80 - .../cloud-tests/actions/run-platform-scan.ts | 11 +- .../actions/update-cloud-credentials.ts | 80 - .../components/ChatPlaceholder.tsx | 50 +- .../components/CloudConnectionCard.tsx | 180 - .../components/CloudSettingsModal.test.tsx | 207 + .../components/CloudSettingsModal.tsx | 63 +- .../components/EmptyState.test.tsx | 224 + .../cloud-tests/components/EmptyState.tsx | 84 +- .../cloud-tests/components/FindingsTable.tsx | 196 +- .../cloud-tests/components/ProviderTabs.tsx | 34 +- .../cloud-tests/components/ResultsView.tsx | 84 +- .../components/TestsLayout.test.tsx | 232 + .../cloud-tests/components/TestsLayout.tsx | 107 +- .../app/(app)/[orgId]/cloud-tests/layout.tsx | 13 + .../app/(app)/[orgId]/cloud-tests/page.tsx | 362 +- .../[orgId]/components/AppShellWrapper.tsx | 28 +- .../(app)/[orgId]/components/AppSidebar.tsx | 54 +- .../components/app-shell-search-groups.tsx | 193 +- .../[controlId]/actions/delete-control.ts | 69 - .../components/ControlDeleteDialog.test.tsx | 170 + .../components/ControlDeleteDialog.tsx | 27 +- .../components/ControlHeaderActions.test.tsx | 135 + .../components/ControlHeaderActions.tsx | 6 + .../controls/[controlId]/data/getControl.ts | 43 - .../data/getOrganizationControlProgress.ts | 105 - .../[controlId]/data/getRelatedPolicies.ts | 45 - .../[orgId]/controls/[controlId]/page.tsx | 68 +- .../components/CreateControlSheet.tsx | 38 +- .../components/controls-table.test.tsx | 170 + .../controls/components/controls-table.tsx | 6 +- .../(app)/[orgId]/controls/data/queries.ts | 61 +- .../[orgId]/controls/hooks/useControls.ts | 85 + .../src/app/(app)/[orgId]/controls/layout.tsx | 13 + .../src/app/(app)/[orgId]/controls/page.tsx | 157 +- .../[orgId]/documents/[formType]/page.tsx | 17 - .../submissions/[submissionId]/page.tsx | 16 - .../components/CompanyFormPageClient.test.tsx | 256 + .../components/CompanyFormPageClient.tsx | 27 +- .../components/CompanyOverviewCards.tsx | 4 +- ...CompanySubmissionDetailPageClient.test.tsx | 347 + .../CompanySubmissionDetailPageClient.tsx | 17 +- .../components/CompanySubmissionWizard.tsx | 2 - .../DocumentFindingsSection.test.tsx | 387 + .../components/DocumentFindingsSection.tsx | 89 +- .../app/(app)/[orgId]/documents/layout.tsx | 13 + .../actions/delete-framework.ts | 68 - .../components/FrameworkDeleteDialog.test.tsx | 173 + .../components/FrameworkDeleteDialog.tsx | 28 +- .../components/FrameworkOverview.test.tsx | 75 + .../components/FrameworkOverview.tsx | 42 +- .../frameworks/[frameworkInstanceId]/page.tsx | 68 +- .../requirements/[requirementKey]/page.tsx | 106 +- .../components/AddFrameworkModal.test.tsx | 200 + .../components/AddFrameworkModal.tsx | 182 +- .../components/FrameworksOverview.test.tsx | 69 + .../components/FrameworksOverview.tsx | 20 +- .../components/ToDoOverview.test.tsx | 238 + .../frameworks/components/ToDoOverview.tsx | 93 +- .../getSingleFrameworkInstanceWithControls.ts | 70 - .../[orgId]/frameworks/hooks/useFrameworks.ts | 83 + .../app/(app)/[orgId]/frameworks/layout.tsx | 13 +- .../[orgId]/frameworks/lib/getFrameworks.ts | 11 - .../(app)/[orgId]/frameworks/lib/getPeople.ts | 10 +- .../src/app/(app)/[orgId]/frameworks/page.tsx | 247 +- .../components/PlatformIntegrations.test.tsx | 205 + .../components/PlatformIntegrations.tsx | 117 +- .../app/(app)/[orgId]/integrations/layout.tsx | 13 + .../app/(app)/[orgId]/integrations/page.tsx | 47 +- .../app/(app)/[orgId]/knowledge-base/page.tsx | 48 +- .../app/src/app/(app)/[orgId]/layout.test.tsx | 143 + apps/app/src/app/(app)/[orgId]/layout.tsx | 50 +- apps/app/src/app/(app)/[orgId]/page.tsx | 46 +- .../[employeeId]/actions/update-employee.ts | 2 +- .../components/EmployeeDetails.tsx | 48 +- .../people/[employeeId]/hooks/useEmployee.ts | 72 + .../all/actions/addEmployeeWithoutInvite.ts | 3 +- .../people/all/actions/reactivateMember.ts | 2 +- .../people/all/actions/removeMember.ts | 6 +- .../people/all/actions/revokeInvitation.ts | 4 +- .../people/all/actions/updateMemberRole.ts | 165 - .../components/InviteMembersModal.test.tsx | 107 + .../all/components/InviteMembersModal.tsx | 57 +- .../people/all/components/MemberRow.tsx | 41 +- .../all/components/MultiRoleCombobox.tsx | 54 +- .../components/MultiRoleComboboxContent.tsx | 150 +- .../components/MultiRoleComboboxTrigger.tsx | 24 +- .../people/all/components/TeamMembers.tsx | 8 +- .../all/components/TeamMembersClient.tsx | 41 +- .../all/components/csv-invite-parser.ts | 100 + .../all/components/invite-form-schema.ts | 34 + .../people/all/hooks/useTeamMembers.ts | 127 + .../people/components/PeoplePageTabs.tsx | 2 +- .../components/EmployeesOverview.tsx | 6 +- .../components/DeviceDropdownMenu.test.tsx | 182 + .../devices/components/DeviceDropdownMenu.tsx | 17 +- .../devices/components/PolicyImagePreview.tsx | 2 +- .../people/devices/hooks/useDevices.ts | 52 + .../src/app/(app)/[orgId]/people/layout.tsx | 12 +- .../app/src/app/(app)/[orgId]/people/page.tsx | 8 +- .../(overview)/hooks/usePoliciesOverview.ts | 2 +- .../[orgId]/policies/(overview)/page.tsx | 37 +- .../[policyId]/actions/mapPolicyToControls.ts | 70 - .../[policyId]/actions/regenerate-policy.ts | 89 - .../actions/switch-policy-display-format.ts | 49 - .../actions/unmapPolicyFromControl.ts | 63 - .../[policyId]/components/PdfViewer.tsx | 115 +- .../components/PolicyAlerts.test.tsx | 177 + .../[policyId]/components/PolicyAlerts.tsx | 103 +- .../components/PolicyArchiveSheet.test.tsx | 136 + .../components/PolicyArchiveSheet.tsx | 152 +- ...PolicyControlMappingConfirmDeleteModal.tsx | 66 - .../components/PolicyControlMappingModal.tsx | 107 - .../components/PolicyControlMappings.test.tsx | 139 + .../components/PolicyControlMappings.tsx | 77 +- .../components/PolicyDeleteDialog.test.tsx | 173 + .../components/PolicyDeleteDialog.tsx | 43 +- .../components/PolicyHeaderActions.test.tsx | 190 + .../components/PolicyHeaderActions.tsx | 185 +- .../components/PolicyPageTabs.test.tsx | 242 + .../[policyId]/components/PolicyPageTabs.tsx | 70 +- .../components/PolicyStatusBadge.tsx | 12 +- .../components/PolicyVersionsTab.test.tsx | 295 + .../components/PolicyVersionsTab.tsx | 164 +- .../components/PublishVersionDialog.test.tsx | 169 + .../components/PublishVersionDialog.tsx | 39 +- .../[policyId]/components/RecentAuditLogs.tsx | 238 +- .../components/UpdatePolicyOverview.test.tsx | 189 + .../components/UpdatePolicyOverview.tsx | 87 +- .../[orgId]/policies/[policyId]/data/index.ts | 366 +- .../editor/components/PolicyDetails.test.tsx | 281 + .../editor/components/PolicyDetails.tsx | 175 +- .../components/ai/policy-ai-assistant.tsx | 2 +- .../policies/[policyId]/hooks/useAuditLogs.ts | 2 + .../policies/[policyId]/hooks/usePolicy.ts | 144 +- .../[policyId]/hooks/usePolicyVersions.ts | 166 + .../[orgId]/policies/[policyId]/page.tsx | 86 +- .../FullPolicyHeaderActions.test.tsx | 80 + .../components/FullPolicyHeaderActions.tsx | 34 +- .../all/components/PoliciesTableDS.tsx | 4 + .../policies/all/components/PolicyFilters.tsx | 22 +- .../all/components/PolicyPageActions.test.tsx | 125 + .../all/components/PolicyPageActions.tsx | 30 +- .../all/components/policies-table-columns.tsx | 4 + .../all/components/policies-table.tsx | 5 +- .../[orgId]/policies/all/data/queries.ts | 57 - .../[orgId]/policies/all/data/validations.ts | 24 - .../policies/all/hooks/usePolicyActions.ts | 14 + .../src/app/(app)/[orgId]/policies/layout.tsx | 7 +- .../[questionnaireId]/data/queries.ts | 46 - .../questionnaire/[questionnaireId]/page.tsx | 41 +- .../actions/create-trigger-token.ts | 45 - .../components/KnowledgeBaseDocumentLink.tsx | 40 +- .../components/QuestionnaireTabs.tsx | 24 +- .../[orgId]/questionnaire/components/types.ts | 61 + .../hooks/useKnowledgeBaseDocView.ts | 26 + .../hooks/useKnowledgeBaseDocs.ts | 133 + .../questionnaire/hooks/useManualAnswers.ts | 75 + .../hooks/useQuestionnaireActions.ts | 28 +- .../hooks/useQuestionnaireAutoAnswer.ts | 7 +- .../useQuestionnaireDetail.ts | 1 - .../useQuestionnaireDetailHandlers.ts | 9 +- .../useQuestionnaireDetailState.ts | 4 - .../hooks/useQuestionnaireParse.ts | 18 +- .../hooks/useQuestionnaireSingleAnswer.ts | 1 - .../questionnaire/hooks/useQuestionnaires.ts | 55 + .../questionnaire/hooks/useSOADocument.ts | 177 + .../AdditionalDocumentsSection.test.tsx | 226 + .../components/AdditionalDocumentsSection.tsx | 562 +- .../context/components/ContextSection.tsx | 7 +- .../knowledge-base/data/queries.ts | 131 - .../actions/save-manual-answer.ts | 142 - .../components/ManualAnswersSection.tsx | 364 +- .../components/PublishedPoliciesSection.tsx | 3 +- .../(app)/[orgId]/questionnaire/layout.tsx | 13 + .../questionnaire/new_questionnaire/page.tsx | 32 +- .../app/(app)/[orgId]/questionnaire/page.tsx | 393 +- .../soa/components/CreateSOADocument.test.tsx | 123 + .../soa/components/CreateSOADocument.tsx | 67 +- .../soa/components/EditableSOAFields.tsx | 72 +- .../soa/components/SOADocumentInfo.tsx | 175 +- .../soa/components/SOAFrameworkTable.tsx | 172 +- .../soa/components/SOAFrameworkTabs.tsx | 34 +- .../soa/components/SOAMobileRow.tsx | 127 + .../components/SOAPendingApprovalAlert.tsx | 50 +- .../questionnaire/soa/components/SOATable.tsx | 130 +- .../soa/components/SubmitApprovalDialog.tsx | 16 +- .../questionnaire/soa/hooks/useSOAAutoFill.ts | 6 - .../actions/delete-questionnaire.ts | 65 - .../components/QuestionnaireHistory.tsx | 64 +- .../components/QuestionnaireOverview.tsx | 3 +- .../questionnaire/start_page/data/queries.ts | 54 - .../hooks/useQuestionnaireHistory.ts | 7 +- .../risk/(overview)/RisksTable.test.tsx | 243 + .../[orgId]/risk/(overview)/RisksTable.tsx | 149 +- .../(overview)/actions/get-risks-action.ts | 13 - .../components/table/RiskColumns.tsx | 15 +- .../[orgId]/risk/(overview)/data/getRisks.ts | 81 - .../risk/(overview)/data/validations.ts | 23 - .../(app)/[orgId]/risk/(overview)/page.tsx | 141 +- .../actions/regenerate-risk-mitigation.ts | 61 - .../[riskId]/components/RiskActions.test.tsx | 116 + .../risk/[riskId]/components/RiskActions.tsx | 113 +- .../components/RiskPageClient.test.tsx | 181 + .../[riskId]/components/RiskPageClient.tsx | 304 +- .../app/(app)/[orgId]/risk/[riskId]/page.tsx | 115 +- .../risk/[riskId]/tasks/[taskId]/page.tsx | 40 +- .../app/src/app/(app)/[orgId]/risk/layout.tsx | 13 + .../src/app/(app)/[orgId]/security/layout.tsx | 9 +- .../penetration-tests/actions/billing.ts | 304 - .../hooks/use-penetration-tests.test.tsx | 21 +- .../hooks/use-penetration-tests.ts | 10 +- .../components/table/ApiKeysTable.test.tsx | 118 + .../components/table/ApiKeysTable.tsx | 264 +- .../table/CreateApiKeySheet.test.tsx | 123 + .../components/table/CreateApiKeySheet.tsx | 222 + .../components/table/ScopeSelector.tsx | 181 + .../settings/api-keys/lib/scope-presets.ts | 71 + .../(app)/[orgId]/settings/api-keys/page.tsx | 68 +- .../settings/billing/billing-actions.tsx | 69 + .../(app)/[orgId]/settings/billing/page.tsx | 119 +- .../BrowserConnectionClient.test.tsx | 97 + .../components/BrowserConnectionClient.tsx | 27 +- .../settings/browser-connection/page.tsx | 3 + .../settings/components/SettingsSidebar.tsx | 2 + .../settings/components/SettingsTabs.test.tsx | 109 + .../settings/components/SettingsTabs.tsx | 14 +- .../context-hub/ContextTable.test.tsx | 178 + .../settings/context-hub/ContextTable.tsx | 57 +- .../components/context-form.test.tsx | 132 + .../context-hub/components/context-form.tsx | 57 +- .../components/context-list.test.tsx | 105 + .../context-hub/components/context-list.tsx | 29 +- .../context-hub/data/getContextEntries.ts | 93 - .../context-hub/hooks/useContextEntries.ts | 87 + .../[orgId]/settings/context-hub/page.tsx | 28 +- .../src/app/(app)/[orgId]/settings/layout.tsx | 3 + .../RoleNotificationSettings.test.tsx | 157 + .../components/RoleNotificationSettings.tsx | 114 + .../data/getRoleNotificationSettings.ts | 41 + .../hooks/useRoleNotifications.ts | 62 + .../settings/notifications/loading.tsx | 52 + .../[orgId]/settings/notifications/page.tsx | 26 + .../src/app/(app)/[orgId]/settings/page.tsx | 140 +- .../settings/portal/portal-settings.test.tsx | 123 + .../settings/portal/portal-settings.tsx | 81 +- .../components/EditRolePageClient.tsx | 61 + .../settings/roles/[roleId]/loading.tsx | 58 + .../[orgId]/settings/roles/[roleId]/page.tsx | 54 + .../components/PermissionMatrix.test.tsx | 300 + .../roles/components/PermissionMatrix.tsx | 352 + .../roles/components/RoleForm.test.tsx | 252 + .../settings/roles/components/RoleForm.tsx | 148 + .../roles/components/RolesPageClient.tsx | 40 + .../roles/components/RolesTable.test.tsx | 169 + .../settings/roles/components/RolesTable.tsx | 241 + .../settings/roles/components/SystemRoles.tsx | 78 + .../settings/roles/constants/system-roles.ts | 41 + .../[orgId]/settings/roles/hooks/useRole.ts | 33 + .../[orgId]/settings/roles/hooks/useRoles.ts | 83 + .../(app)/[orgId]/settings/roles/loading.tsx | 59 + .../roles/new/components/NewRoleForm.tsx | 54 + .../[orgId]/settings/roles/new/loading.tsx | 58 + .../(app)/[orgId]/settings/roles/new/page.tsx | 33 + .../app/(app)/[orgId]/settings/roles/page.tsx | 25 + .../settings/roles/system/[roleName]/page.tsx | 51 + .../system/[roleName]/system-role-detail.tsx | 29 + .../components/AddSecretDialog.test.tsx | 119 + .../secrets/components/AddSecretDialog.tsx | 52 +- .../components/EditSecretDialog.test.tsx | 137 + .../secrets/components/EditSecretDialog.tsx | 43 +- .../components/table/SecretsTable.test.tsx | 178 + .../secrets/components/table/SecretsTable.tsx | 123 +- .../settings/secrets/hooks/useSecrets.ts | 103 + .../(app)/[orgId]/settings/secrets/page.tsx | 65 +- .../user/actions/update-email-preferences.ts | 68 - .../EmailNotificationPreferences.tsx | 325 +- .../user/hooks/useEmailPreferences.ts | 66 + .../app/(app)/[orgId]/settings/user/page.tsx | 83 +- .../(app)/[orgId]/tasks/[taskId]/actions.ts | 86 - .../tasks/[taskId]/actions/delete-task.ts | 69 - .../actions/generate-suggestions.ts | 44 +- .../[automationId]/actions/sanitize-error.ts | 1 - .../actions/task-automation-actions.ts | 80 +- .../components/AutomationPageClient.tsx | 9 - .../components/AutomationSettingsDialogs.tsx | 63 +- .../message-part/file-writing-activity.tsx | 2 +- .../chat/message-part/prompt-info.tsx | 2 +- .../chat/message-part/prompt-secret.tsx | 30 +- .../chat/message-part/research-activity.tsx | 2 +- .../evaluation/EvaluationCriteriaCard.tsx | 4 +- .../model-selector/use-available-models.tsx | 2 +- .../workflow/workflow-visualizer-simple.tsx | 3 - .../hooks/use-automation-versions.ts | 2 +- .../[automationId]/hooks/use-chat-handlers.ts | 2 +- .../hooks/use-task-automation-execution.ts | 36 +- .../hooks/use-task-automation.ts | 34 +- .../[automationId]/lib/chat-context.tsx | 1 - .../components/AutomationOverview.tsx | 573 +- .../overview/components/MetricsSection.tsx | 234 +- .../overview/hooks/use-automation-runs.ts | 26 +- .../[automationId]/overview/page.tsx | 99 +- .../components/AutomationRunsCard.tsx | 371 +- .../components/BrowserAutomations.tsx | 7 +- .../[taskId]/components/SingleTask.test.tsx | 265 + .../tasks/[taskId]/components/SingleTask.tsx | 804 +- .../[taskId]/components/TaskAutomations.tsx | 349 +- .../[taskId]/components/TaskDeleteDialog.tsx | 86 +- .../components/TaskIntegrationChecks.tsx | 161 +- .../components/TaskPropertiesSidebar.test.tsx | 193 + .../components/TaskPropertiesSidebar.tsx | 455 +- .../browser-automations/AutomationItem.tsx | 38 +- .../BrowserAutomationsList.test.tsx | 140 + .../BrowserAutomationsList.tsx | 7 +- .../findings/CreateFindingSheet.test.tsx | 192 + .../findings/CreateFindingSheet.tsx | 5 +- .../components/findings/FindingItem.tsx | 4 +- .../components/findings/FindingsList.test.tsx | 195 + .../components/findings/FindingsList.tsx | 11 +- .../tasks/[taskId]/hooks/use-task-activity.ts | 1 - .../hooks/use-task-automation-runs.ts | 1 - .../[taskId]/hooks/use-task-automations.ts | 2 +- .../[orgId]/tasks/[taskId]/hooks/use-task.ts | 74 +- .../[taskId]/hooks/useBrowserAutomations.ts | 12 +- .../tasks/[taskId]/hooks/useBrowserContext.ts | 24 +- .../[taskId]/hooks/useBrowserExecution.ts | 11 +- .../[taskId]/hooks/useIntegrationChecks.ts | 146 + .../app/(app)/[orgId]/tasks/[taskId]/page.tsx | 115 +- .../tasks/actions/deleteTaskAttachment.ts | 81 - .../tasks/actions/getTaskAttachmentUrl.ts | 96 - .../(app)/[orgId]/tasks/actions/updateTask.ts | 46 - .../[orgId]/tasks/actions/updateTaskOrder.ts | 50 - .../[orgId]/tasks/actions/updateTaskStatus.ts | 68 - .../BulkTaskAssigneeChangeModal.tsx | 28 +- .../tasks/components/BulkTaskDeleteModal.tsx | 27 +- .../components/BulkTaskStatusChangeModal.tsx | 45 +- .../tasks/components/CreateTaskSheet.tsx | 62 +- .../ModernSingleStatusTaskList.test.tsx | 262 + .../components/ModernSingleStatusTaskList.tsx | 68 +- .../[orgId]/tasks/components/StatusGroup.tsx | 13 +- .../[orgId]/tasks/components/TaskList.tsx | 9 +- .../tasks/components/TasksPageClient.test.tsx | 166 + .../tasks/components/TasksPageClient.tsx | 18 +- .../app/(app)/[orgId]/tasks/hooks/useTasks.ts | 167 + .../src/app/(app)/[orgId]/tasks/layout.tsx | 19 +- apps/app/src/app/(app)/[orgId]/tasks/page.tsx | 271 +- .../trust/components/approve-dialog.test.tsx | 97 + .../trust/components/approve-dialog.tsx | 5 +- .../trust/components/deny-dialog.test.tsx | 81 + .../[orgId]/trust/components/deny-dialog.tsx | 5 +- .../trust/components/revoke-dialog.test.tsx | 79 + .../trust/components/revoke-dialog.tsx | 5 +- .../src/app/(app)/[orgId]/trust/layout.tsx | 13 + apps/app/src/app/(app)/[orgId]/trust/page.tsx | 586 +- .../portal-settings/actions/custom-domain.ts | 218 - .../portal-settings/actions/custom-links.ts | 155 - .../actions/trust-portal-switch.ts | 109 - .../actions/update-allowed-domains.ts | 60 - .../actions/update-trust-favicon.ts | 133 - .../actions/update-trust-overview.ts | 37 - .../actions/update-trust-portal-faqs.ts | 61 - .../actions/update-trust-portal-frameworks.ts | 100 - .../actions/vendor-settings.ts | 82 - .../components/AllowedDomainsManager.test.tsx | 88 + .../components/AllowedDomainsManager.tsx | 41 +- .../components/BrandSettings.test.tsx | 78 + .../components/BrandSettings.tsx | 30 +- ...tPortalAdditionalDocumentsSection.test.tsx | 121 + .../TrustPortalAdditionalDocumentsSection.tsx | 191 +- .../TrustPortalCustomLinks.test.tsx | 167 + .../components/TrustPortalCustomLinks.tsx | 180 +- .../components/TrustPortalDomain.test.tsx | 116 + .../components/TrustPortalDomain.tsx | 125 +- .../components/TrustPortalFaqBuilder.test.tsx | 118 + .../components/TrustPortalFaqBuilder.tsx | 130 +- .../components/TrustPortalOverview.test.tsx | 137 + .../components/TrustPortalOverview.tsx | 81 +- .../components/TrustPortalSwitch.test.tsx | 275 + .../components/TrustPortalSwitch.tsx | 453 +- .../components/TrustPortalVendors.test.tsx | 139 + .../components/TrustPortalVendors.tsx | 48 +- .../components/UpdateTrustFavicon.test.tsx | 99 + .../components/UpdateTrustFavicon.tsx | 89 +- .../components/TrustSettingsClient.test.tsx | 126 + .../components/TrustSettingsClient.tsx | 30 +- .../app/(app)/[orgId]/trust/settings/page.tsx | 45 +- .../(overview)/actions/deleteVendor.ts | 86 - .../(overview)/actions/get-vendors-action.ts | 17 - .../components/VendorDeleteCell.tsx | 22 +- .../components/VendorsTable.test.tsx | 242 + .../(overview)/components/VendorsTable.tsx | 172 +- .../vendors/(overview)/data/queries.ts | 70 - .../vendors/(overview)/data/validations.ts | 27 - .../(app)/[orgId]/vendors/(overview)/page.tsx | 89 +- .../actions/regenerate-vendor-mitigation.ts | 61 - .../actions/task/create-task-action.ts | 56 - .../actions/task/revalidate-upload.ts | 32 - .../actions/task/update-task-action.ts | 71 - .../actions/trigger-vendor-risk-assessment.ts | 87 - .../actions/update-vendor-inherent-risk.ts | 37 - .../actions/update-vendor-residual-risk.ts | 37 - .../components/VendorActions.test.tsx | 134 + .../[vendorId]/components/VendorActions.tsx | 90 +- .../components/VendorDetailTabs.tsx | 470 +- .../VendorInherentRiskChart.test.tsx | 101 + .../components/VendorInherentRiskChart.tsx | 12 +- .../components/VendorPageClient.test.tsx | 183 + .../components/VendorPageClient.tsx | 8 +- .../VendorResidualRiskChart.test.tsx | 101 + .../components/VendorResidualRiskChart.tsx | 12 +- .../components/VendorResidualRiskForm.tsx | 47 +- .../secondary-fields/secondary-fields.tsx | 7 +- .../update-secondary-fields-form.tsx | 95 +- .../tasks/create-vendor-task-form.test.tsx | 154 + .../tasks/create-vendor-task-form.tsx | 55 +- .../update-title-and-description-form.tsx | 58 +- .../forms/risks/InherentRiskForm.test.tsx | 129 + .../forms/risks/InherentRiskForm.tsx | 27 +- .../forms/risks/ResidualRiskForm.test.tsx | 129 + .../forms/risks/ResidualRiskForm.tsx | 27 +- .../(app)/[orgId]/vendors/[vendorId]/page.tsx | 150 +- .../review/components/VendorReviewClient.tsx | 4 - .../secondary-fields/secondary-fields.tsx | 51 +- .../components/title/update-task-sheet.tsx | 54 +- .../[vendorId]/tasks/[taskId]/page.tsx | 82 +- .../vendors/actions/create-vendor-action.ts | 257 - .../actions/search-global-vendors-action.ts | 50 - .../vendors/backup-overview/layout.tsx | 114 +- .../VendorNameAutocompleteField.tsx | 37 +- .../vendors/components/create-vendor-form.tsx | 102 +- .../components/create-vendor-sheet.test.tsx | 110 + .../components/create-vendor-sheet.tsx | 4 + .../src/app/(app)/[orgId]/vendors/layout.tsx | 13 + apps/app/src/app/(app)/admin/layout.tsx | 14 +- apps/app/src/app/(app)/layout.tsx | 15 +- apps/app/src/app/(app)/no-access/page.tsx | 36 +- .../app/(app)/onboarding/[orgId]/layout.tsx | 25 +- .../onboarding/actions/complete-onboarding.ts | 6 +- .../setup/components/FrameworkSelection.tsx | 43 +- .../setup/components/OnboardingStepInput.tsx | 33 +- apps/app/src/app/(app)/setup/go/[id]/page.tsx | 16 +- .../(app)/setup/hooks/useOnboardingForm.ts | 9 +- apps/app/src/app/(app)/setup/layout.tsx | 27 +- .../app/(app)/setup/loading/[orgId]/page.tsx | 12 - .../MinimalOrganizationSwitcher.tsx | 30 +- apps/app/src/app/(app)/upgrade/layout.tsx | 8 +- apps/app/src/app/api/auth/[...all]/route.ts | 288 +- apps/app/src/app/api/auth/test-db/route.ts | 14 +- .../app/api/auth/test-grant-access/route.ts | 22 +- apps/app/src/app/api/auth/test-login/route.ts | 49 +- .../automations/[automationId]/runs/route.ts | 39 - apps/app/src/app/api/chat/route.ts | 82 - .../src/app/api/cloud-tests/findings/route.ts | 235 - .../app/api/cloud-tests/legacy-scan/route.ts | 104 + .../app/api/cloud-tests/providers/route.ts | 150 - .../src/app/api/email-preferences/route.ts | 71 + .../app/api/evidence-forms/analyze/route.ts | 20 +- apps/app/src/app/api/frameworks/route.ts | 21 - apps/app/src/app/api/health/route.ts | 20 +- .../integrations/relevant-tasks/route.ts} | 105 +- .../app/api/invitations/[id]/route.test.ts | 134 + .../src/app/api/people/invite/route.test.ts | 241 + apps/app/src/app/api/people/invite/route.ts | 269 + .../app/api/policies/[policyId]/chat/route.ts | 2 +- .../src/app/api/policies/publish-all/route.ts | 38 + apps/app/src/app/api/qa/approve-org/route.ts | 10 +- apps/app/src/app/api/qa/delete-user/route.ts | 10 +- .../api/questionnaire/trigger-token/route.ts | 49 + .../app/src/app/api/retool/reset-org/route.ts | 8 +- apps/app/src/app/api/revalidate/path/route.ts | 2 - .../[riskId]/regenerate-mitigation/route.ts | 97 + apps/app/src/app/api/secrets/[id]/route.ts | 212 - apps/app/src/app/api/secrets/route.ts | 138 - .../src/app/api/training/certificate/route.ts | 98 + apps/app/src/app/api/user-frameworks/route.ts | 5 +- .../[vendorId]/regenerate-mitigation/route.ts | 97 + .../app/src/app/api/vendors/research/route.ts | 44 + apps/app/src/app/page.tsx | 92 +- apps/app/src/app/posthog.ts | 6 - apps/app/src/app/providers.tsx | 2 - .../preferences/actions/update-preferences.ts | 69 - .../app/unsubscribe/preferences/client.tsx | 54 +- apps/app/src/components/RecentAuditLogs.tsx | 179 + .../src/components/ai-elements/code-block.tsx | 554 + .../components/ai-elements/conversation.tsx | 167 + .../src/components/ai-elements/message.tsx | 370 + .../components/ai-elements/prompt-input.tsx | 1341 ++ .../src/components/ai-elements/reasoning.tsx | 230 + .../src/components/ai-elements/shimmer.tsx | 78 + apps/app/src/components/ai-elements/tool.tsx | 174 + apps/app/src/components/ai/chat-avatar.tsx | 34 - apps/app/src/components/ai/chat-empty.tsx | 17 - apps/app/src/components/ai/chat-text-area.tsx | 101 - apps/app/src/components/ai/chat.tsx | 225 +- apps/app/src/components/ai/icons.tsx | 144 - apps/app/src/components/ai/markdown.tsx | 11 - apps/app/src/components/ai/message.tsx | 296 - apps/app/src/components/ai/messages.tsx | 32 - apps/app/src/components/ai/risk-display.tsx | 41 - .../src/components/auth/jwt-token-manager.tsx | 77 - .../src/components/comments/CommentItem.tsx | 5 +- .../src/components/comments/CommentList.tsx | 4 +- .../comments/CommentRichTextField.tsx | 10 +- apps/app/src/components/comments/Comments.tsx | 96 +- .../src/components/editor/advanced-editor.tsx | 7 + .../src/components/editor/policy-editor.tsx | 7 +- apps/app/src/components/error-fallback.tsx | 3 + .../organization/delete-organization.test.tsx | 99 + .../organization/delete-organization.tsx | 38 +- .../organization/transfer-ownership.test.tsx | 123 + .../forms/organization/transfer-ownership.tsx | 13 +- ...update-organization-advanced-mode.test.tsx | 100 + .../update-organization-advanced-mode.tsx | 44 +- ...te-organization-evidence-approval.test.tsx | 110 + .../update-organization-evidence-approval.tsx | 32 +- .../update-organization-logo.test.tsx | 101 + .../organization/update-organization-logo.tsx | 85 +- .../update-organization-name.test.tsx | 131 + .../organization/update-organization-name.tsx | 33 +- .../update-organization-website.test.tsx | 66 + .../update-organization-website.tsx | 33 +- .../forms/policies/create-new-policy.test.tsx | 129 + .../forms/policies/create-new-policy.tsx | 39 +- .../forms/policies/policy-overview.test.tsx | 122 + .../forms/policies/policy-overview.tsx | 48 +- .../policies/update-policy-form.test.tsx | 120 + .../forms/policies/update-policy-form.tsx | 43 +- .../forms/risks/InherentRiskForm.tsx | 42 +- .../forms/risks/ResidualRiskForm.tsx | 37 +- .../forms/risks/create-risk-form.test.tsx | 90 + .../forms/risks/create-risk-form.tsx | 41 +- .../forms/risks/risk-overview.test.tsx | 153 + .../components/forms/risks/risk-overview.tsx | 273 +- .../risks/task/update-task-form.test.tsx | 116 + .../forms/risks/task/update-task-form.tsx | 46 +- .../risks/task/update-task-overview-form.tsx | 44 +- .../forms/risks/update-risk-form.test.tsx | 97 + .../forms/risks/update-risk-form.tsx | 54 +- apps/app/src/components/header.tsx | 6 +- .../ConnectIntegrationDialog.test.tsx | 267 + .../integrations/ConnectIntegrationDialog.tsx | 157 +- .../integrations/ManageIntegrationDialog.tsx | 96 +- .../src/components/layout/MinimalHeader.tsx | 21 +- .../layout/MinimalOrganizationSwitcher.tsx | 28 +- apps/app/src/components/main-menu.tsx | 8 +- apps/app/src/components/mobile-menu.tsx | 5 +- .../onboarding/OnboardingLayout.tsx | 5 - .../src/components/organization-switcher.tsx | 31 +- .../risks/charts/InherentRiskChart.test.tsx | 95 + .../risks/charts/InherentRiskChart.tsx | 19 +- .../risks/charts/ResidualRiskChart.test.tsx | 95 + .../risks/charts/ResidualRiskChart.tsx | 19 +- .../risks/charts/RiskMatrixChart.tsx | 90 +- .../components/risks/charts/RisksAssignee.tsx | 111 +- .../risks/charts/risks-by-department.tsx | 33 +- .../components/risks/risk-overview.test.tsx | 105 + .../src/components/risks/risk-overview.tsx | 28 +- .../sheets/create-risk-sheet.test.tsx | 103 + .../components/sheets/create-risk-sheet.tsx | 4 + .../components/sidebar-collapse-button.tsx | 22 +- apps/app/src/components/sidebar.tsx | 16 +- .../components/task-items/StatusCircle.tsx | 18 +- .../task-items/TaskItemActivityTimeline.tsx | 5 +- .../task-items/TaskItemCreateDialog.test.tsx | 82 + .../task-items/TaskItemCreateDialog.tsx | 76 +- .../task-items/TaskItemDescriptionView.tsx | 18 +- .../TaskItemEditableDescription.tsx | 6 +- .../task-items/TaskItemEditableTitle.tsx | 6 +- .../task-items/TaskItemFocusSidebar.tsx | 57 +- .../task-items/TaskItemFocusView.test.tsx | 171 + .../task-items/TaskItemFocusView.tsx | 394 +- .../task-items/TaskItemItem.test.tsx | 248 + .../components/task-items/TaskItemItem.tsx | 776 +- .../components/task-items/TaskItemList.tsx | 19 +- .../task-items/TaskItemPagination.tsx | 75 - .../src/components/task-items/TaskItems.tsx | 405 +- .../components/task-items/TaskItemsBody.tsx | 93 - .../task-items/TaskItemsContent.tsx | 127 - .../task-items/TaskItemsFilters.tsx | 140 - .../task-items/TaskItemsHeader.test.tsx | 101 + .../components/task-items/TaskItemsHeader.tsx | 75 +- .../components/task-items/TaskItemsInline.tsx | 61 - .../task-items/TaskRichDescriptionField.tsx | 56 +- .../task-items/TaskSmartForm.test.tsx | 185 + .../components/task-items/TaskSmartForm.tsx | 12 +- .../custom-task/CustomTaskItemMainContent.tsx | 75 +- .../hooks/use-task-item-activity.ts | 4 +- .../hooks/use-task-item-attachment-upload.ts | 1 - .../components/task-items/task-item-utils.ts | 42 +- ...erifyRiskAssessmentTaskItemSkeletonRow.tsx | 6 +- .../tests/charts/tests-by-assignee.tsx | 130 +- apps/app/src/data/getOrganizations.ts | 37 - apps/app/src/data/tools/index.ts | 11 - apps/app/src/data/tools/organization.ts | 42 - apps/app/src/data/tools/policies.ts | 86 - apps/app/src/data/tools/risks-tool.ts | 97 - apps/app/src/data/tools/user.ts | 28 - apps/app/src/env.mjs | 16 +- apps/app/src/hooks/use-access-requests.ts | 9 - apps/app/src/hooks/use-api-keys.ts | 111 +- apps/app/src/hooks/use-api-swr.ts | 107 +- apps/app/src/hooks/use-api.ts | 126 +- apps/app/src/hooks/use-attachments.ts | 45 + apps/app/src/hooks/use-audit-logs.ts | 69 + .../app/src/hooks/use-integration-platform.ts | 174 +- .../app/src/hooks/use-organization-members.ts | 12 +- .../src/hooks/use-organization-mutations.ts | 75 + apps/app/src/hooks/use-people-api.ts | 15 + apps/app/src/hooks/use-permissions.ts | 54 + apps/app/src/hooks/use-policy-mutations.ts | 55 + apps/app/src/hooks/use-risk-mutations.ts | 52 + apps/app/src/hooks/use-risks.ts | 69 +- apps/app/src/hooks/use-scroll-to-bottom.ts | 29 - apps/app/src/hooks/use-streamable-text.tsx | 58 - apps/app/src/hooks/use-task-mutations.ts | 71 + .../hooks/use-trust-portal-custom-links.ts | 83 + .../src/hooks/use-trust-portal-documents.ts | 100 + .../src/hooks/use-trust-portal-settings.ts | 193 + apps/app/src/hooks/use-users.ts | 23 - apps/app/src/hooks/use-vendors.ts | 35 + apps/app/src/lib/api-client.ts | 148 +- apps/app/src/lib/api-key.ts | 67 +- apps/app/src/lib/api-server.ts | 86 + apps/app/src/lib/compliance.ts | 90 + apps/app/src/lib/db/employee.ts | 17 - apps/app/src/lib/evidence-download.ts | 32 +- apps/app/src/lib/pdf-generator.ts | 4 +- apps/app/src/lib/permissions.server.ts | 94 + apps/app/src/lib/permissions.test.ts | 133 + apps/app/src/lib/permissions.ts | 229 + apps/app/src/lib/stripe.ts | 2 +- apps/app/src/lib/unsubscribe.ts | 9 +- apps/app/src/middleware.test.ts | 382 +- apps/app/src/proxy.ts | 62 +- apps/app/src/test-utils/helpers/middleware.ts | 10 +- apps/app/src/test-utils/mocks/db.ts | 17 + apps/app/src/test-utils/mocks/permissions.ts | 92 + .../trigger/tasks/email/new-policy-email.ts | 2 +- .../tasks/email/publish-all-policies-email.ts | 2 +- .../tasks/email/weekly-task-digest-email.ts | 2 +- .../onboard-organization-helpers.ts | 9 +- .../src/trigger/tasks/task/policy-schedule.ts | 34 +- .../src/trigger/tasks/task/task-schedule.ts | 33 +- .../tasks/task/weekly-task-reminder.ts | 17 +- apps/app/src/types/index.ts | 16 + apps/app/src/utils/auth-client.ts | 48 +- apps/app/src/utils/auth.test.ts | 75 + apps/app/src/utils/auth.ts | 833 +- apps/app/src/utils/jwt-manager.ts | 270 - apps/app/src/utils/permissions.ts | 76 +- apps/app/src/utils/server-tracking.ts | 9 - apps/app/vitest.config.mjs | 30 + apps/app/vitest.config.mts | 1 - .../[orgId]/components/EmployeeTasksList.tsx | 40 +- .../components/policy/PolicyCarousel.tsx | 25 +- .../components/policy/PortalPdfViewer.tsx | 64 +- .../tasks/DeviceAgentAccordionItem.tsx | 407 +- .../components/tasks/FleetPolicyItem.tsx | 76 +- .../tasks/GeneralTrainingAccordionItem.tsx | 111 +- .../tasks/PoliciesAccordionItem.tsx | 150 +- .../tasks/PolicyImageResetModal.tsx | 10 +- .../tasks/PolicyImageUploadModal.tsx | 55 +- .../components/video/CarouselControls.tsx | 2 +- .../components/video/VideoCarousel.tsx | 49 +- .../[orgId]/components/video/YoutubeEmbed.tsx | 10 +- .../[orgId]/documents/[formType]/page.tsx | 2 +- .../policy/[policyId]/PolicyAcceptButton.tsx | 37 +- .../(app)/(home)/actions/getPolicyPdfUrl.ts | 90 - .../(home)/actions/markPolicyAsCompleted.ts | 80 - .../(home)/actions/markVideoAsCompleted.ts | 208 - apps/portal/src/app/(public)/auth/page.tsx | 9 +- apps/portal/src/app/actions/login.ts | 63 - apps/portal/src/app/actions/logout.ts | 11 - .../portal/src/app/api/auth/[...all]/route.ts | 146 +- .../app/api/portal/accept-policies/route.ts | 71 + .../api/portal/mark-policy-completed/route.ts | 64 + .../api/portal/mark-video-completed/route.ts | 109 + .../app/api/portal/policy-pdf-url/route.ts | 85 + .../src/app/components/google-sign-in.tsx | 6 +- .../src/app/components/microsoft-sign-in.tsx | 4 +- apps/portal/src/app/components/otp-form.tsx | 56 +- apps/portal/src/app/components/otp.tsx | 7 +- .../src/app/components/theme-switch.tsx | 8 +- apps/portal/src/app/lib/auth-client.ts | 11 +- apps/portal/src/app/lib/auth.ts | 241 +- apps/portal/src/app/lib/permissions.ts | 70 +- apps/portal/src/env.mjs | 16 +- apps/portal/src/hooks/use-update-policy.ts | 1 + apps/portal/src/utils/logger.ts | 9 +- bun.lock | 255 +- packages/auth/package.json | 26 + packages/auth/src/index.ts | 17 + packages/auth/src/permissions.ts | 219 + packages/auth/src/server.ts | 231 + packages/auth/tsconfig.json | 13 + .../migration.sql | 9 + .../migration.sql | 31 + .../migration.sql | 22 + .../migration.sql | 2 + .../migration.sql | 5 + .../migration.sql | 2 + .../migration.sql | 5 + packages/db/prisma/schema/auth.prisma | 21 +- .../prisma/schema/notification-policy.prisma | 19 + packages/db/prisma/schema/organization.prisma | 4 + packages/db/prisma/schema/policy.prisma | 9 + packages/db/prisma/schema/shared.prisma | 3 + packages/device-agent/src/main/auth.ts | 7 +- packages/device-agent/src/main/index.ts | 1 + packages/device-agent/src/main/tray.ts | 9 + packages/docs/openapi.json | 14701 +++++++++------- packages/email/lib/check-unsubscribe.ts | 159 +- packages/ui/src/components/editor/index.tsx | 2 +- 960 files changed, 67631 insertions(+), 35323 deletions(-) create mode 100644 .claude/commands/audit-design-system.md create mode 100644 .claude/commands/audit-hooks.md create mode 100644 .claude/commands/audit-rbac.md create mode 100644 .claude/commands/audit-tests.md create mode 100644 .claude/commands/production-readiness.md create mode 100644 CLAUDE.md delete mode 100644 CODE_OF_CONDUCT.md create mode 100644 apps/api/.cursorrules create mode 100644 apps/api/CLAUDE.md create mode 100644 apps/api/src/assistant-chat/assistant-chat-tools.ts create mode 100644 apps/api/src/audit/audit-log.constants.ts create mode 100644 apps/api/src/audit/audit-log.controller.ts create mode 100644 apps/api/src/audit/audit-log.interceptor.spec.ts create mode 100644 apps/api/src/audit/audit-log.interceptor.ts create mode 100644 apps/api/src/audit/audit-log.resolvers.ts create mode 100644 apps/api/src/audit/audit-log.utils.ts create mode 100644 apps/api/src/audit/audit.module.ts create mode 100644 apps/api/src/audit/skip-audit-log.decorator.ts create mode 100644 apps/api/src/auth/auth.controller.ts create mode 100644 apps/api/src/auth/auth.server.ts delete mode 100644 apps/api/src/auth/internal-token.guard.ts create mode 100644 apps/api/src/auth/permission.guard.spec.ts create mode 100644 apps/api/src/auth/permission.guard.ts create mode 100644 apps/api/src/auth/public.decorator.ts create mode 100644 apps/api/src/auth/require-permission.decorator.ts create mode 100644 apps/api/src/auth/service-token.config.ts create mode 100644 apps/api/src/auth/skip-org-check.decorator.ts create mode 100644 apps/api/src/cloud-security/cloud-security-legacy.service.ts create mode 100644 apps/api/src/cloud-security/cloud-security-query.service.ts create mode 100644 apps/api/src/controls/controls.controller.ts create mode 100644 apps/api/src/controls/controls.module.ts create mode 100644 apps/api/src/controls/controls.service.ts create mode 100644 apps/api/src/controls/dto/create-control.dto.ts create mode 100644 apps/api/src/email/trigger-email.ts create mode 100644 apps/api/src/frameworks/dto/add-frameworks.dto.ts create mode 100644 apps/api/src/frameworks/frameworks-scores.helper.ts create mode 100644 apps/api/src/frameworks/frameworks-upsert.helper.ts create mode 100644 apps/api/src/frameworks/frameworks.controller.spec.ts create mode 100644 apps/api/src/frameworks/frameworks.controller.ts create mode 100644 apps/api/src/frameworks/frameworks.module.ts create mode 100644 apps/api/src/frameworks/frameworks.service.spec.ts create mode 100644 apps/api/src/frameworks/frameworks.service.ts create mode 100644 apps/api/src/knowledge-base/dto/save-manual-answer.dto.ts create mode 100644 apps/api/src/knowledge-base/knowledge-base.controller.spec.ts create mode 100644 apps/api/src/knowledge-base/knowledge-base.service.spec.ts create mode 100644 apps/api/src/notifications/check-unsubscribe.spec.ts create mode 100644 apps/api/src/people/dto/update-email-preferences.dto.ts create mode 100644 apps/api/src/people/people-fleet.helper.ts create mode 100644 apps/api/src/people/people.controller.spec.ts create mode 100644 apps/api/src/people/people.service.spec.ts create mode 100644 apps/api/src/policies/dto/upload-policy-pdf.dto.ts create mode 100644 apps/api/src/questionnaire/questionnaire.controller.spec.ts create mode 100644 apps/api/src/questionnaire/questionnaire.service.spec.ts create mode 100644 apps/api/src/risks/dto/get-risks-query.dto.ts create mode 100644 apps/api/src/roles/dto/create-role.dto.ts create mode 100644 apps/api/src/roles/dto/update-role.dto.ts create mode 100644 apps/api/src/roles/roles.controller.spec.ts create mode 100644 apps/api/src/roles/roles.controller.ts create mode 100644 apps/api/src/roles/roles.module.ts create mode 100644 apps/api/src/roles/roles.service.spec.ts create mode 100644 apps/api/src/roles/roles.service.ts create mode 100644 apps/api/src/secrets/encryption.util.ts create mode 100644 apps/api/src/secrets/secrets.controller.ts create mode 100644 apps/api/src/secrets/secrets.module.ts create mode 100644 apps/api/src/secrets/secrets.service.ts create mode 100644 apps/api/src/security-penetration-tests/pentest-billing.controller.ts create mode 100644 apps/api/src/security-penetration-tests/pentest-billing.service.ts create mode 100644 apps/api/src/stripe/stripe.module.ts create mode 100644 apps/api/src/stripe/stripe.service.ts delete mode 100644 apps/api/src/tasks/internal-task-notification.controller.ts create mode 100644 apps/api/src/trigger/email/send-email.ts create mode 100644 apps/api/src/trigger/policies/update-policy-helpers.ts create mode 100644 apps/api/src/trigger/policies/update-policy-prompts.ts create mode 100644 apps/api/src/trigger/policies/update-policy.ts create mode 100644 apps/api/src/utils/assignment-filter.spec.ts create mode 100644 apps/api/src/utils/assignment-filter.ts create mode 100644 apps/api/src/utils/compliance-filters.ts create mode 100644 apps/api/src/utils/department-visibility.spec.ts create mode 100644 apps/api/src/utils/department-visibility.ts create mode 100644 apps/app/components.json delete mode 100644 apps/app/src/actions/add-comment.ts delete mode 100644 apps/app/src/actions/change-organization.ts delete mode 100644 apps/app/src/actions/context-hub/create-context-entry-action.ts delete mode 100644 apps/app/src/actions/context-hub/delete-context-entry-action.ts delete mode 100644 apps/app/src/actions/context-hub/update-context-entry-action.ts delete mode 100644 apps/app/src/actions/controls/create-control-action.ts delete mode 100644 apps/app/src/actions/floating.ts delete mode 100644 apps/app/src/actions/integrations/delete-integration-connection.ts delete mode 100644 apps/app/src/actions/integrations/retrieve-integration-session-token.ts delete mode 100644 apps/app/src/actions/integrations/update-integration-settings-action.ts delete mode 100644 apps/app/src/actions/organization/add-frameworks-to-organization-action.ts delete mode 100644 apps/app/src/actions/organization/create-api-key-action.ts delete mode 100644 apps/app/src/actions/organization/delete-organization-action.ts delete mode 100644 apps/app/src/actions/organization/revoke-api-key-action.ts delete mode 100644 apps/app/src/actions/organization/update-organization-advanced-mode-action.ts delete mode 100644 apps/app/src/actions/organization/update-organization-logo-action.ts delete mode 100644 apps/app/src/actions/organization/update-organization-name-action.ts delete mode 100644 apps/app/src/actions/organization/update-organization-website-action.ts delete mode 100644 apps/app/src/actions/policies/archive-policy.ts delete mode 100644 apps/app/src/actions/policies/create-new-policy.ts delete mode 100644 apps/app/src/actions/policies/create-version.ts delete mode 100644 apps/app/src/actions/policies/delete-policy.ts delete mode 100644 apps/app/src/actions/policies/delete-version.ts delete mode 100644 apps/app/src/actions/policies/deny-requested-policy-changes.ts delete mode 100644 apps/app/src/actions/policies/discard-draft-changes.ts delete mode 100644 apps/app/src/actions/policies/get-policy-versions.ts delete mode 100644 apps/app/src/actions/policies/migrate-policies-to-versioning.ts delete mode 100644 apps/app/src/actions/policies/publish-all.ts delete mode 100644 apps/app/src/actions/policies/publish-version.ts delete mode 100644 apps/app/src/actions/policies/restore-version-to-draft.ts delete mode 100644 apps/app/src/actions/policies/set-active-version.ts delete mode 100644 apps/app/src/actions/policies/submit-policy-for-approval-action.ts delete mode 100644 apps/app/src/actions/policies/submit-version-for-approval.ts delete mode 100644 apps/app/src/actions/policies/update-draft.ts delete mode 100644 apps/app/src/actions/policies/update-policy-action.ts delete mode 100644 apps/app/src/actions/policies/update-policy-form-action.ts delete mode 100644 apps/app/src/actions/policies/update-policy-overview-action.ts delete mode 100644 apps/app/src/actions/risk/create-risk-action.ts delete mode 100644 apps/app/src/actions/risk/task/update-task-action.ts delete mode 100644 apps/app/src/actions/risk/update-inherent-risk-action.ts delete mode 100644 apps/app/src/actions/risk/update-residual-risk-action.ts delete mode 100644 apps/app/src/actions/risk/update-residual-risk-enum-action.ts delete mode 100644 apps/app/src/actions/risk/update-risk-action.ts delete mode 100644 apps/app/src/actions/tasks.ts delete mode 100644 apps/app/src/actions/tasks/create-task-action.ts delete mode 100644 apps/app/src/actions/tasks/regenerate-task-action.ts create mode 100644 apps/app/src/app/(app)/[orgId]/auditor/layout.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/cloud-tests/actions/create-trigger-token.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/cloud-tests/actions/disconnect-cloud.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/cloud-tests/actions/update-cloud-credentials.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/cloud-tests/components/CloudConnectionCard.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/cloud-tests/components/CloudSettingsModal.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/cloud-tests/components/EmptyState.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/cloud-tests/components/TestsLayout.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/cloud-tests/layout.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/controls/[controlId]/actions/delete-control.ts create mode 100644 apps/app/src/app/(app)/[orgId]/controls/[controlId]/components/ControlDeleteDialog.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/controls/[controlId]/components/ControlHeaderActions.test.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/controls/[controlId]/data/getControl.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/controls/[controlId]/data/getRelatedPolicies.ts create mode 100644 apps/app/src/app/(app)/[orgId]/controls/components/controls-table.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/controls/hooks/useControls.ts create mode 100644 apps/app/src/app/(app)/[orgId]/controls/layout.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/documents/components/CompanyFormPageClient.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/documents/components/CompanySubmissionDetailPageClient.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/documents/components/DocumentFindingsSection.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/documents/layout.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/frameworks/[frameworkInstanceId]/actions/delete-framework.ts create mode 100644 apps/app/src/app/(app)/[orgId]/frameworks/[frameworkInstanceId]/components/FrameworkDeleteDialog.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/frameworks/[frameworkInstanceId]/components/FrameworkOverview.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/frameworks/components/AddFrameworkModal.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/frameworks/components/FrameworksOverview.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/frameworks/components/ToDoOverview.test.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/frameworks/data/getSingleFrameworkInstanceWithControls.ts create mode 100644 apps/app/src/app/(app)/[orgId]/frameworks/hooks/useFrameworks.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/frameworks/lib/getFrameworks.ts create mode 100644 apps/app/src/app/(app)/[orgId]/integrations/components/PlatformIntegrations.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/integrations/layout.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/layout.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/people/[employeeId]/hooks/useEmployee.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/people/all/actions/updateMemberRole.ts create mode 100644 apps/app/src/app/(app)/[orgId]/people/all/components/InviteMembersModal.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/people/all/components/csv-invite-parser.ts create mode 100644 apps/app/src/app/(app)/[orgId]/people/all/components/invite-form-schema.ts create mode 100644 apps/app/src/app/(app)/[orgId]/people/all/hooks/useTeamMembers.ts create mode 100644 apps/app/src/app/(app)/[orgId]/people/devices/components/DeviceDropdownMenu.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/people/devices/hooks/useDevices.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/actions/mapPolicyToControls.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/actions/regenerate-policy.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/actions/switch-policy-display-format.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/actions/unmapPolicyFromControl.ts create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/PolicyAlerts.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/PolicyArchiveSheet.test.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/PolicyControlMappingConfirmDeleteModal.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/PolicyControlMappingModal.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/PolicyControlMappings.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/PolicyDeleteDialog.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/PolicyHeaderActions.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/PolicyPageTabs.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/PolicyVersionsTab.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/PublishVersionDialog.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/components/UpdatePolicyOverview.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/editor/components/PolicyDetails.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/hooks/useAuditLogs.ts create mode 100644 apps/app/src/app/(app)/[orgId]/policies/[policyId]/hooks/usePolicyVersions.ts create mode 100644 apps/app/src/app/(app)/[orgId]/policies/all/components/FullPolicyHeaderActions.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/policies/all/components/PolicyPageActions.test.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/policies/all/data/queries.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/policies/all/data/validations.ts create mode 100644 apps/app/src/app/(app)/[orgId]/policies/all/hooks/usePolicyActions.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/[questionnaireId]/data/queries.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/actions/create-trigger-token.ts create mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/hooks/useKnowledgeBaseDocView.ts create mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/hooks/useKnowledgeBaseDocs.ts create mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/hooks/useManualAnswers.ts create mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/hooks/useQuestionnaires.ts create mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/hooks/useSOADocument.ts create mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/knowledge-base/additional-documents/components/AdditionalDocumentsSection.test.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/knowledge-base/data/queries.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/knowledge-base/manual-answers/actions/save-manual-answer.ts create mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/layout.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/soa/components/CreateSOADocument.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/soa/components/SOAMobileRow.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/start_page/actions/delete-questionnaire.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/questionnaire/start_page/data/queries.ts create mode 100644 apps/app/src/app/(app)/[orgId]/risk/(overview)/RisksTable.test.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/risk/(overview)/actions/get-risks-action.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/risk/(overview)/data/getRisks.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/risk/(overview)/data/validations.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/risk/[riskId]/actions/regenerate-risk-mitigation.ts create mode 100644 apps/app/src/app/(app)/[orgId]/risk/[riskId]/components/RiskActions.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/risk/[riskId]/components/RiskPageClient.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/risk/layout.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/security/penetration-tests/actions/billing.ts create mode 100644 apps/app/src/app/(app)/[orgId]/settings/api-keys/components/table/ApiKeysTable.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/api-keys/components/table/CreateApiKeySheet.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/api-keys/components/table/CreateApiKeySheet.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/api-keys/components/table/ScopeSelector.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/api-keys/lib/scope-presets.ts create mode 100644 apps/app/src/app/(app)/[orgId]/settings/billing/billing-actions.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/browser-connection/components/BrowserConnectionClient.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/components/SettingsTabs.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/context-hub/ContextTable.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/context-hub/components/context-form.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/context-hub/components/context-list.test.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/settings/context-hub/data/getContextEntries.ts create mode 100644 apps/app/src/app/(app)/[orgId]/settings/context-hub/hooks/useContextEntries.ts create mode 100644 apps/app/src/app/(app)/[orgId]/settings/notifications/components/RoleNotificationSettings.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/notifications/components/RoleNotificationSettings.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/notifications/data/getRoleNotificationSettings.ts create mode 100644 apps/app/src/app/(app)/[orgId]/settings/notifications/hooks/useRoleNotifications.ts create mode 100644 apps/app/src/app/(app)/[orgId]/settings/notifications/loading.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/notifications/page.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/portal/portal-settings.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/[roleId]/components/EditRolePageClient.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/[roleId]/loading.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/[roleId]/page.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/components/PermissionMatrix.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/components/PermissionMatrix.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/components/RoleForm.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/components/RoleForm.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/components/RolesPageClient.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/components/RolesTable.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/components/RolesTable.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/components/SystemRoles.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/constants/system-roles.ts create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/hooks/useRole.ts create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/hooks/useRoles.ts create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/loading.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/new/components/NewRoleForm.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/new/loading.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/new/page.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/page.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/system/[roleName]/page.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/roles/system/[roleName]/system-role-detail.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/secrets/components/AddSecretDialog.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/secrets/components/EditSecretDialog.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/secrets/components/table/SecretsTable.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/settings/secrets/hooks/useSecrets.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/settings/user/actions/update-email-preferences.ts create mode 100644 apps/app/src/app/(app)/[orgId]/settings/user/hooks/useEmailPreferences.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/actions.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/actions/delete-task.ts create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/SingleTask.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/TaskPropertiesSidebar.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/browser-automations/BrowserAutomationsList.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/findings/CreateFindingSheet.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/findings/FindingsList.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/hooks/useIntegrationChecks.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/tasks/actions/deleteTaskAttachment.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/tasks/actions/getTaskAttachmentUrl.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/tasks/actions/updateTask.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/tasks/actions/updateTaskOrder.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/tasks/actions/updateTaskStatus.ts create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/components/ModernSingleStatusTaskList.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/components/TasksPageClient.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/hooks/useTasks.ts create mode 100644 apps/app/src/app/(app)/[orgId]/trust/components/approve-dialog.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/components/deny-dialog.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/components/revoke-dialog.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/layout.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/actions/custom-domain.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/actions/custom-links.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/actions/trust-portal-switch.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/actions/update-allowed-domains.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/actions/update-trust-favicon.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/actions/update-trust-overview.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/actions/update-trust-portal-faqs.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/actions/update-trust-portal-frameworks.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/actions/vendor-settings.ts create mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/AllowedDomainsManager.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/BrandSettings.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalAdditionalDocumentsSection.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalCustomLinks.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalDomain.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalFaqBuilder.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalOverview.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalSwitch.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/TrustPortalVendors.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/portal-settings/components/UpdateTrustFavicon.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/trust/settings/components/TrustSettingsClient.test.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/(overview)/actions/deleteVendor.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/(overview)/actions/get-vendors-action.ts create mode 100644 apps/app/src/app/(app)/[orgId]/vendors/(overview)/components/VendorsTable.test.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/(overview)/data/queries.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/(overview)/data/validations.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/actions/regenerate-vendor-mitigation.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/actions/task/create-task-action.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/actions/task/revalidate-upload.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/actions/task/update-task-action.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/actions/trigger-vendor-risk-assessment.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/actions/update-vendor-inherent-risk.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/actions/update-vendor-residual-risk.ts create mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/components/VendorActions.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/components/VendorInherentRiskChart.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/components/VendorPageClient.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/components/VendorResidualRiskChart.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/components/tasks/create-vendor-task-form.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/forms/risks/InherentRiskForm.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/vendors/[vendorId]/forms/risks/ResidualRiskForm.test.tsx delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/actions/create-vendor-action.ts delete mode 100644 apps/app/src/app/(app)/[orgId]/vendors/actions/search-global-vendors-action.ts create mode 100644 apps/app/src/app/(app)/[orgId]/vendors/components/create-vendor-sheet.test.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/vendors/layout.tsx delete mode 100644 apps/app/src/app/api/automations/[automationId]/runs/route.ts delete mode 100644 apps/app/src/app/api/chat/route.ts delete mode 100644 apps/app/src/app/api/cloud-tests/findings/route.ts create mode 100644 apps/app/src/app/api/cloud-tests/legacy-scan/route.ts delete mode 100644 apps/app/src/app/api/cloud-tests/providers/route.ts create mode 100644 apps/app/src/app/api/email-preferences/route.ts delete mode 100644 apps/app/src/app/api/frameworks/route.ts rename apps/app/src/app/{(app)/[orgId]/integrations/actions/get-relevant-tasks.ts => api/integrations/relevant-tasks/route.ts} (60%) create mode 100644 apps/app/src/app/api/invitations/[id]/route.test.ts create mode 100644 apps/app/src/app/api/people/invite/route.test.ts create mode 100644 apps/app/src/app/api/people/invite/route.ts create mode 100644 apps/app/src/app/api/policies/publish-all/route.ts create mode 100644 apps/app/src/app/api/questionnaire/trigger-token/route.ts create mode 100644 apps/app/src/app/api/risks/[riskId]/regenerate-mitigation/route.ts delete mode 100644 apps/app/src/app/api/secrets/[id]/route.ts delete mode 100644 apps/app/src/app/api/secrets/route.ts create mode 100644 apps/app/src/app/api/training/certificate/route.ts create mode 100644 apps/app/src/app/api/vendors/[vendorId]/regenerate-mitigation/route.ts create mode 100644 apps/app/src/app/api/vendors/research/route.ts delete mode 100644 apps/app/src/app/unsubscribe/preferences/actions/update-preferences.ts create mode 100644 apps/app/src/components/RecentAuditLogs.tsx create mode 100644 apps/app/src/components/ai-elements/code-block.tsx create mode 100644 apps/app/src/components/ai-elements/conversation.tsx create mode 100644 apps/app/src/components/ai-elements/message.tsx create mode 100644 apps/app/src/components/ai-elements/prompt-input.tsx create mode 100644 apps/app/src/components/ai-elements/reasoning.tsx create mode 100644 apps/app/src/components/ai-elements/shimmer.tsx create mode 100644 apps/app/src/components/ai-elements/tool.tsx delete mode 100644 apps/app/src/components/ai/chat-avatar.tsx delete mode 100644 apps/app/src/components/ai/chat-empty.tsx delete mode 100644 apps/app/src/components/ai/chat-text-area.tsx delete mode 100644 apps/app/src/components/ai/icons.tsx delete mode 100644 apps/app/src/components/ai/markdown.tsx delete mode 100644 apps/app/src/components/ai/message.tsx delete mode 100644 apps/app/src/components/ai/messages.tsx delete mode 100644 apps/app/src/components/ai/risk-display.tsx delete mode 100644 apps/app/src/components/auth/jwt-token-manager.tsx create mode 100644 apps/app/src/components/forms/organization/delete-organization.test.tsx create mode 100644 apps/app/src/components/forms/organization/transfer-ownership.test.tsx create mode 100644 apps/app/src/components/forms/organization/update-organization-advanced-mode.test.tsx create mode 100644 apps/app/src/components/forms/organization/update-organization-evidence-approval.test.tsx create mode 100644 apps/app/src/components/forms/organization/update-organization-logo.test.tsx create mode 100644 apps/app/src/components/forms/organization/update-organization-name.test.tsx create mode 100644 apps/app/src/components/forms/organization/update-organization-website.test.tsx create mode 100644 apps/app/src/components/forms/policies/create-new-policy.test.tsx create mode 100644 apps/app/src/components/forms/policies/policy-overview.test.tsx create mode 100644 apps/app/src/components/forms/policies/update-policy-form.test.tsx create mode 100644 apps/app/src/components/forms/risks/create-risk-form.test.tsx create mode 100644 apps/app/src/components/forms/risks/risk-overview.test.tsx create mode 100644 apps/app/src/components/forms/risks/task/update-task-form.test.tsx create mode 100644 apps/app/src/components/forms/risks/update-risk-form.test.tsx create mode 100644 apps/app/src/components/integrations/ConnectIntegrationDialog.test.tsx create mode 100644 apps/app/src/components/risks/charts/InherentRiskChart.test.tsx create mode 100644 apps/app/src/components/risks/charts/ResidualRiskChart.test.tsx create mode 100644 apps/app/src/components/risks/risk-overview.test.tsx create mode 100644 apps/app/src/components/sheets/create-risk-sheet.test.tsx create mode 100644 apps/app/src/components/task-items/TaskItemCreateDialog.test.tsx create mode 100644 apps/app/src/components/task-items/TaskItemFocusView.test.tsx create mode 100644 apps/app/src/components/task-items/TaskItemItem.test.tsx delete mode 100644 apps/app/src/components/task-items/TaskItemPagination.tsx delete mode 100644 apps/app/src/components/task-items/TaskItemsBody.tsx delete mode 100644 apps/app/src/components/task-items/TaskItemsContent.tsx delete mode 100644 apps/app/src/components/task-items/TaskItemsFilters.tsx create mode 100644 apps/app/src/components/task-items/TaskItemsHeader.test.tsx delete mode 100644 apps/app/src/components/task-items/TaskItemsInline.tsx create mode 100644 apps/app/src/components/task-items/TaskSmartForm.test.tsx delete mode 100644 apps/app/src/data/getOrganizations.ts delete mode 100644 apps/app/src/data/tools/index.ts delete mode 100644 apps/app/src/data/tools/organization.ts delete mode 100644 apps/app/src/data/tools/policies.ts delete mode 100644 apps/app/src/data/tools/risks-tool.ts delete mode 100644 apps/app/src/data/tools/user.ts create mode 100644 apps/app/src/hooks/use-attachments.ts create mode 100644 apps/app/src/hooks/use-audit-logs.ts create mode 100644 apps/app/src/hooks/use-organization-mutations.ts create mode 100644 apps/app/src/hooks/use-permissions.ts create mode 100644 apps/app/src/hooks/use-policy-mutations.ts create mode 100644 apps/app/src/hooks/use-risk-mutations.ts delete mode 100644 apps/app/src/hooks/use-scroll-to-bottom.ts delete mode 100644 apps/app/src/hooks/use-streamable-text.tsx create mode 100644 apps/app/src/hooks/use-task-mutations.ts create mode 100644 apps/app/src/hooks/use-trust-portal-custom-links.ts create mode 100644 apps/app/src/hooks/use-trust-portal-documents.ts create mode 100644 apps/app/src/hooks/use-trust-portal-settings.ts delete mode 100644 apps/app/src/hooks/use-users.ts create mode 100644 apps/app/src/lib/api-server.ts create mode 100644 apps/app/src/lib/compliance.ts create mode 100644 apps/app/src/lib/permissions.server.ts create mode 100644 apps/app/src/lib/permissions.test.ts create mode 100644 apps/app/src/lib/permissions.ts create mode 100644 apps/app/src/test-utils/mocks/permissions.ts create mode 100644 apps/app/src/utils/auth.test.ts delete mode 100644 apps/app/src/utils/jwt-manager.ts create mode 100644 apps/app/vitest.config.mjs delete mode 100644 apps/portal/src/app/(app)/(home)/actions/getPolicyPdfUrl.ts delete mode 100644 apps/portal/src/app/(app)/(home)/actions/markPolicyAsCompleted.ts delete mode 100644 apps/portal/src/app/(app)/(home)/actions/markVideoAsCompleted.ts delete mode 100644 apps/portal/src/app/actions/login.ts delete mode 100644 apps/portal/src/app/actions/logout.ts create mode 100644 apps/portal/src/app/api/portal/accept-policies/route.ts create mode 100644 apps/portal/src/app/api/portal/mark-policy-completed/route.ts create mode 100644 apps/portal/src/app/api/portal/mark-video-completed/route.ts create mode 100644 apps/portal/src/app/api/portal/policy-pdf-url/route.ts create mode 100644 packages/auth/package.json create mode 100644 packages/auth/src/index.ts create mode 100644 packages/auth/src/permissions.ts create mode 100644 packages/auth/src/server.ts create mode 100644 packages/auth/tsconfig.json create mode 100644 packages/db/prisma/migrations/20260305100001_add_policy_visibility/migration.sql create mode 100644 packages/db/prisma/migrations/20260305100002_add_organization_role_table_for_dynamic_roles/migration.sql create mode 100644 packages/db/prisma/migrations/20260305100003_role_based_notifications/migration.sql create mode 100644 packages/db/prisma/migrations/20260305100004_add_jwks_expires_at/migration.sql create mode 100644 packages/db/prisma/migrations/20260305100005_change_organization_role_permissions_to_text/migration.sql create mode 100644 packages/db/prisma/migrations/20260305100006_add_api_key_scopes/migration.sql create mode 100644 packages/db/prisma/migrations/20260305100007_add_api_key_prefix/migration.sql create mode 100644 packages/db/prisma/schema/notification-policy.prisma diff --git a/.claude/commands/audit-design-system.md b/.claude/commands/audit-design-system.md new file mode 100644 index 0000000000..0bffe84dca --- /dev/null +++ b/.claude/commands/audit-design-system.md @@ -0,0 +1,61 @@ +# Audit & Fix Design System Usage + +Audit the specified files or directories for proper design system usage. **Fix every issue found immediately.** + +## Key Concept + +The design system is **`@trycompai/design-system`** — an external npm package. It is the **single source of truth** for all UI components. + +**`@comp/ui` is the OLD component library** being phased out. It should ONLY be used as a last resort when there is absolutely no equivalent in `@trycompai/design-system`. + +## Rules + +### 1. Always check `@trycompai/design-system` first + +For every `@comp/ui` import you find: +1. Check if the component exists in `@trycompai/design-system` by looking at the package exports +2. If it exists → **migrate immediately** +3. Only if there is absolutely NO equivalent in the design system should `@comp/ui` remain + +Do NOT maintain a hardcoded list — **always check the actual DS package exports** to see what's available. The DS is actively growing and may have new components. + +### 2. Use DS primitives for layout, text, and spacing + +- **Pages**: Use `PageLayout` and `PageHeader` — not custom `
` wrappers +- **Spacing/Layout**: Use `Stack` (vertical), `HStack` (horizontal), `Grid` — not `
` +- **Text**: Use `Text` with `size`, `weight`, `variant` props — not raw `

`, ``, or `

` with Tailwind text classes +- **Sections**: Use `Section` with `title`/`description` — not custom card/header combos +- **Settings**: Use `SettingGroup` and `SettingRow` for settings pages +- **Empty states**: Use `Empty`, `EmptyHeader`, `EmptyTitle`, `EmptyDescription` +- **Tables**: Use DS `Table` with `variant="bordered"` for data tables +- **Icons**: Use `@trycompai/design-system/icons` — not `lucide-react` or `@carbon/icons-react` + +### 3. DS component constraints + +These `@trycompai/design-system` components do **NOT** accept `className`: +- `Text` — wrap in `
` if custom styling needed +- `Stack`, `HStack` — wrap in `
` if custom styling needed +- `Badge` — wrap in `
` if custom styling needed +- `Button` — use `variant`/`size` props; wrap in `
` for positioning + +If you see `className` passed to any of these, **fix it by wrapping in a div**. + +### 4. Component patterns + +- **Sheet**: `Sheet > SheetContent > SheetHeader + SheetBody` +- **Drawer**: `Drawer > DrawerContent > DrawerHeader > DrawerTitle` +- **Collapsible**: `Collapsible > CollapsibleTrigger + CollapsibleContent` + +## Process + +1. Read every file in the target path +2. For every `@comp/ui` import, check the `@trycompai/design-system` package to see if an equivalent exists +3. **If yes**: Change the import and update any incompatible props +4. Look for raw HTML layout patterns (`
`, `

`) that should use DS primitives (`Stack`, `Text`, etc.) +5. Check for `className` on DS components that don't support it — **wrap in div** +6. After all fixes, run `bun run --filter '@comp/app' build` to verify +7. Report a summary of what was migrated/fixed + +## Target + +$ARGUMENTS diff --git a/.claude/commands/audit-hooks.md b/.claude/commands/audit-hooks.md new file mode 100644 index 0000000000..479dabd26e --- /dev/null +++ b/.claude/commands/audit-hooks.md @@ -0,0 +1,37 @@ +# Audit & Fix Hooks / API Usage + +Audit the specified files or directories for proper hook and API usage patterns. **Fix every issue found immediately.** + +## Forbidden Patterns (fix on sight) + +1. **`useAction` from `next-safe-action`** — Replace with a custom SWR hook or `useOrganizationMutations`/`usePolicyMutations`/etc. that calls `apiClient` directly +2. **Server actions that mutate via `@db`** — Delete the server action and ensure the component uses an API hook instead. Read-only server actions are OK temporarily. +3. **Direct `@db` access in client components** — Replace with `apiClient` call via a hook +4. **Direct `@db` access in Next.js pages for mutations** — Replace with `serverApi` call +5. **Raw `fetch()` without `credentials: 'include'`** — Replace with `apiClient` +6. **`apiClient` with third argument** (e.g., `apiClient.post(url, body, orgId)`) — Remove the third arg. Org context comes from session cookies. + +## Required Patterns (add if missing) + +1. **Data fetching in client components**: Must use `useSWR` with `apiClient` or a custom hook (e.g., `useTask`, `usePolicy`) +2. **Mutations in client components**: Must use custom hooks wrapping `apiClient` (e.g., `useOrganizationMutations`, `useRiskActions`) +3. **Data fetching in server components**: Must use `serverApi` from `apps/app/src/lib/api-server.ts` +4. **SWR hooks**: Use `fallbackData` for SSR initial data, `revalidateOnMount: !initialData` +5. **API response handling**: Lists = `response.data.data`, single resources = `response.data` +6. **`useSWR` `mutate()` safety**: Guard against undefined in optimistic updaters +7. **`Array.isArray()` checks**: When consuming data from SWR that could be stale + +## Process + +1. Read every file in the target path +2. Search for forbidden patterns (`useAction`, `@db` imports in client code, raw `fetch`, server action imports) +3. **Fix each issue immediately**: + - If `useAction` → create or use an existing API hook, remove server action import + - If raw `apiClient` in component → move to a hook if it's a repeated pattern + - If `@db` in client/page mutation → replace with `serverApi` or `apiClient` hook +4. After all fixes, run `bun run --filter '@comp/app' build` to verify +5. Report a summary of what was fixed + +## Target + +$ARGUMENTS diff --git a/.claude/commands/audit-rbac.md b/.claude/commands/audit-rbac.md new file mode 100644 index 0000000000..c042dd50bd --- /dev/null +++ b/.claude/commands/audit-rbac.md @@ -0,0 +1,50 @@ +# Audit & Fix RBAC / Audit Logs + +Audit the specified files or directories for RBAC and audit log compliance. **Fix every issue found immediately.** + +## Rules + +### API Endpoints (NestJS — `apps/api/src/`) +1. **Every mutation endpoint** (POST, PATCH, PUT, DELETE) MUST have `@RequirePermission('resource', 'action')`. If missing, **add it**. +2. **Read endpoints** (GET) should have `@RequirePermission('resource', 'read')`. If missing, **add it**. +3. **Self-endpoints** (e.g., `/me/preferences`) may skip `@RequirePermission` — authentication via `HybridAuthGuard` is sufficient. +4. **Controller format**: Must use `@Controller({ path: 'name', version: '1' })`, NOT `@Controller('v1/name')`. If wrong, **fix it**. +5. **Guards**: Use `@UseGuards(HybridAuthGuard, PermissionGuard)` at controller or endpoint level. Never skip PermissionGuard. +6. **Webhooks**: External webhook endpoints use `@Public()` — no auth required. + +### Frontend Components (`apps/app/src/`) +1. **Every mutation element** (button, form submit, toggle, switch, file upload) MUST be gated with `usePermissions` from `@/hooks/use-permissions`. If not: + - **Create/Add buttons**: **Wrap** with `{hasPermission('resource', 'create') &&