.cursor/skills/spatie-laravel-data/SKILL.md
Create and manage Data Transfer Objects (DTOs), requests, and resources using Spatie Laravel Data v4. Use when the user mentions DTOs, Laravel Data, Spatie Data, or needs to handle request validation and resource transformation in Laravel.
npx skillsauth add kikoseijo/ai-contracts spatie-laravel-dataInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Always extend Spatie\LaravelData\Data when creating a new data object.
use Spatie\LaravelData\Data;
use Carbon\CarbonImmutable;
class PostData extends Data
{
public function __construct(
public string $title,
public string $content,
public ?CarbonImmutable $published_at
) {}
}
Use the static from method to quickly create data objects from arrays, Eloquent models, or requests:
// From an array
$post = PostData::from([
'title' => 'Hello World',
'content' => 'My content',
'published_at' => null,
]);
// From an Eloquent Model
$post = PostData::from(Post::findOrFail($id));
Inject the Data object directly into controller methods. Laravel Data will automatically validate the incoming request and instantiate the object.
class DataController
{
public function __invoke(PostData $postData)
{
// $postData is already validated and instantiated
Post::create($postData->toArray());
return redirect()->back();
}
}
Laravel Data automatically infers validation rules based on PHP property types:
required when a property cannot be nullnullable when a property can be nullnumeric when a property type is int or floatstring when a property type is stringboolean when a property type is boolarray when a property type is arrayenum:* when a property type is a native enumTo add custom rules that cannot be inferred, use attributes from Spatie\LaravelData\Attributes\Validation\:
use Spatie\LaravelData\Attributes\Validation\Min;
class PostData extends Data
{
public function __construct(
#[Min(5)]
public string $title,
) {}
}
1. DO NOT manually implement toResponse for basic JSON responses.
Spatie Laravel Data objects automatically implement Responsable (via the ResponsableData trait in the base Data class). Returning a Data object from a controller automatically converts it to a JSON response.
❌ Bad (Redundant):
class AgentListResponseDTO extends Data
{
public function __construct(
public readonly DataCollection $agents,
) {}
// ❌ DO NOT DO THIS: It is already handled by Spatie Laravel Data
public function toResponse($request): JsonResponse
{
return response()->json($this, 200);
}
}
✅ Good:
class AgentListResponseDTO extends Data
{
public function __construct(
public readonly DataCollection $agents,
) {}
// ✅ Just return the DTO from your controller, Laravel Data handles the response automatically
}
2. Use typed arrays with DocBlocks instead of DataCollection
Spatie Laravel Data v4 supports native arrays typed via DocBlocks. This is the preferred C.O.R.E. way because it simplifies hydration, avoids immutability issues with DataCollection, and keeps the code cleaner. NEVER use #[DataCollectionOf] or DataCollection.
❌ Bad (Cumbersome and violates new C.O.R.E. rules):
class CognitiveContextDTO extends Data
{
public function __construct(
#[DataCollectionOf(WorkerResultDTO::class)]
public private(set) ?DataCollection $telemetry = null,
) {}
}
✅ Good (Native typed arrays):
class CognitiveContextDTO extends Data
{
public function __construct(
/** @var array<int, WorkerResultDTO> */
public private(set) array $telemetry = [],
) {}
public function recordTelemetry(WorkerResultDTO $entry): self
{
$clone = clone $this;
$clone->telemetry[] = $entry; // ✅ Simple array append works perfectly
return $clone;
}
}
3. DO NOT use variadic parameters (...$items) or manual logic in DTO constructors.
C.O.R.E. DTOs are pure data structures. Using variadic parameters or manual assignment logic in the constructor breaks Spatie Laravel Data's ::from() hydration from JSON payloads.
❌ Bad (Breaks JSON hydration):
class AiMessageData extends Data
{
#[DataCollectionOf(CitationDTO::class)]
public readonly DataCollection $citations;
public function __construct(
public readonly string $response,
CitationDTO ...$citations, // ❌ Variadic parameter
) {
// ❌ Manual logic in constructor
$this->citations = CitationDTO::collect(array_values($citations), DataCollection::class);
}
}
✅ Good (Pure promoted properties):
class AiMessageData extends Data
{
public function __construct(
public readonly string $response,
#[DataCollectionOf(CitationDTO::class)]
public readonly ?DataCollection $citations = null, // ✅ Promoted property
) {}
}
If you need custom functionality, you can build your own base data class using Spatie's traits and interfaces (e.g., ResponsableData, IncludeableData, TransformableData, ValidateableData).
use Spatie\LaravelData\Concerns\BaseData;
use Spatie\LaravelData\Concerns\TransformableData;
use Spatie\LaravelData\Contracts\BaseData as BaseDataContract;
use Spatie\LaravelData\Contracts\TransformableData as TransformableDataContract;
abstract class CustomData implements BaseDataContract, TransformableDataContract
{
use BaseData;
use TransformableData;
}
testing
LA SUPER GUÍA DEL AGENTE PERFECTO. Reglas estrictas de arquitectura C.O.R.E. para controladores, uso de Spatie Data y prohibición de modificar el paquete ai-contracts. Úsalo SIEMPRE que trabajes en controladores, DTOs o interactúes con el paquete sunnyface-ai-contracts en proyectos consumidores.
development
Briefing obligatorio del paquete sunnyface/ai-contracts. Activa SIEMPRE que toques DTOs, webhooks, comunicación Hub-Spoke, o el namespace Sunnyface\Contracts. Contiene reglas irrompibles y dónde leer los contratos reales en vendor/.
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.