# Competitor Data Maintenance Guide


**Last Updated:** 2025-11-20

This guide explains how to maintain competitor data in `v2/data/competitors_data.php`, including adding new competitors, updating existing data, and validating changes.

## Data Structure Reference

### Basic Entry Structure

```php
'{slug}' => [
    'slug' => '{slug}',
    'name' => '{Display Name}',
    'rating' => '{rating}', // e.g., '4.3'
    'reviews' => '{count}', // e.g., '368'
    'description' => '{Full description paragraph}',
    'category' => '{Category}', // e.g., 'HR-Software', 'Zeiterfassung'
    'focus' => '{Focus/Use Case}',
    'target' => '{Target Audience}', // e.g., 'Unternehmen', 'Agenturen'
    'logo_alt' => '{Logo Alt Text}',
    'logo_class' => '{CSS Classes}', // e.g., 'brightness-0 invert' or ''
    'pricing' => [
        'starting_price' => '{price}',  // Keep for backward compatibility, e.g., '89.00'
        'price_unit' => '{unit}',       // Fallback if no plans, e.g., 'pro Standort pro Monat'
        'currency' => '{currency}',     // e.g., 'EUR', 'USD'
        'plans' => [                     // Optional: array of pricing plans
            [
                'name' => '{Plan Name}',                    // Required: e.g., 'Starter', 'Basic', 'Professional'
                'description' => '{Description}',            // Optional: plan description
                'price' => '{price}',                       // Required: numeric string (e.g., '89.00') or text ('Auf Anfrage', 'Kostenlos')
                'price_text' => '{Formatted Price}',        // Optional: formatted display text (e.g., '€89,00')
                'frequency' => '{Frequency}',               // Optional: e.g., '/ User / Monat', '/ Standort / Monat'
                'recommendation' => '{Recommendation}',     // Optional: e.g., 'Empfohlen für 1-5 User'
            ],
            // ... more plans
        ],
    ],
    'faq' => [
        [
            'question' => '{Question text}',
            'answer' => '{Answer text with HTML allowed}',
        ],
        // ... more FAQ items
    ],
    'rating_distribution' => [
        '5' => ['percentage' => {int}, 'count' => {int}],
        '4' => ['percentage' => {int}, 'count' => {int}],
        '3' => ['percentage' => {int}, 'count' => {int}],
        '2' => ['percentage' => {int}, 'count' => {int}],
        '1' => ['percentage' => {int}, 'count' => {int}],
    ],
    'detailed_ratings' => [
        'benutzerfreundlichkeit' => [
            'score' => {float},
            'category' => '{category}',
            'average' => {float},
        ],
        // ... more detailed ratings
    ],
    'schema' => [
        'name' => '{Schema Name}',
        'description' => '{Schema Description}',
        'url' => '{url-slug}',
    ],
    'has_details' => true|false,
    'details' => [ // Only if has_details is true
        'sections' => [
            [
                'title' => '{Section Title}',
                'type' => 'list'|'paragraph'|'mixed',
                'items' => ['Item 1', 'Item 2'], // for list type
                'content' => '{Paragraph content}', // for paragraph type
                'items_with_descriptions' => [ // for mixed type
                    [
                        'title' => '{Item Title}',
                        'description' => '{Item Description}',
                    ],
                ],
            ],
        ],
    ],
],
```

## Adding a New Competitor

### Step 1: Gather Required Information

Collect the following data:

- Competitor name and slug
- Rating and review count
- Full product description
- Category and focus
- Target audience
- Pricing information
- FAQ items (5-7 questions)
- Rating distribution (if available)
- Detailed ratings (if available)
- Logo information
- Details section (if applicable)

### Step 2: Create Entry in competitors_data.php

1. **Open `v2/data/competitors_data.php`**
2. **Find `getAllCompetitorsData()` function**
3. **Add new entry** in alphabetical order by slug
4. **Follow structure** from existing entries
5. **Set `has_details`** based on whether Details section exists

### Step 3: Validate Entry

```bash
php -l v2/data/competitors_data.php
```

Check for:

- Valid PHP syntax
- No double commas
- Proper string escaping
- Matching brackets
- Correct array structure

### Step 4: Test Entry

```php
require_once 'v2/data/competitors_data.php';
$competitor = getCompetitorData('{slug}');
var_dump($competitor);
```

Verify:

- Entry loads correctly
- All fields present
- Data structure matches expectations

## Updating Existing Competitor Data

### Step 1: Identify What Needs Updating

Common update scenarios:

- Rating/review count changed
- Pricing updated
- Description needs revision
- FAQ items added/removed
- Details section added/removed
- Logo information changed

### Step 2: Update Entry

1. **Find competitor entry** in `competitors_data.php`
2. **Update specific fields** (don't replace entire entry)
3. **Maintain structure** and formatting
4. **Update related fields** if needed (e.g., if rating changes, update distribution)

### Step 3: Validate Changes

```bash
php -l v2/data/competitors_data.php
```

### Step 4: Verify in Browser

Test the comparison page to ensure:

- Data displays correctly
- No visual issues
- Details section works (if applicable)
- FAQ accordion functions

## Validation Procedures

### Syntax Validation

Always validate PHP syntax after changes:

```bash
php -l v2/data/competitors_data.php
```

### Data Consistency Validation

Run validation scripts:

```bash
python3 scripts/data/validate_extracted_data.py
php scripts/data/validate_and_compare.php
```

### Rating Distribution Validation

Ensure:

- Rating distribution counts sum to total reviews
- Percentages sum to ~100% (allow 95-105% range)
- All star levels (1-5) have entries

### FAQ Validation

Check:

- All FAQ items have both question and answer
- Answers contain proper HTML formatting
- No empty questions or answers
- Typical count: 5-7 FAQ items per competitor

### Details Section Validation

If `has_details` is true:

- Verify `details['sections']` array exists
- Check each section has `title` and `type`
- Verify content matches type (items for list, content for paragraph, etc.)
- Ensure proper string escaping

## Common Update Scenarios

### Scenario 1: Rating Changed

**Update:**

- `rating` field
- `rating_distribution` (if available)
- `schema['rating']` (if present)

**Validate:**

- Rating distribution still sums correctly
- No syntax errors

### Scenario 2: Pricing Updated

**For Simple Pricing:**

- `pricing['starting_price']`
- `pricing['price_unit']` (if changed)
- `pricing['currency']` (if changed)

**For Multi-Plan Pricing:**

- `pricing['plans']` array with plan entries
- Each plan must have `name` and `price` (required)
- Optional fields: `description`, `price_text`, `frequency`, `recommendation`
- Price can be numeric string (e.g., '89.00') or text ('Auf Anfrage', 'Kostenlos', 'Individuelles Angebot')

**Validate:**

- Price format is consistent (e.g., '89.00' not '89')
- Currency code is correct
- Plans array has required fields (name, price)
- Price format is valid (numeric or known text values)

### Scenario 3: Description Revised

**Update:**

- `description` field
- `schema['description']` (if present)

**Validate:**

- Description is full text, not placeholder
- No HTML in description (unless intentional)
- Proper string escaping

### Scenario 4: FAQ Added/Removed

**Update:**

- `faq` array

**Validate:**

- All items have question and answer
- Array structure is correct
- No syntax errors

### Scenario 5: Details Section Added

**Update:**

- Set `has_details` to `true`
- Add `details['sections']` array

**Validate:**

- Section structure matches component expectations
- Content type matches structure (list/paragraph/mixed)
- Proper string escaping for all content

## String Escaping Rules

### Single Quotes

Escape single quotes in strings:

```php
'description' => 'It\'s a great tool',
```

### Backslashes

Escape backslashes:

```php
'description' => 'Path: C:\\Users\\...',
```

### Newlines

Use `\n` for newlines in strings:

```php
'content' => 'Line 1\nLine 2',
```

### HTML in Answers

FAQ answers can contain HTML:

```php
'answer' => '<strong>Bold text</strong> and <a href="#">links</a>',
```

## Best Practices

1. **Always Backup** before making changes
2. **Validate Syntax** after every change
3. **Test in Browser** before committing
4. **Follow Existing Patterns** for consistency
5. **Document Changes** in commit messages
6. **Review Related Fields** when updating (e.g., rating → distribution)
7. **Use Descriptive Slugs** (lowercase, hyphens for spaces)
8. **Maintain Alphabetical Order** in entries
9. **Keep Descriptions Full** (not placeholders)
10. **Verify Details Sections** structure matches component

## Troubleshooting

### Issue: PHP Syntax Error

**Check:**

- Double commas (`,,`)
- Unmatched brackets
- String escaping
- Trailing commas

**Fix:**

- Remove double commas
- Match brackets
- Escape special characters
- Remove trailing commas in arrays

### Issue: Entry Not Loading

**Check:**

- Slug matches exactly (case-sensitive)
- Entry exists in `getAllCompetitorsData()` array
- No syntax errors preventing file load

**Fix:**

- Verify slug spelling
- Check entry is in correct array
- Fix syntax errors

### Issue: Details Section Not Displaying

**Check:**

- `has_details` is `true`
- `details['sections']` exists
- Section structure is correct
- Component includes Details section

**Fix:**

- Set `has_details` to `true`
- Add `details['sections']` array
- Verify structure matches component expectations
- Check component includes Details section

## Related Documentation

- `docs/guides/comparison-pages/COMPARISON_PAGES_GUIDE.md` - Comparison page creation
- `docs/guides/comparison-pages/DATA_MIGRATION_GUIDE.md` - Data migration process
- `docs/audit/comparison-pages/MASTER_AUDIT_REPORT.md` - Audit findings
- `.cursor/rules/comparison-pages.mdc` - Cursor rules
