google-agents-cli-scaffold
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
laravel-models
Eloquent model patterns and database layer. Use when working with models, database entities, Eloquent ORM, or when user mentions models, eloquent, relationships, casts, observers, database entities.
Full skill instructions
Models represent database tables and domain entities.
Related guides:
Models should:
<?php
declare(strict_types=1);
namespace App\Models;
use App\Builders\OrderBuilder;
use App\Enums\OrderStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Order extends Model
{
use HasFactory;
protected function casts(): array
{
return [
'status' => OrderStatus::class,
'total' => 'integer',
];
}
// Custom Query Builder
public function newEloquentBuilder($query): OrderBuilder
{
return new OrderBuilder($query);
}
// Relationships
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function items(): HasMany
{
return $this->hasMany(OrderItem::class);
}
}
Define casts for type safety:
protected function casts(): array
{
return [
'status' => OrderStatus::class, // Enum
'total' => 'integer', // Integer
'is_paid' => 'boolean', // Boolean
'metadata' => OrderMetadataData::class, // DTO
'completed_at' => 'datetime', // Carbon
'tags' => 'array', // JSON array
];
}
Available casts:
'integer', 'real', 'float', 'double''string', 'boolean''array', 'json', 'object', 'collection''date', 'datetime', 'immutable_date', 'immutable_datetime''timestamp''encrypted', 'encrypted:array', 'encrypted:collection', 'encrypted:json', 'encrypted:object'public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class, 'customer_id', 'id');
}
public function orders(): HasMany
{
return $this->hasMany(Order::class);
}
public function items(): HasMany
{
return $this->hasMany(OrderItem::class);
}
public function profile(): HasOne
{
return $this->hasOne(UserProfile::class);
}
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class)
->withTimestamps()
->withPivot('assigned_at');
}
public function deployments(): HasManyThrough
{
return $this->hasManyThrough(Deployment::class, Environment::class);
}
// MorphTo
public function commentable(): MorphTo
{
return $this->morphTo();
}
// MorphMany
public function comments(): MorphMany
{
return $this->morphMany(Comment::class, 'commentable');
}
use Illuminate\Database\Eloquent\Casts\Attribute;
protected function fullName(): Attribute
{
return Attribute::make(
get: fn () => "{$this->first_name} {$this->last_name}",
);
}
// Usage
$user->full_name; // "John Doe"
protected function password(): Attribute
{
return Attribute::make(
set: fn (string $value) => bcrypt($value),
);
}
// Usage
$user->password = 'secret'; // Automatically hashed
protected function email(): Attribute
{
return Attribute::make(
get: fn (string $value) => strtolower($value),
set: fn (string $value) => strtolower(trim($value)),
);
}
Simple helper methods are acceptable:
class Order extends Model
{
public function isPending(): bool
{
return $this->status === OrderStatus::Pending;
}
public function isCompleted(): bool
{
return $this->status === OrderStatus::Completed;
}
public function canBeCancelled(): bool
{
return $this->isPending() || $this->status === OrderStatus::Processing;
}
}
But NOT business logic:
// ❌ Bad - business logic in model
class Order extends Model
{
public function cancel(): void
{
DB::transaction(function () {
$this->update(['status' => OrderStatus::Cancelled]);
$this->refundPayment();
$this->notifyCustomer();
});
}
}
// ✅ Good - business logic in action
class CancelOrderAction
{
public function __invoke(Order $order): Order
{
return DB::transaction(function () use ($order) {
$order->update(['status' => OrderStatus::Cancelled]);
resolve(RefundPaymentAction::class)($order);
resolve(NotifyCustomerAction::class)($order);
return $order;
});
}
}
For model lifecycle hooks:
<?php
declare(strict_types=1);
namespace App\Observers;
use App\Models\Order;
use Illuminate\Support\Str;
class OrderObserver
{
public function creating(Order $order): void
{
if (! $order->uuid) {
$order->uuid = Str::uuid();
}
}
public function created(Order $order): void
{
// Dispatch event, queue job, etc.
}
public function updating(Order $order): void
{
// Before update
}
public function updated(Order $order): void
{
// After update
}
public function deleted(Order $order): void
{
// After delete
}
}
Register in AppServiceProvider:
use App\Models\Order;
use App\Observers\OrderObserver;
public function boot(): void
{
Order::observe(OrderObserver::class);
}
Extract reusable behavior:
Use in models:
class Order extends Model
{
use HasUuid;
}
// Route
Route::get('/orders/{order}', [OrderController::class, 'show']);
// Controller - automatically receives Order model
public function show(Order $order) { }
Route::get('/orders/{order:uuid}', [OrderController::class, 'show']);
public function resolveRouteBinding($value, $field = null)
{
return $this->where($field ?? 'id', $value)
->where('is_active', true)
->firstOrFail();
}
All models should be unguarded by default.
In your AppServiceProvider::boot() method, call Model::unguard():
<?php
declare(strict_types=1);
namespace App\Providers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Model::unguard();
}
}
Do NOT use $fillable or $guarded properties on your models:
// ✅ Good - no fillable/guarded
class Order extends Model
{
protected function casts(): array
{
return [
'status' => OrderStatus::class,
];
}
}
// ❌ Bad - don't use fillable
class Order extends Model
{
protected $fillable = ['name', 'email'];
}
// ❌ Bad - don't use guarded
class Order extends Model
{
protected $guarded = [];
}
Important: Always validate input in Form Requests before passing to Actions/Models.
// Disable timestamps
public $timestamps = false;
// Custom timestamp columns
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'updated_date';
use Illuminate\Database\Eloquent\SoftDeletes;
class Order extends Model
{
use SoftDeletes;
}
Usage:
$order->delete(); // Soft delete
$order->forceDelete(); // Permanent delete
$order->restore(); // Restore
Order::withTrashed()->find($id);
Order::onlyTrashed()->get();
Query results return Collections:
$orders = Order::all(); // Illuminate\Database\Eloquent\Collection
$orders->filter(fn($order) => $order->isPending());
$orders->map(fn($order) => $order->total);
$orders->sum('total');
app/Models/
├── Order.php
├── User.php
├── Concerns/
│ ├── HasUuid.php
│ ├── BelongsToTenant.php
│ └── Searchable.php
└── Contracts/
└── Searchable.php
it('can mass assign attributes', function () {
$order = Order::create([
'user_id' => 1,
'status' => 'pending',
'total' => 1000,
'notes' => 'Test order',
]);
expect($order->user_id)->toBe(1)
->and($order->total)->toBe(1000);
});
it('casts status to enum', function () {
$order = Order::factory()->create(['status' => 'pending']);
expect($order->status)->toBeInstanceOf(OrderStatus::class);
});
it('has user relationship', function () {
$order = Order::factory()->create();
expect($order->user)->toBeInstanceOf(User::class);
});
Models should:
Model::unguard() in AppServiceProviderModels should NOT:
$fillable or $guarded propertiesProject scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
Set up tracing, logging, and monitoring for deployed ADK agents across Cloud Trace, BigQuery, and third-party platforms.
Enterprise Azure infrastructure architect generating Bicep or Terraform from workload descriptions.
Plan and configure production-ready Azure Kubernetes Service clusters with Day-0 and Day-1 best practices.
Raw mechanical interfaces fusing Swiss typographic print with military terminal aesthetics. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects. For data-heavy dashboards, portfolios, or editorial sites that need to feel like declassified blueprints.
Web search, scraping, extraction, crawling, and monitoring via ScrapeGraph AI CLI.
Skill for working with Firebase Hosting (Classic). Use this when you want to deploy static web apps, Single Page Apps (SPAs), or simple microservices. Do NOT use for Firebase App Hosting.
Deploy and manage web apps with Firebase App Hosting. Use this skill when deploying Next.js/Angular apps with backends.
Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".
Build SEO-optimized pages at scale using templates, data, and proven playbook patterns.
Design and build isolated, reusable Convex backend components with clear boundaries and app-facing wrappers.
Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".
Opus.ai: Revolutionize Your Web Experience
Build a no-code AI app in minutes.
An IDE for code migration from legacy to modern frameworks through coding agents.
Automate CGI animation in live-action scenes
Branded artistic QR-code concepts
Launch a website in seconds with AI.
Streamline Your Coding Experience with AI Code Helper
Convert any screenshot or design to clean code.