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

Percentage Laravel Package

satoved/percentage

satoved/percentage offers simple helpers for percentage calculations in PHP and Laravel, including percent of a value, percentage change, discounts, and formatted output, with a clean API for everyday pricing and reporting tasks.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is a leaf-node presentation concern — a Laravel Nova field class, and possibly a small static math helper. That is the correct place for a third-party micro-package: the admin UI edge, never the domain layer. Fit is good only if the product already runs Nova (confirm v4/v5) and the requirement is genuinely thin — capture, display, or light formatting of a percentage on internal, staff-correctable screens. Any attempt to use it as the source of truth for pricing, billing, commissions, or compliance math is an architectural violation and should be declined at intake.

Integration feasibility. Mechanically easy. There is no service provider, config, or publish step: Nova resolves the field class directly from a resource, and the calculator (if present) is instantiated in application code. Feasibility is high and the code volume is near zero. The real effort is verification, not integration — budget a half-day to a day.

Technical risk. The dominant risk is an identity ambiguity: registry metadata calls it "A Laravel Nova field," while the package description pitches a framework-agnostic percentage calculator with optional Laravel integration. Those are different products with different blast radii, and the source must be inspected before any commitment. Secondary risks, in order of severity:

  • Silent unit error (0–100 vs 0–1). A hundred-fold mistake throws no exception, fails no validation, and surfaces weeks later in a customer-facing export.
  • No ecosystem signal. 7 stars, 0 dependents, single maintainer, no issue history. There is no early-warning system and no patch path when Nova major-upgrades the Vue asset pipeline.
  • Client-side masking mistaken for validation. DevTools, CSV imports, artisan commands, and queued jobs all bypass a JS mask.
  • Rounding drift if rounding is performed at hydration, dehydration, and display rather than in one place.

Key questions.

  1. Which identity is actually shipped in src/ — a Field subclass, static helpers (Percentage::of()), or both?
  2. What unit is persisted when a user submits 12.5 — 12.5 or 0.125?
  3. Where is validation enforced server-side, and do ->min() / ->max() / ->step() translate to HTML attributes only?
  4. What are the helper return types, rounding convention, and behavior at 0, negatives, and large values?
  5. Is the license, test suite, and compiled asset build present and committed?
  6. Which Nova and PHP versions are declared, and which have actually been tested?

Integration Approach

Stack fit. PHP/Laravel + Nova only. Outside Nova, the field has no reusable value; the calculator is trivially replaceable by a ~50-line class or bcmath. Adopt only where Nova is already a sunk cost and the percentage widget is the sole requirement.

Migration path. None required — this is additive and greenfield. Install with an exact pinned version, not ^1.0; a floating constraint can change stored-unit behavior or break on a Nova upgrade without warning. Record the pin and any local patches in a short ADR.

Compatibility. Verify Nova 4/5 (Vue 3 asset pipeline), PHP version, and locale handling before writing feature code. Add "open every resource using InternalPercentage and confirm render and persist on index, detail, create, and update" to the Nova upgrade checklist permanently.

Sequencing.

  1. Day-one spike. composer require, open composer.json and src/, determine identity. Then curl the endpoint with 0, 0.5, 12.5, 100, 150, abc, and comma-decimal 12,5, and read the raw DB column each time. Do not proceed until persistence semantics are proven.
  2. Characterization tests first. Assert what lands in the database — not what the form displays. This is the only reliable defense against a silent unit error.
  3. Wrap before use. App\Nova\Fields\InternalPercentage extends the vendor class and owns rules, step, and attribute naming; one file to patch or replace. Bind a PercentageCalculator interface for the math helper and keep rounding policy inside that implementation.
  4. Normalize at the model boundary. Unit conversion belongs in an accessor/mutator so the domain is independent of the package and the assumption is testable.
  5. Pilot on one low-traffic resource, all four screens, one non-en-US locale.
  6. Expand only after pass — and stop there. Do not standardize across admin surfaces.

Priced fallback is mandatory before greenlight: a custom ~100-line Nova field plus a small Vue component, or a plain number field plus server-side ->rules().

Operational Impact

Maintenance. We are effectively the maintainer. The package is small enough that vendoring the source into a private repository or copying it into app/Nova/Fields/ is cheap — and that should be the default posture, not a contingency. Ongoing cost is not in running the code but in re-verifying every field instance on each Nova upgrade.

Support. None upstream: no SLA, no issue history, no production forks. Tolerable for internal admin surfaces where a wrong value is annoying and correctable. Not acceptable for security-sensitive, audited, or customer-facing surfaces.

Scaling. Compute cost is trivial. The scaling concern is breadth: each additional Nova resource using the field is another surface to re-test on upgrade. The wrapper class keeps this linear and auditable; unwrapped vendor calls scattered across resources make it unbounded.

Failure modes.

  • Silent unit error (0.125 stored where 12.5 was intended) — worst case, undetectable until downstream reporting.
  • Field renders on detail but silently fails to persist on index.
  • Post-Nova-upgrade: blank field, raw <input>, or Vue console error, discovered in production admin rather than CI.
  • JS mask bypassed by CSV import, artisan command, or queued job writing the same column.
  • Comma-decimal locale input silently truncated (12,5 → 12) or rejected.
  • Rounding drift between hydrate, dehydrate, and display paths.

Ramp-up. Negligible for any Laravel developer — half a day to a day including verification. The verification is the work.

Decision posture. This is an admin UX accelerator, not a platform dependency. It can shave roughly a day off a small internal ticket. It should never sit on a critical path, block a release, or appear on a strategic roadmap, and it should not be described as a differentiator. Greenlight for internal Nova screens with a pinned version, a wrapper, characterization tests, and a priced in-house fallback. Decline for anything where a silent 0–100 unit error becomes a data-integrity or revenue incident. If the spike shows semantic mismatches — wrong storage unit, missing server-side validation, absent locale handling — build the custom field; patching the vendor will cost more than writing it.

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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package