Scan seeder data files for broken foreign key references — find constants used without getReference() and fix them
Scanned 6/5/2026
Install via CLI
openskills install event4u-app/agent-config---
model_tier: medium
name: fix:seeder
pack: engineering-base
tier: 2
cluster: fix
sub: seeder
skills: [eloquent]
description: Scan seeder data files for broken foreign key references — find constants used without getReference() and fix them
suggestion:
eligible: true
trigger_description: "the seeder is broken, foreign key errors in seeders"
trigger_context: "seeder error output or recent edits in database/seeders/"
framework: laravel
workspaces:
- agent-config-maintainer
packs:
- meta
---
# /fix seeder
Scans all `PhpDataSeeder` data files for foreign key references that use raw seeder constants
instead of `getReference()`. Raw constants don't trigger lazy initialization of the referenced
seeder, causing "items not available" errors when seeders run in unpredictable order.
## The Rule
In a seeder data file loaded by `FooSeeder`:
- **Own seeder constants** are OK: `FooSeeder::REFERENCE_KEY_X` (these are primary keys, not foreign keys)
- **Other seeder constants** are WRONG: `BarSeeder::REFERENCE_KEY_Y` (foreign key — must use `getReference()`)
### ✅ Correct — triggers lazy initialization
```php
'cat_id' => MaterialDeliveryBillCategorySeeder::getReference(
MaterialDeliveryBillCategorySeeder::REFERENCE_CATEGORY_A
)->getId(),
```
### ❌ Wrong — raw constant, no lazy initialization
```php
'cat_id' => MaterialDeliveryBillCategorySeeder::REFERENCE_CATEGORY_A,
```
## Step 1: Run the scanner script
Run the automated scanner inside the Docker container:
```bash
docker compose exec -T <php-service> php .augment/scripts/scan-seeder-violations.php
```
The script (``.augment/scripts/scan-seeder-violations.php``) automatically:
1. Finds all `PhpDataSeeder` / `JsonDataSeeder` classes and their `$dataFile` paths
2. Scans each data file for foreign seeder constants used without `getReference()`
3. Distinguishes PHP files (auto-fixable) from JSON files (manual fix needed)
### What the scanner flags
**Violation** = a `Seeder::CONSTANT` used directly (not via `getReference()`)
where the seeder class is NOT the owner of the data file.
**Not flagged:**
- `OtherSeeder::getReference(...)` — correct
- `OtherSeeder::getReferences()` — correct
- `OwnSeeder::CONSTANT` — own primary key, correct
- Known exceptions (circular dependencies) — configured in the scanner script
### Known Exceptions
Currently there are **no exceptions**. All circular dependencies have been resolved.
**Pattern for resolving circular dependencies:** Use two-phase seeding. The data file seeds
records with placeholder values (e.g., empty arrays). The Seeder's `run()` method then updates
records with the real values using `getReference()`. Since `run()` is called after all seeders
are initialized, the circular dependency is broken.
Example: `UserWageTypeRuleSeeder` seeds `lohnart_lv` as empty arrays in the data file,
then populates them with project numbers via `ProjectSeeder::getReference()` in `run()`.
If a new exception is truly needed, add it to `.augment/scripts/scan-seeder-violations.php`
in the `$exceptions` array. Format: `'OwnerSeeder' => ['AllowedForeignSeeder']`.
## Step 2: Report findings
Present a table of all violations:
```
| # | Data File | Line | Violation | Owning Seeder |
|---|-----------|------|-----------|---------------|
| 1 | material-delivery-bill-catalog-data.php:11 | CategorySeeder::REFERENCE_A | CatalogSeeder |
```
Then ask the user:
> 1. Fix all violations automatically
> 2. Fix interactively (ask for each)
> 3. Report only — don't fix
## Step 3: Fix violations
For each violation, replace the raw constant with a `getReference()` call:
**Before:**
```php
'foreign_key_column' => OtherSeeder::REFERENCE_CONSTANT,
```
**After:**
```php
'foreign_key_column' => OtherSeeder::getReference(
OtherSeeder::REFERENCE_CONSTANT
)->getId(),
```
### Choosing the getter method
- Default: `->getId()` (most foreign keys are IDs)
- If the column name suggests a different attribute, use the appropriate getter
(e.g., `'name' => ...` might need `->getName()`)
- If unsure, check the referenced model's primary key or the column definition
### Extract to variable when referenced multiple times
If the same `getReference()` call would appear multiple times in one data file,
extract it to a variable at the top of the file:
```php
$category = MaterialDeliveryBillCategorySeeder::getReference(
MaterialDeliveryBillCategorySeeder::REFERENCE_CATEGORY_A
);
return [
[
'cat_id' => $category->getId(),
'cat_name' => $category->getName(),
],
];
```
## Step 4: Verify
After fixing, run the seeder to verify:
```bash
docker compose exec -T <php-service> php artisan db:seed --env=testing
```
If it fails, investigate and fix the remaining issues.
## Rules
- **Do NOT commit or push.** Only apply local changes.
- **Do NOT change the seeder classes** — only the data files.
- **Do NOT change the DataSeeder framework** — only fix data file references.
- When in doubt about the getter method, check the model class.
No comments yet. Be the first to comment!