ワンクリックで
albatros
Albatros accounting API integration via Saloon. Use when working with app/Services/Albatros/, AlbatrosConnector, or Albatros DTOs.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Albatros accounting API integration via Saloon. Use when working with app/Services/Albatros/, AlbatrosConnector, or Albatros DTOs.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Readonly data containers with typed factory methods (`fromArray`, `fromModel`, `fromCollection`, `fromRequest`) used to pass structured data between application layers — especially for external API responses, Eloquent models, and service boundaries. Use this skill whenever creating, reviewing, or refactoring DTOs, Data Transfer Objects, value objects for inter-layer communication, or mapping payloads from APIs, models, or collections into typed PHP objects. Also trigger when the user mentions spatie/laravel-data alternatives, data mapping, or payload normalization in a Laravel context.
Eloquent model conventions for mass assignment, casts, relationship naming, activity logging, and mandatory model tests (CRUD + relations).
Single-purpose business logic classes that encapsulate one well-defined business operation. Actions are the primary location for business logic in Laravel applications, invoked from controllers, commands, or jobs.
Laravel Blade template conventions covering components, output escaping, security, structure, and formatting.
Artisan console command classes that serve as the CLI entry point for operations. Commands validate input and delegate all business logic to Actions or Services.
Thin HTTP entry points that validate input, delegate to Actions or Services, and return a response. Controllers contain no business logic.
| name | albatros |
| description | Albatros accounting API integration via Saloon. Use when working with app/Services/Albatros/, AlbatrosConnector, or Albatros DTOs. |
| compatible_agents | ["architect","implement","refactor","review"] |
app/Services/Albatros/, its connector, requests, or DTO mapping.AlbatrosConnector extends Saloon\Http\Connectorconfig('albatros.base_url').env, mapped through config/albatros.php; never hardcode secrets.AlbatrosService wraps all API calls and returns typed DTOs or Collection of DTOsCache for reference data (addresses, accounts, VAT codes, etc.)fetchAllPages() helper with lastIndex parameterRequests/{Resource}/: Requests/Adresse/, Requests/PkKreditor/, Requests/Mandant/, etc.$lastIndex and $pageSize for paginationHasBody + HasJsonBodyDataObjects/ with fromArray() factoryfromArray()clearCache() method when data needs refreshingfetchAllPages(), document and keep retry/backoff explicit (attempts + delay) for predictable operations.lastIndex as the stop sentinel unless API docs specify a different terminal token.items + lastIndex) before DTO mapping.decimal:2// AlbatrosConnector
class AlbatrosConnector extends Connector
{
public function resolveBaseUrl(): string
{
return config('albatros.base_url');
}
protected function defaultHeaders(): array
{
return [
'Mandant' => config('albatros.mandant'),
'Authorization' => 'Bearer ' . config('albatros.token'),
];
}
}
// List request with pagination
class ListAdressenRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $lastIndex = '',
protected int $pageSize = 100,
) {}
public function resolveEndpoint(): string
{
return '/Adresse';
}
protected function defaultQuery(): array
{
return array_filter([
'lastIndex' => $this->lastIndex,
'pageSize' => $this->pageSize,
]);
}
}
// DTO with German domain terms — acceptable for Albatros API
readonly class AdresseData
{
public function __construct(
public string $ID,
public ?string $Name,
public ?string $Strasse,
public ?string $PLZ,
public ?string $Ort,
) {}
public static function fromArray(array $data): static
{
return new static(
ID: (string) ($data['ID'] ?? $data['id'] ?? ''),
Name: $data['Name'] ?? $data['name'] ?? null,
Strasse: $data['Strasse'] ?? $data['strasse'] ?? null,
PLZ: $data['PLZ'] ?? $data['plz'] ?? null,
Ort: $data['Ort'] ?? $data['ort'] ?? null,
);
}
}
// Service with caching
public function getAdressen(): Collection
{
return Cache::remember($this->cacheKey('adressen'), 3600, fn () =>
$this->fetchAllPages(fn ($lastIndex) => new ListAdressenRequest(lastIndex: $lastIndex))
);
}
public function clearCache(): void
{
Cache::forget($this->cacheKey('adressen'));
}
// Service pagination + error handling pattern
use Illuminate\Support\Collection;
use Saloon\Exceptions\Request\RequestException;
private function fetchAllPages(callable $requestFactory): Collection
{
$all = collect();
$lastIndex = '';
do {
$response = retry(3, function () use ($requestFactory, $lastIndex) {
return $this->connector->send($requestFactory($lastIndex));
}, 200);
if (! $response->successful()) {
throw new RequestException($response, 'Albatros request failed.');
}
$payload = $response->json();
$items = collect($payload['items'] ?? []);
$all = $all->merge($items->map(fn (array $row) => AdresseData::fromArray($row)));
$lastIndex = (string) ($payload['lastIndex'] ?? '');
} while ($lastIndex !== '');
return $all;
}
private function cacheKey(string $segment): string
{
return sprintf('albatros.%s.%s', config('albatros.mandant'), $segment);
}
// Minimal config/albatros.php pattern
return [
'base_url' => env('ALBATROS_BASE_URL'),
'mandant' => env('ALBATROS_MANDANT'),
'token' => env('ALBATROS_TOKEN'),
];
// Mocked Saloon test note (no real API calls)
Saloon::fake([
'*' => MockResponse::make(['items' => [], 'lastIndex' => ''], 200),
]);
fetchAllPages() for paginated endpoints — manual pagination loopsfromArray()decimal:2clearCache() when reference data is updatedSaloon/SKILL.md — Saloon connector and request patternsDTO/SKILL.md — DTO conventions with fromArray factoryServices/SKILL.md — service class wrapping API calls