Starter SaaS API multi-tenant (Laravel 12) com isolamento por organização (workspace), RBAC por organização (Spatie Permission), autenticação via Sanctum (Bearer tokens), filas com Redis, Docker e Swagger/OpenAPI. Inclui módulo opcional de Billing (Pagar.me) desacoplado do core.
- Auth: register/login/logout + refresh token com rotação +
GET /api/v1/me - Multi-tenancy:
X-Organization-Idobrigatório para rotas multi-tenant - RBAC por organização: roles
owner|admin|member+ permissions para Projects e Members - Projects: CRUD + archive/restore + soft delete
- Observabilidade:
GET /api/v1/health, logs em JSON,X-Request-Id - Docs: Swagger UI em
/api/docse OpenAPI JSON em/api/docs.json - CI: GitHub Actions rodando lint/análise/testes
O código de domínio fica em src/ (organizado por bounded contexts), e o compartilhado em src/Shared.
docker compose up --build- API base:
http://localhost:8080/api/v1 - Swagger UI:
http://localhost:8080/api/docs
cp .env.example .env
php -r "file_exists('database/database.sqlite') || touch('database/database.sqlite');"
php artisan key:generate
php artisan migrate --seed
php artisan servePara endpoints multi-tenant, envie:
X-Organization-Id: {org_id}
O middleware Src\Shared\Middleware\SetOrganizationContext valida membership e configura o contexto da org (incluindo o team id do Spatie Permission). O organization_id não é aceito via body/query.
- Roles:
owner,admin,member - Permissions:
project.create,project.view,project.update,project.deletemembers.manage
Seeder: database/seeders/PermissionSeeder.php.
Ative via env:
BILLING_PROVIDER=pagarme
Webhook:
POST /api/v1/webhooks/pagarme- Assinatura HMAC SHA-256 do body bruto (
PAGARME_WEBHOOK_SECRET)
composer cicomposer lint(Pint check)composer analyse(PHPStan/Larastan)composer test(PHPUnit)
# register
curl -X POST http://localhost:8080/api/v1/auth/register \
-H 'Content-Type: application/json' \
-d '{"name":"Alice","email":"alice@example.com","password":"password123"}'
# login
curl -X POST http://localhost:8080/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"alice@example.com","password":"password123"}'
# create org
curl -X POST http://localhost:8080/api/v1/organizations \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"Acme"}'
# create project (multi-tenant)
curl -X POST http://localhost:8080/api/v1/projects \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "X-Organization-Id: $ORG_ID" \
-H 'Content-Type: application/json' \
-d '{"name":"Project 1","description":"Demo"}'- Contribuindo:
CONTRIBUTING.md - Segurança:
SECURITY.md
MIT