refactor(core): enhance SDK structure and documentation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
2026-01-18 21:48:25 +03:00
parent 3da69c03e1
commit d214eecebe
378 changed files with 10514 additions and 496 deletions

View File

@@ -0,0 +1,130 @@
<?php
/*
// MODULE_CONTRACT: Defines the primary transport layer for the Alfa Bank BaaS API.
// RESPONSIBILITY: To manage mTLS configuration, authentication state, retries, and middleware for all BaaS API interactions.
// INPUTS: AlfaConfig (DTO), SignerInterface (service).
// OUTPUTS: An authenticated Saloon Connector instance capable of sending requests.
// NOTES:
// - Supports separate keys for Transport (mTLS) and Signing (JWS/CMS).
// - Uses `login` method for OAuth 2.0 Client Credentials flow.
// - Compatible with Saloon v3.
// LINKS: AlfaBankServiceProvider.php#bind_connector
*/
namespace Apoloz\AlfaBank\Core;
// <SECTION name="module_imports" intent="Import necessary contracts, services, and base framework components for the connector's operation.">
// <BELIEF_STATE "Saloon's plugin architecture requires importing traits for features like retries and timeouts. Local contracts (SignerInterface) are imported for dependency injection.">
use Apoloz\AlfaBank\Contracts\SignerInterface;
use Apoloz\AlfaBank\Http\Middleware\AlfaResponseMiddleware;
use Apoloz\AlfaBank\Http\Middleware\RequestIdMiddleware;
use Apoloz\AlfaBank\Http\Pagination\AlfaOffsetPaginator;
use Apoloz\AlfaBank\Requests\Auth\GetTokenRequest;
use Saloon\Http\Connector;
use Saloon\Http\Request;
use Saloon\PaginationPlugin\Contracts\HasPagination;
use Saloon\PaginationPlugin\OffsetPaginator;
use Saloon\Traits\RequestProperties\HasTries;
use Saloon\Traits\Plugins\HasTimeout;
class AlfaBankConnector extends Connector implements HasPagination
{
use HasTimeout;
use HasTries;
public function __construct(
protected AlfaConfig $alfaConfig,
protected ?SignerInterface $signer = null
) {
$this->tries = 3;
$this->retryInterval = 500;
}
public function resolveBaseUrl(): string
{
return $this->alfaConfig->baseUrl;
}
protected function defaultConfig(): array
{
$config = [
'cert' => $this->alfaConfig->certificatePath,
'ssl_key' => $this->alfaConfig->privateKeyPath,
'verify' => true,
];
if ($this->alfaConfig->caBundlePath) {
$config['verify'] = $this->alfaConfig->caBundlePath;
}
return $config;
}
protected function defaultMiddleware(): array
{
return [];
}
public function boot(\Saloon\Http\PendingRequest $pendingRequest): void
{
$pendingRequest->middleware()->onResponse(new AlfaResponseMiddleware());
$pendingRequest->middleware()->onRequest(new RequestIdMiddleware());
}
public function paginate(Request $request): OffsetPaginator
{
return new AlfaOffsetPaginator($this, $request);
}
public function login(?string $clientId = null, ?string $clientSecret = null): static
{
// Allow overriding config via method arguments
$clientId = $clientId ?? $this->alfaConfig->clientId;
$clientSecret = $clientSecret ?? $this->alfaConfig->clientSecret;
if (!$clientId || !$clientSecret) {
throw new \RuntimeException("Client ID/Secret not configured.");
}
$request = new GetTokenRequest(
clientId: $clientId,
clientSecret: $clientSecret,
grantType: 'client_credentials'
);
// Send request (using self to reuse cert/ssl config)
// We temporarily disable auth middleware if we had any,
// but here we are raw, so it's fine.
$response = $this->send($request);
$data = $response->dto();
$this->authenticate(new \Saloon\Http\Auth\TokenAuthenticator($data->access_token));
return $this;
}
// </SECTION>
// <SECTION name="signer_accessor" intent="Provide access to the configured signing service for requests that require a digital signature.">
// <BELIEF_STATE "Requests should not instantiate their own signing logic. The connector acts as a service locator, providing the globally-configured Signer service. This ensures that all signatures are generated consistently.">
public function getSigner(): SignerInterface
{
if (!$this->signer) {
throw new \RuntimeException("No signer configured for this connector.");
}
return $this->signer;
}
// </SECTION>
// <SECTION name="logging_mutator" intent="Allow attaching a PSR-3 logger to the connector for debugging.">
// <BELIEF_STATE "Logging should be an optional, opt-in feature. This method provides a fluent interface to attach a logging middleware, which will automatically sanitize sensitive data before output.">
public function withLogging(\Psr\Log\LoggerInterface $logger): static
{
$middleware = new \Apoloz\AlfaBank\Http\Middleware\LoggingMiddleware($logger);
$this->middleware()->onRequest([$middleware, 'onRequest']);
$this->middleware()->onResponse([$middleware, 'onResponse']);
return $this;
}
// </SECTION>
}