Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/UitbreidenOS/UitKit --skill laravel명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | laravel |
| description | - Building or maintaining a Laravel 11 application |
composer show laravel/framework)Define relationships directly on the model:
// app/Models/Post.php
class Post extends Model
{
protected $fillable = ['title', 'body', 'published_at', 'user_id'];
protected $casts = [
'published_at' => 'datetime',
];
// Relationships
public function author(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class)->withTimestamps();
}
// Local query scope
public function scopePublished(Builder $query): void
{
$query->whereNotNull('published_at')
->where('published_at', '<=', now());
}
public function scopeByAuthor(Builder $query, int $userId): void
{
$query->where('user_id', $userId);
}
}
// Usage
Post::published()->byAuthor($userId)->with('author', 'tags')->paginate(20);
Always eager load associations in list queries. Use withCount for aggregate counts without full collection load:
Post::published()->withCount('comments')->get();
// Adds comments_count attribute to each Post
// app/Jobs/SendInvoiceEmail.php
class SendInvoiceEmail implements ShouldQueue
{
use Queueable, Dispatchable, InteractsWithQueue, SerializesModels;
public int $tries = 5;
public int $timeout = 30;
public int $backoff = 60; // seconds between retries
public function __construct(
private readonly Invoice $invoice,
) {}
public function handle(InvoiceMailer $mailer): void
{
$mailer->send($this->invoice);
}
public function failed(Throwable $exception): void
{
Log::error('Invoice email failed', [
'invoice_id' => $this->invoice->id,
=> ->(),
]);
}
}
::();
::()->(()->());
::()->();
Configure Horizon queues in config/horizon.php:
'environments' => [
'production' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default', 'mailers', 'critical'],
'processes' => 10,
'tries' => 3,
'timeout' => 60,
],
],
],
// app/Livewire/PostForm.php
class PostForm extends Component
{
#[Validate('required|min:3')]
public string $title = '';
#[Validate('required|min:10')]
public string $body = '';
// Lifecycle hooks
public function mount(Post $post = null): void
{
if ($post) {
$this->title = $post->title;
$this->body = $post->body;
}
}
// Runs on every Livewire request
public function updated(string $property): void
{
$this->validateOnly($property);
}
public function save(): void
{
$this->validate();
::([
=> ->title,
=> ->body,
=> ()->(),
]);
->();
->();
}
{
();
}
}
<!-- resources/views/livewire/post-form.blade.php -->
<form wire:submit="save">
<input wire:model.live="title" type="text" />
@error('title') <span>{{ $message }}</span> @enderror
<textarea wire:model="body"></textarea>
@error('body') <span>{{ $message }}</span> @enderror
<button type="submit" wire:loading.attr="disabled">Save</button>
</form>
Livewire 3 lifecycle order: boot → mount → hydrate → updated* → render → dehydrate.
API token authentication:
// config/auth.php — add sanctum guard
'guards' => [
'api' => [
'driver' => 'sanctum',
'provider' => 'users',
],
],
Issue tokens:
// app/Http/Controllers/AuthController.php
public function login(LoginRequest $request): JsonResponse
{
if (! Auth::attempt($request->only('email', 'password'))) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
$token = $request->user()->createToken(
name: 'api-token',
abilities: ['read', 'write'],
expiresAt: now()->addDays(30),
);
return response()->json(['token' => $token->plainTextToken]);
}
public function logout(Request $request): JsonResponse
{
$request->user()->currentAccessToken()->delete();
()->([ => ]);
}
Protect routes:
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', [UserController::class, 'show']);
Route::apiResource('posts', PostController::class);
});
For SPA authentication use cookie-based sessions via Sanctum::actingAs() in tests and the EnsureFrontendRequestsAreStateful middleware.
// tests/Feature/PostControllerTest.php
use App\Models\{Post, User};
use function Pest\Laravel\{actingAs, getJson, postJson};
beforeEach(function () {
$this->user = User::factory()->create();
});
it('lists published posts', function () {
Post::factory()->count(3)->published()->create();
Post::factory()->draft()->create(); // should not appear
actingAs($this->user)
->getJson('/api/posts')
->assertOk()
->assertJsonCount(3, 'data');
});
it('creates a post', function () {
$data = Post::factory()->make()->only(['title', ]);
(->user)
->(, )
->()
->(, []);
(::())->();
});
(, function () {
()->();
});
Run: php artisan test --parallel
Octane keeps the application in memory between requests. Code that is safe in traditional PHP may break under Octane:
// UNSAFE — static state persists across requests
class RequestContext
{
private static ?User $currentUser = null; // leaks between requests
public static function setUser(User $u): void { static::$currentUser = $u; }
}
// SAFE — use request-scoped bindings
app()->scoped(RequestContext::class, fn () => new RequestContext());
Warm-up callbacks preload expensive bootstrapping:
// config/octane.php
'warm' => [
...Octane::defaultServicesToWarm(),
App\Services\CurrencyRateCache::class,
],
Use octane:start and octane:reload (not restart) to apply code changes without downtime:
php artisan octane:start --server=frankenphp --workers=8
php artisan octane:reload # hot reload after deploy
A complete Livewire 3 comment form with optimistic UI and Pest tests:
// app/Livewire/CommentBox.php
class CommentBox extends Component
{
public int $postId;
#[Validate('required|min:5|max:1000')]
public string $body = '';
public function addComment(): void
{
$this->validate();
Comment::create([
'body' => $this->body,
'post_id' => $this->postId,
'user_id' => auth()->id(),
]);
$this->reset('body');
$this->dispatch('comment-added');
}
public function render(): View
{
return view('livewire.comment-box');
}
}
// tests/Feature/CommentBoxTest.php
use Livewire\Livewire;
(, function () {
= ::()->();
= ::()->();
::()
->(::, [ => ->id])
->(, )
->()
->()
->(, );
(::())->();
});