Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/TheSerchCp/SEAM/llms.txt

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

The Users module provides a complete CRUD interface for managing every account registered in SEAM. Administrators can list all users in a responsive table, open a modal form to create a new account, edit an existing user’s name, email, role, or password, and permanently delete a record. Every mutation is immediately reflected across all connected clients through the real-time EventBus data:changed event.

Table columns

The users table is driven by the USER_COLUMNS definition. Each entry maps a human-readable label to the key returned by the API:
const USER_COLUMNS = [
    { label: '#',      key: 'idUser'    },
    { label: 'Nombre', key: 'full_name' },
    { label: 'Email',  key: 'email'     },
    { label: 'Rol',    key: 'roleName'  },
];

Validation schemas

Two schemas govern the user forms. The create schema requires all fields including a confirmed password, while the edit schema makes the password fields optional (leave blank to keep the existing password).
// Create — all fields required
const USER_SCHEMA = {
    name:            { required: true, text: true, minLength: 2 },
    email:           { required: true, email: true },
    password:        { required: true, password: true },
    confirmPassword: { required: true, password: true, match: 'password' }
};

// Edit — password is optional
const USER_EDIT_SCHEMA = {
    name:  { required: true, text: true, minLength: 2 },
    email: { required: true, email: true },
    password: { password: true },
    confirmPassword: {
        custom: (val, _, formData) => {
            const pwd = formData.get('password') ?? '';
            if (!pwd.trim()) return true;
            if (!val.trim()) return 'Confirma la nueva contraseña';
            return val === pwd || 'Los campos no coinciden';
        }
    },
};

Service functions

The service layer is a thin wrapper that delegates every call to the users repository.

getUsers()

Returns the full list of registered users from GET /users.

getUserById(id)

Fetches a single user object from GET /users/:id.

createUser(data)

Registers a new account via POST /auth/register.

updateUser(id, data)

Updates an existing user via PUT /users/:id.

removeUser(id)

Permanently deletes a user account via DELETE /users/:id.
// users.service.js
import * as UsersRepo from '../repositories/users.repository.js';

export const getUsers    = ()         => UsersRepo.getAllUsers();
export const getUserById = (id)       => UsersRepo.getUserById(id);
export const createUser  = (data)     => UsersRepo.createUser(data);
export const updateUser  = (id, data) => UsersRepo.updateUser(id, data);
export const removeUser  = (id)       => UsersRepo.deleteUserById(id);

API endpoints

// users.repository.js
import { ApiClient } from '../core/ApiClient.js';

export const getAllUsers    = ()         => ApiClient.get('/users');
export const getUserById   = (id)       => ApiClient.get(`/users/${id}`);
export const createUser    = (data)     => ApiClient.post('/auth/register', data);
export const updateUser    = (id, data) => ApiClient.put(`/users/${id}`, data);
export const deleteUserById = (id)      => ApiClient.delete(`/users/${id}`);
MethodPathService function
GET/usersgetUsers()
GET/users/:idgetUserById(id)
POST/auth/registercreateUser(data)
PUT/users/:idupdateUser(id, data)
DELETE/users/:idremoveUser(id)

Request payloads

Create user

const userData = {
    full_name: formData.name,
    email:     formData.email,
    password:  formData.password,
    roleId:    parseInt(formData.idRole),
};
await createUser(userData);
full_name
string
required
The user’s display name. Minimum 2 characters.
email
string
required
A valid, unique e-mail address.
password
string
required
Must satisfy the application password policy.
roleId
number
required
The numeric ID of the role to assign.

Update user

const userData = {
    full_name: formData.name,
    email:     formData.email,
    roleId:    parseInt(formData.idRole),
};
// Only included when the admin enters a new password
if (formData.password?.trim()) {
    userData.password = formData.password;
}
await updateUser(idUser, userData);
full_name
string
required
Updated display name.
email
string
required
Updated e-mail address.
roleId
number
required
Updated role ID.
password
string
New password. Omit this field to leave the password unchanged.

Real-time updates

The users page subscribes to two EventBus channels so the table stays fresh for all connected clients without a manual refresh.
// Triggered by mutations on THIS client
const unsub = EventBus.on('page:reload', updateUsersTable);

// Triggered by mutations from OTHER clients via WebSocket
const unsubSocket = EventBus.on('data:changed', async (payload) => {
    if (shouldUpdatePage('users', payload?.operation)) {
        // Skip if this socket initiated the event — page:reload already fired
        if (payload?.initiatorSocketId === EventBus.socketId) return;
        await updateUsersTable();
    }
});
The shouldUpdatePage('users', operation) helper checks against the OPERATION_LISTENERS.users array:
// OperationListeners.js
users: ['auth:register', 'auth:login', 'users:create', 'users:update', 'users:delete'],
Any backend event matching one of those operation strings causes the local table to re-render automatically.
Cleanup unsubscribers are registered with registerPageCleanup() so EventBus listeners are removed when the router navigates away from the Users page, preventing memory leaks and duplicate updates.

Build docs developers (and LLMs) love