Leo Counter enforces a simple two-role permission model: admin and member. The very first account created in a fresh installation automatically becomes the admin — there is no separate seeding step or environment variable required. All subsequent accounts are created by that admin from the user management panel, and they receive theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/juanVillamilEchavarria/Leo_Counter-app/llms.txt
Use this file to discover all available pages before exploring further.
member role by default. Every authenticated user, regardless of role, can view and update their own profile information and change their own password.
Roles
Admin
Full access to the application. Can manage all users (create, edit, delete, reset passwords), access the configuration panel, view soft-deleted records, and perform hard deletes.
Member
Access to all finance features (accounts, movements, budgets, reports). Can update their own profile and password. Cannot access user management or the configuration panel.
role column is stored in the users table with a default of member. The migration that adds it is:
AdminMiddleware checks this column on every request to a protected route:
User Fields
| Field | Type | Notes |
|---|---|---|
id | UUID | Primary key, non-incrementing |
name | string | Display name |
email | string | Unique, used for login |
password | string | Hashed with bcrypt (BCRYPT_ROUNDS=12) |
role | string | admin or member |
email_verified_at | timestamp | Nullable |
remember_token | string | Standard Laravel remember-me token |
First-Time Admin Setup
When there are no users in the database, Leo Counter’sRedirectIfUsersAreEmptyMiddleware intercepts every request to the login page and redirects to /register. After the first account is created, that route is locked by RedirectIfUserExistsMiddleware, which bounces any subsequent visit to /register back to the login page.
Run migrations and seeders
Navigate to /register
Open
http://localhost:8080/register in your browser. Because no users exist yet, the middleware redirects you here automatically from the home page.Fill in the registration form
Enter a name, email address, and password. On submission,
RegisteredUserController dispatches CreateTheAdminUserCommand, which creates the user with the admin role.Once the first user exists, any visit to
/register is caught by RedirectIfUserExistsMiddleware and redirected to route('login'). There is no public self-registration for additional accounts — only the admin can create new users.Admin: Managing Other Users
All user management routes are protected by both theauth middleware and AdminMiddleware. They are accessible under /usuarios.
Available Routes
| Method | Path | Action |
|---|---|---|
GET | /usuarios | List all users |
GET | /usuarios/create | Show create-user form |
POST | /usuarios | Create a new user |
GET | /usuarios/{usuario}/edit | Show edit form |
PUT | /usuarios/{usuario} | Update name and email |
DELETE | /usuarios/{usuario} | Delete a user |
PUT | /usuarios/{usuario}/password | Reset another user’s password |
Creating a New User
- Via the UI
- What happens server-side
- Navigate to Usuarios → Crear Usuario (
/usuarios/create). - Fill in Nombre, Email, and Contraseña.
- Click Guardar. The new account is created with the
memberrole.
Resetting Another User’s Password
An admin can reset any user’s password without knowing the current one:UsuarioController::changePassword(), which dispatches ChangeUserPasswordCommand with only id and newPassword — no current-password verification is required at the admin level.
Deleting a User
DestroyUsuarioCommand. This is a hard delete on the users table — the record is permanently removed.
Self-Service: Profile and Password
Every authenticated user can manage their own account through the profile routes, which requireauth but not AdminMiddleware.
Profile Routes
| Method | Path | Route name | Description |
|---|---|---|---|
GET | /profile | profile.index | View own profile |
PUT | /profile | profile.update | Update own name and email |
GET | /profile/password | profile.password.index | View password-change form |
PUT | /profile/password | profile.password.update | Change own password |
Updating Profile Information
ProfileController::update() accepts name and email, then dispatches UpdatePublicDataCommand:
Changing Own Password
PasswordController::update() requires the current password for verification before applying the change, using ChangeOwnPasswordCommand:
Middleware Reference
RedirectIfUsersAreEmptyMiddleware
RedirectIfUsersAreEmptyMiddleware
Applied to the guest route group (login, forgot password, etc.). When
User::exists() returns false, it redirects the visitor to /register instead of showing the login form. Once at least one user is registered, this middleware becomes a no-op.RedirectIfUserExistsMiddleware
RedirectIfUserExistsMiddleware
Applied exclusively to
GET /register and POST /register. When User::exists() returns true, it redirects the visitor to route('login'), making registration impossible for subsequent visitors.AdminMiddleware
AdminMiddleware
Applied to the inner route group that contains
/usuarios, /configuracion, and the soft-delete routes. Checks auth()->user()->role === 'admin'; aborts with HTTP 403 if the condition fails.