php-commerce/CLAUDE.md
Snider ce0669d0a0
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
docs: add CLAUDE.md project instructions
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-13 13:38:02 +00:00

5.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What This Is

lthn/php-commerce — A Laravel package providing orders, subscriptions, invoices, and payment processing. This is a package (not a standalone app), tested with Orchestra Testbench.

Commands

composer run lint          # vendor/bin/pint
composer run test          # vendor/bin/pest
vendor/bin/pint --dirty    # Format changed files only
vendor/bin/pest --filter=CheckoutFlowTest  # Run single test file
vendor/bin/pest --filter="checkout"         # Run tests matching name

Architecture

Dual Namespace System

The package has two PSR-4 roots, serving different purposes:

  • Core\Mod\Commerce\ (root ./) — The module: models, services, events, Livewire components, routes. Boot.php extends ServiceProvider with event-driven lazy-loading via $listens.
  • Core\Service\Commerce\ (root ./Service/) — The service definition layer: implements ServiceDefinition for the platform's service registry (admin menus, entitlements, versioning).

Boot & Event System

Boot.php uses the Core Framework's event-driven lazy-loading — handlers only fire when the relevant subsystem initialises:

public static array $listens = [
    AdminPanelBooting::class => 'onAdminPanel',
    ApiRoutesRegistering::class => 'onApiRoutes',
    WebRoutesRegistering::class => 'onWebRoutes',
    ConsoleBooting::class => 'onConsole',
];

Livewire components are registered inside onAdminPanel() and onWebRoutes(), not auto-discovered. All components use the commerce.admin.* or commerce.web.* naming prefix.

Payment Gateways

Pluggable via PaymentGatewayContract in Services/PaymentGateway/:

  • BTCPayGateway — Cryptocurrency (default when enabled)
  • StripeGateway — Card payments (SaaS)

The default gateway is resolved by checking config('commerce.gateways.btcpay.enabled') — BTCPay takes priority when enabled.

Multi-Entity Hierarchy (Commerce Matrix)

The system supports a three-tier entity model configured in config.php under matrix and entities:

  • M1 (Master Company) — Owns the product catalogue, source of truth
  • M2 (Facade/Storefront) — Selects from M1 catalogue, can override content
  • M3 (Dropshipper) — Full catalogue inheritance, no management responsibility

PermissionMatrixService controls cross-entity access. It has a "training mode" (prompts for undefined permissions) and "strict mode" (undefined = denied).

SKU System

SKUs encode entity lineage: {m1_code}-{m2_code}-{master_sku}. SkuParserService decodes them; SkuBuilderService constructs them; SkuLineageService tracks provenance.

Domain Events

Events in Events/ trigger listeners for loose coupling:

  • OrderPaidCreateReferralCommission
  • SubscriptionCreatedRewardAgentReferralOnSubscription
  • SubscriptionRenewedResetUsageOnRenewal
  • SubscriptionCancelled, SubscriptionUpdated

ProvisionSocialHostSubscription is a subscriber (listens to multiple events).

Livewire Components

Located in View/Modal/ (not Livewire/):

  • View/Modal/Web/ — User-facing (checkout, invoices, subscription management)
  • View/Modal/Admin/ — Admin panel (managers for orders, coupons, products, etc.)

Scheduled Commands

Console/ has artisan commands registered in onConsole(): dunning processing, renewal reminders, exchange rate refresh, usage sync to Stripe, referral commission maturation, expired order cleanup, and tree planting for subscribers.

Key Directories

Boot.php              # ServiceProvider, event registration, singleton bindings
config.php            # Currencies, gateways, tax, dunning, fraud, matrix settings
Service/Boot.php      # ServiceDefinition for platform registry (admin menus, entitlements)
Models/               # Eloquent models
Services/             # Business logic (singletons registered in Boot::register())
Services/PaymentGateway/  # Gateway contract + implementations
Contracts/            # Interfaces (e.g., Orderable)
Events/               # Domain events
Listeners/            # Event handlers
View/Modal/           # Livewire components (Admin/ and Web/)
Routes/               # web.php, api.php, admin.php, console.php
Migrations/           # Database schema
Console/              # Artisan commands
tests/                # Pest tests using Orchestra Testbench

Conventions

  • UK English — colour, organisation, centre, behaviour
  • PSR-12 via Laravel Pint
  • Pest for testing (not PHPUnit syntax)
  • Strict typesdeclare(strict_types=1); in all files
  • Final classes by default unless inheritance is intended
  • Type hints on all parameters and return types
  • Livewire + Flux Pro for UI components (not vanilla Alpine)
  • Font Awesome Pro for icons (not Heroicons)
  • Naming — Models: singular PascalCase; Tables: plural snake_case; Livewire: {Feature}Page, {Feature}Modal

Don't

  • Don't use Heroicons (use Font Awesome Pro)
  • Don't use vanilla Alpine components (use Flux Pro)
  • Don't create controllers for Livewire pages
  • Don't use American English spellings