Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Generali Client Bundle Laravel Package

mpp/generali-client-bundle

A Symfony bundle that integrates the Generali client into your application, offering ready-made service configuration and convenient access to Generali APIs. Streamlines setup and keeps Generali integrations consistent across PHP projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat the bundle as a reference implementation, not an installable dependency. In a Laravel app, composer require mpp/generali-client-bundle leaves you with a *Bundle class that never runs, a Configuration.php tree that is never loaded, and Resources/config/services.yaml definitions that are never parsed.

First three files to open, in order:

  1. Resources/config/services.yaml — the shortest path to the real API surface. It shows which underlying classes do the HTTP work, what they're aliased to, and what's injected into them. This tells you what to extract.
  2. DependencyInjection/Configuration.php — the config schema. This is your spec for what goes in config/generali.php: base URL, credentials, timeout, retry settings, environment toggles. Port these keys verbatim, do not rename them.
  3. composer.json — confirms which base client package you should require instead (mpp/generali-client or similar). That package, not the bundle, is what you actually install.

Minimal viable first use case: a read-only call against the Generali sandbox. Pick one — a quote, a product list, a contract fetch — and prove you can authenticate and receive a hydrated response before writing any domain code. If the transport is SOAP (historically likely for Generali France), confirm sandbox credentials and WSDL access exists before you spend a day on glue.

// config/generali.php — translated from Configuration.php
return [
    'base_uri'     => env('GENERALI_BASE_URI'),
    'credentials'  => [
        'key'    => env('GENERALI_KEY'),
        'secret' => env('GENERALI_SECRET'),
    ],
    'timeout'      => 30,
];

Then bind the extracted client in a GeneraliServiceProvider:

$this->app->singleton(GeneraliClient::class, fn ($app) =>
    new GeneraliClient(config('generali'))
);

That is the entire "getting started" — the rest is the day-to-day patterns below.

Implementation Patterns

Anti-corruption layer first, transport second. Before wiring anything, define the interface your domain will actually call. Everything downstream depends on this being framework-neutral.

interface InsuranceGateway
{
    public function quote(QuoteRequest $req): Quote;
    public function subscribe(Subscriber $sub): Subscription;
    public function getContract(string $id): Contract;
}

Bind a GeneraliGateway adapter behind it. Your controllers, jobs, and models never see a Symfony type, a PSR-7 request, or a Generali DTO name. When you need a second carrier, you add an adapter — you don't touch the callers.

Config translation pattern. The bundle's Configuration.php node is nested and typically uses ->children()->scalarNode(...) style. Flatten it into a Laravel config file, keep key names identical, and validate with config() defaults rather than a Symfony config tree. A one-line Config::set() in a test overrides anything you'd otherwise mock.

Service-provider binding pattern. One provider, one file:

final class GeneraliServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(GeneraliTransport::class, fn ($app) => new GeneraliTransport(
            http: $app->make(\GuzzleHttp\Client::class),
            config: $app->make('config')->get('generali'),
        ));

        $this->app->bind(InsuranceGateway::class, GeneraliGateway::class);
    }
}

Keep the transport (HTTP/SoapClient) and the gateway (DTO mapping) as separate bindings. You will want to swap transport for testing without rewriting mapping.

Fake adapter for local dev and CI. Bind FakeInsuranceGateway when app()->environment('local', 'testing'). Return canned DTOs that match real sandbox responses byte-for-byte. This is the single highest-value piece of glue — it decouples your dev loop from Generali's sandbox availability, which will be flaky.

Queue all write operations. Never call subscribe() synchronously in a request path. Job → gateway → idempotency key → reconciliation. Idempotency keys must be stored before the call, so partial-success is always recoverable:

$key = (string) Str::uuid();
Cache::put("generali:subscribe:{$key}", 'pending', now()->addDay());
SubscribeToGenerali::dispatch($request, $key);

Shadow-read, then cut over writes. Ship reads first (contract lookups, product catalogue) where wrong answers are visible but harmless. Only enable write paths after a reconciliation job exists that can compare your local state to Generali's contract state on demand.

Contract tests against the sandbox, scheduled. A handful of tests — one per flow you actually use — hitting sandbox in a nightly CI job. This is the only thing that catches schema drift when the insurer silently renames a field.

Gotchas and Tips

  • The bundle boot never happens in Laravel. vendor/mpp/generali-client-bundle/ will sit on disk doing nothing. If you're debugging "why isn't my service bound?", that's the answer. Delete the bundle dependency, require the base client.
  • Autoconfigured tags don't resolve. If the bundle relies on implements EventSubscriberInterface or #[AsCommand] autoconfiguration, those classes are inert in Laravel. Any event listeners or console commands the bundle ships must be re-registered manually or ignored.
  • Symfony\Component\HttpKernel\Bundle\Bundle will leak. If you try to new the bundle manually to poke at services, you pull in a class hierarchy Laravel doesn't provide. Read the source; don't instantiate.
  • Credential handling is the real risk, not the code. Expect mTLS or signed-request auth tuned to MPP's secret store. Port to Laravel's config() + a secret manager; don't hardcode paths. Watch certificate expiry — these failures are silent until the first real call fails.
  • SOAP vs REST matters for DTO mapping. If the underlying client is WSDL-driven, DTO mapping is generated and brittle: a single xsd:string → xsd:date change upstream becomes a runtime exception or, worse, a silently wrong decimal. Wrap every call site in try/catch that logs the raw payload before hydration.
  • Never let Generali DTOs escape the gateway. The moment a Contract model from the bundle appears in a controller or Eloquent relation, you've coupled your domain to the carrier and made adding a second insurer a rewrite.
  • Pin the fork. Pin to a commit SHA in composer.json, not a version constraint. There is no release cadence to rely on.
  • Assume you own the code from day one. No stars, no dependents, no maintainer response path. Register the fork in your internal repo, name an owner, diff quarterly against mon-petit-placement upstream.
  • Licence and provenance check before this reaches production. Confirm the licence permits forking and vendoring, and confirm nothing proprietary to MPP is baked into the mapping layer. Read LICENSE and composer.json before you copy a single file.
  • The critical path is Generali, not code. Sandbox access, credentials, and partner onboarding take weeks. The PHP work takes days. Start the commercial/onboarding track first; spike the code in parallel.
  • Extension point worth keeping: the gateway interface. That is your escape hatch — when (not if) the upstream bundle goes unmaintained or the DTO contract shifts, the interface is what lets you swap a rewritten adapter in without touching callers.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource