Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/0m1n3m/contacts-db/llms.txt

Use this file to discover all available pages before exploring further.

Contacts DB uses a three-tier role system to control what each team member can see and do. Every user is assigned exactly one role — admin, editor, or viewer — stored in the users.role column. The role is checked on every protected route by the RoleMiddleware, which returns a 403 Forbidden response if the user’s role is not in the allowed list. This means you can safely mix roles on a team without worrying about accidental data modification by read-only members.

Roles overview

The table below summarises what each role can do across the four main areas of the application.
RoleContactsTasksProjectsAdmin
adminFull CRUD + bulk delete + import + exportFull CRUD, sees all tasksFull CRUDManage invitations, access /dashboard
editorCreate, read, update + export (no delete)Create, read, update, delete own/assigned tasksFull CRUDNone
viewerRead-only (list + show)View + change status on assigned tasksRead-onlyNone

Detailed permissions

Admins have unrestricted access to every part of Contacts DB.Contacts
  • View, create, edit, and delete individual contacts
  • Bulk-delete multiple contacts in one operation
  • Import contacts from a CSV file
  • Export contacts to CSV
Tasks
  • Create, edit, delete, and change the status of any task
  • View all tasks in the system, regardless of who created them or who is assigned
Projects
  • Create, edit, view, and delete projects
Administration
  • Send and manage team invitations at /admin/invitations
  • Access the /dashboard route (shared with editors)
Editors can contribute content but cannot permanently remove contacts or manage team members.Contacts
  • View, create, and edit contacts
  • Export contacts to CSV
  • Cannot delete individual contacts
  • Cannot bulk-delete contacts
Tasks
  • Create new tasks and edit existing ones
  • Delete tasks
  • View tasks they created or are assigned to (the scopeVisibleTo query scope filters the list automatically — see Managing Tasks for details)
  • Change task status
Projects
  • Create, edit, view, and delete projects (full CRUD)
Administration
  • Cannot send or view invitations
  • Can access the /dashboard route
Viewers have a strictly read-only experience. They can browse data but cannot make any changes.Contacts
  • View the contact list and individual contact pages
  • Export contacts to CSV
  • Cannot create, edit, or delete contacts
Tasks
  • View tasks they are assigned to (the scopeVisibleTo scope hides all other tasks)
  • Change task status
  • Cannot create, edit, or delete tasks
Projects
  • View projects only
Administration
  • No access to admin routes or the dashboard
Viewers cannot create any content. Attempting to access a write route — such as /contacts/create — while signed in as a viewer returns a 403 Forbidden error immediately.

Route middleware

Contacts DB registers the role guard under the role middleware alias. You apply it by passing a colon-separated list of allowed roles. Multiple roles are separated by commas and evaluated with OR logic — the user only needs to match one.
// Syntax
->middleware('role:admin')          // admin only
->middleware('role:admin,editor')   // admin OR editor
Here is a real example from routes/web.php showing how the contact creation route is protected:
Route::get('/contacts/create', [ContactController::class, 'create'])
    ->middleware(['auth', 'verified', 'role:admin,editor'])
    ->name('contacts.create');
The RoleMiddleware resolves the authenticated user, normalises role strings to lowercase, and checks whether $user->role is in the allowed list:
// app/Http/Middleware/RoleMiddleware.php
public function handle(Request $request, Closure $next, ...$roles): Response
{
    $user = $request->user();

    if (!$user) {
        abort(403);
    }

    if (count($roles) === 0) {
        return $next($request);
    }

    $roles = array_map(fn ($r) => trim(strtolower($r)), $roles);
    $userRole = strtolower((string) $user->role);

    if (!in_array($userRole, $roles, true)) {
        abort(403);
    }

    return $next($request);
}
If no roles are passed to the middleware (i.e. ->middleware('role')), the middleware allows the request through — this is a developer convenience and should not be relied on for access control.

Assigning roles

Roles are stored in the users.role string column, which defaults to viewer:
// database/migrations/2026_04_20_131347_add_role_to_users_table.php
$table->string('role')->default('viewer')->index();
Roles are assigned in two ways:
  1. Seeder — the AdminUserSeeder sets the first user’s role to admin during initial setup.
  2. Invitations — when an admin sends an invitation they choose the role (admin, editor, or viewer). That role is stored on the user_invitations record and applied to the new user account the moment the invitation is accepted.
You can also update a role directly in the database or via a custom admin panel if your deployment requires it.

Task visibility scope

Editors and viewers do not see all tasks — the scopeVisibleTo query scope on the Task model filters the result set based on the authenticated user’s role and assignment status. Admins bypass the scope entirely. Refer to Managing Tasks for a full explanation of how the scope is constructed and used.

Build docs developers (and LLMs) love