- About Annotation Management System
- Features
- Tech Stack
- Installation - Local Development
- Development Environment
- Changelog
- Contributing
- Available Scripts
- Releasing a new version
- Security
- License
- Credits
Annotation Management System is a Laravel-based annotation management system. The application manages annotators (users), their roles, and permissions via an Inertia/React SPA.
It includes a complete setup for both the backend and frontend, with support for both DDEV and Native (PHP, Composer, etc. running locally) development environments.
- Support for both DDEV and Native development environments
- React 19 / Inertia.js 2 frontend with Vite for faster development
- Tailwind CSS v4 with React Aria Components for accessible, keyboard-navigable UI
- SCSS support with PostCSS
- TypeScript (strict mode)
- Automated code formatting (PHP, JS/TS, SCSS)
- Git hooks for code quality
- Comprehensive test suite using Pest (backend) and Jest (frontend)
- Role-based access control using Spatie Laravel Permission
- Dark mode support
- Responsive design
- GitHub Actions for CI/CD
-
Backend:
- Laravel 12.x
- PHP 8.4
- MySQL/SQLite
- Laravel Pint (Code Styling)
- PHPStan / Larastan (Static Analysis at level 8)
- Pest (Testing)
-
Frontend:
- React 19 with Inertia.js 2
- TypeScript (strict mode)
- Tailwind CSS v4
- React Aria Components (accessibility-first UI primitives)
- Lucide React (icons)
- Sonner (toast notifications)
- Vite
- ESLint + Prettier + Stylelint
In order to start developing with Annotation Management System, you will need to read the guide in the LOCAL-DEVELOPMENT.md file.
The application supports two development environments, controlled by APP_DEVELOPMENT_ENV in your .env file:
APP_DEVELOPMENT_ENV |
How to run commands |
|---|---|
native |
Run directly: composer …, npm …, php artisan …, vendor/bin/… |
ddev |
Prefix with ddev: ddev composer …, ddev npm …, ddev artisan …, ddev exec vendor/bin/… |
All commands in this document are shown in native form. DDEV users: add the
ddevprefix to every command — e.g.composer testbecomesddev composer test,npm run devbecomesddev npm run dev, andphp artisan migratebecomesddev artisan migrate.
Please see CHANGELOG for more information on what has changed recently.
To contribute to the application, follow these steps:
- Fork this repository.
- Read the CONTRIBUTING file.
- Create a branch:
git checkout -b <branch_name>. - Make your changes and commit them:
git commit -m '<commit_message>' - Push to the original branch:
git push origin <project_name>/<location> - Create the pull request
After making changes, follow this workflow:
composer lint # format everything (Rector + Pint + ESLint + Prettier)
composer test # verify nothing broke (lint + types + Pest)This application uses Laravel Pint for PHP code styling, managed via Composer scripts.
composer lint # format all code — fix mode (Rector + Pint + ESLint + Prettier)
composer test:lint # dry-run checks only — no modifications (CI-friendly)Run the full test suite (lint + static analysis + Pest) via:
composer test:backend
# or composer testTo run or filter Pest tests directly:
composer test:backend # all tests
composer test:backend -- --filter TestName # filter by name
composer test:backend -- --testsuite=Feature # specific suiteddev composer test:backend ddev composer test:backend -- --filter UserControllerTest
ddev composer test:backend -- --filter "it creates a user" ddev composer test:backend -- --filter UserControllerTest --coverageTo run with code coverage (requires Xdebug):
XDEBUG_MODE=coverage ddev composer test:coverageWe use Laravel with Pest for end-to-end browser testing via Playwright. This replaces Jest component tests with real Chromium testing.
Prerequisites:
# 1. Kill any running dev servers (to avoid port conflicts)
pkill -f "vite" || pkill -f "composer run dev" || true
# 2. Build frontend assets (required)
npm run buildRun tests:
# Headless mode (CI-friendly)
composer test:browser
# Headed mode — watch the browser (debugging)
BROWSER_HEADLESS=false composer test:browserThe in-process server serves compiled assets from public/build/. Without them, Inertia pages fail to load and tests will fail.
Static analysis runs as part of composer test:types:
composer test:types # PHPStan (level 8) + TypeScript tsc --noEmitA pre-commit hook runs automatically on every commit. It:
- Scans staged files for secrets with Gitleaks (blocks commit if secrets detected)
- Runs Rector on staged
.phpfiles (automated refactors) - Runs Pint on staged
.phpfiles (code style formatting) - Runs Prettier / ESLint on staged
.js/.ts/.tsxfiles - Runs Prettier on staged
.scss/.cssfiles
Modified files are re-staged automatically, so the committed code always matches the formatted output.
The hook is installed automatically when you run:
composer installFor Gitleaks, you will need also to install the executable. See GITLEAKS-SECURITY.md for details.
If you need to reinstall it manually (e.g. after cloning without running composer install):
bash tools/git-hooks/install.shDDEV users: Git hooks run on the host machine, not inside the container.
Run
ddev composer installto install dependencies inside the container, but the hook script itself executes on the host usingvendor/bin/rector,vendor/bin/pint, andnpmfrom the project root.Make sure PHP and Node are available in your host shell, or run
ddev composer installfirst to populatevendor/bin/.
Bypassing the hook: If you genuinely need to skip it (e.g. a work-in-progress commit), use
git commit --no-verify. This should be rare.
| Script | Description |
|---|---|
composer run dev |
Start dev server (auto-detects environment) |
composer lint |
Format all code — fix mode (Rector + Pint + ESLint + Prettier) |
composer test:lint |
Dry-run lint checks without modifying files |
composer test:types |
Type analysis (PHPStan level 8 + TypeScript tsc) |
composer test |
Full test suite (lint + types + Pest) |
composer test:coverage |
Pest with code coverage (requires Xdebug) |
composer update:requirements |
Bump Composer + npm dependencies to latest |
| Script | Description |
|---|---|
npm run dev |
Start Vite development server |
npm run build |
Build frontend assets for production |
npm run lint |
ESLint check |
npm run lint:fix |
ESLint auto-fix |
npm run lint:styles |
Stylelint check |
npm run lint:styles:fix |
Stylelint auto-fix |
npm run format |
Prettier formatting (fix mode) |
npm run format:check |
Prettier dry-run |
npm run types |
TypeScript type-check (tsc --noEmit) |
php artisan migrate # migrate the database
php artisan db:seed # seed the database
php artisan migrate:fresh # drop all tables and re-run migrations
php artisan migrate:fresh --seed # fresh migrate + seed
php artisan key:generate # generate application keyWhen using DDEV, the following project-specific shorthand commands are available in addition to the standard ddev prefix rules:
ddev pint # shorthand for ddev exec vendor/bin/pint
ddev analyse # shorthand for ddev exec vendor/bin/phpstan analyse
ddev format # shorthand for pint + npm format
ddev test # shorthand for ddev exec vendor/bin/pestVersion must be updated in two places before tagging:
package.json—"version": "x.x.x"config/app.php—'version' => env('APP_VERSION', 'x.x.x')
After committing your changes, create a new git tag:
git tag -a vx.y.z -m "This is a nice tag name"(for the x.y.z version number, follow the Semantic Versioning guidelines).
Then, push the tag:
git push origin vx.y.zThen, in the GitHub Releases page, create a new Release and correlate it with the tag that you just created.
Also, don't forget to update the CHANGELOG.md file with the new version name, release date, and release notes.
This project implements several security measures:
- Secret Scanning: Gitleaks integration prevents accidental exposure of sensitive information like API keys, passwords, and tokens. See GITLEAKS-SECURITY.md for detailed configuration and usage.
- Security Headers: Custom middleware adds security headers (CSP, HSTS, etc.)
- CSRF Protection: Laravel's built-in CSRF protection
- Role-based Access Control: Using Spatie Laravel Permission package
If you discover any security-related issues, please email info[at]scify.org, instead of using the issue tracker.
This project is open-sourced software licensed under the Apache License, Version 2.0.