Back to list
alexborgognoni

wizard-field

by alexborgognoni

RentPath is a rental property management platform built for European landlords, property managers, and tenants.

0🍴 0📅 Jan 23, 2026

SKILL.md


name: wizard-field description: Guide for adding new fields to application or property wizards. Uses Laravel Precognition with FormRequest rules as single source of truth. Auto-triggers on "add field to wizard", "new wizard field", "add to application form", "add to property form", "wizard validation".

Adding Wizard Fields Guide

You are helping add new fields to RentPath's multi-step wizard forms (Application Wizard or Property Wizard).

Arguments

This skill accepts optional arguments to specify the field and wizard:

UsageBehavior
/wizard-fieldInteractive - ask for field details
/wizard-field emergency_contactAdd field named emergency_contact
/wizard-field application emergency_contactAdd to application wizard specifically
/wizard-field property energy_ratingAdd to property wizard specifically
/wizard-field application.identity nationalityAdd to specific step
/wizard-field --step=financialFocus on the financial step

Argument interpretation:

  • Field name - The database/form field to add
  • Wizard type (application, property) - Which wizard to modify
  • Step (identity, financial, specs, etc.) - Which step the field belongs to
  • wizard.step format - Explicit wizard and step specification

Before You Start

  1. Read the validation pattern: docs/patterns/validation.md
  2. Read the wizard pattern: docs/patterns/wizard.md
  3. Identify which wizard: Application (tenant) or Property (manager)

Validation Architecture

RentPath uses Laravel Precognition for real-time validation:

  • Backend FormRequest rules are the single source of truth
  • Frontend uses Precognition requests to validate against backend rules
  • No Zod schemas - validation is not duplicated
Frontend (Precognition) → Backend (FormRequest) → Database

Tools to Use

TaskToolCommand/Action
Check Step FormRequestReadapp/Http/Requests/Property/Steps/ or Application/Steps/
Check modelReadapp/Models/Application.php or Property.php
Create migrationBashphp artisan make:migration add_[field]_to_[table]
Check typesReadresources/js/types/index.d.ts
Check wizard hookReadresources/js/hooks/use-property-wizard.ts or use-application-wizard.ts
Run validationBashphp artisan test --filter=Validation

Step-by-Step Implementation

1. Create Database Migration

php artisan make:migration add_[field_name]_to_[table_name] --no-interaction
public function up(): void
{
    Schema::table('applications', function (Blueprint $table) {
        $table->string('new_field')->nullable();
    });
}

Run migration:

php artisan migrate

2. Update Model

Add to fillable:

// app/Models/Application.php
protected $fillable = [
    // ... existing fields
    'new_field',
];

Add casts if needed:

protected function casts(): array
{
    return [
        'flag_field' => 'boolean',
        'complex_field' => 'array',
    ];
}

3. Update Step FormRequest (Backend Validation)

Find the appropriate step FormRequest and add the field:

// app/Http/Requests/Application/Steps/IdentityStepRequest.php

public function rules(): array
{
    return [
        // ... existing rules
        'new_field' => ['required', 'string', 'max:255'],
    ];
}

public function messages(): array
{
    return [
        // ... existing messages
        'new_field.required' => 'New field is required',
        'new_field.max' => 'New field must be less than 255 characters',
    ];
}

4. Update TypeScript Types

// resources/js/types/index.d.ts

interface Application {
    // ... existing fields
    new_field: string | null;
}

5. Update Wizard Hook Step Config

Add the field to the step's fields array for Precognition targeting:

// resources/js/hooks/use-application-wizard.ts or use-property-wizard.ts

export const APPLICATION_STEPS: WizardStepConfig<ApplicationStep>[] = [
    {
        id: 'identity',
        title: 'Identity & Legal Eligibility',
        shortTitle: 'Identity',
        fields: [
            // ... existing fields
            'new_field', // Add here - IMPORTANT for step validation
        ],
    },
    // ...
];

Why fields array matters:

  • Precognition uses Precognition-Validate-Only header with these field names
  • validateFieldAndRecalculateMaxStep uses this to know which step a field belongs to
  • If field is missing from array, validation won't target it correctly

Also add to initial data:

function getInitialData(draft?: DraftApplication): ApplicationWizardData {
    return {
        // ... existing fields
        new_field: draft?.new_field || '',
    };
}

6. Update Wizard Step Component

// resources/js/components/application-wizard/steps/[Step]Step.tsx

interface StepProps {
    data: ApplicationWizardData;
    errors: Record<string, string>;
    touchedFields: Record<string, boolean>;
    updateField: (field: string, value: any) => void;
    markFieldTouched: (field: string) => void;
    onFieldBlur: (field: string) => void; // Validates + recalculates maxStepReached
}

export function IdentityStep({ data, errors, touchedFields, updateField, markFieldTouched, onFieldBlur }: StepProps) {
    return (
        <div className="space-y-4">
            {/* New field */}
            <div className="space-y-2">
                <Label htmlFor="new_field">
                    New Field <span className="text-error">*</span>
                </Label>
                <Input
                    id="new_field"
                    value={data.new_field}
                    onChange={(e) => updateField('new_field', e.target.value)}
                    onBlur={() => onFieldBlur('new_field')}
                    aria-invalid={touchedFields.new_field && !!errors.new_field}
                    className={touchedFields.new_field && errors.new_field ? 'border-error' : ''}
                />
                {touchedFields.new_field && errors.new_field && <p className="text-sm text-error">{errors.new_field}</p>}
            </div>
        </div>
    );
}

Key patterns:

  • updateField clears the error for that field
  • onFieldBlur validates the field AND recalculates maxStepReached if field is from a previous step
  • Errors only show when field is touched (prevents cascade errors on mount)
  • aria-invalid must be set for scroll-to-first-error to work

7. Update Controller/Service (if needed)

If the field requires special handling:

// app/Services/ApplicationService.php

// In the publish/submit method, ensure field is handled
$application->update([
    // ... existing fields
    'new_field' => $data['new_field'],
]);

8. Add Translations (i18n)

Translations are organized by route/domain. Add to the appropriate wizard file:

// For Application Wizard: resources/lang/en/wizard/application.php
// For Property Wizard: resources/lang/en/wizard/property.php

return [
    'steps' => [
        'identity' => [
            // ... existing fields
            'newField' => [
                'label' => 'New Field',
                'placeholder' => 'Enter value...',
            ],
        ],
    ],
];

Remember to add translations for all 4 locales (en, de, fr, nl). See docs/architecture/i18n.md for the full translation structure.

9. Update Tests

// tests/Feature/ApplicationWizardValidationTest.php

test('application requires new_field', function () {
    $user = User::factory()->withTenantProfile()->create();

    $response = $this->actingAs($user)
        ->post('/applications', [
            // ... other required fields
            'new_field' => '',  // Empty
        ]);

    $response->assertSessionHasErrors('new_field');
});

10. Update Factory (for tests)

// database/factories/ApplicationFactory.php

public function definition(): array
{
    return [
        // ... existing fields
        'new_field' => fake()->sentence(),
    ];
}

Which Step Does the Field Belong To?

Application Wizard Steps

StepFormRequestFields
1. IdentityIdentityStepRequestName, DOB, nationality, ID documents
2. HouseholdHouseholdStepRequestMove-in, occupants, pets
3. FinancialFinancialStepRequestEmployment, income, proof
4. SupportSupportStepRequestCo-signers, guarantors, insurance
5. HistoryHistoryStepRequestAddress, references, credit
6. AdditionalAdditionalStepRequestExtra documents, notes
7. ConsentConsentStepRequestDeclarations, signature

Property Wizard Steps

StepFormRequestFields
1. TypeTypeStepRequestProperty type, subtype
2. LocationLocationStepRequestAddress, country
3. SpecsSpecsStepRequestBedrooms, bathrooms, size
4. AmenitiesAmenitiesStepRequestKitchen, amenities
5. EnergyEnergyStepRequestEnergy class, heating
6. PricingPricingStepRequestRent, currency, availability
7. MediaMediaStepRequestTitle, description, images

Documentation References

  • docs/patterns/validation.md - Precognition validation strategy
  • docs/patterns/wizard.md - Wizard architecture
  • docs/modules/applications.md - Application fields
  • docs/modules/properties.md - Property fields

Checklist

  • Migration created and run
  • Model updated (fillable, casts)
  • Step FormRequest updated with rules and messages
  • TypeScript types updated
  • Wizard hook step config updated (fields array)
  • Wizard hook initial data updated
  • Step component updated with UI and onBlur handler
  • Service/Controller updated (if needed)
  • Translations added
  • Tests written
  • Factory updated
  • Manual testing in browser

Score

Total Score

65/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon