# Spectral Rules Generator - Usage Guide

This guide explains how to use the Spectral rules generator in this project to create, update, and test validation rules for OpenAPI schema components.

## Table of Contents

1. [Overview](#overview)
2. [Generating Basic Rulesets](#generating-basic-rulesets)
3. [Generating Enhanced Rulesets](#generating-enhanced-rulesets)
4. [Generating Recursive Rulesets](#generating-recursive-rulesets)
5. [Testing Rulesets](#testing-rulesets)
6. [Using Rulesets with Spectral](#using-rulesets-with-spectral)
7. [Customizing Rules](#customizing-rules)
8. [Troubleshooting](#troubleshooting)

## Overview

This project includes three ruleset generators:

1. **Basic Generator** (`generate-rulesets.js`): Creates simple validation rules for schema components
2. **Enhanced Generator** (`enhanced-generate-rulesets.js`): Creates detailed validation rules for all properties inside the "spec" field
3. **Recursive Generator** (`recursive-generate-rulesets.js`): Creates comprehensive validation rules for all nested properties at any depth

The generated rulesets are used with Spectral to validate API definitions against the schema components.

## Generating Basic Rulesets

To generate basic ruleset files for all schema components:

```bash
# Navigate to the spectral-rulesets directory
cd packages/inventory/src/resources/spectral-rulesets

# Run the basic generator
node generate-rulesets.js
```

This will create ruleset files for all schema components in the OpenAPI specification with basic validation rules.

## Generating Enhanced Rulesets

To generate enhanced ruleset files with detailed validation for spec field properties:

```bash
# Navigate to the spectral-rulesets directory
cd packages/inventory/src/resources/spectral-rulesets

# Run the enhanced generator
node enhanced-generate-rulesets.js
```

This will create ruleset files with comprehensive validation rules for all properties inside the "spec" field of each schema component.

## Generating Recursive Rulesets

To generate recursive ruleset files with validation for all nested properties at any depth:

```bash
# Navigate to the spectral-rulesets directory
cd packages/inventory/src/resources/spectral-rulesets

# Run the recursive generator
node recursive-generate-rulesets.js
```

This will create ruleset files with the most comprehensive validation rules, including:

- Validation for all properties at any nesting level
- Type checking for deeply nested objects and arrays
- Required field validation at all levels
- Enum value validation at all levels
- Prevention of additional properties at all levels
- Support for oneOf, anyOf, and allOf schemas

### Comparison of Generator Types

| Feature | Basic | Enhanced | Recursive |
|---------|-------|----------|-----------|
| Root field validation | ✅ | ✅ | ✅ |
| Top-level spec properties | ❌ | ✅ | ✅ |
| Nested spec properties | ❌ | ✅ (limited) | ✅ |
| Deep nesting support | ❌ | ❌ | ✅ |
| oneOf/anyOf/allOf support | ❌ | ❌ | ✅ |
| Array item validation | ❌ | ✅ (limited) | ✅ |
| Nested array validation | ❌ | ❌ | ✅ |
| Rule count | Low | Medium | High |

## Testing Rulesets

To test the generated rulesets:

```bash
# Test basic rulesets
node test-ruleset.js

# Test enhanced rulesets
node test-enhanced-ruleset.js

# Test recursive rulesets
node test-recursive-ruleset.js
```

These scripts will verify that all ruleset files are loaded correctly and report statistics on the number of rules.

## Using Rulesets with Spectral

To use the generated rulesets with Spectral in your code:

```javascript
import { Spectral } from '@stoplight/spectral-core';
import { getCombinedRuleset } from './spectral-rulesets/combined-ruleset.js';

async function validateApiDefinition(apiDefinition, componentType) {
  // Get the combined ruleset
  const combinedRuleset = await getCombinedRuleset();
  
  // Get the ruleset for the specific component type
  const ruleset = combinedRuleset[`api.ibm.com_v1_${componentType.toLowerCase()}.ruleset.yaml`];
  
  if (!ruleset) {
    throw new Error(`No ruleset found for component type: ${componentType}`);
  }
  
  // Create a new Spectral instance
  const spectral = new Spectral();
  
  // Set the ruleset
  spectral.setRuleset(ruleset);
  
  // Run validation
  const results = await spectral.run(apiDefinition);
  
  return results;
}

// Example usage
const apiDefinition = {
  kind: "API",
  apiVersion: "api.ibm.com/v1",
  metadata: {
    name: "example-api",
    version: "1.0.0"
  },
  spec: {
    "api-spec": {
      "$path": "/path/to/api-spec"
    },
    "policy-sequence": [
      { "$ref": "reference/to/policy" }
    ]
  }
};

validateApiDefinition(apiDefinition, "API")
  .then(results => {
    if (results.length === 0) {
      console.log("API definition is valid!");
    } else {
      console.log("Validation errors:", results);
    }
  })
  .catch(error => {
    console.error("Validation failed:", error);
  });
```

## Customizing Rules

You can customize the generated rules by editing the ruleset files directly or by modifying the generator scripts.

### Editing Ruleset Files

Each ruleset file follows this structure:

```javascript
export default {
  "rules": {
    "rule-name": {
      "description": "Rule description",
      "severity": "error",
      "given": "$",
      "then": {
        "field": "fieldName",
        "function": "truthy"
      }
    },
    // More rules...
  }
};
```

You can add, modify, or remove rules as needed.

### Modifying Generator Scripts

To customize the rule generation logic:

1. Open the generator script (`generate-rulesets.js`, `enhanced-generate-rulesets.js`, or `recursive-generate-rulesets.js`)
2. Modify the relevant functions to change how rules are generated
3. Run the script to regenerate the ruleset files

#### Customizing the Recursive Generator

The recursive generator uses a powerful recursive function called `processObjectProperties` that can be customized to:

- Change the depth of recursion (default is 10 levels)
- Add special handling for specific property types
- Modify rule severity based on property paths
- Add custom validation logic for specific properties

## Troubleshooting

### Common Issues

1. **Module not found errors**: Make sure you're using the correct import paths and that all dependencies are installed.

2. **Schema component not found**: Check that the component name matches exactly what's in the OpenAPI specification.

3. **Validation not working as expected**: Verify that the ruleset is being loaded correctly and that the API definition matches the expected structure.

### Debugging Tips

- Use `console.log` to debug the ruleset generation process
- Check the structure of the generated ruleset files
- Run the test scripts to verify that rulesets are loaded correctly

## Updating Rulesets After Schema Changes

When the OpenAPI specification changes:

1. Run the appropriate generator to regenerate all ruleset files:
   ```bash
   # For basic rules
   node generate-rulesets.js
   
   # For enhanced rules
   node enhanced-generate-rulesets.js
   
   # For recursive rules
   node recursive-generate-rulesets.js
   ```

2. Update the combined ruleset file if new components were added:
   ```bash
   # Edit combined-ruleset.js to include new components
   ```

3. Test the updated rulesets:
   ```bash
   # Test the appropriate ruleset
   node test-recursive-ruleset.js
   ```

4. Commit the changes to version control.

// Made with Bob
