resources/boost/skills/albatros/SKILL.md
Albatros accounting API integration via Saloon. Use when working with app/Services/Albatros/, AlbatrosConnector, or Albatros DTOs.
npx skillsauth add codebar-ag/coding-guidelines albatrosInstall 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.
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 callstesting
Translation and localization conventions for Laravel. Use when adding user-facing strings, creating translation files, or working with lang/ directory.
tools
Reusable behaviour shared across multiple unrelated classes. Traits provide shared Eloquent scopes, accessors, lifecycle hooks, and small stateless helper methods.
development
Tailwind CSS v4 styling conventions. Use when working with CSS, Tailwind utilities, or customizing the theme in Laravel projects.
development
Orchestration classes that coordinate multiple Actions, external APIs, or domain operations into a cohesive workflow. Services own transaction boundaries and third-party API integrations.