leads/core
A Laravel/PHP core package for lead management, offering reusable models, contracts, and services to capture, organize, and track leads. Provides a lightweight, extensible foundation for building custom lead workflows.
Architecture fit — leads/core presents as a Laravel package in the lead-management domain (intake, attribution, routing, lifecycle state — inferred from naming, not verified). The 1.2.1 release adds one concrete data point that the prior assessment lacked: the package ships a DateCaster, i.e. Eloquent attribute-casting behaviour. That is meaningful. A package that owns casts is not a pure domain library — it sits inside the persistence layer and expects to influence how model attributes are read and written. That pushes the scope question from "unknown" toward "mid-weight, persistence-aware," which raises the cost of clean separation. It still does not tell us whether migrations, routes, views, and policies ship too, so the package remains unvetted, but the prior framing of "no evidence in either direction" is no longer accurate.
Integration feasibility — Composer-level installation is trivially cheap; the actual cost sits in three unknowns: (1) whether it owns database tables that must coexist with our schema, (2) whether it assumes a specific auth, tenancy, or queue model, and (3) whether its public surface is an interface we can depend on or an implementation we would be coupling to. The release narrows (3): a caster is an implementation detail with a wide blast radius, and if it is applied via a base model or trait rather than opt-in per attribute, adoption becomes an inheritance commitment. Feasibility is plausible but unproven — a timeboxed spike is still required, but it can now start from a named file rather than a blank repository.
Technical risk — High, and concentrated in trust rather than capability:
composer audit against it in anger. Transitive dependency risk is opaque.Positive signals, recorded deliberately — auto-generated changelog in the release-drafter format, PR-based contribution with a linked pull request, and semver discipline (patch bump for a compatible widening). These are hygiene indicators, not quality indicators, but they distinguish the project from an abandoned dump and they are the first evidence of process we have seen.
Key questions
DateCaster opt-in per attribute, applied via a trait, or bound globally? Global binding is a veto-level finding.Stack fit — Start with composer.json: PHP constraint, Laravel major, and any first-party laravel/* pins. Framework coupling is the usual trap — service provider conventions, facade registration, and global helpers that collide with ours. Adding to that list: attribute casts are resolved through the model, so check whether the package expects a base model, a trait, or a per-attribute declaration. If it targets a Laravel major we have already left, the real cost of adoption is a fork, and that should be priced in from the outset.
Migration path — Adopt behind a boundary. Install into a single bounded context (inbound lead capture is the natural first candidate) and wrap it in our own repository/port interface so the package is swappable without touching domain code. Its Eloquent models must not leak into our domain layer — and with 1.2.1 in view, neither must its casts. Declare our own datetime normalisation at the boundary and let the package's caster operate inside it, not instead of it. If it ships migrations, prefix its tables and treat its schema as an internal implementation detail we do not query directly.
Compatibility — Enumerate explicitly: PHP version, Laravel version, database driver parity (MySQL/Postgres/SQLite), queue driver assumptions, and any reliance on global state or container bindings. The datetime change makes driver parity concrete: MySQL DATETIME truncates by default while Postgres timestamptz does not, and minute-precision parsing will behave differently across the two on seconds and fractional input. Test against our actual driver, not SQLite.
Sequencing
composer audit. Diff 1.2.0...1.2.1 and read the test added alongside the caster change; a patch with no accompanying test is itself a finding.Maintenance — Assume we own it. With zero dependents, upstream fixes will not arrive on our schedule, and a single maintainer means the roadmap is one person's attention span. The PR-and-changelog workflow is a genuine positive — it makes our own rebases easier — but it does not transfer ownership. Require a private fork with a named internal owner and a rebase cadence before adoption, not after the first incident.
Support — No evidence of a support channel, published SLA, or security policy. Internal escalation is the only realistic path. Record that explicitly in the adoption decision so it is not rediscovered during an outage.
Scaling — Unknown pending audit. Watch specifically for synchronous per-lead work on the request path, N+1 queries in listing or deduplication, and missing indexes on attribution and lookup keys. Load-test the lead write path before any volume commitment — lead ingestion is typically a high-write, bursty workload and a poor fit for chatty per-record logic.
Failure modes
^ ranges.composer audit in CI and a vendor review before merge.Ramp-up — Low for a Laravel-fluent engineer to install and exercise; medium-to-high to trust. Budget roughly one engineer-week for audit plus spike, plus ongoing fractional ownership for the fork.
Verdict on 1.2.1 — Does not change the recommendation. The release is small, non-breaking, and well-behaved, and it improves confidence marginally on project hygiene while raising a new and specific correctness question about datetime handling. Adopt the audit-and-spike path unchanged; add datetime semantics to the spike's exit criteria.
How can I help you explore Laravel packages today?