Skip to main content

Overview

OdontologyApp implements a comprehensive Role-Based Access Control (RBAC) system with three primary roles: Admin, Doctor, and Secretary. Each role has a specific set of permissions that control access to features and data. Permissions Location: src/lib/permissions.js

User Roles

Admin

Full system access including user management, configuration, and administrative tools.

Doctor

Clinical operations including patient records, medical histories, and treatment planning.

Secretary

Patient registration, appointment scheduling, and administrative support.

Permission System

Permission Categories

Permissions are organized into logical modules:
  • Patient Management - Creating, viewing, editing, and deleting patient records
  • Appointment Management - Scheduling and managing appointments
  • Clinical Operations - Medical records, odontograms, anamnesis, indications
  • Operational Tools - Reminders, inventory, reports
  • Administration - Users, doctors, branches, security, system logs

Checking Permissions

The system provides a helper function to verify if a role has a specific permission:
import { hasPermission } from '$lib/permissions';

// Check if a doctor can edit medical records
if (hasPermission('doctor', 'EDIT_MEDICAL_RECORDS')) {
  // Allow access
}

Complete Permission Matrix

Patient Management

PermissionAdminDoctorSecretaryDescription
VIEW_PATIENTSAccess patient list and records
CREATE_PATIENTSRegister new patients
EDIT_PATIENTSModify patient information
DELETE_PATIENTSRemove patients from system
PRINT_PATIENTSPrint or export patient files

Appointment Management

PermissionAdminDoctorSecretaryDescription
VIEW_APPOINTMENTSView appointment calendar
CREATE_APPOINTMENTSSchedule new appointments
EDIT_APPOINTMENTSModify existing appointments
CANCEL_APPOINTMENTSCancel or delete appointments
Doctors can view appointments but cannot create or modify them. This workflow ensures secretaries manage scheduling while doctors focus on clinical work.

Clinical Operations

PermissionAdminDoctorSecretaryDescription
VIEW_MEDICAL_RECORDSView patient medical history
CREATE_MEDICAL_RECORDSCreate new medical records
EDIT_MEDICAL_RECORDSModify medical records
VIEW_ODONTOGRAMView dental chart
EDIT_ODONTOGRAMUpdate dental chart
VIEW_ANAMNESISView patient health history
EDIT_ANAMNESISModify anamnesis records
VIEW_INDICATIONSView medical indications
CREATE_INDICATIONSCreate new indications
VIEW_ATTACHMENTSView patient files/images
UPLOAD_ATTACHMENTSUpload files to patient records
Only doctors and admins can modify clinical data. Secretaries have read-only access to support patient communication and administrative tasks.

Operational Features

PermissionAdminDoctorSecretaryDescription
VIEW_REMINDERSView reminder dashboard
SEND_REMINDERSSend WhatsApp/Email reminders
VIEW_INVENTORYView inventory levels
MANAGE_INVENTORYManage stock and supplies
VIEW_REPORTSAccess financial reports

Administration

PermissionAdminDoctorSecretaryDescription
VIEW_DOCTORSView doctor list
MANAGE_DOCTORSCreate/edit/delete doctors
MANAGE_BRANCHESManage clinic locations
MANAGE_USERSCreate and manage user accounts
VIEW_LOGSView system audit logs
ACCESS_ROADMAPView development roadmap
MANAGE_SECURITYManage user permissions
VIEW_TREATMENTSView treatment catalog
MANAGE_TREATMENTSModify treatment definitions
VIEW_DOCSAccess system documentation
All administrative functions are restricted to the Admin role to maintain system integrity and security.

Permission Enforcement

Server-Side Protection

All API endpoints verify permissions using the checkPermission middleware:
import { checkPermission, forbiddenResponse } from '$lib/server/checkPermission';

export async function GET({ locals }) {
  if (!locals.user) {
    return json({ message: "No autorizado" }, { status: 401 });
  }

  if (!(await checkPermission(locals, "VIEW_PATIENTS"))) {
    return forbiddenResponse();
  }
  
  // Process request
}

Route-Level Protection

The server hook (src/hooks.server.js) enforces role-based route access:
const restrictedToAdmin = [
  '/admin/settings',
  '/admin/treatments',
  '/admin/reports',
  '/users',
  '/branches',
  '/logs',
];

if (isAdminRoute && user.role !== 'admin') {
  throw redirect(303, '/dashboard?error=unauthorized');
}

Database-Level Permissions

Permissions Table

The permissions table stores all available permissions:
CREATE TABLE permissions (
    id INT AUTO_INCREMENT PRIMARY KEY,
    code VARCHAR(60) UNIQUE NOT NULL,
    label VARCHAR(100) NOT NULL,
    module VARCHAR(60) NOT NULL,
    description TEXT,
    sort_order INT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

User Permissions Table

The user_permissions table enables granular permission assignment:
CREATE TABLE user_permissions (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    permission_id INT NOT NULL,
    granted TINYINT(1) DEFAULT 1,
    granted_by INT,
    granted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY unique_user_perm (user_id, permission_id),
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
);
This architecture supports future enhancements for custom per-user permissions beyond the default role-based assignments.

Role Definitions in Code

Admin Role

Admins have all permissions in the system:
export const ROLE_PERMISSIONS = {
  admin: Object.values(PERMISSIONS), // All permissions
  // ...
};

Doctor Role

Doctors have clinical-focused permissions:
doctor: [
  PERMISSIONS.VIEW_PATIENTS,
  PERMISSIONS.EDIT_PATIENTS,
  PERMISSIONS.PRINT_PATIENTS,
  PERMISSIONS.VIEW_APPOINTMENTS,
  PERMISSIONS.VIEW_MEDICAL_RECORDS,
  PERMISSIONS.CREATE_MEDICAL_RECORDS,
  PERMISSIONS.EDIT_MEDICAL_RECORDS,
  PERMISSIONS.VIEW_ODONTOGRAM,
  PERMISSIONS.EDIT_ODONTOGRAM,
  PERMISSIONS.VIEW_ANAMNESIS,
  PERMISSIONS.EDIT_ANAMNESIS,
  PERMISSIONS.VIEW_INDICATIONS,
  PERMISSIONS.CREATE_INDICATIONS,
  PERMISSIONS.VIEW_ATTACHMENTS,
  PERMISSIONS.UPLOAD_ATTACHMENTS,
  PERMISSIONS.VIEW_INVENTORY,
  PERMISSIONS.VIEW_DOCTORS,
  PERMISSIONS.VIEW_DOCS,
]

Secretary Role

Secretaries manage administrative and front-office tasks:
secretary: [
  PERMISSIONS.VIEW_PATIENTS,
  PERMISSIONS.CREATE_PATIENTS,
  PERMISSIONS.EDIT_PATIENTS,
  PERMISSIONS.PRINT_PATIENTS,
  PERMISSIONS.VIEW_APPOINTMENTS,
  PERMISSIONS.CREATE_APPOINTMENTS,
  PERMISSIONS.EDIT_APPOINTMENTS,
  PERMISSIONS.CANCEL_APPOINTMENTS,
  PERMISSIONS.VIEW_MEDICAL_RECORDS,
  PERMISSIONS.VIEW_ODONTOGRAM,
  PERMISSIONS.VIEW_ANAMNESIS,
  PERMISSIONS.VIEW_INDICATIONS,
  PERMISSIONS.VIEW_ATTACHMENTS,
  PERMISSIONS.VIEW_REMINDERS,
  PERMISSIONS.SEND_REMINDERS,
  PERMISSIONS.VIEW_DOCTORS,
  PERMISSIONS.VIEW_DOCS,
]

Best Practices

Each role should only have the minimum permissions necessary to perform their job functions. Doctors don’t need user management access, and secretaries don’t need to modify clinical records.
Clinical and administrative tasks are separated between doctors and secretaries to ensure proper workflows and accountability.
All permission definitions are centralized in permissions.js, making it easy to audit and modify access control policies.
Never rely solely on client-side permission checks. All API endpoints must verify permissions independently.

Authentication

Learn how users log in and sessions are managed

Doctor Management

Managing doctor accounts and assignments

Branch Management

Multi-location clinic configuration

Build docs developers (and LLMs) love