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

Clearance Laravel Package

rivalex/clearance

A drop-in Laravel admin panel for spatie/laravel-permission. Manage permissions, roles, guards and settings via Livewire 4 + Flux UI, with contextual authorization, parent-bounded ceiling roles, and optional super admin.

View on GitHub
Deep Wiki
Context7
1.0.2

Added

  • Force dark mode config + Settings toggle — mirrors the same feature just shipped in rivalex/lingua. Clearance's own CSS uses a class-based dark: variant that follows the host app's <html class="dark"> ancestor; hosts with no class-based dark toggle (or whose real OS/browser scheme doesn't match a deliberately-dark host layout) previously rendered Clearance unstyled/illegible even though the rest of the page was fine. config('clearance.dark_mode.force') (env CLEARANCE_FORCE_DARK_MODE) sets the default; a new "Appearance" card in /clearance/settings (Livewire\Settings\AppearanceSettings, DB-backed via ClearanceSettings::get/set('dark_mode.force', ...)) overrides it live, same DB-over-config precedence as Lingua. New anonymous component <x-clearance::dark-scope> (resources/views/components/dark-scope.blade.php) wraps the resolved value in an optional .dark ancestor div around the existing .clearance scope div; every one of the 25 Blade views that previously opened with a bare <div class="clearance ..."> now opens with <x-clearance::dark-scope ...> instead (content and any extra utility classes on the wrapper preserved 1:1).

Fixed

  • dark: variant was OS-preference-based, not class-based — resources/css/clearance.css imported tailwindcss without ever declaring [@custom-variant](https://github.com/custom-variant) dark (&:where(.dark, .dark *)); (present in Lingua's CSS entry, missing here), so every dark: utility Clearance itself authors compiled under Tailwind v4's default strategy — [@media](https://github.com/media) (prefers-color-scheme: dark) — completely ignoring any .dark class on <html>. Confirmed live against rivalex.test/clearance: with <html class="dark"> already present (this host's layout is deliberately dark-only), borders/nav pills/muted text using Clearance's own dark: classes still rendered in their light-mode colors, because the compiled CSS gated them on the OS color-scheme media query instead. Added the same [@custom-variant](https://github.com/custom-variant) dark declaration Lingua uses; rebuilt src/dist/css/clearance.min.css now contains zero prefers-color-scheme rules and the expected :where(.dark, .dark *) selectors, verified against the live page (border/nav theming now correct with force/.dark set, independent of OS scheme).
  • Dashboard <flux:card> stat tiles rendered an unstyled white background with invisible (white-on-white) numbers, even after the [@custom-variant](https://github.com/custom-variant) dark fix above. Root cause is narrower and unrelated to the OS-vs-class issue: Flux's own component markup (vendor/livewire/flux/stubs/resources/views/flux/card/index.blade.php) uses a compound utility, dark:[:where(&)]:bg-white/10 (a custom dark: variant stacked on an arbitrary [:where(&)]: bracket variant). Confirmed both livewire/flux (v2.15.0) and tailwindcss/[@tailwindcss](https://github.com/tailwindcss)/vite (v4.3.3) are already latest, so this isn't a version-lag issue — verified directly against the compiled CSS that sibling utilities from the same Flux template line compile fine individually ([:where(&)]:bg-white, [:where(&)]:p-6, [:where(&)]:rounded-xl, plain-stacked dark:border-white/10), but the doubly-stacked dark:[:where(&)]:bg-white/10 never gets generated at all — a genuine Tailwind v4 limitation combining a [@custom-variant](https://github.com/custom-variant)-defined variant with an arbitrary bracket variant on the same utility. Worked around in resources/css/clearance.css with a plain (non-arbitrary) [data-flux-card] { [@apply](https://github.com/apply) dark:bg-white/10; } override, keyed off the stable data-flux-card attribute Flux's card root div already carries — compiles correctly (:where(.dark, .dark *) .clearance [data-flux-card]) and doesn't touch light mode. Verified live: all four dashboard stat tiles now show correct numbers and translucent-dark backgrounds.
  • update-changelog.yml CI workflow hardcoded ref: main (both the actions/checkout step and stefanzweifel/git-auto-commit-action's branch:) — this repo's only branch is master (git ls-remote --heads origin confirms no main ref exists), so every run since this workflow was added failed at checkout (git fetch ... refs/heads/main* finding nothing, retried 3x, exit 1). Both hardcoded to master.
  • codecov/patch failing at 60.00% vs a 78.02% target on the dark-mode commit — new AppearanceSettings.php shipped with zero tests. Added tests/Unit/T67AppearanceSettingsTest.php (mount defaults, config-fallback, DB-overrides-config precedence, save persistence for both true/false) — Livewire/Settings/AppearanceSettings now at 100% coverage; full suite 381/381 passing.

1.0.1

Fixed

  • Permission naming allows _ in segments (V6) — PermissionService::validate()'s gruppo-azione regex constrained each segment to [a-z0-9], so any name containing _ was rejected as an invalid symbol regardless of naming_separator config (e.g. user_profile-manage failed). Segments now accept [a-z0-9_]; the separator itself, spaces, dots, and all other symbols remain rejected. Compounding client-side bug: the custom-ability Alpine slugify() helper in permission-form.blade.php stripped _ to - before the value ever reached the server, so typing an underscore into the custom-ability pill input silently became a dash even after the backend fix. Both the regex (src/Services/PermissionService.php) and the JS slugifier (resources/views/livewire/permissions/permission-form.blade.php) now preserve _. SPEC.md §C and V6 updated to document underscore as a valid segment character. New Pest cases in T3PermissionServiceTest cover accepted underscore names and rejected other-symbol names (@, #, space, !).

1.0.0

First public release. rivalex/clearance is a Livewire 4 + Flux UI admin panel for managing permissions, roles, and contextual authorization on top of spatie/laravel-permission, installable via a single artisan command.

Requirements

PHP ^8.3 · Laravel ^12.0|^13.0 · spatie/laravel-permission ^6.0 · livewire/livewire ^3.0|^4.0 · livewire/flux ^2.14.

Added

  • Panel navigation bar — a shared <x-clearance::nav /> component (resources/views/components/nav.blade.php) rendering a Dashboard/Permissions/Roles/Guards/Settings switcher, placed immediately below the page header on all five top-level panel pages (dashboard.blade.php, guards/guard-manager.blade.php, permissions/permission-manager.blade.php, roles/role-manager.blade.php, settings/manager.blade.php). Modeled on the equivalent rivalex/lingua nav component: flux:button per route, active route highlighted via request()->routeIs(). New ui.common.nav.* translation keys added across all 9 bundled locales.
  • PRODUCT.md / DESIGN.md — committed design system documentation (Impeccable skill format): strategic brand/register/personas in PRODUCT.md, visual tokens (OKLCH ink/red/tinted-neutral ramps, typography, component rules) in DESIGN.md + .impeccable/design.json sidecar, generated from the existing clearance.css [@theme](https://github.com/theme) tokens.
  • roles.form.advanced progressive disclosure — role creation/edit form now collapses scope, context types, and parent-role selection behind a native <details>/<summary> "Advanced settings" section (auto-expanded when a contextual scope or parent role is already set), reducing the always-visible control count on the form.
  • Admin panel — Livewire 4 + Flux UI components for Permissions, Roles, Guards, Settings, and a Dashboard, mountable as pre-built routes (/clearance/*) or as individually embeddable Livewire components.
  • Contextual authorization — role and permission checks scoped to a specific model instance (e.g. a Store, Tenant, or Project): $user->canIn(), $user->hasRoleIn() (via the HasClearance trait), the [@canin](https://github.com/canin)/[@hasrolein](https://github.com/hasrolein) Blade directives, and the ContextService/Clearance facade for use outside a User model context. Resolution merges contextual-role grants with global-role grants, then applies per-context forced_on/forced_off overrides.
  • Ceiling roles — a role can declare a parent role whose permission set acts as an upper bound (RoleMeta.parent_role_id). Child permissions exceeding the parent's ceiling are silently trimmed; a role cannot be both a parent and a child (single-level enforcement).
  • Fine-grained write permissions — one clearance-{section}-write permission per panel section (permissions, roles, guards, settings, users), seeded automatically by the installer and independent from the coarse clearance-access read permission.
  • Super Admin — an automatically-provisioned super_admin role synced with all clearance-* permissions, with alias detection for pre-existing admin-like roles during install, and an opt-in Gate::before() bypass (super_admin_gate_bypass, default false).
  • Users module (opt-in via modules.users) — per-user panel for global and contextual role assignment, plus per-context permission overrides (clr_ctx_overrides), scoped to a specific context model instance.
  • Settings panel — per-role/guard display metadata (name, description, sanitized SVG icon, color), a configurable default role with optional auto-assignment on registration and bulk-assignment to existing users, and a show_icons toggle.
  • Guards management — database-backed guards injected into auth.guards at boot, restricted to an allow-listed set of drivers.
  • clearance:install command — publishes config and migrations, detects and bootstraps spatie/laravel-permission if absent, seeds all clearance-* permissions and the super_admin role, and supports --user, --role, --super-admin-role, and --force.
  • clearance:backfill command — adopts Clearance into an existing Spatie installation: seeds display metadata and role scope for pre-existing roles, and imports guards from config/auth.php; supports --only and --dry-run.
  • i18n — 9 bundled languages (ar, en, es, fr, hi, it, pt, ru, zh) with an identical key set across all locales, enforced by a dedicated parity test.
  • Extensibility — HasClearance trait (contextual auth methods, includes Spatie's HasRoles), HasPermissionGroups trait (permission-group UI accessors for custom Permission subclasses), ClearanceContextable contract (custom context labels), and reusable Blade components (x-clearance::message, clipboard, validation-errors, icon set).
  • SVG sanitization — SvgSanitizer, an allow-list-based sanitizer (tags, attributes, on* handlers, javascript: URIs, CSS injection vectors) applied to every user-supplied icon before storage and at render time.

Security

This release ships after a dedicated pre-publication security audit and two follow-up hardening passes. Highlights:

  • Per-context forced_off overrides are deny-authoritative — they now win even when the same permission is also granted via a global role (previously the override could be silently defeated).
  • Privilege-escalation ceilings on every path that grants a permission: an actor cannot grant themselves a permission, cannot grant a permission they don't themselves hold, and cannot touch clearance-* permissions — enforced both for direct per-user grants and for role-level permission syncing.
  • clearance-* permissions are protected end-to-end: they cannot be renamed, deleted, or created/added to any role outside the package's own install flow.
  • [@canin](https://github.com/canin)/[@hasrolein](https://github.com/hasrolein) fail closed (return false, not a 500) for unauthenticated guests.
  • naming_separator is validated at boot against a strict allow-list, closing the only path by which it reaches raw SQL fragments.
  • Migrations that depend on Spatie's roles/permissions tables fail with an actionable message if run before clearance:install, instead of a cryptic foreign-key error.
  • No known vulnerable dependencies (composer audit clean).

Full audit trail, findings, and fixes: docs/plans/security-audit/plan.md.

Fixed

  • clearance.layout config was dead — changing it had no effect on any panel page. Livewire 4 only wraps a full-page component's rendered view in a layout when ->layout() is explicitly called on it, otherwise it silently falls back to the host app's config('livewire.component_layout'); nothing in Clearance ever called ->layout(), so the package's own layout config key (and its doc comment referencing the wrong Livewire config name) was read nowhere and had zero effect regardless of value. Added Rivalex\Clearance\Concerns\HasClearanceLayout (applies config('clearance.layout') via ->layout() only when set, otherwise leaves Livewire's own default untouched) and wired it into every full-page component's render()/placeholder(): Dashboard, Roles\RoleManager, Guards\GuardManager, Permissions\PermissionManager, Settings\SettingsManager, Users\UserClearanceManager. Corrected the config comment to reference livewire.component_layout. Covered by tests/Unit/T11ClearanceLayoutTest.php.
  • [P0] Permission-pill keyboard/screen-reader accessibility — role-form.blade.php and permission-form.blade.php permission pills used class="hidden" on their checkbox input, removing them from the tab order and killing the focus ring; selected state was color-only. Now uses sr-only (focusable, screen-reader visible), a has-[:focus-visible]:ring-2 focus ring on the pill, and a checkmark icon as a non-color selected-state signal.
  • [P1] Dashboard decorative rainbow colors — stat-card icons and action buttons used arbitrary Tailwind hues (sky/amber/emerald/rose) with no semantic meaning, violating the design system's "one signal = red for danger" rule. Icons now render in a muted neutral tone; buttons use the default ink primary; the four stats are differentiated by label/position only.
  • [P2] zinc-* raw Tailwind utilities instead of the brand neutral ramp — 413 occurrences across 25 Blade view files bypassed the tinted hue-260 --color-gray-* ramp defined in clearance.css in favor of Tailwind's default untinted zinc palette. Migrated to gray-* project-wide (Flux component color="zinc" props left untouched — that's Flux's own neutral-palette API, unrelated to the raw utility drift).
  • [P2] Off-token colors on badges/buttons — color="green" primary Save/Add buttons (guard, permission, role create/edit triggers) reverted to the default ink primary; amber/sky informational badges (locked-role badge, guard-type badge, contextual-role-context badge) converted to neutral; checkbox accent colors switched from text-sky-600 to the ink token.
  • Filename typo — resources/images/clearance-mark-horizzontale.svg renamed to clearance-mark-horizontal.svg; references updated in branding.blade.php and README.md.
  • [P0, follow-up] Permission pills in role-form.blade.php collided with the danger signal — granted CRUD-category pills still rendered green/red/amber (create/read/update=green, delete=red, custom=amber); a granted delete ability used the same red reserved for destructive actions, collapsing "you hold this ability" and "this is dangerous" into one signal. Granted pills (including the locked/always-on variant) now fill with the ink token + checkmark regardless of category; delete-type abilities are marked by a small trash icon instead of the danger hue.
  • [P1, follow-up] Contextual permission panel showed the same permission list twice with no explanation — users/contextual-roles-panel.blade.php listed a role's permissions once as a disabled read-only grid and again as toggleable "extra permissions" checkboxes, with no indication of what checking the second grid actually does (it explicitly pins that permission to this context so it survives future role changes — it does not grant anything the role doesn't already grant). Added an inline hint (user_clearance.extra_perms.extra_perms_hint, all 9 locales) clarifying the relationship instead of restructuring the two lists, since collapsing them would misrepresent genuinely distinct override semantics.
  • Create permission/role forms kept stale data after a successful save — new-permission-modal/new-role-modal use a static Livewire :key, so Flux reuses the same component instance every time the modal reopens instead of remounting it; PermissionForm::save() and RoleForm::save() closed the modal and dispatched their *-saved event but never reset the component's public state. Both now explicitly reset the create-mode fields (and validation state) right after a successful create; edit mode is unaffected.
  • Dashboard "Permission Groups" stat showed the permission count, not the group count — Dashboard.php built a raw SELECT DISTINCT SUBSTR(...) subquery and called ->count() on it; Eloquent's aggregate count() discards custom select() columns and runs a plain COUNT(*), so the "distinct" never applied and the stat silently equaled permissions_count. Replaced with Permission::all()->pluck('permission_group')->unique()->count(), matching the grouping already used by HasPermissionGroups::getPermissionGroupAttribute().
  • text-align:right CSS-inheritance leak into inline (non-teleported) modals — Flux modals in this app render in place rather than teleporting to <body>, so a modal declared inside a <td class="text-right"> action cell had its heading/description inherit the cell's right alignment. Found and fixed on guards/guard-manager.blade.php and roles/role-manager.blade.php, then found again (same pattern, different files) on settings/role-meta-table.blade.php and settings/guard-meta-table.blade.php (the "Edit metadata" modal on the Settings page). Fixed by moving the alignment onto an inner flex justify-end wrapper and dropping text-right from the <td> itself.
  • Role name field and "Locked" toggle silently vanished from the create/edit Role modal — role-form.blade.php had [@if](https://github.com/if)($isSuperAdmin) disabled [@endif](https://github.com/endif) written directly inside the attribute list of a self-closing <flux:input> / <flux:checkbox> tag; Blade's component-tag compiler couldn't match the tag as a result and left it uncompiled/unrendered, while the sibling [@if](https://github.com/if)/[@endif](https://github.com/endif) statement still got processed as plain PHP by a separate compiler pass — so the field silently disappeared instead of erroring. Replaced with the standard :disabled="$isSuperAdmin" dynamic-attribute binding (already the working pattern in guard-form.blade.php).
  • Create/Edit Role modal ignored its md:w-[52rem] width — Flux ships an un-layered default modal rule (max-width: 36rem) that wins over any Tailwind [@layer](https://github.com/layer) utilities class regardless of specificity or source order; a modal requesting a wider layout was silently clamped back to 36rem. Fixed by forcing the width/max-width utilities with Tailwind v4's ! important suffix (md:w-[52rem]! md:max-w-[52rem]!); npm run build re-run to ship the updated src/dist/css/clearance.min.css.
  • Inconsistent modal header/footer layout package-wide — normalized every modal to the same shape: heading + description separated from the body by a border-b, action buttons separated by a border-t and laid out flex justify-between (single-action modals use justify-end). Applied to roles/delete-role.blade.php (all three confirm branches), permissions/delete-permission.blade.php, permissions/permission-form.blade.php, guards/guard-form.blade.php (also converted from a raw <header><h3>/<p></header> to flux:heading/flux:text — the only modal in the package not using Flux's typography components), settings/edit-meta.blade.php, users/assign-role-modal.blade.php, and users/remove-assignment-modal.blade.php.
  • Panel nav bar never highlighted the active route — <x-clearance::nav /> picked the "active" tab via request()->routeIs(), which only works during the request that actually resolves the named route. Dashboard, RoleManager, GuardManager, and SettingsManager are all #[Lazy] Livewire components: their real content (including the nav) renders over Livewire's internal follow-up "component" request, not the original page request, so routeIs() always returned false there and every tab rendered as unselected ghost — only the non-lazy PermissionManager page ever highlighted correctly. Fixed by having each page pass its own tab explicitly (<x-clearance::nav active="roles" /> etc.) instead of inferring it from the ambient request.
  • [follow-up] Role-form permission pills lost their category colors — the P0 accessibility follow-up above (ink-fill + checkmark/trash icons for every granted pill) traded away the create/read/update=green, delete=red, custom=amber coding used everywhere else in the panel. Removed the checkmark/trash icons (redundant once the pill itself is visibly filled/colored) and reinstated the color scheme by reusing the data-checked + ability-color pattern already working in permission-form.blade.php (added the missing .crud-pills.amber CSS rule). The "locked" always-granted pills (e.g. clearance-* for super_admin) intentionally keep the ink fill — granted-and-immutable stays a distinct signal from granted-and-toggleable.
  • Reconciled i18n key drift (French locale was missing keys used by the live UI).
  • Removed an orphaned Hierarchy Livewire module left over from an earlier design (superseded by ceiling roles) that referenced deleted classes.
  • Fixed a broken static-analysis configuration that had been silently preventing composer analyse from running.
  • Clarified the install-time warning shown when a User model is missing HasClearance/HasRoles.

Changed / Breaking

  • super_admin_gate_bypass now defaults to false (previously true). Applications relying on the global Gate bypass must opt in explicitly.
  • ContextService::resolveFor() deny-override semantics: a forced_off override now always denies, even against a global-role grant (see Security above).
  • RoleService::syncPermissions() and UserClearanceService::syncGlobalExtraPermissions()/syncContextualExtraPermissions() gained a required leading Authenticatable $actor parameter to enforce the privilege-escalation ceiling. Any code calling these services directly must pass the acting user.
  • Minimum PHP raised to ^8.3; Laravel 10.x support dropped, 13.x added.
Clearance

[1.0.2] - 2026-07-28

Added

  • Force dark mode config + Settings toggle — mirrors the same feature just shipped in rivalex/lingua. Clearance's own CSS uses a class-based dark: variant that follows the host app's <html class="dark"> ancestor; hosts with no class-based dark toggle (or whose real OS/browser scheme doesn't match a deliberately-dark host layout) previously rendered Clearance unstyled/illegible even though the rest of the page was fine. config('clearance.dark_mode.force') (env CLEARANCE_FORCE_DARK_MODE) sets the default; a new "Appearance" card in /clearance/settings (Livewire\Settings\AppearanceSettings, DB-backed via ClearanceSettings::get/set('dark_mode.force', ...)) overrides it live, same DB-over-config precedence as Lingua. New anonymous component <x-clearance::dark-scope> (resources/views/components/dark-scope.blade.php) wraps the resolved value in an optional .dark ancestor div around the existing .clearance scope div; every one of the 25 Blade views that previously opened with a bare <div class="clearance ..."> now opens with <x-clearance::dark-scope ...> instead (content and any extra utility classes on the wrapper preserved 1:1).

Fixed

  • dark: variant was OS-preference-based, not class-based — resources/css/clearance.css imported tailwindcss without ever declaring [@custom-variant](https://github.com/custom-variant) dark (&:where(.dark, .dark *)); (present in Lingua's CSS entry, missing here), so every dark: utility Clearance itself authors compiled under Tailwind v4's default strategy — [@media](https://github.com/media) (prefers-color-scheme: dark) — completely ignoring any .dark class on <html>. Confirmed live against rivalex.test/clearance: with <html class="dark"> already present (this host's layout is deliberately dark-only), borders/nav pills/muted text using Clearance's own dark: classes still rendered in their light-mode colors, because the compiled CSS gated them on the OS color-scheme media query instead. Added the same [@custom-variant](https://github.com/custom-variant) dark declaration Lingua uses; rebuilt src/dist/css/clearance.min.css now contains zero prefers-color-scheme rules and the expected :where(.dark, .dark *) selectors, verified against the live page (border/nav theming now correct with force/.dark set, independent of OS scheme).
  • Dashboard <flux:card> stat tiles rendered an unstyled white background with invisible (white-on-white) numbers, even after the [@custom-variant](https://github.com/custom-variant) dark fix above. Root cause is narrower and unrelated to the OS-vs-class issue: Flux's own component markup (vendor/livewire/flux/stubs/resources/views/flux/card/index.blade.php) uses a compound utility, dark:[:where(&)]:bg-white/10 (a custom dark: variant stacked on an arbitrary [:where(&)]: bracket variant). Confirmed both livewire/flux (v2.15.0) and tailwindcss/[@tailwindcss](https://github.com/tailwindcss)/vite (v4.3.3) are already latest, so this isn't a version-lag issue — verified directly against the compiled CSS that sibling utilities from the same Flux template line compile fine individually ([:where(&)]:bg-white, [:where(&)]:p-6, [:where(&)]:rounded-xl, plain-stacked dark:border-white/10), but the doubly-stacked dark:[:where(&)]:bg-white/10 never gets generated at all — a genuine Tailwind v4 limitation combining a [@custom-variant](https://github.com/custom-variant)-defined variant with an arbitrary bracket variant on the same utility. Worked around in resources/css/clearance.css with a plain (non-arbitrary) [data-flux-card] { [@apply](https://github.com/apply) dark:bg-white/10; } override, keyed off the stable data-flux-card attribute Flux's card root div already carries — compiles correctly (:where(.dark, .dark *) .clearance [data-flux-card]) and doesn't touch light mode. Verified live: all four dashboard stat tiles now show correct numbers and translucent-dark backgrounds.
  • update-changelog.yml CI workflow hardcoded ref: main (both the actions/checkout step and stefanzweifel/git-auto-commit-action's branch:) — this repo's only branch is master (git ls-remote --heads origin confirms no main ref exists), so every run since this workflow was added failed at checkout (git fetch ... refs/heads/main* finding nothing, retried 3x, exit 1). Both hardcoded to master.
  • codecov/patch failing at 60.00% vs a 78.02% target on the dark-mode commit — new AppearanceSettings.php shipped with zero tests. Added tests/Unit/T67AppearanceSettingsTest.php (mount defaults, config-fallback, DB-overrides-config precedence, save persistence for both true/false) — Livewire/Settings/AppearanceSettings now at 100% coverage; full suite 381/381 passing.

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.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc