Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
# Path-based git attributes
# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html

# Ignore all test and documentation with "export-ignore".
# Keep development files out of the Composer package. docs, llms.txt and
# resources/boost ship with it, for AI assistants and Laravel Boost.
/.gitattributes export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/.github export-ignore
/.editorconfig export-ignore
/phpunit.xml.dist export-ignore
/.scrutinizer.yml export-ignore
/pint.json export-ignore
/tests export-ignore
/.editorconfig export-ignore
/AGENTS.md export-ignore
/CLAUDE.md export-ignore
/node_modules export-ignore
/package.json export-ignore
/pnpm-lock.yaml export-ignore
/tsconfig.json export-ignore
/vitest.config.ts export-ignore
54 changes: 0 additions & 54 deletions .github/workflows/run-tests.yml

This file was deleted.

169 changes: 169 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
name: tests

on:
pull_request:
push:
branches:
- main
- next-gen

# The unreleased javaabu/* dependencies come from VCS repositories; the job's own
# token keeps Composer within GitHub's API limits
env:
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ github.token }}"}}'

jobs:
pint:
runs-on: ubuntu-latest

name: Pint

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.4
coverage: none

- name: Install dependencies
run: composer update --prefer-dist --no-interaction --no-progress

- name: Check code style
run: vendor/bin/pint --test

js:
runs-on: ubuntu-latest

name: React pages (typecheck, tests)

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Setup Node
uses: actions/setup-node@v5
with:
node-version: 22
package-manager-cache: false

# The default store is inside a node_modules folder, which breaks the declaration
# build of @javaabu/forms (installed from git and built on install): Javaabu/react-forms#20
- name: Install dependencies
run: pnpm install --frozen-lockfile --store-dir "$RUNNER_TEMP/pnpm-store"

- name: Typecheck
run: pnpm typecheck

- name: Test
run: pnpm test

without-translatable:
runs-on: ubuntu-latest

name: Without javaabu/translatable

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.4
extensions: curl, mbstring, zip, pdo, sqlite, pdo_sqlite
coverage: none

- name: Install dependencies without translatable
run: |
composer remove --dev javaabu/translatable --no-interaction --no-update
composer update --prefer-dist --no-interaction --no-progress

- name: Execute tests
run: vendor/bin/phpunit --testsuite Package

activitylog-v4:
runs-on: ubuntu-latest

name: spatie/laravel-activitylog v4

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.4
extensions: curl, mbstring, zip, pdo, sqlite, pdo_sqlite
coverage: none

# The matrix's prefer-stable legs install v5 and its prefer-lowest legs v4.10;
# this keeps the latest v4 covered
- name: Install dependencies with activitylog v4
run: |
composer require --dev "spatie/laravel-activitylog:^4.10" --no-interaction --no-update
composer update --prefer-dist --no-interaction --no-progress

- name: Execute tests
run: vendor/bin/phpunit

tests:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
php: [ 8.4, 8.5 ]
laravel: [ 12.*, 13.* ]
stability: [ prefer-lowest, prefer-stable ]
include:
- laravel: 12.*
testbench: 10.*
- laravel: 13.*
testbench: 11.*

name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }}

env:
COVERAGE: ${{ matrix.php == '8.4' && matrix.laravel == '13.*' && matrix.stability == 'prefer-stable' }}

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: curl, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, iconv
coverage: ${{ env.COVERAGE == 'true' && 'pcov' || 'none' }}

- name: Install dependencies
run: |
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update
composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress

- name: Show the activitylog version
run: composer show spatie/laravel-activitylog | grep versions

- name: Execute tests
if: env.COVERAGE != 'true'
run: vendor/bin/phpunit

- name: Execute tests with coverage
if: env.COVERAGE == 'true'
run: vendor/bin/phpunit --coverage-clover build/coverage.xml

- name: Upload coverage to Codecov
if: env.COVERAGE == 'true'
uses: codecov/codecov-action@v5
with:
files: build/coverage.xml
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ vendor
coverage
.phpunit.result.cache
.idea
node_modules
.phpunit.cache
19 changes: 0 additions & 19 deletions .scrutinizer.yml

This file was deleted.

4 changes: 0 additions & 4 deletions .styleci.yml

This file was deleted.

48 changes: 48 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# permissions: notes for AI coding agents

`javaabu/permissions` wraps spatie/laravel-permission with a registration API for permissions, roles and policies, multi-auth helpers, and role management (routes, controller, JSON API, Blade and Inertia pages). Other Javaabu packages depend on its registration API, so treat `Permissions`, `PermissionGroup`, `ResourcePolicy` and `Route::roles()` as public contracts.

## Layout

| Path | What |
| --- | --- |
| `src/Permissions.php` | Facade over `PermissionRegistry`, plus `sync()`, `ignoreMigrations()`, `permissionName()` |
| `src/Registry` | `PermissionRegistry` (groups, roles, policies, guards), `PermissionGroup`, `RoleDefinition` |
| `src/Sync` | `PermissionSyncer` and `SyncResult`, used by `permissions:sync` and `PermissionsSeeder` |
| `src/Policies` | `ResourcePolicy` base class and `RolePolicy` |
| `src/Traits/HasRoles.php` | Trait for user models (includes spatie's) |
| `src/Models` | `Role` and `Permission`, extending spatie's |
| `src/Routing/RoleRoutes.php`, `src/Http` | `Route::roles()`, `RolesController`, `RoleRequest`, resources |
| `src/Views/ViewRenderer.php` | Renders Blade (`permissions::roles.index`) or Inertia (`permissions::Roles/Index`) |
| `resources/views/roles` | Blade pages, built with javaabu/forms v2 components |
| `resources/js` | Inertia React pages (`Pages/Roles`), components (`@javaabu/permissions`) and the Blade script (`roles.ts`), registered with javaabu/manifest |
| `src/Support/Translations.php`, `src/Models/Translatable` | Optional javaabu/translatable support for role descriptions |
| `config/permissions.php` | Package options; `config/permission.php` is spatie's, preconfigured |
| `database` | Migrations, factories and the seeder (`Javaabu\Permissions\Database\…`) |
| `lang/dv.json` | Dhivehi; English strings are the keys |
| `docs`, `llms.txt` | Docusaurus pages for docs.javaabu.com and the index for AI assistants |
| `resources/boost` | Laravel Boost guideline and skill, shipped in the package |
| `tests` | Testbench tests; two guards (`web` → `User`, `web_admin` → `Admin`). `tests/Translatable` needs javaabu/translatable (suite `Translatable`); `tests/js` are Vitest tests |

## Rules

- Follow Javaabu codestyle ([boost-javaabu-guidelines](https://github.com/Javaabu/boost-javaabu-guidelines)): snake_case variables and properties, camelCase methods, early returns, `#[Test]` and `it_…` test names. Pint enforces formatting.
- Nothing may assume the `web` guard or `App\Models\User`. Type-hint users as `Model`, and test behaviour on both guards.
- Registration must not touch the database; only the syncer writes.
- Package policies are applied after boot and must never replace a policy already on the gate, except from `config('permissions.policies')`.
- No hard dependencies on javaabu/helpers, javaabu/activitylog, javaabu/translatable or Inertia. Optional packages are feature-detected and tested both ways; CI runs the `Package` suite with translatable removed.
- Every page exists in Blade and React with the same props and behaviour. Use logical utilities only (`ms-`, `text-start`); a test rejects `ml-`, `text-left` and the like in Blade views. Component tags of optional packages (`<x-translatable::…>`) go in their own partial.
- Every user-facing string goes through `__()` with an English key, and gets a Dhivehi line in `lang/dv.json`. Use Thaana in tests of user-facing behaviour. List uncertain translations in `docs/advanced-usage/translations.md`.
- Every change needs tests, docs (linked from `llms.txt`), the Boost skill if it changes how the package is used, and a line in `CHANGELOG.md`.
- Work on the `next-gen` branch; don't commit to `main`.

## Commands

```bash
composer install
composer lint # vendor/bin/pint --test
composer format # vendor/bin/pint
composer test # vendor/bin/phpunit
pnpm install # the React pages' dev tooling
pnpm check # typecheck and Vitest
```
20 changes: 17 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
# Changelog

All notable changes will be documented in this file
All notable changes will be documented in this file. See [docs/upgrading.md](docs/upgrading.md) for moving from v2.

## 1.0.0 - 202X-XX-XX
## 3.0.0 - unreleased

- initial release
- Permission registration API: `Permissions::register()`, `resource()`, `role()`, grouped permissions with translatable descriptions and labels
- `php artisan permissions:sync` (with `--guard` and `--prune`), `PermissionsSeeder` and `Permissions::sync()`
- Overridable package policies: `Permissions::policy()`, `config('permissions.policies')`, and `Gate::policy()` in the app
- `ResourcePolicy` base class with custom abilities, ownership and guard support; `RolePolicy`
- Multi-auth: `permissions.guards`, per-group and per-role guards, `Permissions::guardFor()`, `Permissions::check()`, guard-aware `anyPermission()` and `@anypermission`
- Role management: `Route::roles()`, an overridable `RolesController` with a JSON API
- Role pages in Blade (javaabu/forms v2) and Inertia React (@javaabu/forms, shipped through javaabu/manifest), right-to-left ready, with select all per permission group; `permissions.layout` and `layout_section` options
- npm dependencies (`@javaabu/forms`, `@javaabu/onu`, React, `@inertiajs/react`) are declared for the React pages only, so `php artisan manifest:check` doesn't ask Blade apps for them
- React components for apps: `RoleForm`, `PermissionGroupFields`, `RoleActions` from `@javaabu/permissions`
- `RoleResource` includes `can`, `links` and `permissions_count`
- Optional javaabu/translatable support for role descriptions: `Models\Translatable\Role`, `Support\Translations`, and a migration adding `translations` and `lang` to the roles table
- Dhivehi translations
- Activity logging is optional, through spatie/laravel-activitylog v4 or v5; on v5 the changes go in `attribute_changes`
- Requires PHP 8.4, Laravel 12 or 13, javaabu/forms v2 and javaabu/manifest
- Breaking: no longer requires javaabu/helpers or javaabu/activitylog; `Role` no longer implements `AdminModel` or uses `LogsActivity`; factories moved to `Javaabu\Permissions\Database\Factories`; `updateRole()` no longer reads `get_setting()`
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
Loading
Loading