madebyclowd/laravel-auto-sequence
Laravel Auto Sequence generates unique, sequential numbers for Eloquent models, ideal for invoice, order, and ticket IDs. Configure prefixes, suffixes, padding, and reset periods with simple model traits.
INV-2026-00001, include a branch prefix, or reset monthly is a product/brand decision, not a schema decision. The format_template ({type_code}, {date:d-M-Y}, {seq:5}) and period settings let us change numbering rules without a migration or model rewrite.transaction_mode (gapless vs gap_tolerant), max_value with SequenceExhaustedException, allow_manual => false, and continuous recycling are policy switches. If finance or a tax authority requires unbroken invoice numbering, that's a one-line config decision — and a scoping conversation we can have with legal early rather than in the release crunch.scope (e.g. tenant_id) isolates counters per tenant/branch, and type_relation derives prefix from a relationship with a default_type fallback. This means "sell to multi-branch customers" or "spin up a second entity" doesn't require a new numbering service — it's configuration.period closure supports fiscal-year resets (April 1st, etc.). Entering a market with a non-calendar fiscal year becomes a config task instead of a bespoke feature.sequences table with row locking, retry semantics, and period partitioning — realistically a few days to build and an ongoing tail of duplicate-number incidents at month boundaries and under concurrent writes. Buying gets a composite-key counter table, pluggable locking drivers, and pre-allocation for throughput.REF-{seq:8} reference that never resets. Avoids one column doing two jobs.sequence:list, sequence:reset --value=, and sequence:verify --repair turn "our invoice numbers jumped / duplicated" from a data-migration fire drill into a runbook command. That's a support-cost decision worth naming.Adopt when most of these hold:
Look elsewhere / avoid when:
pre_allocation is explicitly incompatible with gapless mode. Pick one and say so up front.noeviction). If gaps are unacceptable, throughput is capped.sequences table. Workable (load_migrations => false is honored in tests), but expect friction and document it.To executives (30 seconds). We need sequential, formatted, non-duplicating document numbers — invoices, orders, credit notes. Today that's either hand-rolled code with a known duplicate risk at month boundaries and under concurrent load, or manual process. This MIT-licensed Laravel package gives us compliant numbering, per-tenant and per-branch isolation, and fiscal-year resets as configuration. It removes a recurring class of finance-visible defects and unblocks multi-entity sales conversations — for roughly the cost of an integration, not a build. The one caveat: it's a small, low-adoption open-source package, so we treat it as "adopt with a fork plan," not "adopt and forget."
To engineering. One contract (Sequenceable) and one trait (HasSequenceNumber); numbering rules live in getSequenceConfig(). It handles counter allocation, period partitioning, and locking (configurable driver, with the database driver using a bounded lock timeout rather than blocking the worker). There's real operational tooling — sequence:install, sequence:list, sequence:reset, and sequence:verify --repair for drift between the counter and the actual max in the table. Watch the known edges: manual override silently skips generation if the column isn't null, file/array cache drivers can't lock, soft deletes don't recycle until forceDelete(), and pre-allocation needs a dedicated non-evicting cache store or you get silent gaps. We pin the version, wrap the trait behind our own base model so a swap is a one-file change, and add a concurrent-creation test to CI on day one.
Decision framing. Treat this as a low-cost, reversible bet: adopt behind a thin internal abstraction, keep our own integration test for duplicate prevention, and revisit if throughput or compliance requirements outgrow it.
How can I help you explore Laravel packages today?