Skip to content

Conversation

@pujitm
Copy link
Member

@pujitm pujitm commented Jul 24, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a comprehensive validation system for organizer data, including structural and referential integrity checks for views and organizers.
    • Added new data models for resources, folders, references, and views, with strong typing and validation.
    • Implemented a sequential validation processor with configurable fail-fast behavior and detailed error reporting.
    • Added a dedicated service for managing and validating Docker organizer configuration files.
  • Bug Fixes

    • Corrected spelling of error-related properties from "errorOccured" to "errorOccurred" in multiple services to ensure consistent error handling.
  • Tests

    • Added extensive unit tests for organizer validation logic, view structure validation, and the validation processor to ensure correctness across various edge cases and scenarios.
    • Added comprehensive tests verifying validation processor behavior under diverse conditions.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 24, 2025

Walkthrough

This update introduces a type-safe, modular validation framework for organizer data structures, along with comprehensive DTOs and validation logic for organizer views and resources. It adds new services for configuration management, extensive validation utilities, and robust test suites covering structural and referential integrity, including edge cases and error handling.

Changes

File(s) Change Summary
validation-processor.ts, validation-processor.test.ts, organizer-view.validation.ts, organizer-view.validation.test.ts, organizer.validation.ts, organizer.validation.test.ts Added a type-safe validation processor with configurable fail-fast behavior and multiple result interpreters. Introduced comprehensive organizer view validation logic including root existence, missing children, duplicates, cycles, nesting depth, and orphan detection. Added organizer-wide validation functions for structural and referential integrity. Included extensive test suites covering normal, edge cases, error propagation, and fail-fast scenarios.
organizer.dto.ts Introduced DTO classes for organizer resources, folders, references, views, and the root organizer structure using class-validator and GraphQL decorators for validation and schema generation.
docker-config.service.ts Added a new injectable service class DockerConfigService extending a generic configuration persister for managing Docker organizer configuration files, including validation using the new DTOs and integrity checks.
auth.service.ts, notifications.service.ts, plugin.service.ts, utils.ts Fixed typos in error-related property names from errorOccured to errorOccurred for consistent naming and to prevent runtime issues.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant DockerConfigService
    participant OrganizerV1 DTO
    participant Validator

    Client->>DockerConfigService: validate(config)
    DockerConfigService->>OrganizerV1 DTO: Validate structure
    OrganizerV1 DTO-->>DockerConfigService: Structured result or errors
    DockerConfigService->>Validator: Run integrity checks
    Validator-->>DockerConfigService: Error(s) or validated config
    DockerConfigService-->>Client: Throw errors or return validated config
Loading
sequenceDiagram
    participant Client
    participant ValidationProcessor
    participant Step1
    participant Step2

    Client->>ValidationProcessor: process(input, config)
    ValidationProcessor->>Step1: Run validator
    Step1-->>ValidationProcessor: Result
    alt Error and failFast
        ValidationProcessor-->>Client: Return errors
    else No error or not failFast
        ValidationProcessor->>Step2: Run validator
        Step2-->>ValidationProcessor: Result
        ValidationProcessor-->>Client: Return aggregated result
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

New validators march in line,
With folders, refs, and views entwined.
Errors caught and cycles found,
Integrity checks now tightly bound.
Tests abound, the code is neat—
Organizer’s logic is complete!
🗂️✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/docker-folder

🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @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
Contributor

@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: 4

🧹 Nitpick comments (2)
api/src/unraid-api/organizer/organizer.dto.ts (1)

79-82: Consider implementing proper type discrimination for entries validation

The current setup with @Type(() => Object) bypasses deep validation of the entries dictionary values. Since entries can contain either OrganizerFolder or OrganizerResourceRef, consider implementing a custom validator or using a discriminator pattern to ensure proper validation of each entry type.

api/src/unraid-api/organizer/organizer.validation.test.ts (1)

18-37: Consider extracting shared test helpers

The helper functions createRef, createFolder, and createView are duplicated from organizer-view.validation.test.ts. Consider extracting these to a shared test utilities file to maintain DRY principles.

Create a new file api/src/unraid-api/organizer/__tests__/test-helpers.ts:

import {
    OrganizerFolder,
    OrganizerResourceRef,
    OrganizerView,
} from '@app/unraid-api/organizer/organizer.dto.js';

export const createRef = (id: string, target: string): OrganizerResourceRef => ({
    id,
    type: 'ref' as const,
    target,
});

export const createFolder = (id: string, name: string, children: string[]): OrganizerFolder => ({
    id,
    type: 'folder' as const,
    name,
    children,
});

export const createView = (
    partial: Partial<OrganizerView> & Pick<OrganizerView, 'root' | 'entries'>
): OrganizerView => ({
    id: 'view1',
    name: 'Test View',
    ...partial,
});
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 86b6c4f and e885d0e.

📒 Files selected for processing (8)
  • api/src/core/utils/validation/validation-processor.test.ts (1 hunks)
  • api/src/core/utils/validation/validation-processor.ts (1 hunks)
  • api/src/unraid-api/graph/resolvers/docker/docker-config.service.ts (1 hunks)
  • api/src/unraid-api/organizer/organizer-view.validation.test.ts (1 hunks)
  • api/src/unraid-api/organizer/organizer-view.validation.ts (1 hunks)
  • api/src/unraid-api/organizer/organizer.dto.ts (1 hunks)
  • api/src/unraid-api/organizer/organizer.validation.test.ts (1 hunks)
  • api/src/unraid-api/organizer/organizer.validation.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
api/**/*

📄 CodeRabbit Inference Engine (.cursor/rules/api-rules.mdc)

api/**/*: Use pnpm as the only package manager
Always run scripts from api/package.json unless specifically requested otherwise

Files:

  • api/src/core/utils/validation/validation-processor.test.ts
  • api/src/unraid-api/graph/resolvers/docker/docker-config.service.ts
  • api/src/unraid-api/organizer/organizer-view.validation.ts
  • api/src/unraid-api/organizer/organizer.validation.ts
  • api/src/unraid-api/organizer/organizer-view.validation.test.ts
  • api/src/unraid-api/organizer/organizer.dto.ts
  • api/src/unraid-api/organizer/organizer.validation.test.ts
  • api/src/core/utils/validation/validation-processor.ts
api/**/*.{test,spec}.{js,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/api-rules.mdc)

api/**/*.{test,spec}.{js,ts,tsx}: Use Vitest as the test suite; do not use Jest
Prefer not to mock simple dependencies in tests

Files:

  • api/src/core/utils/validation/validation-processor.test.ts
  • api/src/unraid-api/organizer/organizer-view.validation.test.ts
  • api/src/unraid-api/organizer/organizer.validation.test.ts
api/src/unraid-api/**/*

📄 CodeRabbit Inference Engine (.cursor/rules/api-rules.mdc)

Prefer adding new files to the NestJS repository located at api/src/unraid-api/ instead of the legacy code

Files:

  • api/src/unraid-api/graph/resolvers/docker/docker-config.service.ts
  • api/src/unraid-api/organizer/organizer-view.validation.ts
  • api/src/unraid-api/organizer/organizer.validation.ts
  • api/src/unraid-api/organizer/organizer-view.validation.test.ts
  • api/src/unraid-api/organizer/organizer.dto.ts
  • api/src/unraid-api/organizer/organizer.validation.test.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: mdatelle
PR: unraid/api#1533
File: web/components/Docker/Edit.vue:16-32
Timestamp: 2025-07-24T18:48:44.035Z
Learning: In web/components/Docker/Edit.vue, the hardcoded configuration values in the config ref are intentional temporary/dummy data used during initial UI development phase while building out the real Docker components, as clarified by mdatelle in PR #1533.
Learnt from: pujitm
PR: unraid/api#1352
File: packages/unraid-api-plugin-generator/src/create-plugin.ts:91-112
Timestamp: 2025-04-21T18:27:36.482Z
Learning: For utility functions like file operations in api plugin generators, pujitm prefers minimal error handling rather than verbose try/catch blocks for each operation, as errors will propagate properly to higher level error handlers.
api/src/core/utils/validation/validation-processor.test.ts (11)

Learnt from: CR
PR: unraid/api#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T13:59:55.481Z
Learning: Test suite is VITEST, do not use jest in the API codebase

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/api-rules.mdc:0-0
Timestamp: 2025-07-21T14:00:06.258Z
Learning: Applies to api/**/*.{test,spec}.{js,ts,tsx} : Use Vitest as the test suite; do not use Jest

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify proper error handling in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify state changes by updating the store in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/components/**/*.ts : Test component behavior and output, not implementation details

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/components/**/*.ts : Test component interactions (clicks, inputs, etc.)

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify state changes after actions in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Test async operations completely in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/components/**/*.ts : Check for expected prop handling and event emissions in component tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Test action side effects and state changes in store tests

Learnt from: elibosley
PR: #1120
File: plugin/scripts/build-plugin-and-txz.ts:132-147
Timestamp: 2025-02-06T15:32:09.488Z
Learning: For validation steps in build scripts where the goal is to fail fast on invalid state, simple error handling (console.error + process.exit) is appropriate since we want to abort the build process immediately.

api/src/unraid-api/graph/resolvers/docker/docker-config.service.ts (5)

Learnt from: mdatelle
PR: #1533
File: web/components/Docker/Edit.vue:16-32
Timestamp: 2025-07-24T18:48:44.035Z
Learning: In web/components/Docker/Edit.vue, the hardcoded configuration values in the config ref are intentional temporary/dummy data used during initial UI development phase while building out the real Docker components, as clarified by mdatelle in PR #1533.

Learnt from: pujitm
PR: #1367
File: packages/unraid-api-plugin-connect/src/pubsub/user.service.ts:44-52
Timestamp: 2025-04-23T20:19:42.542Z
Learning: The project uses a custom or extended implementation of NestJS ConfigService that includes a set() method for runtime configuration mutation, unlike the standard @nestjs/config package which only provides getter methods.

Learnt from: pujitm
PR: #1367
File: packages/unraid-api-plugin-connect/src/pubsub/user.service.ts:44-52
Timestamp: 2025-04-23T20:19:42.542Z
Learning: The project uses a custom ConfigService implementation that includes a set() method for runtime configuration mutation, unlike the standard @nestjs/config package which only provides getter methods.

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/api-rules.mdc:0-0
Timestamp: 2025-07-21T14:00:06.258Z
Learning: Applies to api/src/unraid-api/**/* : Prefer adding new files to the NestJS repository located at api/src/unraid-api/ instead of the legacy code

Learnt from: CR
PR: unraid/api#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T13:59:55.481Z
Learning: Prefer adding new files to the NestJS repo located at api/src/unraid-api/ instead of the legacy code

api/src/unraid-api/organizer/organizer-view.validation.ts (1)

Learnt from: elibosley
PR: #1120
File: plugin/scripts/build-plugin-and-txz.ts:132-147
Timestamp: 2025-02-06T15:32:09.488Z
Learning: For validation steps in build scripts where the goal is to fail fast on invalid state, simple error handling (console.error + process.exit) is appropriate since we want to abort the build process immediately.

api/src/unraid-api/organizer/organizer.validation.ts (1)

Learnt from: elibosley
PR: #1352
File: packages/unraid-api-plugin-connect/src/config.entity.ts:16-26
Timestamp: 2025-04-21T18:44:15.414Z
Learning: For the Unraid API project, class-validator should be used for validation to avoid mismatches between different validation schemas (like Zod).

api/src/unraid-api/organizer/organizer-view.validation.test.ts (16)

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify proper error handling in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify state changes by updating the store in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify state changes after actions in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Test action side effects and state changes in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Test async operations completely in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/components/**/*.ts : Verify that the expected elements are rendered in component tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify actions are called with correct parameters in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/components/**/*.ts : Test component behavior and output, not implementation details

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/components/**/*.ts : Test component interactions (clicks, inputs, etc.)

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/api-rules.mdc:0-0
Timestamp: 2025-07-21T14:00:06.258Z
Learning: Applies to api/**/*.{test,spec}.{js,ts,tsx} : Use Vitest as the test suite; do not use Jest

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/components/**/*.ts : Use findAll to check for multiple elements

Learnt from: CR
PR: unraid/api#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T13:59:55.481Z
Learning: Test suite is VITEST, do not use jest in the API codebase

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/components/**/*.ts : Verify element existence with expect(element.exists()).toBe(true)

Learnt from: elibosley
PR: #1120
File: plugin/scripts/build-plugin-and-txz.ts:132-147
Timestamp: 2025-02-06T15:32:09.488Z
Learning: For validation steps in build scripts where the goal is to fail fast on invalid state, simple error handling (console.error + process.exit) is appropriate since we want to abort the build process immediately.

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/components/**/*.ts : Stub complex child components that aren't the focus of the test

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/components/**/*.ts : Check for expected prop handling and event emissions in component tests

api/src/unraid-api/organizer/organizer.dto.ts (4)

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/api-rules.mdc:0-0
Timestamp: 2025-07-21T14:00:06.258Z
Learning: Applies to api/src/unraid-api/**/* : Prefer adding new files to the NestJS repository located at api/src/unraid-api/ instead of the legacy code

Learnt from: CR
PR: unraid/api#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T13:59:55.481Z
Learning: Prefer adding new files to the NestJS repo located at api/src/unraid-api/ instead of the legacy code

Learnt from: elibosley
PR: #1352
File: packages/unraid-api-plugin-connect/src/config.entity.ts:37-39
Timestamp: 2025-04-21T18:44:24.383Z
Learning: The project prefers using class-validator decorators directly on entity classes rather than separate Zod schemas to maintain type consistency between GraphQL entities and validation rules.

Learnt from: CR
PR: unraid/api#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T13:59:55.481Z
Learning: All GraphQL under web/ must follow this naming convention (.query.ts for queries, .mutation.ts for mutations)

api/src/unraid-api/organizer/organizer.validation.test.ts (16)

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify proper error handling in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify state changes by updating the store in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify state changes after actions in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Test async operations completely in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Test action side effects and state changes in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify actions are called with correct parameters in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/api-rules.mdc:0-0
Timestamp: 2025-07-21T14:00:06.258Z
Learning: Applies to api/src/unraid-api/**/* : Prefer adding new files to the NestJS repository located at api/src/unraid-api/ instead of the legacy code

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/api-rules.mdc:0-0
Timestamp: 2025-07-21T14:00:06.258Z
Learning: Applies to api/**/*.{test,spec}.{js,ts,tsx} : Use Vitest as the test suite; do not use Jest

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Verify actions are called with the right parameters in store tests

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/store/**/*.ts : Test getter dependencies are properly mocked in store tests

Learnt from: CR
PR: unraid/api#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T13:59:55.481Z
Learning: Test suite is VITEST, do not use jest in the API codebase

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/{components,store,mocks}/**/*.ts : Reset mocks between tests with vi.clearAllMocks()

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/{components,store,mocks}/**/*.ts : Remember that vi.mock() calls are hoisted

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/{components,store,mocks}/**/*.ts : Use vi.mock() for module-level mocks

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/{components,store,mocks}/**/*.ts : Clear mocks between tests to ensure isolation

Learnt from: CR
PR: unraid/api#0
File: .cursor/rules/web-testing-rules.mdc:0-0
Timestamp: 2025-07-21T14:01:04.139Z
Learning: Applies to web/test/{components,store,mocks}/**/*.ts : Specify return values for component methods with vi.spyOn()

api/src/core/utils/validation/validation-processor.ts (1)

Learnt from: elibosley
PR: #1120
File: plugin/scripts/build-plugin-and-txz.ts:132-147
Timestamp: 2025-02-06T15:32:09.488Z
Learning: For validation steps in build scripts where the goal is to fail fast on invalid state, simple error handling (console.error + process.exit) is appropriate since we want to abort the build process immediately.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build API
  • GitHub Check: Test API
  • GitHub Check: Build Web App
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (6)
api/src/core/utils/validation/validation-processor.ts (3)

39-75: Well-designed type system for validation framework

The type definitions provide excellent type safety with proper inference of input types and step results. The use of conditional types and mapped types ensures compile-time safety across the validation pipeline.


178-181: Type assertion is acceptable here

The (errors as any) type assertion is necessary because TypeScript cannot statically verify the dynamic assignment to the errors object keyed by step names. This is a reasonable trade-off for the flexibility provided by the validation framework.


196-215: Comprehensive set of result interpreters

The ResultInterpreters object provides a well-thought-out collection of helper functions for common validation patterns. The naming is intuitive and the implementations are correct.

api/src/core/utils/validation/validation-processor.test.ts (1)

1-155: Comprehensive test coverage for validation processor

The test suite thoroughly covers all major functionality of the validation processor including fail-fast behavior, different result interpreters, and edge cases. Good use of Vitest as per project standards.

api/src/unraid-api/organizer/organizer-view.validation.ts (1)

1-201: Excellent implementation of view structure validation

The module provides comprehensive validation with well-separated concerns. The cycle detection with path tracking, depth validation with configurable limits, and orphan detection are all correctly implemented. The documentation clearly explains each validation step.

api/src/unraid-api/organizer/organizer.validation.test.ts (1)

514-530: Verify error handling behavior in test

The test simulates an error on the second validateViewStructure call, but the comment at line 525 suggests view2 wasn't processed. However, the test expects only 2 views in the results. Please verify if this correctly tests the error handling behavior - should failed validations be included in the results or skipped entirely?

Copy link
Contributor

@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: 0

🧹 Nitpick comments (1)
api/src/core/utils/validation/validation-processor.ts (1)

195-195: Consider avoiding the any type assertion.

The type assertion to any works but bypasses TypeScript's type checking.

You could maintain type safety by using a type-safe assignment:

-                (errors as any)[step.name] = result;
+                const typedErrors = errors as Record<string, unknown>;
+                typedErrors[step.name] = result;

Or leverage TypeScript's ability to handle the assignment without assertion since the types should align correctly.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e885d0e and a5b9c74.

📒 Files selected for processing (2)
  • api/src/core/utils/validation/validation-processor.test.ts (1 hunks)
  • api/src/core/utils/validation/validation-processor.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • api/src/core/utils/validation/validation-processor.test.ts
🧰 Additional context used
📓 Path-based instructions (1)
api/**/*

📄 CodeRabbit Inference Engine (.cursor/rules/api-rules.mdc)

api/**/*: Use pnpm as the only package manager
Always run scripts from api/package.json unless specifically requested otherwise

Files:

  • api/src/core/utils/validation/validation-processor.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: mdatelle
PR: unraid/api#1533
File: web/components/Docker/Edit.vue:16-32
Timestamp: 2025-07-24T18:48:44.035Z
Learning: In web/components/Docker/Edit.vue, the hardcoded configuration values in the config ref are intentional temporary/dummy data used during initial UI development phase while building out the real Docker components, as clarified by mdatelle in PR #1533.
Learnt from: pujitm
PR: unraid/api#1352
File: packages/unraid-api-plugin-generator/src/create-plugin.ts:91-112
Timestamp: 2025-04-21T18:27:36.482Z
Learning: For utility functions like file operations in api plugin generators, pujitm prefers minimal error handling rather than verbose try/catch blocks for each operation, as errors will propagate properly to higher level error handlers.
api/src/core/utils/validation/validation-processor.ts (1)

Learnt from: elibosley
PR: #1120
File: plugin/scripts/build-plugin-and-txz.ts:132-147
Timestamp: 2025-02-06T15:32:09.488Z
Learning: For validation steps in build scripts where the goal is to fail fast on invalid state, simple error handling (console.error + process.exit) is appropriate since we want to abort the build process immediately.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build API
  • GitHub Check: Build Web App
  • GitHub Check: Test API
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (2)
api/src/core/utils/validation/validation-processor.ts (2)

39-84: Type definitions are well-structured and type-safe.

The advanced TypeScript types correctly handle the validation pipeline's type inference needs.


211-230: ResultInterpreters provides comprehensive helper functions.

The helper functions cover common validation patterns effectively and are correctly implemented.

@pujitm pujitm changed the title [WIP] feat: add docker organization config feat: add organizer data structure for docker folders Jul 25, 2025
Copy link
Contributor

@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: 0

🧹 Nitpick comments (1)
api/src/unraid-api/auth/auth.service.ts (1)

121-121: Consider fixing the variable name throughout instead of renaming during destructuring.

While this maintains functionality, it would be cleaner to fix the misspelled variable name on line 127 rather than renaming the correctly spelled property during destructuring.

Apply this diff to use consistent spelling throughout:

-            const { errors, errorOccurred: errorOccured } = await batchProcess(
+            const { errors, errorOccurred } = await batchProcess(
                 permissionActions,
                 ({ resource, action }) =>
                     this.authzService.addPermissionForUser(apiKeyId, resource, action)
             );

-            if (errorOccured) {
+            if (errorOccurred) {
                 this.logger.warn(`Some permissions failed to sync for API key ${apiKeyId}:`, errors);
             }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a5b9c74 and c286126.

📒 Files selected for processing (7)
  • api/src/unraid-api/auth/auth.service.ts (1 hunks)
  • api/src/unraid-api/graph/resolvers/docker/docker-config.service.ts (1 hunks)
  • api/src/unraid-api/graph/resolvers/notifications/notifications.service.ts (1 hunks)
  • api/src/unraid-api/organizer/organizer-view.validation.test.ts (1 hunks)
  • api/src/unraid-api/organizer/organizer.validation.ts (1 hunks)
  • api/src/unraid-api/plugin/plugin.service.ts (1 hunks)
  • api/src/utils.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • api/src/utils.ts
  • api/src/unraid-api/plugin/plugin.service.ts
  • api/src/unraid-api/graph/resolvers/docker/docker-config.service.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • api/src/unraid-api/organizer/organizer-view.validation.test.ts
  • api/src/unraid-api/organizer/organizer.validation.ts
🧰 Additional context used
📓 Path-based instructions (2)
api/**/*

📄 CodeRabbit Inference Engine (.cursor/rules/api-rules.mdc)

api/**/*: Use pnpm as the only package manager
Always run scripts from api/package.json unless specifically requested otherwise

Files:

  • api/src/unraid-api/auth/auth.service.ts
  • api/src/unraid-api/graph/resolvers/notifications/notifications.service.ts
api/src/unraid-api/**/*

📄 CodeRabbit Inference Engine (.cursor/rules/api-rules.mdc)

Prefer adding new files to the NestJS repository located at api/src/unraid-api/ instead of the legacy code

Files:

  • api/src/unraid-api/auth/auth.service.ts
  • api/src/unraid-api/graph/resolvers/notifications/notifications.service.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build Web App
  • GitHub Check: Build API
  • GitHub Check: Test API
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
api/src/unraid-api/graph/resolvers/notifications/notifications.service.ts (1)

185-185: LGTM! Typo correction for property name consistency.

The spelling correction from errorOccured to errorOccurred aligns with proper English spelling and ensures consistency with the batchProcess utility's return value.

Also applies to: 191-191

@github-actions
Copy link
Contributor

This plugin has been deployed to Cloudflare R2 and is available for testing.
Download it at this URL:

https://preview.dl.unraid.net/unraid-api/tag/PR1540/dynamix.unraid.net.plg

@pujitm pujitm marked this pull request as ready for review July 25, 2025 14:26
Copy link
Member

@elibosley elibosley left a comment

Choose a reason for hiding this comment

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

This is really awesome, just had some thoughts about possibly leveraging some OOTB solutions for common patterns.

const steps = [
{
name: 'emailFormat',
validator: (input: ComplexInput) =>
Copy link
Member

Choose a reason for hiding this comment

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

Is this kind of thing something we should be using class-validator for? Or is this more specialized?

@@ -0,0 +1,230 @@
/**
* @fileoverview Type-safe sequential validation processor
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, my only question here is should we have utilized a library to provide the type-safe validations, and then add the chaining logic ourselves? Seems like it could be a case of not-built-here but it may be 100% necessary

Copy link
Member

Choose a reason for hiding this comment

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

Here's what AI said: 🛠️ TL;DR Recommendation
Use Zod or Valibot if you want standard schema-based validation.

Stick with your custom createValidationProcessor if:

You want step-named error reporting

You need typed per-step errors

You want fail-fast customization

You want full flexibility over validator logic

Copy link
Member Author

Choose a reason for hiding this comment

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

ik it's kinda crazy that the zod's out there aren't great for validating trees/graphs. the more convincing benefit is the fact that we can unit test validation steps + pipelines individually as opposed to the zod refine style.

);

const { errors, errorOccured } = await batchProcess(
const { errors, errorOccurred: errorOccured } = await batchProcess(
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion for later - should we move to https://www.npmjs.com/package/p-map instead of the custom batchProcess - just thinking about developer maintainability and documentation as that library is essentially the same functionality but with a bit more control and options.

Copy link
Member Author

Choose a reason for hiding this comment

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

💯 that looks perfect

});

describe('findCycleInView', () => {
it('should return null when no cycle exists', () => {
Copy link
Member

Choose a reason for hiding this comment

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

This is really cool.

expect(result).toEqual(['root1', 'root1']);
});

it('should detect simple two-node cycle', () => {
Copy link
Member

Choose a reason for hiding this comment

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

This too, you've literally built a file system you weren't kidding!

/**
* Finds duplicate children in folder entries.
*/
export function findDuplicateChildren(
Copy link
Member

Choose a reason for hiding this comment

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

Would we be better suited with a drop-in lib like: https://github.com/dagrejs/graphlib/wiki instead of building these data structures by hand?

Alternatively, I see a world where we publish this as a separate library on our org, this is very cool code.

IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
Copy link
Member

Choose a reason for hiding this comment

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

Oh ! You are using class validator for this...

@pujitm pujitm changed the title feat: add organizer data structure for docker folders chore: add organizer data structure for docker folders Jul 29, 2025
@pujitm pujitm merged commit dfe363b into main Jul 29, 2025
11 checks passed
@pujitm pujitm deleted the feat/docker-folder branch July 29, 2025 18:41
mdatelle pushed a commit that referenced this pull request Jul 30, 2025
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Introduced a comprehensive validation system for organizer data,
including structural and referential integrity checks for views and
organizers.
* Added new data models for resources, folders, references, and views,
with strong typing and validation.
* Implemented a sequential validation processor with configurable
fail-fast behavior and detailed error reporting.
* Added a dedicated service for managing and validating Docker organizer
configuration files.

* **Bug Fixes**
* Corrected spelling of error-related properties from "errorOccured" to
"errorOccurred" in multiple services to ensure consistent error
handling.

* **Tests**
* Added extensive unit tests for organizer validation logic, view
structure validation, and the validation processor to ensure correctness
across various edge cases and scenarios.
* Added comprehensive tests verifying validation processor behavior
under diverse conditions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.

2 participants