Breaking Changes - Grazulex/laravel-arc GitHub Wiki

๐Ÿšจ Breaking Changes

Laravel Arc v2.0 Breaking Changes

This document outlines all breaking changes introduced in Laravel Arc v2.0. While we've maintained backward compatibility where possible, some changes were necessary to improve the package's architecture and features.

๐Ÿ”„ Major Changes

1. Unified Property Attribute

Impact: High - Requires manual migration

Before (v1.x):

use LaravelArc\Attributes\PropertyType;
use LaravelArc\Attributes\Required;
use LaravelArc\Attributes\Validation;
use LaravelArc\Attributes\Default;

class User extends Model
{
    #[PropertyType('string')]
    #[Required(true)]
    #[Validation('min:2|max:100')]
    #[Default('Guest')]
    public string $name;
}

After (v2.0):

use Grazulex\LaravelArc\Attributes\Property;
use Grazulex\LaravelArc\Traits\HasArcProperties;

class User extends Model
{
    use HasArcProperties;

    #[Property(
        type: 'string',
        required: true,
        minLength: 2,
        maxLength: 100,
        default: 'Guest'
    )]
    public string $name;
}

Migration Path:

  • Replace multiple attributes with single #[Property()] attribute
  • Add HasArcProperties trait to models
  • Update validation syntax to use parameter-based rules

2. Namespace Changes

Impact: High - Requires import updates

Changed Namespaces:

v1.x v2.0
LaravelArc\Attributes\* Grazulex\LaravelArc\Attributes\*
LaravelArc\Traits\* Grazulex\LaravelArc\Traits\*
LaravelArc\Exceptions\* Grazulex\LaravelArc\Exceptions\*
LaravelArc\Contracts\* Grazulex\LaravelArc\Contracts\*

Migration Path:

  • Update all use statements to new namespace
  • Search and replace across codebase
  • Update any string references to class names

3. Method Signature Changes

Impact: Medium - May require code updates

validateAttributes() โ†’ validateData()

Before (v1.x):

$isValid = $model->validateAttributes($data);
// Returns: boolean

After (v2.0):

$validator = $model->validateData($data);
$isValid = !$validator->fails();
// Returns: Illuminate\Validation\Validator

getAttributeDefinition() โ†’ getArcProperty()

Before (v1.x):

$definition = $model->getAttributeDefinition('name');

After (v2.0):

$property = $model->getArcProperty('name');

setAttributeValue() โ†’ setArcProperty()

Before (v1.x):

$model->setAttributeValue('name', 'John');

After (v2.0):

$model->setArcProperty('name', 'John');

4. Configuration Structure

Impact: Medium - Requires config file update

Before (v1.x):

// config/laravel-arc.php
return [
    'strict_mode' => false,
    'auto_validation' => true,
    'cache_enabled' => true,
    'cache_ttl' => 3600,
];

After (v2.0):

// config/laravel-arc.php
return [
    'auto_discovery' => [
        'enabled' => true,
        'cache_duration' => 3600,
    ],
    'validation' => [
        'auto_generate' => true,
        'strict_mode' => false,
        'cache_rules' => true,
    ],
    'debug' => [
        'enabled' => env('APP_DEBUG', false),
        'log_transformations' => false,
    ],
    'pipeline' => [
        'cache_results' => true,
        'parallel_processing' => false,
    ],
];

Migration Path:

  • Republish configuration file: php artisan vendor:publish --provider="Grazulex\LaravelArc\LaravelArcServiceProvider" --tag="config" --force
  • Map old settings to new structure
  • Test configuration changes

5. Validation Rule Format

Impact: Medium - Automatic migration in most cases

Before (v1.x):

#[Validation('min:5|max:100|unique:users,email')]
public string $email;

After (v2.0):

#[Property(
    type: 'email',
    minLength: 5,
    maxLength: 100,
    rules: ['unique:users,email']
)]
public string $email;

Migration Path:

  • Convert string validation rules to parameter-based rules where possible
  • Use rules parameter for complex/custom validation rules
  • Test validation behavior after migration

๐Ÿ”ง Minor Changes

6. Enum Attribute Consolidation

Impact: Low - Simple syntax change

Before (v1.x):

#[PropertyType('enum')]
#[EnumClass(UserStatus::class)]
public UserStatus $status;

After (v2.0):

#[Property(type: 'enum', enum: UserStatus::class)]
public UserStatus $status;

7. Custom Cast Attribute

Impact: Low - Simple syntax change

Before (v1.x):

#[PropertyType('object')]
#[CustomCast(Money::class)]
public Money $price;

After (v2.0):

#[Property(type: 'object', cast: Money::class)]
public Money $price;

8. Default Value Attribute

Impact: Low - Simple syntax change

Before (v1.x):

#[PropertyType('string')]
#[Default('active')]
public string $status;

After (v2.0):

#[Property(type: 'string', default: 'active')]
public string $status;

๐Ÿšซ Removed Features

9. Deprecated Attributes

Impact: High - Must migrate to new syntax

Removed Attributes:

  • #[PropertyType()]
  • #[Required()]
  • #[Validation()]
  • #[Default()]
  • #[EnumClass()]
  • #[CustomCast()]
  • #[Nullable()]
  • #[MinLength()]
  • #[MaxLength()]

Migration Path: All functionality is now available through the unified #[Property()] attribute.

10. Legacy Method Aliases

Impact: Medium - Update method calls

Removed Methods:

  • validateAttributes() โ†’ Use validateData()
  • getAttributeDefinition() โ†’ Use getArcProperty()
  • setAttributeValue() โ†’ Use setArcProperty()
  • getAttributeRules() โ†’ Use getValidationRules()

11. Old Configuration Keys

Impact: Medium - Update configuration

Removed Configuration Keys:

  • strict_mode โ†’ Use validation.strict_mode
  • auto_validation โ†’ Use validation.auto_generate
  • cache_enabled โ†’ Use validation.cache_rules and pipeline.cache_results
  • cache_ttl โ†’ Use auto_discovery.cache_duration

โš ๏ธ Behavioral Changes

12. Validation Error Handling

Impact: Low - Better error information

Before (v1.x):

try {
    $model->save();
} catch (ValidationException $e) {
    $errors = $e->getMessage(); // String message
}

After (v2.0):

try {
    $model->save();
} catch (ValidationException $e) {
    $errors = $e->errors(); // Detailed error array
    $messages = $e->getMessages(); // Formatted messages
}

13. Type Casting Behavior

Impact: Low - More predictable casting

Change: Type casting is now more strict and consistent. Values that cannot be safely cast will throw exceptions instead of silent failures.

Before (v1.x):

$model->age = 'invalid'; // Might silently fail or cast unpredictably

After (v2.0):

$model->age = 'invalid'; // Throws TypeException with clear message

14. Validation Rule Generation

Impact: Low - More comprehensive rules

Change: Validation rules are now generated more intelligently, with better support for complex types and relationships.

๐Ÿ” Migration Detection

Automated Detection

Use the built-in analysis command to detect migration needs:

# Analyze all models for migration needs
php artisan arc:analyze --migration

# Get detailed migration report
php artisan arc:analyze --migration --verbose

# Check specific model
php artisan arc:analyze --model=User --migration

Manual Detection

Search your codebase for these patterns:

# Find old attribute usage
grep -r "#\[PropertyType" app/
grep -r "#\[Required" app/
grep -r "#\[Validation" app/

# Find old method calls
grep -r "validateAttributes" app/
grep -r "getAttributeDefinition" app/
grep -r "setAttributeValue" app/

# Find old namespace usage
grep -r "LaravelArc\\" app/

๐Ÿ› ๏ธ Migration Tools

Automated Migration Script

#!/usr/bin/env php
<?php
// migrate-to-v2.php

require_once 'vendor/autoload.php';

class ArcV2Migrator
{
    private array $attributeMap = [
        'PropertyType' => 'type',
        'Required' => 'required',
        'Default' => 'default',
        'EnumClass' => 'enum',
        'CustomCast' => 'cast',
    ];

    public function migrateFile(string $filePath): void
    {
        $content = file_get_contents($filePath);
        $originalContent = $content;

        // Update namespaces
        $content = str_replace(
            'LaravelArc\\',
            'Grazulex\\LaravelArc\\',
            $content
        );

        // Add HasArcProperties trait
        $content = preg_replace(
            '/(class\s+\w+\s+extends\s+Model\s*\{)/',
            '$1\n    use HasArcProperties;\n',
            $content
        );

        // Convert old attributes to Property attribute
        $content = $this->convertAttributes($content);

        // Update method calls
        $content = $this->updateMethodCalls($content);

        if ($content !== $originalContent) {
            file_put_contents($filePath, $content);
            echo "Migrated: {$filePath}\n";
        }
    }

    private function convertAttributes(string $content): string
    {
        // This is a simplified example - real implementation would be more complex
        $patterns = [
            // Convert simple PropertyType
            '/\#\[PropertyType\([\'"]([^\'"]*)[\'"]+\)\]/' => '#[Property(type: \'$1\')]',
            
            // Convert PropertyType + Required
            '/\#\[PropertyType\([\'"]([^\'"]*)[\'"]+\)\]\s*\#\[Required\(([^)]*)\)\]/' => 
                '#[Property(type: \'$1\', required: $2)]',
        ];

        return preg_replace(array_keys($patterns), array_values($patterns), $content);
    }

    private function updateMethodCalls(string $content): string
    {
        $methodMap = [
            'validateAttributes' => 'validateData',
            'getAttributeDefinition' => 'getArcProperty',
            'setAttributeValue' => 'setArcProperty',
        ];

        foreach ($methodMap as $old => $new) {
            $content = str_replace($old, $new, $content);
        }

        return $content;
    }

    public function migrateDirectory(string $directory): void
    {
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($directory)
        );

        foreach ($iterator as $file) {
            if ($file->getExtension() === 'php') {
                $this->migrateFile($file->getPathname());
            }
        }
    }
}

// Usage
$migrator = new ArcV2Migrator();
$migrator->migrateDirectory('app/Models');
$migrator->migrateDirectory('app/Http/Controllers');
$migrator->migrateDirectory('tests');

echo "Migration complete! Please review changes and test thoroughly.\n";

Manual Migration Checklist

# 1. Update composer.json
"grazulex/laravel-arc": "^2.0"

# 2. Update dependencies
composer update

# 3. Republish config
php artisan vendor:publish --provider="Grazulex\LaravelArc\LaravelArcServiceProvider" --tag="config" --force

# 4. Clear caches
php artisan config:clear
php artisan cache:clear

# 5. Run analysis
php artisan arc:analyze --migration

# 6. Run tests
php artisan test

# 7. Manual code review
# Check for any remaining old syntax

๐Ÿงจ Testing Migration

Pre-Migration Tests

Before migrating, create tests to verify current functionality:

class PreMigrationTest extends TestCase
{
    public function test_current_validation_works()
    {
        $user = new User();
        $user->name = 'Test User';
        $user->email = '[email protected]';
        
        $this->assertTrue($user->save());
    }
    
    public function test_current_validation_fails()
    {
        $user = new User();
        $user->name = ''; // Invalid
        
        $this->expectException(ValidationException::class);
        $user->save();
    }
}

Post-Migration Tests

After migration, verify functionality still works:

class PostMigrationTest extends TestCase
{
    public function test_migrated_validation_works()
    {
        $user = new User();
        $user->name = 'Test User';
        $user->email = '[email protected]';
        
        $this->assertTrue($user->save());
    }
    
    public function test_new_features_work()
    {
        $user = new User();
        $user->name = '  test user  '; // Should be transformed
        
        $this->assertEquals('Test User', $user->name);
    }
}

๐ŸŽ† Benefits After Migration

After completing the migration, you'll have access to:

๐Ÿ†• New Features

  • Transformation Pipeline - Automatic data transformation
  • Auto-Discovery - Intelligent relationship detection
  • Enhanced Type Safety - Better PHP 8+ integration
  • Debug Tools - Built-in debugging and analysis
  • Performance Improvements - Better caching and optimization

๐Ÿ”ง Improved Developer Experience

  • Unified Syntax - Single attribute for all property configuration
  • Better IDE Support - Enhanced autocompletion and static analysis
  • Cleaner Code - Less verbose attribute syntax
  • Better Error Messages - More detailed validation feedback

๐Ÿš€ Performance Benefits

  • Improved Caching - Better performance for large applications
  • Memory Optimization - More efficient memory usage
  • Lazy Loading - Optional lazy loading for expensive operations

๐Ÿ†˜ Support

If you encounter issues during migration:

  1. Check Migration Guide for detailed instructions
  2. Use analysis tools: php artisan arc:analyze --migration
  3. Review FAQ for common migration issues
  4. Search GitHub Issues for similar problems
  5. Create an issue with specific migration problems
  6. Join Discussions for community help

Breaking changes are never fun, but v2.0's improvements make the migration worthwhile! ๐Ÿš€ The new unified syntax and powerful features will significantly improve your development experience.