# Workflow Permission Management Solution

## Problem

Previously, workflow step permissions were generated using database IDs (`step_{id}`), causing permission mappings to break when workflows were republished:

1. **Old System**: `step_123`, `step_124`, etc.
2. **Issue**: New workflow versions get new database IDs
3. **Result**: Permission-to-role mappings are lost

## Solution

### 1. Stable Permission Naming

Changed `StepTemplate::getPermissionName()` to use stable identifiers:

```php
// New stable format:
workflow_{orgId}_{subjectType}_{systemKey}
// OR (fallback):
workflow_{orgId}_{subjectType}_pos{position}_{labelSlug}
```

**Examples**:
- `workflow_1_Order_approval`
- `workflow_1_ProjectCharter_pos2_financial_review`

### 2. Permission Migration Service

Created `PermissionMigrator` service that:
- Migrates old `step_*` permissions to new stable names
- Preserves all role-permission mappings
- Cleans up orphaned permissions

### 3. Automatic Migration

Modified `TemplatePublisher` to automatically run migration on publish:
- Ensures permissions are migrated when workflow is published
- Preserves existing role assignments

### 4. Migration Command

Added `workflow:migrate-permissions` Artisan command:

```bash
# Migrate permissions
php artisan workflow:migrate-permissions

# Include cleanup of orphaned permissions
php artisan workflow:migrate-permissions --cleanup

# Dry run to see what would change
php artisan workflow:migrate-permissions --dry-run
```

## Benefits

1. **Permission Stability**: Step permissions remain consistent across workflow versions
2. **Role Preservation**: User access is maintained when workflows are republished
3. **Backward Compatibility**: Automatic migration from old to new system
4. **Clean Architecture**: Stable naming based on business logic, not database internals

## Usage

### For Fresh Systems (No Existing Data)

The system automatically uses stable naming. Optionally run:
```bash
# Ensure all workflow permissions exist
php artisan workflow:ensure-permissions

# Preview what permissions would be created
php artisan workflow:ensure-permissions --dry-run
```

### For Systems with Existing Workflows

Run the migration command once to convert existing permissions:
```bash
php artisan workflow:migrate-permissions --cleanup
```

### Commands Reference

| Command | Purpose | Use Case |
|---------|---------|----------|
| `workflow:ensure-permissions` | Create missing permissions with stable names | Fresh systems |
| `workflow:migrate-permissions` | Migrate old permissions to stable names | Legacy systems |
| `--dry-run` | Preview changes without applying | Testing |
| `--cleanup` | Remove orphaned permissions | Maintenance |

### Permission Format Details

**With System Key** (Preferred):
- Format: `workflow_{orgId}_{subjectType}_{systemKey}`
- Example: `workflow_1_Order_approval`
- Stable across all workflow versions

**Without System Key** (Fallback):
- Format: `workflow_{orgId}_{subjectType}_pos{position}_{labelSlug}`  
- Example: `workflow_1_Order_pos3_quality_check`
- Stable as long as position and label don't change

## Testing

The solution includes comprehensive testing via:
- Dry-run mode to preview changes
- Transaction-based migrations for safety
- Detailed logging of all permission changes