Security
Three authorization layers, soft-delete by default, automatic audit log: secure with zero extra code.
The three-layer model
- Feature flag (
OrganizationFeature) — module-level kill-switch. No module resource is served if the organization has not enabled it. - ACL permission (
PermissionCodes) — fine-grained authorization, per role and per user, applied via#[IsGranted(...)]on every mutating method, includingbulk-*. - Voter — ownership and organization scope,
denyAccessUnlessGranted(Voter::ATTR, $entity)before every per-entity mutation.
The three layers are mandatory, in this order. No route ships if any is missing.
Soft-delete by default
Every business entity carries SoftDeletableTrait. A delete sets deleted_at, the Doctrine soft_delete filter masks rows automatically, and a super-admin can restore through a ROLE_SUPER_ADMIN-gated route. No silent data loss.
Automatic audit log
The #[Auditable] attribute on an entity produces a complete trail (create, update, delete, restore), enriched with actor and changed fields. Useful for compliance, essential for diagnostics.
JWT + tenant scoping
The API uses signed JWT tokens. The X-ORGANIZATION header binds every call to a tenant, validated by CrossOrgGuard before any processing. Cross-org access is never possible, not even via mass-assignment.