fase 2.1: roles editables (modelo skeen.role) y permisos por accion (43 claves, 9 grupos) con enforcement en backend y gating en frontend; editor de roles/permisos/menus en Configuracion
This commit is contained in:
@@ -885,7 +885,9 @@ export interface WacrmLead {
|
||||
created_at: string | null;
|
||||
}
|
||||
|
||||
export type FrontendRole = 'admin' | 'medico' | 'recepcion' | 'enfermeria' | 'cosmetologia' | 'psicologa' | 'farmacia' | 'gerencia' | 'marketing' | 'lectura';
|
||||
// Los roles son configurables (modelo skeen.role): el código es libre, por eso
|
||||
// el tipo ya no es una unión cerrada. ROLE_LABELS queda solo como respaldo.
|
||||
export type FrontendRole = string;
|
||||
|
||||
// Acciones de la Agenda (espejo de AGENDA_PERMS en skeen_whatsapp/roles.py).
|
||||
export type AgendaPerm = 'ver' | 'agendar' | 'editar' | 'eliminar' | 'visitas';
|
||||
@@ -996,6 +998,8 @@ export interface FrontendUser {
|
||||
login: string;
|
||||
name: string;
|
||||
role: FrontendRole;
|
||||
// Nombre del rol configurado en skeen.role (para roles personalizados).
|
||||
role_name?: string;
|
||||
must_change_password?: boolean;
|
||||
last_login?: string | null;
|
||||
active?: boolean;
|
||||
@@ -1004,11 +1008,54 @@ export interface FrontendUser {
|
||||
agenda_perms?: AgendaPerm[] | null;
|
||||
// Lista propia del usuario; null = hereda del rol. La usa solo el editor.
|
||||
agenda_perms_custom?: AgendaPerm[] | null;
|
||||
// Permisos por acción vigentes (rol + overrides), resueltos por el backend.
|
||||
perms?: Record<string, boolean> | null;
|
||||
// Solo rol 'medico': hr.employee vinculado (null si no hay vínculo)
|
||||
employee_id?: number | null;
|
||||
employee_name?: string | null;
|
||||
}
|
||||
|
||||
// ---- Roles configurables (skeen.role) ----
|
||||
export interface Role {
|
||||
id: number;
|
||||
code: string;
|
||||
name: string;
|
||||
rank: number;
|
||||
sequence: number;
|
||||
active: boolean;
|
||||
is_system: boolean;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface RoleUserRef {
|
||||
code: string;
|
||||
name: string;
|
||||
rank: number;
|
||||
active: boolean;
|
||||
is_system: boolean;
|
||||
}
|
||||
|
||||
// ---- Permisos por acción ----
|
||||
export interface PermItem {
|
||||
key: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface PermGroup {
|
||||
grupo: string;
|
||||
label: string;
|
||||
permisos: PermItem[];
|
||||
}
|
||||
|
||||
export interface PermsResponse {
|
||||
status: string;
|
||||
catalogo: PermGroup[];
|
||||
por_rol: Record<string, Record<string, boolean>>;
|
||||
defaults: Record<string, Record<string, boolean>>;
|
||||
roles: RoleUserRef[];
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export interface Receta {
|
||||
id: number;
|
||||
name: string;
|
||||
@@ -1552,6 +1599,40 @@ export const odooApi = {
|
||||
return data;
|
||||
},
|
||||
|
||||
// ---- Roles configurables ----
|
||||
async listRoles(opts?: { includeInactive?: boolean }): Promise<{ status: string; roles: Role[]; total: number; message?: string }> {
|
||||
const { data } = await axios.get(`${ODOO_BASE}/skeen/frontend/v1/roles`, {
|
||||
params: opts?.includeInactive ? { include_inactive: 1 } : undefined,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
|
||||
async createRole(payload: { name: string; rank?: number; sequence?: number; description?: string; active?: boolean }): Promise<{ status: string; role: Role; message?: string }> {
|
||||
const { data } = await axios.post(`${ODOO_BASE}/skeen/frontend/v1/roles`, payload);
|
||||
return data;
|
||||
},
|
||||
|
||||
async updateRole(id: number, payload: { name?: string; rank?: number; sequence?: number; active?: boolean; description?: string }): Promise<{ status: string; role: Role; message?: string }> {
|
||||
const { data } = await axios.put(`${ODOO_BASE}/skeen/frontend/v1/roles/${id}`, payload);
|
||||
return data;
|
||||
},
|
||||
|
||||
async deleteRole(id: number): Promise<{ status: string; role?: Role; en_uso?: number; message?: string }> {
|
||||
const { data } = await axios.delete(`${ODOO_BASE}/skeen/frontend/v1/roles/${id}`);
|
||||
return data;
|
||||
},
|
||||
|
||||
// ---- Permisos por acción ----
|
||||
async getPermisos(): Promise<PermsResponse> {
|
||||
const { data } = await axios.get(`${ODOO_BASE}/skeen/frontend/v1/permisos`);
|
||||
return data;
|
||||
},
|
||||
|
||||
async putPermisos(payload: { role_code?: string; permisos?: Record<string, boolean>; por_rol?: Record<string, Record<string, boolean>> }): Promise<{ status: string; por_rol: Record<string, Record<string, boolean>>; guardados: number; message?: string }> {
|
||||
const { data } = await axios.put(`${ODOO_BASE}/skeen/frontend/v1/permisos`, payload);
|
||||
return data;
|
||||
},
|
||||
|
||||
// Health
|
||||
async healthCheck(): Promise<unknown> {
|
||||
const { data } = await axios.get(`${ODOO_BASE}/skeen/frontend/v1/health`);
|
||||
|
||||
Reference in New Issue
Block a user