Skip to content

Commit 029ada0

Browse files
committed
fix: wip
1 parent 6bdc34f commit 029ada0

File tree

5 files changed

+1414
-191
lines changed

5 files changed

+1414
-191
lines changed

README.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,146 @@ Once installed, you're ready to start coding with Cursor, Claude Code, or your A
4949
| Generate Action | Generate Laravel Restify action classes for custom business logic |
5050
| Generate Getter | Generate Laravel Restify getter classes for data transformation |
5151
| Generate Match Filter | Generate Laravel Restify match filter classes for advanced filtering |
52+
| Debug Application | Comprehensive debugging tool for Laravel Restify applications with health checks and diagnostics |
53+
| Upgrade Restify | Automated tool to upgrade Laravel Restify from version 9.x to 10.x with migration assistance |
5254

5355
## Available Documentation
5456

5557
| Package | Coverage |
5658
|---------|----------|
5759
| Laravel Restify | Complete documentation including API methods, field types, authentication, authorization, and performance guides |
5860

61+
## Specialized Tools
62+
63+
### Debug Application Tool
64+
65+
The Debug Application Tool provides comprehensive diagnostics for Laravel Restify applications, helping developers identify and resolve common issues quickly.
66+
67+
#### Features
68+
69+
- **System Health Check**: Laravel version, PHP compatibility, environment validation, cache/storage testing
70+
- **Configuration Analysis**: App config, database setup, Restify configuration validation
71+
- **Database Health**: Connection testing, migration status, performance checks
72+
- **Restify Analysis**: Repository discovery, route validation, service provider verification
73+
- **Performance Analysis**: Memory usage, cache/session driver optimization suggestions
74+
- **Automatic Issue Detection**: Severity classification with detailed reporting
75+
- **Safe Auto-Fixes**: Automatically resolve common configuration problems
76+
77+
#### Parameters
78+
79+
- `check_type` (optional): Target specific areas - 'all', 'config', 'database', 'restify', 'performance', 'health' (default: 'all')
80+
- `detailed_output` (optional): Include comprehensive diagnostic details (default: true)
81+
- `fix_issues` (optional): Automatically resolve common configuration problems (default: false)
82+
- `export_report` (optional): Save detailed markdown reports to storage/logs (default: false)
83+
- `include_suggestions` (optional): Provide actionable improvement recommendations (default: true)
84+
85+
#### Usage Examples
86+
87+
```bash
88+
# Run complete diagnostic
89+
Debug Application with check_type="all"
90+
91+
# Check only database health
92+
Debug Application with check_type="database"
93+
94+
# Run with automatic fixes
95+
Debug Application with fix_issues=true
96+
97+
# Export detailed report
98+
Debug Application with export_report=true detailed_output=true
99+
```
100+
101+
### Upgrade Restify Tool
102+
103+
The Upgrade Restify Tool automates the migration process from Laravel Restify 9.x to 10.x, ensuring smooth transitions with comprehensive analysis and backup creation.
104+
105+
#### Features
106+
107+
- **PHP Attributes Migration**: Converts static `$model` properties to modern `#[Model]` attributes
108+
- **Field-Level Configuration**: Migrates static `$search`/`$sort` arrays to field-level methods
109+
- **Configuration Compatibility**: Checks and validates config file compatibility
110+
- **Backup Creation**: Automatically creates backups before making changes
111+
- **Comprehensive Reporting**: Detailed analysis with migration recommendations
112+
- **Interactive Mode**: Confirmation prompts for each repository migration
113+
- **Complexity Scoring**: Evaluates repository complexity for prioritization
114+
115+
#### Parameters
116+
117+
- `dry_run` (optional): Preview changes without applying them (default: true)
118+
- `migrate_attributes` (optional): Convert static `$model` properties to PHP attributes (default: true)
119+
- `migrate_fields` (optional): Convert static `$search`/`$sort` arrays to field-level methods (default: true)
120+
- `check_config` (optional): Check and report config file compatibility (default: true)
121+
- `backup_files` (optional): Create backups of modified files (default: true)
122+
- `interactive` (optional): Prompt for confirmation before each change (default: true)
123+
- `path` (optional): Specific path to scan for repositories (defaults to app/Restify)
124+
125+
#### Migration Process
126+
127+
1. **Repository Discovery**: Scans for Laravel Restify repositories in standard locations
128+
2. **Analysis Phase**: Evaluates each repository for migration requirements
129+
3. **Backup Creation**: Creates timestamped backups of files before modification
130+
4. **Attribute Migration**: Converts `public static $model = Model::class;` to `#[Model(Model::class)]`
131+
5. **Field Migration**: Moves search/sort configuration to field-level methods
132+
6. **Configuration Check**: Validates config file compatibility with v10
133+
7. **Comprehensive Reporting**: Provides detailed migration report with next steps
134+
135+
#### Usage Examples
136+
137+
```bash
138+
# Dry run analysis (recommended first step)
139+
Upgrade Restify with dry_run=true
140+
141+
# Apply migrations with backups
142+
Upgrade Restify with dry_run=false backup_files=true
143+
144+
# Migrate only attributes
145+
Upgrade Restify with dry_run=false migrate_fields=false
146+
147+
# Non-interactive mode
148+
Upgrade Restify with dry_run=false interactive=false
149+
150+
# Custom repository path
151+
Upgrade Restify with path="/app/Custom/Repositories"
152+
```
153+
154+
#### Before & After Examples
155+
156+
**Before (Laravel Restify 9.x):**
157+
```php
158+
class PostRepository extends Repository
159+
{
160+
public static string $model = Post::class;
161+
162+
public static array $search = ['title', 'content'];
163+
public static array $sort = ['created_at', 'title'];
164+
165+
public function fields(RestifyRequest $request): array
166+
{
167+
return [
168+
field('title'),
169+
field('content'),
170+
];
171+
}
172+
}
173+
```
174+
175+
**After (Laravel Restify 10.x):**
176+
```php
177+
use Binaryk\LaravelRestify\Attributes\Model;
178+
179+
#[Model(Post::class)]
180+
class PostRepository extends Repository
181+
{
182+
public function fields(RestifyRequest $request): array
183+
{
184+
return [
185+
field('title')->searchable()->sortable(),
186+
field('content')->searchable(),
187+
];
188+
}
189+
}
190+
```
191+
59192
## Manually Registering the MCP Server
60193

61194
Sometimes you may need to manually register the Restify Boost MCP server with your editor of choice. You should register the MCP server using the following details:

src/Docs/en/api/fields.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,79 @@ class AvatarStore implements Storable
13741374
You can use the <code>php artisan restify:store AvatarStore</code> command to generate a store file.
13751375
</alert>
13761376

1377+
## Lazy Loading
1378+
1379+
Fields can be configured to lazy load relationships, which is particularly useful for computed attributes that depend on related models. This helps avoid N+1 queries by ensuring relationships are loaded only when needed.
1380+
1381+
### Making Fields Lazy
1382+
1383+
Use the `lazy()` method to mark a field for lazy loading:
1384+
1385+
```php
1386+
public function fields(RestifyRequest $request)
1387+
{
1388+
return [
1389+
// Lazy load the 'tags' relationship when displaying profileTagNames
1390+
field('profileTagNames', fn() => $this->model()->profileTagNames)
1391+
->lazy('tags'),
1392+
1393+
// Lazy load using the field's attribute name (if it matches the relationship)
1394+
field('tags', fn() => $this->model()->tags->pluck('name'))
1395+
->lazy(),
1396+
1397+
// Another example with user relationship
1398+
field('authorName', fn() => $this->model()->user->name ?? 'Unknown')
1399+
->lazy('user'),
1400+
];
1401+
}
1402+
```
1403+
1404+
### How It Works
1405+
1406+
When you have a model attribute like this:
1407+
1408+
```php
1409+
class Post extends Model
1410+
{
1411+
public function getProfileTagNamesAttribute(): array
1412+
{
1413+
return $this->tags()->pluck('name')->toArray();
1414+
}
1415+
1416+
public function tags()
1417+
{
1418+
return $this->belongsToMany(Tag::class);
1419+
}
1420+
}
1421+
```
1422+
1423+
You can create a field that efficiently loads this data:
1424+
1425+
```php
1426+
field('profileTagNames', fn() => $this->model()->profileTagNames)
1427+
->lazy('tags')
1428+
```
1429+
1430+
This ensures that:
1431+
1. The `tags` relationship is loaded before the field value is computed
1432+
2. Multiple fields using the same relationship won't cause additional queries
1433+
3. The computed value can safely access the relationship data
1434+
1435+
### Lazy Loading Methods
1436+
1437+
The `CanLoadLazyRelationship` trait provides the following methods:
1438+
1439+
- `lazy(?string $relationshipName = null)` - Mark the field as lazy and optionally specify the relationship name
1440+
- `isLazy(RestifyRequest $request)` - Check if the field is configured for lazy loading
1441+
- `getLazyRelationshipName()` - Get the name of the relationship to lazy load
1442+
1443+
### Benefits
1444+
1445+
- **Performance**: Prevents N+1 queries when dealing with computed attributes
1446+
- **Efficiency**: Relationships are loaded only once, even if multiple fields depend on them
1447+
- **Flexibility**: Works with any relationship type (BelongsTo, HasMany, ManyToMany, etc.)
1448+
- **Clean Code**: Keeps your field definitions simple while ensuring optimal database usage
1449+
13771450
## Utility Methods
13781451

13791452
### Repository Management

src/Docs/en/api/relations.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,29 @@ $isSearchable = $field->isSearchable(); // true
344344
$attributes = $field->getSearchables(); // ['name']
345345
```
346346

347+
#### Custom Search Callbacks
348+
349+
For advanced search scenarios, you can provide a custom callback to completely control the search behavior:
350+
351+
```php
352+
BelongsTo::make('user')->searchable(function ($query, $request, $value, $field, $repository) {
353+
return $query->whereHas('user', function ($q) use ($value) {
354+
$q->where('name', 'ilike', "%{$value}%")
355+
->orWhere('email', 'ilike', "%{$value}%")
356+
->orWhere('phone', 'like', "%{$value}%");
357+
});
358+
})
359+
```
360+
361+
The callback receives the following parameters:
362+
- `$query` - The main query builder instance
363+
- `$request` - The current RestifyRequest instance
364+
- `$value` - The search value from the request
365+
- `$field` - The BelongsTo field instance
366+
- `$repository` - The current repository instance
367+
368+
This approach provides maximum flexibility for complex search requirements while maintaining the same API interface.
369+
347370
## HasOne
348371

349372
The `HasOne` field corresponds to a `hasOne` Eloquent relationship.

0 commit comments

Comments
 (0)