tomatophp/tomato-invoices-module
An invoices management module for the TomatoPHP ecosystem, adding invoice creation, tracking, and billing screens to your Filament admin panel. Integrates with other Tomato modules to handle customers, payments, and exports.
Architecture fit. tomatophp/tomato-invoices-module is a package-as-feature-slice: a Laravel package that ships invoice/invoice-item models, migrations, config, and Filament admin resources for CRUD, status tracking, and PDF output. It assumes a host Laravel app already running Filament and — in the common configuration — the broader TomatoPHP admin suite for accounts/customers and panel conventions. As a TPM the architectural question is not "is this good code" but "does adopting it commit us to a bounded context we don't control?" It does: invoice and line-item tables become our system of record for financial data sitting behind vendor-owned migration files. That's an acceptable trade for internal draft/proforma invoicing on a Filament admin; it's not acceptable if invoicing is meant to be a domain we own with its own state machine, numbering guarantees, or non-Filament surfaces.
Integration feasibility. Mechanically this is a Composer install, config/migration/asset publish, migrate, and plugin registration on a Filament panel provider. The real feasibility work is dependency-matrix confirmation before any sprint is committed: Filament major, Laravel major, PHP floor, and sibling tomatophp/* packages. Two signals should shape the plan. First, the v1.0.0 tag (2024-03-09) is the author declaring the public surface — table schema, resource class names, config keys — stable, which is precisely the surface we will subclass and read directly. Second, the release notes contain no changelog, so the tag is a snapshot, not a reviewed release; engineering must derive the specification from the code. Treat "install works" as a half-day spike, not as evidence of fit.
Technical risk. Ranked, with the TPM action attached to each:
Key questions. Which Filament/Laravel/PHP versions are actually constrained in composer.json, and is there a CI matrix proving it? Which tomatophp/* siblings are hard dependencies, and are they also 1.0.0? Does the module own invoice numbering, totals, and tax math, or delegate? Does it model issued/immutable states, credit notes, multi-currency? Is PDF rendering synchronous in the request or queued, and what renders it? Are migrations publishable and is the table prefix configurable? Is there any release cadence or security-reporting process observable over the last 12 months? Does MIT cover our intended redistribution inside a shipped product?
Stack fit. Target host is Laravel 10/11, PHP 8.1+, Filament v3, MySQL/PostgreSQL. Confirm the module's Composer constraints against ours first — a Filament major mismatch is the most common silent blocker in this ecosystem and burns a sprint if discovered late. If our admin is Nova, plain Livewire, or a separate SPA, the module's value collapses to its schema; in that case take the schema and skip the dependency.
Migration path. Frame this to stakeholders as greenfield module adoption, not a data migration. Sequence: install on a scratch branch → publish config/migrations/assets → migrate a seeded dev database → read the resulting schema and generated resources as the de facto spec → fork migrations into our own set → introduce a thin internal adapter (BillingService) so application code never references vendor model classes directly → add our own authorization policies rather than relying on seeded roles/permissions. The adapter is the single highest-leverage decision in the whole program: it converts a future fork-or-replace from a rewrite into a patch, and it's the thing that quietly erodes if not written into onboarding.
Compatibility. Verify against our real matrix, not the README: PHP in CI, Laravel, Filament, DB driver (JSON columns and enum handling diverge across MySQL 5.7/8 and Postgres), and queue driver for PDF jobs. Explicitly check for global registrations that could collide — routes, views, translations, and especially an invoices table name that may already exist in our schema.
Sequencing. Five gates, with exit criteria a TPM can actually track:
Do not parallelize Phase 2 with Phase 1 — the hardening design depends on what the schema actually contains. Communicate this dependency explicitly, because it's the place stakeholders will push to compress the schedule.
Maintenance. Plan on owning this code within one to two quarters. Steady-state effort is three recurring lines: tracking upstream releases, absorbing Filament major upgrades, and our own compliance-driven changes. If we extend by subclassing Filament resources, upstream refactors hit us at upgrade time; the adapter layer is what bounds that cost. Add translation/locale upkeep if invoices reach customers in multiple languages.
Support. The support path is GitHub issues on a community project — no SLA, no contract, no escalation. Acceptable for internal draft/proforma workflows; unacceptable for anything carrying statutory invoicing obligations. Mitigation is an internal fork we can patch plus at least one engineer fluent in the module's internals. The codebase is small enough that this is achievable — but it must be scheduled as an explicit ownership assignment, not assumed as "someone will figure it out."
Scaling. Performance is ordinary Eloquent: fine through thousands to low hundreds of thousands of invoices with indexes on customer, status, and issue date. The real constraints sit elsewhere — PDF rendering is CPU-bound and must be queued, never inline in the Filament request; Filament invoice lists need pagination and eager-loaded line items; and PHP-side totals/tax aggregation will degrade reporting queries. Route financial reporting through our own read model or views, never through admin resources.
Failure modes. Worth tracking in a risk register with owners: (1) Filament bump breaks panel/resource registration — admin 500s; (2) forked-migration collision with upstream — duplicate column/table on deploy, prevented by forking at install; (3) invoice numbering gaps or duplicates under concurrency — this is a compliance incident, not a bug, and must be solved with a DB-level sequence or lock regardless of what ships; (4) PDF worker backlog blocking customer-facing delivery; (5) missing policy or mass-assignment allowing post-issue edits/deletes; (6) hard-delete on records we're legally required to retain.
Ramp-up. Low for a Laravel/Filament-fluent engineer — roughly a day to install and read the resources, a week to be productive in the domain. The non-obvious cost is domain knowledge, not the package: invoicing, tax, and audit rules are not encoded here and no amount of code reading surfaces them. Schedule a finance/accounting stakeholder review of the model of record before Phase 3 and treat their sign-off as a gate, not a courtesy. Team-wide, document the adapter boundary and the "never touch module models directly" rule in the same onboarding page — otherwise the convention erodes within two sprints and the replaceability we paid for quietly disappears.
How can I help you explore Laravel packages today?