geekcodev/filament-max-users
Filament Max Users lets you enforce a maximum number of user accounts in your Filament panel. Set a limit, prevent new users from being created once it's reached, and keep registrations under control with simple configuration. Handy for licensing, plan tiers, demos, and single-tenant apps.
Architecture fit. This is a Filament 5.x panel plugin that surfaces MAX messenger entities (users, chats) as admin resources — list tables, view pages, actions, and localized labels. It sits cleanly in the Laravel/Filament admin layer and delegates all MAX API traffic to geekcodev/max-php-client (now 1.1.9). v1.1.1 is a presentation-and-correctness patch: it does not touch config keys, service signatures, defaults, or the public API, so the architectural contract with the host app is unchanged. The only genuinely structural change is behavioral: default column visibility and column/field ordering are now explicitly fixed and toggleable.
Integration feasibility. Low friction for consumers on the ^1.1 line: composer update geekcodev/filament-max-* geekcodev/max-php-client filament/filament. The transitive filament/filament bump 5.7.8 → 5.9.0 is the one thing that can bite — the constraint ^5.0 is unchanged, so the version actually resolved depends on the host app's lockfile and any other Filament plugins sharing that dependency. Expect minor panel-wide UI drift from Filament 5.9 even where our code is untouched.
Technical risk. Moderate-low, concentrated in three areas:
email, username, last_activity_time disappear from the users list until toggled). Filament persists column-toggle state per user, so users with stored preferences keep their view while new/stale-preference users get the new defaults — i.e. an inconsistent fleet immediately post-deploy.table.username/view.username in lang/ru changed from "Username" to "Никнейм". Keys are stable, so no code breakage, but any internal runbook, screenshot set, or e2e selector keyed on the visible string needs updating.ChatPresenter::safeUrl() restricts href to http/https, closing a javascript:/data: injection path (A03) sourced from MAX API data. That is a real hardening win and a reason not to defer this release. Note it is defense at render time only.GET /chats/{id} returns participants as a {user_id: activity} map rather than a list. Fixed in the client plus a regression test — this is the highest-value line in the changelog for anyone operating group chats.Key questions.
users preferences or session? This determines whether we need a one-time reset to align admins on the new defaults.users.* / chats.* permission names, policies, and deletion behavior truly untouched (changelog says yes) — and does that hold for the new toggleable columns, which may expose fields under a different authorization surface?safeUrl() also applied on ingest/persistence, or only at render? If only render, we accept stored-unsafe data as long as nothing else consumes the link field.Stack fit. Assumes Laravel with a Filament 5 panel already hosting this plugin. No new services, queues, or config keys are introduced; FILAMENT_MAX_USERS_NAVIGATION_GROUP appears only as documentation/.env.example hygiene, not as a new requirement. Integration is a version bump plus a UI-communication exercise, not an architecture change.
Migration path. Standard Composer patch upgrade, no data migration: composer require geekcodev/<package>:^1.1.1, allow filament/filament to float to ≥5.9.0, run the package's publish step only if we have locally forked lang/ files. The removed duplicate view.title key in lang/{ru,en}/chats.php is the one merge hazard: if we vendor-published the language files, re-publish or hand-merge, because our copy now differs from upstream. Resolution behavior for __('...chats.view.title') is unchanged (the second, effective key survives), so no runtime impact is expected.
Compatibility.
full_avatar_url, description, phone_verified_at, username, email, last_activity_time, profile_checked_at now hidden by default for users; icon_url, title, description, link, chat_checked_at hidden for chats. Chat title ("Название из MAX") is dropped from the chat view page entirely and exists only as a hidden list column.Sequencing.
composer security-audit.link value renders non-clickable (safeUrl path).Maintenance. Low steady-state cost: no config or contract surface to track, and the package carries unusually strong guardrails for a Filament plugin — PHPStan level max, PSR-12 clean across 22 files, 54 tests / 187 assertions with failOnRisky/failOnWarning, 97.47% line coverage against a 95% gate, and 19 new tests in this release alone. The three new regression tests specifically pin column order, full toggleable composition, and view-page ordering, which converts future "someone reordered a table" incidents into CI failures. That is exactly the kind of thing a patch release should buy us.
Support. Expect a short spike in admin tickets after deploy: "where did email go", "why is the name in a different place", "Никнейм?". Pre-empt with a one-paragraph release note and a screenshot refresh. Second-order support surface is Filament 5.9 itself — if the panel-wide bump changes unrelated UI, tickets may land on this package's doorstep. lang/ru and lang/en are confirmed synchronized, with only the username label intentionally divergent, so bilingual support remains coherent.
Scaling. Unchanged by this release. The lists use aggregate counts (counts('chatLinks'), counts('chatUsers')) rendered per row; that pattern is fine at small/medium volumes and is the first thing to watch if a MAX account has very many chats or a group has very many participants. Participant-map parsing happens on the action path, not on list rendering, so no new hot path was introduced.
Failure modes.
link is consumed anywhere other than through ChatPresenter::safeUrl() (exports, API responses, emails). Render-time sanitization is not a data-cleanliness guarantee.lang/ files and skip re-publish — the removed duplicate title key will linger harmlessly, but future key edits will silently miss our copy.Ramp-up. Near zero for developers — no new concepts, no config, one composer update. The real ramp-up cost is on admins and support: roughly a 10-minute briefing on toggleable columns and the label change, delivered alongside the deploy. Recommended: adopt this release, since it carries a CVE-driven Filament bump and an XSS-class hardening fix that outweigh the cosmetic churn, and treat the column-order and toggleable-composition tests as the acceptance criteria for the upgrade rather than eyeballing the UI.
How can I help you explore Laravel packages today?