lc-orphaned-records
Find orphaned database records where foreign key parent records don't exist.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Find orphaned database records where foreign key parent records don't exist.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Create a Larascraper scraper (v2 or v3) for a target website, chaining browser actions (click, type, wait, scroll), conditional flow (when/repeatUntil), captcha solving, and file/PDF downloads. Detects the installed major and generates the matching style.
Add or edit a Laracrate file collection in config/laracrate.php with the correct anatomy (disk, access, types, variants, previews, extract/embed, flags, per-model scoping).
Runtime-verified Laravel inspection using the Laravel Boost MCP server (Tinker, Database Query/Schema, Last Error) instead of static grep. Falls back to Docker/Tinker if Boost is not installed.
Scaffold spatie/laravel-permission setup - add the HasRoles trait to a model and generate a roles & permissions seeder.
Audit spatie/laravel-permission usage - permissions used in code but undefined, defined but unused, unprotected routes, guard mismatches, and cache pitfalls.
Extract business logic from a controller or Livewire component method into a Laractions Action class.
| name | lc:orphaned-records |
| description | Find orphaned database records where foreign key parent records don't exist. |
| argument-hint | [analyze | fix | fix --dry-run | table-name | fix table-name] |
| user-invocable | true |
| allowed-tools | Read Grep Bash Edit Write Glob |
Detect orphaned database records where a foreign key column references a parent record that no longer exists. This runs actual queries against the database via Docker.
| Subcommand | Description |
|---|---|
| (no argument) | Scan all tables for orphaned records. Read-only report. |
fix | Find and delete or nullify orphaned records. Asks for confirmation before each table. |
fix --dry-run | Show what cleanup queries would run without executing them. |
[table-name] | Analyze orphaned records in a specific table only. |
fix [table-name] | Fix orphaned records in a specific table, with confirmation. |
Read to examine docker-compose.yml in the project root.container_name or derive from service name).Bash:
docker ps --filter name={container_name} --format '{{.Names}}'
docker compose up -d.If a [table-name] argument is provided, only analyze that table. Otherwise, analyze all tables.
Method A: From Migrations (primary)
Glob to find all database/migrations/*.php files.Grep and Read to parse foreign key definitions:
$table->foreign('column')->references('ref_column')->on('ref_table')$table->foreignId('ref_table_id')->constrained()$table->foreignId('column')->constrained('ref_table')$table->foreignIdFor(Model::class){table}.{column} -> {ref_table}.{ref_column}Method B: From Database (supplementary) If migrations are complex or unclear, query the database directly:
docker exec {container} php artisan tinker --execute="
\$results = DB::select('
SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM information_schema.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_NAME IS NOT NULL
AND TABLE_SCHEMA = DB::getDatabaseName()
');
foreach (\$results as \$r) {
echo \$r->TABLE_NAME . '.' . \$r->COLUMN_NAME . ' -> ' . \$r->REFERENCED_TABLE_NAME . '.' . \$r->REFERENCED_COLUMN_NAME . PHP_EOL;
}
"
For each FK relationship, run a query to find records where the parent doesn't exist:
docker exec {container} php artisan tinker --execute="
\$count = DB::table('{table}')
->whereNotNull('{column}')
->whereNotIn('{column}', DB::table('{ref_table}')->select('{ref_column}'))
->count();
echo '{table}.{column} -> {ref_table}.{ref_column}: ' . \$count . ' orphans';
"
For tables with many records, use a LEFT JOIN approach for better performance:
SELECT COUNT(*) FROM {table} t
LEFT JOIN {ref_table} r ON t.{column} = r.{ref_column}
WHERE t.{column} IS NOT NULL AND r.{ref_column} IS NULL
For each relationship with orphaned records, fetch sample IDs and values:
docker exec {container} php artisan tinker --execute="
\$samples = DB::table('{table}')
->select('id', '{column}')
->whereNotNull('{column}')
->whereNotIn('{column}', DB::table('{ref_table}')->select('{ref_column}'))
->limit(5)
->get();
foreach (\$samples as \$s) {
echo 'ID: ' . \$s->id . ' | {column}: ' . \$s->{column} . PHP_EOL;
}
"
Before reporting orphans, check if the referenced table uses soft deletes:
Grep to check if the referenced model uses SoftDeletes trait.SELECT COUNT(*) FROM {table} t
LEFT JOIN {ref_table} r ON t.{column} = r.{ref_column}
WHERE t.{column} IS NOT NULL AND r.{ref_column} IS NULL
vs.
SELECT COUNT(*) FROM {table} t
INNER JOIN {ref_table} r ON t.{column} = r.{ref_column} AND r.deleted_at IS NOT NULL
WHERE t.{column} IS NOT NULL
Present findings in a structured format:
ORPHANED RECORDS REPORT
========================
Table: operations
-----------------
Column: client_seller_id -> clients.id
Orphaned records: 12
Soft-deleted parents: 3 (these have deleted parent records)
Truly orphaned: 9 (parent record does not exist at all)
Sample IDs: 45, 67, 89, 102, 115
FK onDelete action: SET NULL
Column: property_id -> properties.id
Orphaned records: 0 (clean)
Table: activities
-----------------
Column: activitable_id (polymorphic)
Note: Polymorphic relationships cannot be checked via FK constraints.
Skipped -- use manual inspection if needed.
fix or fix [table-name])For each table with orphaned records, offer the appropriate fix based on FK's onDelete action and column nullability:
For non-nullable FK columns or when records are meaningless without the parent:
DB::table('{table}')
->whereNotNull('{column}')
->whereNotIn('{column}', DB::table('{ref_table}')->select('{ref_column}'))
->delete();
For nullable FK columns where the record is still meaningful:
DB::table('{table}')
->whereNotNull('{column}')
->whereNotIn('{column}', DB::table('{ref_table}')->select('{ref_column}'))
->update(['{column}' => null]);
For production-safe approach, create a migration file:
public function up()
{
DB::statement('DELETE FROM {table} WHERE {column} NOT IN (SELECT {ref_column} FROM {ref_table}) AND {column} IS NOT NULL');
}
Each fix requires explicit user confirmation before executing. The user chooses which option (A, B, or C) for each table.
fix --dry-run)Show exactly what queries would be executed and how many records would be affected, without running any destructive queries. The count queries still run to show impact.
End with a summary:
SUMMARY
========
Tables checked: 35
FK relationships checked: 62
Tables with orphans: 4
Total orphaned records: 47
Soft-deleted parents: 8
Truly orphaned: 39
Polymorphic (skipped): 5
morphTo, morphMany) cannot be checked via FK constraints since they use type+id columns. These are flagged but skipped.