Skip to content

Mariano/stuff#55

Merged
Marfuen merged 8 commits into
mainfrom
mariano/stuff
Feb 17, 2025
Merged

Mariano/stuff#55
Marfuen merged 8 commits into
mainfrom
mariano/stuff

Conversation

@Marfuen
Copy link
Copy Markdown
Contributor

@Marfuen Marfuen commented Feb 17, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced control details, framework overviews, and compliance dashboards for improved data visibility.
    • New page flows ensure organization categories are established before frameworks and policies, simplifying management.
    • Expanded policy documents deliver clearer, more specific guidelines across multiple compliance areas.
    • Improved navigation and interactivity streamline the overall user experience.
  • Style

    • Refined, centered layouts across dashboards, integrations, and settings offer a more balanced visual presentation.

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 17, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
app ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 17, 2025 8:34pm
web ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 17, 2025 8:34pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 17, 2025

Walkthrough

This pull request reorganizes the creation and retrieval processes for organization categories, frameworks, and controls. It introduces new functions and React hooks to fetch server data, refactors page components to utilize these hooks instead of pre-fetched props, and simplifies queries by including related controls directly. Several layout components have been updated for consistent centering, and updates to database schema and migrations add an OrganizationCategory table with associated foreign key constraints and indices. In addition, the PR refines type definitions in tables and expands JSON policy documents while deprecating outdated ones.

Changes

File(s) Change Summary
apps/app/src/actions/framework/select-frameworks-action.ts Introduced createOrganizationCategories; restructured flow to create categories first, then frameworks and policies; simplified framework category query by including controls.
apps/app/src/app/[locale]/(app)/(dashboard)/home/components/FrameworksOverview.tsx Removed isMutating variable from the useFrameworks hook destructuring.
apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/Actions/getOrganizationControl.ts,
.../Components/SingleControl.tsx,
.../hooks/useOrganizationControl.tsx,
.../controls/[id]/page.tsx
Added a server-side action to retrieve organization control data; introduced SingleControl component and custom hook (useOrganizationControl); created a dedicated page for rendering single control details.
apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/Actions/getOrganizationCategories.ts,
.../Actions/getOrganizationFramework.ts,
.../Components/FrameworkControls.tsx,
.../Components/FrameworkOverview.tsx,
.../hooks/useOrganizationCategories.ts,
.../hooks/useOrganizationFramework.ts,
.../frameworks/[frameworkId]/page.tsx
Added server actions, components, and hooks to fetch organization categories and framework data; refactored FrameworkOverview to use frameworkId prop and hooks for data fetching; removed legacy data fetching logic and metadata generation functions.
Multiple layout files in apps/app/src/app/[locale]/(app)/(dashboard)/ (e.g., integrations, policies, risk, risk/register, settings) Updated layout components by adding mx-auto to center content; included minor type signature adjustments in some components.
apps/app/src/components/tables/frameworks/columns.tsx,
apps/app/src/components/tables/frameworks/data-table.tsx
Renamed FrameworkControlType to OrganizationControlType; updated type definitions and modified rendering (e.g., adding navigation links) in table cells.
Files in packages/data/controls/ and packages/data/policies/ (e.g., soc2.json, access_control.json, business_continuity.json, etc.) Updated SOC 2 control descriptions and policy identifiers; introduced multiple new JSON policy documents; removed the deprecated access.json file.
Files in packages/db/prisma/ (migrations, schema.prisma, seed.ts, seedTypes.ts) Added a new OrganizationCategory table with associated columns and constraints; modified foreign keys and unique constraints; introduced a new non-nullable frameworkId column with a foreign key in OrganizationCategory; updated seed logic and type definitions for controls.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant SFA as selectFrameworksAction
    participant C as createOrganizationCategories
    participant F as Framework Creation
    participant P as Policies Creation

    U->>SFA: Initiate framework selection
    SFA->>C: Call createOrganizationCategories(user, frameworkIds)
    C-->>SFA: Categories created
    SFA->>F: Create frameworks (includes controls in query)
    F-->>SFA: Frameworks created
    SFA->>P: Create policies sequentially
    P-->>SFA: Policies created
    SFA-->>U: Operation complete
Loading
sequenceDiagram
    participant U as User
    participant SCP as SingleControlPage
    participant SC as SingleControl Component
    participant H as useOrganizationControl Hook
    participant GO as getOrganizationControl Action
    participant DB as Database

    U->>SCP: Navigate to control page (with controlId)
    SCP->>SC: Render SingleControl(controlId)
    SC->>H: Fetch control data via hook
    H->>GO: Call getOrganizationControl(controlId)
    GO->>DB: Query organization control data
    DB-->>GO: Return control data or error
    GO-->>H: Resolve with control data
    H-->>SC: Provide data, loading, error
    SC-->>U: Render control details or fallback
Loading

Possibly related PRs

  • add baseline migrations #48: Involves modifications to the Control table and new table relationships, with direct relevance to the schema and data handling changes in this PR.

Poem

I’m a bunny, hopping through code so bright,
Digging new paths in frameworks by day and night.
Categories bloom before controls take flight,
In a world of hooks and migrations, all shining light.
With each line and pull, my heart skips a beat 🐇💻,
Celebrating neat changes that make our code complete!
Hop on, dear friend — let’s code with delight!

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (23)
packages/data/policies/privacy.json (1)

145-149: "References" Section Heading
A heading for "References" is provided though no reference items are currently listed. If additional documentation or links are available, consider including them in this section.

packages/data/policies/confidentiality.json (1)

251-303: Robust Access Control Measures
The ordered list here clearly describes the access control measures, emphasizing principles like least privilege and multi-factor authentication. As an enhancement, consider adding a note on periodic reviews of access control practices to keep them up to date.

apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/page.tsx (1)

23-23: Redirect logic might benefit from a fallback or user message.
Redirecting to the homepage if frameworkId is missing prevents the user from understanding why they were redirected. Consider providing a friendly message or a dedicated error page to improve UX.

apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/Components/FrameworkOverview.tsx (2)

25-25: Avoid console logs in production code.
Leaving development logs in shipped code can clutter console output. Consider removing or using a logging utility with log levels.

-  console.log({ data });

48-48: Double chaining on framework?.framework may obscure readability.
If the double nesting is intentional, it's fine. Otherwise, consider flattening the data structure or clarifying naming for clarity.

apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/hooks/useOrganizationFramework.ts (2)

14-21: Improve error messages for better debugging.

The error messages could be more specific to help with debugging.

Apply this diff to improve error messages:

-    throw new Error("Failed to fetch frameworks");
+    throw new Error(`Failed to fetch framework with ID: ${frameworkId}`);
   }

   const data = result.data?.data;
   if (!data) {
-    throw new Error("Invalid response from server");
+    throw new Error(`Server response missing data for framework ID: ${frameworkId}`);
   }

4-7: Use import type for type imports.

The FrameworkWithControls import is only used as a type and should be marked with import type.

Apply this diff to fix the imports:

 import useSWR from "swr";
-import {
-  FrameworkWithControls,
+import type {
+  FrameworkWithControls,
+} from "../Actions/getOrganizationFramework";
+import {
   getOrganizationFramework,
 } from "../Actions/getOrganizationFramework";
🧰 Tools
🪛 Biome (1.9.4)

[error] 4-7: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Add inline type keywords.

(lint/style/useImportType)

apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/hooks/useOrganizationControl.tsx (2)

15-22: Improve error messages for better debugging.

The error messages could be more specific to help with debugging.

Apply this diff to improve error messages:

-    throw new Error("Failed to fetch control");
+    throw new Error(`Failed to fetch control with ID: ${controlId}`);
   }

   const data = result.data?.data;
   if (!data) {
-    throw new Error("Invalid response from server");
+    throw new Error(`Server response missing data for control ID: ${controlId}`);
   }

3-8: Use import type for type imports.

The OrganizationControl and OrganizationControlResponse imports are only used as types and should be marked with import type.

Apply this diff to fix the imports:

-import { OrganizationControl } from "@bubba/db";
+import type { OrganizationControl } from "@bubba/db";
 import useSWR from "swr";
-import {
-  getOrganizationControl,
-  OrganizationControlResponse,
+import type {
+  OrganizationControlResponse,
+} from "../Actions/getOrganizationControl";
+import {
+  getOrganizationControl,
 } from "../Actions/getOrganizationControl";
🧰 Tools
🪛 Biome (1.9.4)

[error] 5-8: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Add inline type keywords.

(lint/style/useImportType)

apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/hooks/useOrganizationCategories.ts (2)

14-14: Remove debug log statement.

The console.log statement should be removed before merging to production.

-  console.log({ result });

16-18: Update error message for clarity.

The error message mentions "frameworks" but the function fetches organization categories.

-    throw new Error("Failed to fetch frameworks");
+    throw new Error("Failed to fetch organization categories");
apps/app/src/components/tables/frameworks/columns.tsx (1)

32-40: Consider adding aria-label for accessibility.

The Link component should have an aria-label to improve accessibility for screen readers.

   <Link
     href={`/controls/${row.original.id}`}
     className="flex flex-col"
+    aria-label={`View details for control ${row.original.name}`}
   >
apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/Components/FrameworkControls.tsx (1)

35-49: Enhance accessibility for the controls list.

The controls list should have proper ARIA attributes and semantic structure.

-        {organizationCategories.map((category) => (
+        {organizationCategories.map((category, index) => (
           <div key={category.id} className="mb-8">
-            <h3 className="text-lg font-semibold mb-4">{category.name}</h3>
+            <h3 
+              id={`category-${category.id}`}
+              className="text-lg font-semibold mb-4"
+            >
+              {category.name}
+            </h3>
             <DataTable
+              aria-labelledby={`category-${category.id}`}
               data={category.organizationControl.map((control) => ({
                 code: control.control.code,
                 description: control.control.description,
apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/Actions/getOrganizationFramework.ts (1)

64-69: Enhance error logging and error messages.

The error handling could be more specific to help with debugging and provide better user feedback.

     } catch (error) {
-      console.error("Error fetching framework:", error);
+      console.error("Error fetching framework:", {
+        error,
+        frameworkId,
+        organizationId: user.organizationId,
+      });
       return {
-        error: "Failed to fetch framework",
+        error: error instanceof Error 
+          ? `Failed to fetch framework: ${error.message}`
+          : "Failed to fetch framework",
       };
     }
apps/app/src/components/tables/frameworks/data-table.tsx (1)

18-25: Optimize table performance with memoization.

The table configuration and columns could be memoized to prevent unnecessary re-renders.

+import { useMemo } from "react";

 export function DataTable({ data }: DataTableProps) {
-  const columns = getColumns();
+  const columns = useMemo(() => getColumns(), []);
 
-  const table = useReactTable({
+  const table = useMemo(() => useReactTable({
     data: data,
     columns,
     getCoreRowModel: getCoreRowModel(),
-  });
+  }), [data, columns]);
apps/app/src/actions/framework/select-frameworks-action.ts (1)

37-41: Consider sequential framework creation for better error handling.

Using Promise.all for framework creation could mask errors if multiple frameworks fail. Consider sequential creation for better error tracking and debugging.

-     await Promise.all(
-       frameworkIds.map((frameworkId) =>
-         createOrganizationFramework(user as User, frameworkId)
-       )
-     );
+     for (const frameworkId of frameworkIds) {
+       await createOrganizationFramework(user as User, frameworkId);
+     }
packages/db/prisma/seed.ts (1)

17-33: Consider environment-based cleanup strategy.

Instead of commenting out cleanup code, consider making it configurable based on environment variables. This allows for flexible seeding strategies in different environments.

+const CLEAN_BEFORE_SEED = process.env.CLEAN_BEFORE_SEED === 'true';

async function main() {
-  // console.log("\n🗑️  Cleaning up existing data...");
-  // Delete in order of dependencies
-  // await prisma.organizationFramework.deleteMany();
+  if (CLEAN_BEFORE_SEED) {
+    console.log("\n🗑️  Cleaning up existing data...");
+    // Delete in order of dependencies
+    await prisma.organizationFramework.deleteMany();
    // ... rest of cleanup code
+    console.log("✅ Database cleaned");
+  }
packages/db/prisma/migrations/20250212204100_add_organization_category_table/migration.sql (1)

4-15: New Table Creation: OrganizationCategory
The new table is defined with essential columns and a primary key on id. Note that while createdAt has a default value, updatedAt does not—ensure that your application logic handles updates to this field appropriately. Also, review whether the absence of a NOT NULL constraint on description meets your business requirements.

packages/data/policies/workstation.json (1)

72-371: Comprehensive Content Organization in Policy Sections
The remaining sections—from the "Purpose and Scope" (starting around line 72) through to the detailed policy requirements for workstation devices, desktop & laptop devices, mobile devices, and removable media—are clearly organized using ordered lists and hierarchical headings. The content is comprehensive and adheres to a consistent format. As a future enhancement, consider including versioning or last-update metadata directly in the document to support change tracking.

packages/data/policies/data_center.json (1)

74-358: Detailed Policy Content and Sectioning
The document continues with clearly delineated sections covering "Purpose and Scope", "Datacenter Security Requirements", "Environmental Controls", "Datacenter Access and Auditing", and "Disaster Recovery and Business Continuity". Each ordered list effectively summarizes the requirements. For future iterations, you might consider adding a revision history or version field in the metadata to help with tracking updates.

apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/Actions/getOrganizationControl.ts (3)

3-3: Use import type for type-only imports.

Since OrganizationControl and Control are only used as types, they should be imported using the import type syntax to ensure proper tree-shaking.

Apply this diff to optimize the imports:

-import { db, OrganizationControl, Control } from "@bubba/db";
+import { db } from "@bubba/db";
+import type { OrganizationControl, Control } from "@bubba/db";
🧰 Tools
🪛 Biome (1.9.4)

[error] 3-3: Some named imports are only used as types.

This import is only used as a type.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Add inline type keywords.

(lint/style/useImportType)


26-30: Enhance the error message for better clarity.

The current error message could be more specific about why the authorization failed.

Apply this diff to improve the error message:

-        error: "Not authorized - no organization found",
+        error: "User is not associated with any organization. Please ensure you are part of an organization to access controls.",

54-59: Enhance error handling with more specific error messages.

While the error handling catches and logs errors, it returns a generic message. Consider categorizing errors and providing more specific messages to help with debugging and user experience.

Apply this diff to improve error handling:

     } catch (error) {
       console.error("Error fetching organization control:", error);
+      if (error instanceof Error) {
+        return {
+          error: `Database operation failed: ${error.message}`,
+        };
+      }
       return {
         error: "Failed to fetch organization control",
       };
     }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec480f5 and 09b3d2c.

📒 Files selected for processing (53)
  • apps/app/src/actions/framework/select-frameworks-action.ts (3 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/(home)/components/FrameworksOverview.tsx (0 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/Actions/getOrganizationControl.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/Components/SingleControl.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/hooks/useOrganizationControl.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/page.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/controls/page.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/Actions/getOrganizationCategories.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/Actions/getOrganizationFramework.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/Components/FrameworkControls.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/Components/FrameworkOverview.tsx (3 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/hooks/useOrganizationCategories.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/hooks/useOrganizationFramework.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/layout.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/page.tsx (2 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/integrations/page.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/layout.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/risk/(overview)/layout.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/risk/[riskId]/layout.tsx (2 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/risk/register/layout.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/settings/layout.tsx (1 hunks)
  • apps/app/src/components/frameworks/framework-controls.tsx (0 hunks)
  • apps/app/src/components/tables/frameworks/columns.tsx (2 hunks)
  • apps/app/src/components/tables/frameworks/data-table.tsx (2 hunks)
  • packages/data/controls/soc2.json (43 hunks)
  • packages/data/policies/access.json (0 hunks)
  • packages/data/policies/access_control.json (1 hunks)
  • packages/data/policies/business_continuity.json (1 hunks)
  • packages/data/policies/change_management.json (1 hunks)
  • packages/data/policies/code_of_conduct.json (1 hunks)
  • packages/data/policies/confidentiality.json (1 hunks)
  • packages/data/policies/corporate_governance.json (1 hunks)
  • packages/data/policies/cyber_risk.json (1 hunks)
  • packages/data/policies/data_center.json (1 hunks)
  • packages/data/policies/data_classification.json (1 hunks)
  • packages/data/policies/disaster_recovery.json (1 hunks)
  • packages/data/policies/human_resources.json (1 hunks)
  • packages/data/policies/incident_response.json (1 hunks)
  • packages/data/policies/information_security.json (1 hunks)
  • packages/data/policies/privacy.json (1 hunks)
  • packages/data/policies/risk_assessment.json (1 hunks)
  • packages/data/policies/risk_management.json (1 hunks)
  • packages/data/policies/software_development.json (1 hunks)
  • packages/data/policies/thirdparty.json (1 hunks)
  • packages/data/policies/vendor_risk_management.json (1 hunks)
  • packages/data/policies/workstation.json (1 hunks)
  • packages/db/prisma/migrations/20250212204100_add_organization_category_table/migration.sql (1 hunks)
  • packages/db/prisma/migrations/20250212205810_fix_unique_constraint/migration.sql (1 hunks)
  • packages/db/prisma/migrations/20250212210730_add_framework_id_to_org_cat/migration.sql (1 hunks)
  • packages/db/prisma/migrations/migration_lock.toml (1 hunks)
  • packages/db/prisma/schema.prisma (4 hunks)
  • packages/db/prisma/seed.ts (2 hunks)
  • packages/db/prisma/seedTypes.ts (1 hunks)
💤 Files with no reviewable changes (3)
  • packages/data/policies/access.json
  • apps/app/src/components/frameworks/framework-controls.tsx
  • apps/app/src/app/[locale]/(app)/(dashboard)/(home)/components/FrameworksOverview.tsx
✅ Files skipped from review due to trivial changes (7)
  • packages/db/prisma/migrations/migration_lock.toml
  • apps/app/src/app/[locale]/(app)/(dashboard)/integrations/page.tsx
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/layout.tsx
  • apps/app/src/app/[locale]/(app)/(dashboard)/risk/(overview)/layout.tsx
  • apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/layout.tsx
  • apps/app/src/app/[locale]/(app)/(dashboard)/risk/[riskId]/layout.tsx
  • apps/app/src/app/[locale]/(app)/(dashboard)/risk/register/layout.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/hooks/useOrganizationCategories.ts

[error] 4-7: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Add inline type keywords.

(lint/style/useImportType)

apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/hooks/useOrganizationFramework.ts

[error] 4-7: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Add inline type keywords.

(lint/style/useImportType)

apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/Components/SingleControl.tsx

[error] 3-6: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Add inline type keywords.

(lint/style/useImportType)

apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/Actions/getOrganizationControl.ts

[error] 3-3: Some named imports are only used as types.

This import is only used as a type.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Add inline type keywords.

(lint/style/useImportType)

apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/hooks/useOrganizationControl.tsx

[error] 5-8: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Add inline type keywords.

(lint/style/useImportType)

🔇 Additional comments (137)
apps/app/src/app/[locale]/(app)/(dashboard)/settings/layout.tsx (2)

7-9: LGTM!

The type definition is correct and follows TypeScript best practices.


13-13: LGTM! Consistent horizontal centering.

The addition of mx-auto aligns with similar updates in other layout components, ensuring consistent horizontal centering across the application.

packages/data/policies/privacy.json (10)

1-11: Metadata Block is Well-Structured
The metadata section clearly defines essential document details such as the ID, slug, name, description, and compliance usage tags. Ensure that future changes (e.g., adding versioning or additional compliance tags) can be easily integrated.


12-17: Primary Heading for the Policy
The level‑1 heading "Privacy Policy" is clearly defined and sets the correct context for the document.


18-22: Subheading for Policy Information
The level‑2 heading "Policy Information" correctly introduces the section containing key policy metadata.


23-50: Table Header Structure Looks Correct
The table in this section neatly defines column headers ("Organization", "Last Review", "Review Frequency", "Approved By", "Classification"). Ensure the header labels align with any styling or documentation standards used elsewhere in your policies.


51-75: Table Data Row with Placeholders
The second table row uses placeholders (e.g., "{{organization}}" and "{{date}}"). Verify that these placeholders are correctly substituted at runtime or during rendering and that they match the expected data format.


78-82: "Purpose and Scope" Heading is Clear
The level‑2 heading "Purpose and Scope" is appropriately placed, setting up the next section's content.


83-91: Concise Policy Scope Description
The paragraph effectively outlines how personal data is managed, including collection, processing, retention, and disposal practices. This clarity is beneficial for compliance documentation.


92-96: "Policy" Section Heading is Appropriately Defined
The heading "Policy" (level‑2) properly introduces the specific guidelines that follow in the ordered list.


97-144: Ordered List of Policy Guidelines is Well-Formatted
The list items cover key privacy practices:

  • Obtaining explicit consent,
  • Limiting personal data collection,
  • Ensuring secure storage accessible only to authorized personnel.

Consider reviewing punctuation or adding clarifying details if needed in future policy revisions.


150-152: JSON Document Closure Check
The JSON document is properly closed with a matching curly brace. Ensure that any extraneous annotations (like dangling line numbers) are not included in the deployed file.

packages/data/policies/confidentiality.json (7)

1-6: Clear JSON Structure and Metadata Definition
The document begins with a well-formed JSON structure including a "type": "doc" and a "metadata" block with control identifiers. Make sure the control IDs (e.g., "CC9.9" and "CC6.1") are consistent with your regulatory or internal standards.


7-16: Effective Use of Headings for Policy Identification
The first two content objects define the policy title and the "Policy Information" section using appropriate heading levels. This clear hierarchical structure aids both rendering and readability.


17-73: Well-Structured Policy Information Table
The table clearly sets out key details: headers (Organization, Last Review, Review Frequency, Approved By, Classification) and a corresponding data row with placeholders (e.g., "{{organization}}" and "{{date}}"). Ensure that your templating or rendering system properly validates and substitutes these placeholders at runtime to prevent any potential display or data integrity issues.


74-125: Comprehensive 'Purpose and Scope' Section
The ordered list outlining the policy's purpose, applicability, and scope is clear and well-documented. The descriptive text effectively communicates who the policy applies to and what constitutes confidential information.


127-195: Detailed Guidelines for Confidential Information Handling
This section provides a thorough set of instructions on how confidential data should be handled. The guidelines on access restriction and encryption are concise and actionable. Consider verifying that these guidelines align with technical implementations elsewhere in your system.


196-250: Clear Non-Disclosure Agreement (NDA) Requirements
The NDA section succinctly states the requirements and expectations regarding NDAs, including the consequences for violations. Confirm that these guidelines are in sync with your organization’s legal policies.


304-344: Concise Incident Reporting and Enforcement Protocols
The final section on incident reporting effectively outlines both the process for reporting breaches and the potential disciplinary actions. This provides a clear guideline for enforcement.

packages/data/controls/soc2.json (13)

12-139: CC1 Updates – Control Environment Enhancements
The CC1.x controls (Board Oversight, Management Philosophy, Organizational Structure, Personnel Policies, and Code of Conduct) now have updated requirement descriptions and policy identifiers. In these segments, the descriptions have been refined to clearly reference the appropriate internal policies—such as "corporate_governance" and "human_resources"—and the procedure, training, and evidence sections have been expanded for clarity. Please verify that these updates align with your updated governance documents.


150-214: CC2 Updates – Communication Controls Refinement
In the CC2.x controls (Internal Communication and External Communication), the requirement descriptions and policyId values have been updated to explicitly reference policies (e.g., "corporate_governance" and "information_security") and to better articulate the procedures and evidence expectations. The improvements provide more direct guidance on internal reporting and external messaging.


225-291: CC3 Updates – Risk Assessment Process Improvements
The CC3.x controls now update the requirement descriptions and policyId fields to refer clearly to "risk_management". This update covers risk assessment methods, fraud risk assessments, and risk identification. The revised text improves precision regarding methodologies, documentation, and review processes. Ensure these changes are consistent with your risk management framework.


325-366: CC4 Updates – Monitoring Activity Enhancements
Within the CC4.x controls (Control Monitoring and Deficiency Management), the descriptions have been refined for clarity, and the associated policyId references (e.g., "information_security" and "risk_management") have been properly updated. The improved language should aid in understanding the procedures for control testing and deficiency remediation.


375-441: CC5 Updates – Strengthening Control Activities
The CC5.x blocks (Control Selection, Technology Controls, and Policy Implementation) now include more descriptive requirement texts. The updated policyId values (such as "information_security" and "corporate_governance") and revised procedure/evidence descriptions offer clearer insight into control design and implementation standards.


450-516: CC6 Updates – Access Control Improvements
For the CC6.x controls (spanning Access Security, Authentication, Account Management, Access Restrictions, and Removal), the requirement entries now feature refined descriptions and updated policyId values (for instance, "access_control" and "information_security"). These changes enhance clarity on how system access, de-provisioning, and account reviews should be managed.


645-766: CC7 Updates – Enhanced Security Event Management
The CC7.x controls (covering Infrastructure Monitoring, Security Event Response, Recovery, Analysis, and Communication) have been updated to reflect precise policies such as "information_security", "incident_response", and "business_continuity_dr". The improved descriptions clearly delineate responsibilities—from real‐time monitoring to post-incident analyses—ensuring alignment with incident management practices.


775-790: CC8.1 Update – Change Authorization Clarification
The Change Authorization control now features an updated description and policyId that reference the "change_management" policy. The procedures and evidence expectations are more clearly laid out, which should help in tracking and approving changes systematically.


800-866: CC9 Updates – Risk Mitigation and Business Continuity Enhancements
The CC9.x controls (including Business Continuity Planning, Vendor Risk Management, and Disaster Recovery Testing) have been refined. The wording now explicitly refers to appropriate policies such as "business_continuity_dr" and "vendor_risk_management", and the procedures and evidence sections are more detailed. These changes should support a more robust risk mitigation strategy.


873-941: A1 Updates – Availability Controls Refinement
The A1.x controls (Availability Commitments, Capacity Planning, and Incident Recovery) have been updated with improved descriptions and consistent references to the "availability" or "business_continuity_dr" policies. The revised text clearly establishes the expectations around monitoring uptime, resource management, and recovery processes.


949-1016: C1 Updates – Confidentiality Control Enhancements
Updates in the C1.x controls (Confidential Information Classification, Access Restrictions for Confidential Data, and Confidential Data Disposal) now clearly articulate the requirements with a specific reference to the "data_classification" policy. The improved descriptions for both procedures and evidence should help ensure that confidential information is handled in compliance with the new classification standards.


1024-1091: PI1 Updates – Processing Integrity Improvements
The PI1.x blocks (Accuracy and Completeness, Input/Output Controls, and Exception Handling) have been revised to reference the "information_security" policy more accurately. Enhanced descriptions in the procedure and evidence sections improve guidance on data validation and exception management, supporting robust processing integrity.


1099-1166: P1 Updates – Privacy Controls Enhancement
The P1.x controls (Privacy Notice, Choice and Consent, and Data Retention and Disposal) now include more precise requirement texts, with updated policyId values set to "privacy". The detailed descriptions for policies, procedures, and evidence provide clearer guidance on how personal data should be handled in accordance with privacy regulations.

apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/page.tsx (2)

4-5: Imports aligned with new component paths.
These imports reflect a reorganization of the framework components. The file paths appear correct and consistent with the updated folder structure.


29-30: Prop-based rendering simplifies the component.
Passing frameworkId directly to FrameworkOverview and FrameworkControls keeps the data flow simpler. Confirm that these child components handle missing or invalid IDs gracefully.

apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/Components/FrameworkOverview.tsx (9)

3-4: New hook-based imports are consistent with the updated approach.
Using useOrganizationCategories and useOrganizationFramework centralizes data fetching, improving maintainability.


18-18: Refined props keep the component focused.
Replacing multiple data props with a single frameworkId effectively decouples the component from implementation details.


21-23: Hooking into organization data.
Retrieving data directly in the component with useOrganizationCategories(frameworkId) and useOrganizationFramework(frameworkId) promotes a cleaner and more reactive code flow.


28-31: Ensure organization controls always exist when reducing.
The organizationControl array is assumed to be defined. If there's any chance it might be null or undefined, consider additional checks to avoid runtime errors.


33-38: Filtering for "compliant" status looks good.
This logic straightforwardly counts compliant controls. Ensure that the status property always contains expected values to avoid mismatches.


52-52: Description field usage looks fine.
No issues spotted here. Proceed as needed.


55-57: Displaying version with a badge.
This consistent approach for the framework version is clear and user-friendly.


86-87: Handling lastAssessed date.
Using date-fns to format the date is a solid choice. Ensure lastAssessed is always a valid Date if present.


95-96: Handling nextAssessment date.
Similar to lastAssessed, confirm the property is valid to avoid runtime errors if data is missing.

apps/app/src/app/[locale]/(app)/(dashboard)/controls/page.tsx (1)

1-3: New “Controls” page stub.
The basic return is fine for a placeholder. Consider adding a descriptive heading or user instructions once the page’s functionality expands.

apps/app/src/app/[locale]/(app)/(dashboard)/frameworks/[frameworkId]/hooks/useOrganizationCategories.ts (1)

28-46: LGTM! Well-structured hook implementation.

The hook implementation follows best practices:

  • Uses SWR for efficient data fetching and caching
  • Disables automatic revalidation appropriately
  • Returns all necessary states (data, loading, error, mutate)
apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/Components/SingleControl.tsx (1)

24-24:

Details

❓ Verification inconclusive

Verify type casting safety.

The type casting of status to StatusType might be unsafe. Consider adding validation or handling invalid status values.


🏁 Script executed:

#!/bin/bash
# Description: Check all possible status values in the codebase
# to ensure they match the StatusType enum

# Search for StatusType enum definition
echo "Searching for StatusType definition..."
ast-grep --pattern 'export type StatusType = $_;'

# Search for all status assignments in the codebase
echo "Searching for status assignments..."
rg -A 1 'status\s*=' --type ts --type tsx

Length of output: 972


Action Required: Verify the safety of the status type conversion in SingleControl.tsx

It appears that the StatusType enum is defined in several components (e.g., in apps/app/src/components/status.tsx, apps/app/src/components/policies/policy-status.tsx, and others). However, our initial search for status assignments was inconclusive because the command flagged an error with the file type (i.e., “unrecognized file type: tsx”). This means that although the cast

status={control?.status.toLowerCase() as StatusType}

appears to work syntactically, we cannot confirm from the automated search that every usage of control?.status indeed produces a string matching one of the allowed values in StatusType.

To ensure runtime safety, please verify that:

  • The value of control.status (after converting to lowercase) always matches one of the permitted values described by StatusType.
  • In cases where it might not match (or when control.status is undefined), appropriate error handling or a fallback is provided.

Consider:

  • Adding a type guard or explicit validation before casting to StatusType
  • Revising the RG search command (e.g., by using a glob pattern to include both .ts and .tsx files) so that the codebase can be thoroughly scanned for similar assignments.

Please review these considerations and update accordingly.

apps/app/src/components/tables/frameworks/columns.tsx (1)

54-54: Verify status type conversion.

Similar to the SingleControl component, the status type conversion should be validated.

packages/db/prisma/seed.ts (1)

191-193:

Details

❓ Verification inconclusive

Verify control filtering logic change.

The control filtering logic has been changed from checking if the control code includes the category code to checking if the control's categoryId matches the category code directly.


🏁 Script executed:

#!/bin/bash
# Check if any controls might be missed due to the new filtering logic
rg -A 5 '"categoryId":' data/controls/ | grep -B 5 '"code":'

Length of output: 117


Manual Verification Required: Control Filtering Logic Update

The change from a substring check to using a direct equality (data.categoryId === categoryCode) appears logically sound. However, our initial verification script did not produce output due to the non-existence of the referenced data/controls/ directory. Please verify manually with the actual dataset to ensure that the new filtering logic does not inadvertently exclude any controls that would have been included with the previous substring-based approach.

  • File: packages/db/prisma/seed.ts (lines 191-193)
  • Action: Manually confirm that all intended controls are correctly filtered with the equality check and that no controls are unintentionally missed.
packages/db/prisma/migrations/20250212205810_fix_unique_constraint/migration.sql (1)

1-11: Verify data integrity before applying migration.

The migration drops a composite unique constraint and adds a new one on the id column. Ensure there are no duplicate IDs in the existing data before applying this migration.

-- Run this query to check for duplicate IDs
SELECT id, COUNT(*) 
FROM "OrganizationCategory" 
GROUP BY id 
HAVING COUNT(*) > 1;
packages/db/prisma/migrations/20250212204100_add_organization_category_table/migration.sql (4)

1-3: Minor SQL Formatting and Nullability Check
The ALTER TABLE command correctly adds the new column organizationCategoryId with type TEXT (which allows NULLs). Verify that allowing NULL values is intentional, and consider removing extra spacing if it’s not stylistically required.


16-21: Index Creation for Data Integrity and Performance
The creation of a standard index on organizationId and a unique index on the combination of organizationId and name is appropriate for enforcing uniqueness and optimizing lookup queries. Confirm that these indices align with your anticipated query patterns.


22-24: Foreign Key Constraint on OrganizationControl
The foreign key constraint linking organizationCategoryId from OrganizationControl to OrganizationCategory(id) with ON DELETE SET NULL and ON UPDATE CASCADE is correctly implemented. Ensure that this cascading behavior is aligned with your application’s data integrity policies.


25-27: Foreign Key Constraint on OrganizationCategory
The addition of a foreign key constraint for organizationId in the OrganizationCategory table—with ON DELETE CASCADE and ON UPDATE CASCADE—is an effective approach to maintain referential integrity with the Organization table. Double-check that the cascading deletion is the desired behavior for your use case.

packages/data/policies/vendor_risk_management.json (1)

1-152: New Vendor Risk Management Policy Document
This JSON document is well-structured with clear metadata and content sections outlining the Vendor Risk Management Policy. Ensure that the placeholder values (e.g., {{organization}} and {{date}}) are correctly replaced at runtime, and that the policy details meet your regulatory and internal requirements.

packages/data/policies/incident_response.json (1)

1-152: New Incident Response Policy Document
The Incident Response Policy is comprehensively defined with appropriate metadata, headings, tables, and a detailed ordered list of response actions. Confirm that the outlined procedures fully address your incident management objectives and that runtime placeholders are handled correctly.

packages/data/policies/data_classification.json (1)

1-152: New Data Classification Policy Document
This new JSON file provides a clear framework for classifying data, including well-defined metadata and policy sections. Verify that the classification levels and the associated handling requirements are consistent with your overall data governance strategy and that dynamic placeholders will be populated as expected.

packages/data/policies/access_control.json (1)

1-152: New Access Control Policy Document
The Access Control Policy document is structured effectively with clear metadata, a detailed information table, and an ordered list outlining the access procedures. Ensure that the prescribed controls align with your security requirements and that any placeholder content is properly substituted in production.

packages/data/policies/change_management.json (7)

1-11: Metadata Section Looks Good:
The metadata block is well-structured with clearly defined keys such as "id", "slug", "name", "description", and "usedBy". This setup will help in consistent identification and rendering of the policy document.


12-17: Title Heading is Clear:
The level 1 heading clearly states the policy title ("Change Management Policy"), establishing immediate clarity about the document’s purpose.


18-22: Section Heading for Policy Information:
The level 2 heading "Policy Information" signals the start of detailed metadata content. This is consistent with expected documentation structure.


23-77: Structured Policy Information Table:
The table structure effectively organizes key policy details. The usage of templated placeholders like "{{organization}}" and "{{date}}" for dynamic insertion is consistent with other policy files.


78-91: Purpose and Scope Section is Well Defined:
The heading and accompanying paragraph clearly articulate the overall aim of the policy—managing changes to systems and infrastructure with review, approval, and documentation processes.


92-144: Policy Directives are Clear and Ordered:
The ordered list details the required steps (submission, review/approval, emergency change exceptions, and post-implementation reviews) effectively. This clarity supports compliance and operational consistency.


145-150: References Section is Prepared for Future Additions:
While the References section does not list specific references yet, its inclusion indicates a design for extensibility. Consider adding concrete references if available.

packages/data/policies/human_resources.json (6)

1-11: Human Resources Policy Metadata is Complete:
The metadata block correctly identifies the document with proper fields, including an appropriate "usedBy" mapping for SOC 2 (e.g., ["CC1.3", "CC1.4"]).


12-17: Title Heading Accurately Reflects Policy Focus:
The level 1 heading "Human Resources Policy" immediately communicates the document's subject matter.


18-22: Section Heading for Policy Information:
The level 2 heading "Policy Information" sets up the context for the table that follows, ensuring organized presentation of data.


23-77: Well-Formatted HR Policy Information Table:
The table is structured to include key cells such as "Organization", "Last Review", "Review Frequency", "Approved By", and "Classification" with appropriate templated values. The use of "HR Director" and "Internal" in the second row adds clarity.


78-91: Purpose and Scope Section Articulates Clear Objectives:
The paragraph succinctly explains the governance around recruitment, performance management, and accountability, aligning well with HR operational needs.


92-144: Detailed HR Policy Directives:
The ordered list of directives covers essential aspects such as background checks, internal control training, and performance evaluations. This section is comprehensive and clearly outlines responsibilities.

packages/data/policies/business_continuity.json (6)

1-11: Business Continuity Metadata is Well-Defined:
The metadata accurately identifies the document, including a descriptive "name", "slug", and "description", which clearly depict the policy’s intent for disaster recovery and system continuity.


12-22: Title and Policy Information Headings Established:
The level 1 heading and subsequent level 2 heading ("Policy Information") effectively frame the document, setting expectations for the detailed sections that follow.


29-84: Comprehensive Policy Information Table:
The table is neatly structured with two rows that provide both static labels and dynamic placeholders. Notably, the "Approved By" cell explicitly names the "IT & Business Continuity Committee", and the classification is marked as "Confidential", which aligns with the sensitive nature of the policy.


86-98: Purpose and Scope Statement is Clear:
The paragraph summarizing the goals of ensuring continuous operation and rapid recovery is concise and informative.


99-151: Detailed Continuity and Recovery Guidelines:
The policy directives in the ordered list cover critical aspects including the identification of essential functions, development and testing of recovery plans, and backup system requirements. This provides a robust framework for business continuity.


152-157: References Section Inclusion:
The References section is properly demarcated for future extension. It may be enhanced later with external references or related documentation.

packages/data/policies/risk_management.json (6)

1-11: Risk Management Metadata is Complete:
All essential fields—such as "id", "slug", "name", and "description"—are present. The "usedBy" array correctly maps SOC 2 controls, ensuring regulatory alignment.


12-22: Document Title and Policy Information Heading:
The level 1 and level 2 headings set a clear context for the risk management framework, ensuring users understand the policy’s focus.


23-77: Well-Structured Policy Information Table:
The table organizes key details using standard cells and placeholders ("{{organization}}", "{{date}}"). This consistency aids in dynamic content rendering across policy documents.


78-91: Purpose and Scope is Clearly Articulated:
The explanatory paragraph effectively outlines the policy's intent to establish a systematic approach to risk management for all business units.


92-144: Risk Mitigation Guidelines are Concise and Actionable:
The ordered list provides clear steps on risk assessments, documentation in a risk register, and implementation of mitigation strategies—key for a robust risk management process.


145-166: References Section Enhances Cross-Document Consistency:
Including a reference to the "Information Security Policy" helps integrate risk management efforts with broader security practices.

packages/data/policies/information_security.json (7)

1-11: Information Security Policy Metadata is Solid:
The metadata block thoroughly defines the document with identifiers, descriptions, and a relevant "usedBy" mapping that supports SOC 2 compliance.


12-17: Title Heading Clearly Communicates the Policy:
The level 1 heading "Information Security Policy" immediately informs the reader of the document’s focus.


18-22: Policy Information Section Heading:
The level 2 heading "Policy Information" sets up the subsequent structured data presentation, mirroring the layout across all policy files.


23-77: Organized Policy Information Table:
The table efficiently structures critical review data. The templated values and explicit roles (such as "CISO") ensure clarity and consistency with other documents in the suite.


79-91: Purpose and Scope Articulated Effectively:
The paragraph explains the security objectives, detailing responsibilities to protect confidentiality, integrity, and availability—key for information security governance.


92-144: Comprehensive Security Directives:
The ordered list provides precise directives regarding asset classification, role-based access, and the implementation of technical security controls (e.g., encryption, firewalls). This section is both thorough and actionable.


145-166: References Section Ensures Policy Integration:
Citing the "Data Classification Policy" reinforces interconnected security practices and supports a comprehensive governance framework.

packages/data/policies/corporate_governance.json (7)

1-11: Metadata and Document Identification:
The metadata block clearly defines the document’s unique ID, slug, name, and description. The inclusion of a “usedBy” field (with SOC 2 mappings) aligns well with our compliance requirements.


12-17: Main Heading:
The primary heading "Corporate Governance Policy" is set at level 1 and provides an immediate, clear title for the document.


18-75: Policy Information Section:
The "Policy Information" subheading (level 2) is immediately followed by a well-structured table that outlines key fields—Organization, Last Review, Review Frequency, Approved By, and Classification. The use of dynamic placeholders (e.g. {{organization}}, {{date}}) is consistent and will facilitate rendering via your templating engine.


78-121: Revision History Section:
This section uses a table to log version details with placeholders for dates. The concise structure here will make tracking document updates straightforward.


122-135: Purpose and Scope Section:
The "Purpose and Scope" heading and accompanying paragraph succinctly communicate the intent of the policy as well as its target audience—board members and senior leadership.


136-211: Policy Details – Board Oversight and Management Responsibilities:
A subheading (level 3) under a broader "Policy" section clearly introduces board oversight responsibilities, followed by an ordered list that details various obligations. The hierarchical structure enhances both readability and maintainability.


213-232: References Section:
The "References" heading with an ordered list (referencing, for example, the Risk Management Policy) effectively supports traceability to related documentation.

packages/data/policies/risk_assessment.json (7)

1-5: Metadata and Controls:
The metadata block correctly defines the document type and includes a "controls" array with appropriate control codes (e.g. CC3.2, CC3.4, CC8.1). This mapping ensures the document’s alignment with our regulatory standards.


7-16: Document Title and Policy Information Heading:
The level 1 heading "Risk Assessment Policy" followed by a level 2 "Policy Information" heading clearly establishes the document’s identity and purpose.


17-73: Policy Information Table:
The table that follows provides a clear presentation of key information. The placeholders (such as {{organization}} and {{date}}) are consistently applied, ensuring smooth integration with dynamic data.


74-78: Purpose and Scope Explanation:
This section concisely details the intent of the policy and its applicability to employees, contractors, and third parties. The structured approach aids understanding for all stakeholders.


127-193: Risk Assessment Process:
The ordered list clearly outlines a formal methodology for risk assessment—including asset identification, threat evaluation, and vulnerability analysis. This level of detail promotes consistent implementation across the organization.


194-246: Risk Mitigation Strategies:
The mitigation section enumerates strategic actions—from risk avoidance to reduction—and emphasizes the need for periodic review, ensuring that risk treatment plans remain effective over time.


247-300: Reporting and Review:
The final section details the reporting requirements and review cadence for risk assessments. The ordered list format underscores accountability by specifying corrective measures for non-compliance.

packages/data/policies/cyber_risk.json (7)

1-5: Metadata and Controls:
The metadata block includes all necessary information along with a comprehensive list of control codes (CC1.1, CC1.2, CC1.3, CC1.4, CC1.5) to support cybersecurity standards.


6-16: Document Title and Introduction:
The title "Cyber Risk Assessment Policy" set as a level 1 heading, together with the subsequent "Policy Information" heading, lays a clear foundation for the document’s intended focus.


17-73: Policy Information Table:
The table presenting details such as Organization, Last Review, Review Frequency, Approved By, and Classification is well-organized. Dynamic placeholders ensure that runtime data can populate key fields effectively.


74-78: Purpose and Scope:
The purpose is stated clearly, emphasizing a structured approach to identifying, evaluating, and mitigating cyber risks. This sets precise expectations on the scope of the policy.


127-193: Cyber Risk Assessment Process:
A clearly defined ordered list outlines the methodology—from asset identification to threat evaluation and risk documentation. This systematic approach is essential for maintaining robust cybersecurity practices.


194-248: Cyber Risk Mitigation Strategies:
The strategies section specifies measures to be implemented based on the severity of risks, including technical safeguards and periodic reviews. The guidance is actionable and comprehensive.


249-315: Reporting and Compliance:
The final section details how cyber risk assessment results should be reported and how compliance will be monitored. Its ordered list format communicates the necessary steps clearly and concisely.

packages/data/policies/thirdparty.json (7)

1-5: Metadata and Controls:
The metadata block is straightforward and includes the required control codes (CC2.3, CC7.3, CC8.1). This foundational information ensures the policy is aligned with organizational standards.


7-16: Title and Policy Information Heading:
The primary heading "Third-Party Management Policy" alongside the "Policy Information" subheading clearly introduces the policy’s subject matter.


17-73: Policy Information Table:
The “Policy Information” table is well structured and makes effective use of placeholders for dynamic values. This uniform format aids integration with downstream systems.


74-126: Purpose and Scope Section:
An ordered list is used to articulate the policy’s purpose and who it applies to—covering IT third-parties, partners, employees, and contractors. The clarity and granularity here are commendable.


127-140: Background Section:
The background provides essential context on the significance of managing third-party relationships for security. This narrative supports the need for rigorous controls.


141-173: References Section:
An ordered list under the "References" heading lists key documents (e.g., Information Security Policy, Security Incident Response Policy) that complement this policy. This linkage enhances overall governance.


174-296: Detailed Policy Requirements:
The policy section is extensive and clearly details the rules, from access restrictions and compliance mandates to risk assessments and audit rights. Each list item is precise; consider a brief legal review to ensure the language meets contractual standards.

packages/data/policies/software_development.json (6)

1-6: Metadata and Controls:
The metadata block correctly defines the document type and includes control codes (e.g., CC6.2, CC7.1, CC7.2, CC8.1) that are pertinent to software development practices and security governance.


7-21: Document Title and Policy Information Heading:
The title "Software Development Lifecycle (SDLC) Policy" is prominently displayed as a level 1 heading, followed by a clear "Policy Information" subheading. This order sets the stage for the detailed policy that follows.


22-78: Policy Information Table:
The key informational table lists fields (Organization, Last Review, Review Frequency, Approved By, Classification) in a consistent format. The dynamic placeholders are used appropriately and will facilitate runtime data integration.


79-131: Purpose and Scope:
Outlined as an ordered list, this section clearly states the intent of the SDLC policy and delineates which teams and roles it applies to. The specificity regarding internal, customer-facing, and third-party software ensures comprehensive coverage.


133-288: SDLC Phases:
The document breaks down the Software Development Lifecycle into six distinct phases. The use of bold markers for each phase name improves legibility, and the detailed explanations provide actionable guidance at every stage—from planning to continuous improvement.


289-343: Security & Compliance Requirements:
This final section mandates key secure coding practices, regular security testing, and strict adherence to legal/regulatory standards. The ordered list makes it easy to follow and serves as an excellent checklist for compliance.

packages/data/policies/workstation.json (2)

1-16: Metadata and Heading Structure Validated
The metadata block (lines 1–5) correctly defines the document type and includes the controls array ["CC6.2", "CC6.7", "CC7.2"], and the heading sections (lines 6–16) clearly introduce the "Workstation Policy" and "Policy Information". This clear segmentation ensures consistency with other policy documents.


17-71: Policy Information Table is Well-Structured
The table defined from lines 17 to 43 (header row) and lines 44 to 71 (content row) is structured appropriately. The use of placeholders such as {{organization}} and {{date}} is clear for dynamic replacement. Please verify that downstream processes correctly substitute these placeholders at runtime.

packages/data/policies/data_center.json (2)

1-16: Clear Metadata and Header for Datacenter Policy
The file’s metadata (lines 1–5) correctly lists relevant control identifiers ["CC6.1", "CC6.2", "CC8.1", "CC7.1"] and establishes the document type. The initial headings (lines 8–16) clearly introduce the "Datacenter Policy" and its associated "Policy Information" section.


17-73: Well-Formatted Policy Information Table
The table structure from lines 17 through 72 defines the header and a sample data row with dynamic placeholders ({{organization}} and {{date}}). This is consistent with our other policy documents. Ensure that the placeholder substitution mechanism is uniform across all policy types.

packages/data/policies/disaster_recovery.json (3)

1-16: Robust Header and Metadata for Disaster Recovery Policy
The metadata (lines 1–5) and the document title ("Disaster Recovery Policy" on lines 8–10) are clearly defined. The controls array ["CC9.1", "CC8.1"] is appropriately set, ensuring this policy aligns with relevant standards.


17-73: Structured Policy Information Table
The table that outlines key policy information (lines 17–72) is well formatted and uses placeholders for dynamic content. The structure mirrors that of other policy documents; just ensure that the integration will correctly supply the actual values for {{organization}} and {{date}}.


74-359: Comprehensive Disaster Recovery Content
The subsequent sections (lines 74–359) thoroughly cover the aspects of disaster recovery planning, including planning requirements, backup and data protection, incident response, and compliance. The ordered lists effectively break down the steps and responsibilities. This comprehensive approach should contribute to a robust disaster recovery strategy.

packages/data/policies/code_of_conduct.json (4)

1-16: Clear Definition of the Code of Conduct Policy
The metadata (lines 1–5) and initial heading (line 10) correctly define the document as the "Code of Conduct Policy". The controls array ["CC1.1", "CC6.1"] is set appropriately. This sets a solid foundation for the detailed policy content that follows.


17-71: Well-Structured Policy Information Section
The policy information table (lines 17–71) accurately presents key fields with dynamic placeholders such as {{organization}} and {{date}}. This familiar structure maintains consistency across our policy documents.


72-289: Detailed Expectations and Guidelines in Policy Section
The "Purpose and Scope" (lines 73–110) and the subsequent policy guidelines (lines 111–289) are comprehensive, covering expected employee behavior, responsibilities, and various workplace expectations. The ordered list format helps ensure clarity and consistency.


290-356: Clear Presentation of Disciplinary Actions
The "Disciplinary Actions" section (lines 290–356) clearly outlines potential consequences for policy violations, using both ordered and bullet lists. The clarity in these repercussions supports effective communication of policy enforcement.

packages/db/prisma/schema.prisma (2)

147-147: Extended Organization Model with Categories
The addition of the OrganizationCategory array field (line 147) to the Organization model correctly establishes a one-to-many relationship where an organization can have multiple categories. This change is in line with the new data requirements.


290-292: New Optional Relation Added to OrganizationControl
The new fields added in the OrganizationControl model (lines 290–292) introduce an optional relation to OrganizationCategory via organizationCategoryId and OrganizationCategory. This enhancement allows for more granular categorization of controls. Please verify that the application logic handles cases where these fields remain null.

apps/app/src/app/[locale]/(app)/(dashboard)/controls/[id]/Actions/getOrganizationControl.ts (1)

13-21: LGTM! Well-structured action setup.

The action is properly configured with:

  • Input validation using Zod
  • Descriptive metadata for tracking
  • Authentication through authActionClient


const compliancePercentage = Math.round(
(compliantControls / totalControls) * 100,
(compliantControls ?? 0 / (totalControls ?? 0)) * 100
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix operator precedence in compliancePercentage calculation.
The ?? operator has lower precedence than division, causing unintended grouping. Wrap each operand in parentheses to get the intended result.

-    (compliantControls ?? 0 / (totalControls ?? 0)) * 100
+    ((compliantControls ?? 0) / (totalControls ?? 0)) * 100
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
(compliantControls ?? 0 / (totalControls ?? 0)) * 100
((compliantControls ?? 0) / (totalControls ?? 0)) * 100

Comment on lines +3 to +5
interface PageProps {
params: Promise<{ id: string }>;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the type of params prop.

The params prop is incorrectly typed as a Promise. In Next.js, page props are already resolved and should not be Promises.

Apply this diff to fix the type:

-  params: Promise<{ id: string }>;
+  params: { id: string };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
interface PageProps {
params: Promise<{ id: string }>;
}
interface PageProps {
params: { id: string };
}

Comment on lines +15 to +20
export interface Requirement {
id: string;
type: string;
description: string;
policyId?: string;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove duplicate interface definition.

The Requirement interface duplicates all fields from ControlRequirement. Since they have the same structure, we should use a single interface to maintain consistency and avoid duplication.

Apply this diff to remove the duplicate interface:

-export interface Requirement {
-  id: string;
-  type: string;
-  description: string;
-  policyId?: string;
-}

 export interface Control {
   name: string;
   description: string;
   code: string;
   domain: string;
   categoryId: string;
-  requirements: Requirement[];
+  requirements: ControlRequirement[];
 }

Also applies to: 31-36

Comment on lines +16 to +17
const { data: control } = useOrganizationControl(controlId);
if (!control) return null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider handling loading and error states.

The component currently returns null when data is not available, but it should handle loading and error states explicitly.

-  const { data: control } = useOrganizationControl(controlId);
-  if (!control) return null;
+  const { data: control, isLoading, error } = useOrganizationControl(controlId);
+
+  if (isLoading) return <div>Loading...</div>;
+  if (error) return <div>Error: {error.message}</div>;
+  if (!control) return <div>No control found</div>;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { data: control } = useOrganizationControl(controlId);
if (!control) return null;
const { data: control, isLoading, error } = useOrganizationControl(controlId);
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!control) return <div>No control found</div>;

Comment on lines +20 to +26
export function FrameworkControls({ frameworkId }: FrameworkControlsProps) {
const { data: organizationCategories } =
useOrganizationCategories(frameworkId);

if (!organizationCategories) {
return null;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add loading and error state handling.

The component currently returns null when data is not available, but it should handle loading and error states explicitly for better user experience.

 export function FrameworkControls({ frameworkId }: FrameworkControlsProps) {
-  const { data: organizationCategories } =
+  const { data: organizationCategories, isLoading, error } =
     useOrganizationCategories(frameworkId);
 
+  if (isLoading) {
+    return <div aria-busy="true">Loading controls...</div>;
+  }
+
+  if (error) {
+    return <div role="alert">Error loading controls: {error.message}</div>;
+  }
+
   if (!organizationCategories) {
     return null;
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function FrameworkControls({ frameworkId }: FrameworkControlsProps) {
const { data: organizationCategories } =
useOrganizationCategories(frameworkId);
if (!organizationCategories) {
return null;
}
export function FrameworkControls({ frameworkId }: FrameworkControlsProps) {
const { data: organizationCategories, isLoading, error } =
useOrganizationCategories(frameworkId);
if (isLoading) {
return <div aria-busy="true">Loading controls...</div>;
}
if (error) {
return <div role="alert">Error loading controls: {error.message}</div>;
}
if (!organizationCategories) {
return null;
}
// ... rest of the component code
}

Comment on lines +58 to +62
if (!organizationCategories) {
return {
error: "Organization categories not found",
};
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect empty check for findMany result.

The findMany operation returns an empty array when no results are found, not null. The current check is incorrect.

-      if (!organizationCategories) {
+      if (organizationCategories.length === 0) {
         return {
           error: "Organization categories not found",
         };
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!organizationCategories) {
return {
error: "Organization categories not found",
};
}
if (organizationCategories.length === 0) {
return {
error: "Organization categories not found",
};
}

Comment on lines 32 to 45
try {
await Promise.all([
// First create categories
await createOrganizationCategories(user as User, frameworkIds);

// Then create frameworks and controls
await Promise.all(
frameworkIds.map((frameworkId) =>
createOrganizationFramework(user as User, frameworkId)
),
createOrganizationPolicy(user as User, frameworkIds),
]);
)
);

// Finally create policies
await createOrganizationPolicy(user as User, frameworkIds);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Wrap operations in a transaction for atomicity.

The sequential operations (creating categories, frameworks, and policies) should be wrapped in a transaction to ensure atomicity. If any operation fails, all changes should be rolled back.

    try {
+     return await db.$transaction(async (tx) => {
        // First create categories
-       await createOrganizationCategories(user as User, frameworkIds);
+       await createOrganizationCategories(user as User, frameworkIds, tx);

        // Then create frameworks and controls
        await Promise.all(
          frameworkIds.map((frameworkId) =>
-           createOrganizationFramework(user as User, frameworkId)
+           createOrganizationFramework(user as User, frameworkId, tx)
          )
        );

        // Finally create policies
-       await createOrganizationPolicy(user as User, frameworkIds);
+       await createOrganizationPolicy(user as User, frameworkIds, tx);

-       return {
-         data: true,
-       };
+       return { data: true };
+     });
    } catch (error) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
await Promise.all([
// First create categories
await createOrganizationCategories(user as User, frameworkIds);
// Then create frameworks and controls
await Promise.all(
frameworkIds.map((frameworkId) =>
createOrganizationFramework(user as User, frameworkId)
),
createOrganizationPolicy(user as User, frameworkIds),
]);
)
);
// Finally create policies
await createOrganizationPolicy(user as User, frameworkIds);
try {
return await db.$transaction(async (tx) => {
// First create categories
await createOrganizationCategories(user as User, frameworkIds, tx);
// Then create frameworks and controls
await Promise.all(
frameworkIds.map((frameworkId) =>
createOrganizationFramework(user as User, frameworkId, tx)
)
);
// Finally create policies
await createOrganizationPolicy(user as User, frameworkIds, tx);
return { data: true };
});
} catch (error) {

Comment on lines +1 to +11
/*
Warnings:

- Added the required column `frameworkId` to the `OrganizationCategory` table without a default value. This is not possible if the table is not empty.

*/
-- AlterTable
ALTER TABLE "OrganizationCategory" ADD COLUMN "frameworkId" TEXT NOT NULL;

-- AddForeignKey
ALTER TABLE "OrganizationCategory" ADD CONSTRAINT "OrganizationCategory_frameworkId_fkey" FOREIGN KEY ("frameworkId") REFERENCES "Framework"("id") ON DELETE CASCADE ON UPDATE CASCADE;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider safer migration strategy for non-nullable column.

Adding a required column without a default value requires an empty table. Consider a safer migration strategy:

  1. Add the column as nullable
  2. Populate the data
  3. Make the column non-nullable
-- Step 1: Add nullable column
ALTER TABLE "OrganizationCategory" ADD COLUMN "frameworkId" TEXT;

-- Step 2: Populate data (example)
UPDATE "OrganizationCategory" SET "frameworkId" = f.id 
FROM "Framework" f 
WHERE /* define your mapping logic */;

-- Step 3: Make non-nullable
ALTER TABLE "OrganizationCategory" ALTER COLUMN "frameworkId" SET NOT NULL;

-- Step 4: Add foreign key
ALTER TABLE "OrganizationCategory" ADD CONSTRAINT "OrganizationCategory_frameworkId_fkey" 
FOREIGN KEY ("frameworkId") REFERENCES "Framework"("id") ON DELETE CASCADE ON UPDATE CASCADE;

Comment on lines +958 to +975
model OrganizationCategory {
id String @id @default(cuid())
name String
description String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

frameworkId String
framework Framework @relation(fields: [frameworkId], references: [id], onDelete: Cascade)

organizationControl OrganizationControl[]

organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)

@@unique([id])
@@index([organizationId])
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

New Prisma Model: OrganizationCategory
The introduction of the OrganizationCategory model (lines 958–975) is well designed. It includes standard fields (ID, name, optional description, created/updated timestamps) along with foreign keys (frameworkId and organizationId) and their relations.

Nitpick: The declaration @@unique([id]) is redundant because the id field is already marked as the primary key and is inherently unique. Additionally, consider adding an index for frameworkId (e.g., @@index([frameworkId])) if you anticipate frequent queries filtering by framework.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant