# Registry Generation Flow - SunLint Rules

> **Document này giải thích chi tiết cách SunLint generate rule registry từ markdown files**

---

## 🎯 Core Concept

**QUAN TRỌNG:** Rule names và descriptions trong SunLint được quản lý tập trung tại **markdown files**, KHÔNG phải JSON configs hay source code.

```
Markdown Files = SOURCE OF TRUTH
         ↓
   Auto Generation
         ↓
Registry JSON Files
```

---

## 📊 Luồng Generation Chi Tiết

### 1. Source Files (Markdown)

**Location:** `coding-quality/rules/`

```
coding-quality/rules/
├── common-en.md          # Common rules (C001-C076)
├── dart-en.md            # Dart-specific rules (D001-D025)
├── security-en.md        # Security rules (S001-S060)
├── typescript-en.md      # TypeScript rules (T001-T021)
├── java-en.md            # Java rules (J001-J006)
├── kotlin-mobile-en.md   # Kotlin rules (K001-K034)
├── reactjs-en.md         # React rules (R001-R009)
└── swift-en.md           # Swift rules (SW001-SW035)
```

**Format trong markdown:**

```markdown
### 📘 Rule D001 – Recommended Lint Rules Should Be Enabled

- **Objective**: Ensure code quality through standard lint configurations
- **Details**: The `analysis_options.yaml` file should include recommended lint packages...
- **Applies to**: Flutter/Dart
- **Tools**: `dart lint` (flutter_lints, very_good_analysis, lints)
- **Principles**: CODE_QUALITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: major
```

### 2. Copy Rules Script

**Script:** `coding-quality/extensions/sunlint/scripts/copy-rules.js`

**Chức năng:**
- Copy tất cả `*-en.md` files từ `coding-quality/rules/`
- Đến `coding-quality/extensions/sunlint/origin-rules/`
- Chỉ copy English versions (`*-en.md`)

**Command:**
```bash
cd coding-quality/extensions/sunlint
node scripts/copy-rules.js
```

**Output:**
```
📋 Copying all rules for packaging...
Source: /path/to/coding-quality/rules
Target: /path/to/coding-quality/extensions/sunlint/origin-rules
✅ Copied: common-en.md
✅ Copied: dart-en.md
✅ Copied: security-en.md
...
✅ Successfully copied 8 rule files
```

**Result:**
```
coding-quality/extensions/sunlint/origin-rules/
├── common-en.md          # Copied from ../../../rules/
├── dart-en.md            # Copied from ../../../rules/
├── security-en.md        # Copied from ../../../rules/
└── ...
```

### 3. Generate Registry Script

**Script:** `coding-quality/extensions/sunlint/scripts/generate-rules-registry.js`

**Chức năng:**
- Parse tất cả files trong `origin-rules/`
- Extract rule information từ markdown format
- Generate JSON registry file

**Parser Logic:**

```javascript
// Tìm rule header: ### 📘 Rule D001 – Rule Name
const ruleHeaderRegex = /###\s*📘\s*Rule\s+([A-Z]+\d+)\s*[–-]\s*(.+)/;

// Parse rule properties
- **Objective**: ${objective}
- **Details**: ${details}
- **Applies to**: ${appliesTo}
- **Tools**: ${tools}
- **Principles**: ${principles}
- **Version**: ${version}
- **Status**: ${status}
- **Severity**: ${severity}
```

**Command:**
```bash
node scripts/generate-rules-registry.js
```

**Output:**
```
📋 Generating rules registry from origin-rules...
Found 8 English rule files
Parsed rule C001: 0 good examples, 0 bad examples, 0 configs
Parsed rule C002: 0 good examples, 0 bad examples, 0 configs
...
Parsed rule D001: 0 good examples, 0 bad examples, 0 configs
...
✅ Generated registry with 257 rules
📁 File: config/rules/rules-registry-generated.json (156.2 KB)
```

### 4. Generated Registry File

**Output File:** `config/rules/rules-registry-generated.json`

**Structure:**

```json
{
  "rules": {
    "D001": {
      "name": "Recommended Lint Rules Should Be Enabled",
      "description": "Ensure code quality through standard lint configurations",
      "category": "Common",
      "severity": "major",
      "languages": ["dart"],
      "version": "1.0",
      "status": "activated",
      "tags": ["Common", "readability", "code-quality"],
      "tools": ["`dart lint` (flutter_lints, very_good_analysis, lints)"],
      "framework": "All",
      "principles": ["CODE_QUALITY"]
    },
    "D002": {
      ...
    }
  }
}
```

---

## 🔄 Complete Flow Diagram

```
┌─────────────────────────────────────────────────────────────┐
│ Step 1: Markdown Files (SOURCE OF TRUTH)                    │
│ Location: coding-quality/rules/                             │
│                                                              │
│ Files:                                                       │
│   - common-en.md                                            │
│   - dart-en.md ← EDIT HERE to change rule names            │
│   - security-en.md                                          │
│   - typescript-en.md                                        │
│   - ...                                                     │
└──────────────────────┬───────────────────────────────────────┘
                       │
                       ↓
┌──────────────────────────────────────────────────────────────┐
│ Step 2: Copy Rules Script                                    │
│ Command: node scripts/copy-rules.js                          │
│                                                               │
│ Action:                                                       │
│   - Copy *-en.md from rules/ to origin-rules/               │
│   - Only English versions                                    │
└──────────────────────┬────────────────────────────────────────┘
                       │
                       ↓
┌──────────────────────────────────────────────────────────────┐
│ Intermediate: origin-rules/                                  │
│ Location: coding-quality/extensions/sunlint/origin-rules/   │
│                                                               │
│ Files: (Copies of source markdown files)                    │
│   - common-en.md                                            │
│   - dart-en.md                                              │
│   - ...                                                     │
└──────────────────────┬────────────────────────────────────────┘
                       │
                       ↓
┌──────────────────────────────────────────────────────────────┐
│ Step 3: Generate Registry Script                             │
│ Command: node scripts/generate-rules-registry.js             │
│                                                               │
│ Action:                                                       │
│   - Parse all *-en.md in origin-rules/                      │
│   - Extract rule ID, name, description, etc.                │
│   - Generate JSON structure                                 │
└──────────────────────┬────────────────────────────────────────┘
                       │
                       ↓
┌──────────────────────────────────────────────────────────────┐
│ Step 4: Generated Registry (AUTO-GENERATED)                 │
│ File: config/rules/rules-registry-generated.json            │
│                                                               │
│ Content:                                                     │
│   {                                                          │
│     "rules": {                                               │
│       "D001": {                                              │
│         "name": "Recommended Lint Rules...",                │
│         "description": "...",                                │
│         ...                                                  │
│       }                                                      │
│     }                                                        │
│   }                                                          │
└──────────────────────┬────────────────────────────────────────┘
                       │
                       ↓
┌──────────────────────────────────────────────────────────────┐
│ Step 5: Used by SunLint CLI & VSCode Extension              │
│                                                               │
│ Usage:                                                       │
│   - UnifiedRuleRegistry loads this JSON                     │
│   - Displays rule names to users                            │
│   - Shows descriptions in error messages                    │
└──────────────────────────────────────────────────────────────┘
```

---

## 🛠️ Practical Usage

### When Creating a New Dart Rule

```bash
# 1. Create rule implementation
vim dart_analyzer/lib/rules/dart/D026_new_rule.dart

# 2. Register in analyzer service
vim dart_analyzer/lib/analyzer_service.dart

# 3. UPDATE MARKDOWN FILES (CRITICAL!)
vim ../../../rules/dart-en.md    # Add rule definition
vim ../../../rules/dart.md       # Add Vietnamese version

# 4. Create examples
vim ../../../rules/examples/en/D026.md
vim ../../../rules/examples/vi/D026.md

# 5. GENERATE REGISTRY (CRITICAL!)
node scripts/copy-rules.js
node scripts/generate-rules-registry.js

# 6. Rebuild Dart binary
cd dart_analyzer
dart compile exe bin/sunlint_dart_analyzer.dart -o bin/sunlint-dart-macos
cp bin/sunlint-dart-macos ../sunlint-dart-macos
cd ..

# 7. Test
node cli.js --rule=D026 --input=/path/to/project --languages=dart
```

### When Updating an Existing Rule Name

```bash
# 1. UPDATE MARKDOWN FIRST
vim ../../../rules/dart-en.md
# Change: ### 📘 Rule D001 – OLD NAME
# To:     ### 📘 Rule D001 – NEW NAME

vim ../../../rules/dart.md
# Update Vietnamese version too

# 2. REGENERATE REGISTRY
node scripts/copy-rules.js
node scripts/generate-rules-registry.js

# 3. Verify the change
grep -A 5 '"D001"' config/rules/rules-registry-generated.json

# 4. Update Dart code comment (optional, for consistency)
vim dart_analyzer/lib/rules/dart/D001_*.dart
# Update: /// D001: NEW NAME

# 5. Test to see new name
node cli.js --rule=D001 --input=/path/to/project --languages=dart
```

---

## 📋 Files Reference

### Source Files (Edit These)

| File | Purpose | When to Edit |
|------|---------|--------------|
| `../../../rules/dart-en.md` | Rule definitions (English) | Adding/updating Dart rules |
| `../../../rules/dart.md` | Rule definitions (Vietnamese) | Adding/updating Dart rules |
| `../../../rules/common-en.md` | Common rules definitions | Adding/updating common rules |
| `../../../rules/security-en.md` | Security rules definitions | Adding/updating security rules |

### Intermediate Files (Auto-copied)

| File | Purpose | Generated By |
|------|---------|--------------|
| `origin-rules/dart-en.md` | Copied source | `scripts/copy-rules.js` |
| `origin-rules/common-en.md` | Copied source | `scripts/copy-rules.js` |

### Generated Files (DO NOT EDIT MANUALLY)

| File | Purpose | Generated By |
|------|---------|--------------|
| `config/rules/rules-registry-generated.json` | Main registry | `scripts/generate-rules-registry.js` |

### Other Registry Files

| File | Purpose | Notes |
|------|---------|-------|
| `config/rules-summary.json` | Summary view | May need manual update if not generated |
| `config/rules/enhanced-rules-registry.json` | Enhanced registry | Different format, separate system |

---

## ⚠️ Common Mistakes

### ❌ Mistake 1: Edit Registry JSON Directly

```bash
# WRONG! Will be overwritten
vim config/rules/rules-registry-generated.json
# Change: "name": "Old Name"
# To:     "name": "New Name"
```

**Why it's wrong:** Next time someone runs `generate-rules-registry.js`, your changes will be lost.

**Correct approach:**
```bash
# RIGHT! Edit source markdown
vim ../../../rules/dart-en.md
# Then regenerate
node scripts/copy-rules.js && node scripts/generate-rules-registry.js
```

### ❌ Mistake 2: Put Display Name in config.json

```json
// WRONG! Not used for display
{
  "id": "D001",
  "name": "My Display Name",  // ❌ Not read by registry
  "category": "dart"
}
```

**Why it's wrong:** `config.json` is only used for rule detection, not for display names.

**Correct approach:**
```markdown
<!-- RIGHT! Put in markdown -->
### 📘 Rule D001 – My Display Name
```

### ❌ Mistake 3: Forget to Regenerate Registry

```bash
# Edit markdown
vim ../../../rules/dart-en.md

# Test immediately
node cli.js --rule=D001 --input=...  # ❌ Still shows old name!
```

**Why it's wrong:** Registry hasn't been regenerated yet.

**Correct approach:**
```bash
# Edit markdown
vim ../../../rules/dart-en.md

# MUST regenerate
node scripts/copy-rules.js
node scripts/generate-rules-registry.js

# Now test
node cli.js --rule=D001 --input=...  # ✅ Shows new name
```

---

## 🔍 Debugging Registry Issues

### Check if Rule Exists in Registry

```bash
# Search for rule in generated registry
grep -A 10 '"D001"' config/rules/rules-registry-generated.json
```

Expected output:
```json
"D001": {
  "name": "Recommended Lint Rules Should Be Enabled",
  "description": "Ensure code quality through standard lint configurations",
  ...
}
```

### Check Markdown Format

```bash
# Check rule definition format in markdown
grep -A 10 "### 📘 Rule D001" ../../../rules/dart-en.md
```

Expected format:
```markdown
### 📘 Rule D001 – Recommended Lint Rules Should Be Enabled

- **Objective**: ...
- **Details**: ...
```

### Verify Copy Step

```bash
# Check if markdown was copied to origin-rules
ls -la origin-rules/dart-en.md

# Compare with source
diff ../../../rules/dart-en.md origin-rules/dart-en.md
```

Should show no differences (or only whitespace/timestamps).

### Test Registry Parser

```bash
# Run generator with verbose output
node scripts/generate-rules-registry.js 2>&1 | grep D001
```

Expected:
```
Parsed rule D001: 0 good examples, 0 bad examples, 0 configs
```

---

## 📚 Related Documentation

- [CREATE_NEW_DART_RULE.md](./skills/CREATE_NEW_DART_RULE.md) - How to create new Dart rules
- [PROJECT_STRUCTURE.md](./PROJECT_STRUCTURE.md) - Overall project structure
- [rules/parser/rule-parser-simple.js](../rules/parser/rule-parser-simple.js) - Parser implementation

---

## 🎓 Key Takeaways

1. **Markdown files** are the single source of truth for rule names and descriptions
2. **Always regenerate** registry after updating markdown files
3. **Never edit** `rules-registry-generated.json` manually
4. **Copy → Generate** is a two-step process that must be done together
5. **Verify** changes in generated JSON before testing

---

## 📝 Version History

### v1.0.0 (2025-01-23)
- Initial documentation of registry generation flow
- Added complete flow diagram
- Added common mistakes and debugging sections
- Added practical usage examples
