Cumplimiento

El dominio de cumplimiento (Compliance) agrupa los endpoints BFF que sostienen la evidencia regulatoria del club: el registro de auditoría de accesos y cambios (Res. AAIP 47/2018, Ley 25.326), el log de dispensación, el control del límite de pacientes (150, Res. 1780/2025), los plazos regulatorios próximos, los datos agregados del informe semestral REPROCANN y un resumen de estado de compliance de toda la organización.

Todas las rutas bajo /api/compliance son de solo lectura (GET) y requieren autenticación mediante Bearer JWT. El endpoint de auditoría exige además rol clínico/staff (los miembros quedan excluidos), y varias rutas resuelven el Tenant-id para aislar los datos por organización.

The audit log model

El registro de auditoría (ActivityLog) documenta quién hizo qué y cuándo a través de la organización. Es la evidencia de "registros aptos" de la Res. 1780/2025 y del registro de accesos/cambios de la Res. AAIP 47/2018.

Properties

  • Name
    id
    Type
    string
    Description

    Identificador del registro.

  • Name
    memberId
    Type
    string
    Description

    ID del miembro asociado al evento.

  • Name
    type
    Type
    ActivityLogType
    Description

    Tipo de evento. Valores posibles:

    • STATUS_CHANGE
    • DOCUMENT_UPLOAD
    • DOCUMENT_DELETE
    • NOTE_ADDED
    • NOTE_DELETED
    • DISPENSATION
    • TRANSACTION
    • MEMBERSHIP_CHANGE
    • PROFILE_UPDATE
    • MEDICAL_UPDATE
    • MEMBER_CREATED
    • APPOINTMENT_SCHEDULED
    • APPOINTMENT_CONFIRMED
    • APPOINTMENT_RESCHEDULED
    • APPOINTMENT_CANCELLED
    • APPOINTMENT_COMPLETED
    • APPOINTMENT_NO_SHOW
    • MEDICAL_ACCESS
    • CONSENT_GRANTED
    • CONSENT_WITHDRAWN
    • DATA_EXPORTED
    • DELETION_REQUESTED
    • ACCOUNT_DELETED
  • Name
    label
    Type
    string
    Description

    Descripción legible del evento.

  • Name
    detail
    Type
    string
    Description

    Detalle adicional del evento.

  • Name
    metadata
    Type
    object
    Description

    Metadata arbitraria asociada al evento.

  • Name
    performedById
    Type
    string
    Description

    ID del actor que ejecutó la acción.

  • Name
    performedByName
    Type
    string
    Description

    Nombre del actor.

  • Name
    ipAddress
    Type
    string
    Description

    Dirección IP registrada.

  • Name
    userAgent
    Type
    string
    Description

    User agent registrado.

  • Name
    referenceId
    Type
    string
    Description

    ID de la entidad referenciada.

  • Name
    referenceType
    Type
    enum
    Description

    Tipo de entidad referenciada: ORDER, ATTACH, TRANSACTION, NOTE, MEMBER o APPOINTMENT.

  • Name
    createdAt
    Type
    string
    Description

    Timestamp del evento (ISO).

Activity log example

{
  "id": "al-1",
  "memberId": "usr_01HQ8XYZABC123",
  "type": "MEDICAL_ACCESS",
  "label": "Acceso a ficha médica",
  "performedById": "staff-1",
  "performedByName": "Dra. Ana Médica",
  "ipAddress": "190.0.0.1",
  "referenceId": "usr_01HQ8XYZABC123",
  "referenceType": "MEMBER",
  "createdAt": "2026-06-17T13:40:00.000Z"
}

GET/api/compliance/audit-log

Registro de auditoría

Retorna el registro de auditoría de toda la organización (accesos, cambios, dispensaciones, etc.). Restringido a roles staff/clínicos: el rol MEMBER queda excluido por el gate de acceso médico.

Si se omite memberId, la respuesta abarca todos los logs del tenant.

Query params opcionales

  • Name
    memberId
    Type
    string
    Description

    Filtra por miembro.

  • Name
    type
    Type
    ActivityLogType
    Description

    Filtra por tipo de evento (ver enum del modelo).

  • Name
    dateFrom
    Type
    string
    Description

    Fecha desde (ISO).

  • Name
    dateTo
    Type
    string
    Description

    Fecha hasta (ISO).

  • Name
    page
    Type
    integer
    Description

    Página.

  • Name
    limit
    Type
    integer
    Description

    Cantidad por página (default 500).

Request

GET
/api/compliance/audit-log
curl -G https://api.cannahub.tech/api/compliance/audit-log \
  -H "Authorization: Bearer {token}" \
  -H "Tenant-id: {tenantId}" \
  -d type=MEDICAL_ACCESS \
  -d limit=500

Response

{
  "activityLogs": [
    {
      "id": "al-1",
      "memberId": "usr_01HQ8XYZABC123",
      "type": "MEDICAL_ACCESS",
      "label": "Acceso a ficha médica",
      "performedById": "staff-1",
      "performedByName": "Dra. Ana Médica",
      "ipAddress": "190.0.0.1",
      "referenceId": "usr_01HQ8XYZABC123",
      "referenceType": "MEMBER",
      "createdAt": "2026-06-17T13:40:00.000Z"
    }
  ],
  "count": 1
}

GET/api/compliance/dispensation

Registro de dispensación

Retorna los registros de dispensación (items de órdenes con información de paciente y lote) para el seguimiento de la distribución de productos. Cada item de cada orden dentro del rango se transforma en un registro individual.

Query params opcionales

  • Name
    from
    Type
    string
    Description

    Fecha desde (YYYY-MM-DD). Filtra por created_at de la orden.

  • Name
    to
    Type
    string
    Description

    Fecha hasta (YYYY-MM-DD).

Campos de cada registro

  • Name
    date
    Type
    string
    Description
    Fecha de la orden (ISO).
  • Name
    patientName
    Type
    string
    Description
    Nombre del paciente.
  • Name
    patientDni
    Type
    string
    Description
    DNI del paciente.
  • Name
    reprocannCode
    Type
    string
    Description
    Código REPROCANN del paciente.
  • Name
    productName
    Type
    string
    Description
    Nombre del producto dispensado.
  • Name
    quantity
    Type
    number
    Description
    Cantidad.
  • Name
    unit
    Type
    string
    Description
    Unidad (default g).
  • Name
    batchNumber
    Type
    string
    Description
    Número de lote.
  • Name
    strainName
    Type
    string
    Description
    Nombre de la cepa.
  • Name
    authorizedBy
    Type
    string
    Description
    Autorizante de la dispensación.
  • Name
    orderId
    Type
    string | number
    Description
    ID (o displayId) de la orden.

Request

GET
/api/compliance/dispensation
curl -G https://api.cannahub.tech/api/compliance/dispensation \
  -H "Authorization: Bearer {token}" \
  -d from=2025-01-01 \
  -d to=2025-06-30

Response

{
  "records": [
    {
      "date": "2025-03-15T14:30:00Z",
      "patientName": "María González",
      "patientDni": "35123456",
      "reprocannCode": "REPRO-2024-AR-001234",
      "productName": "Blue Dream 3.5g",
      "quantity": 2,
      "unit": "g",
      "batchNumber": "B-2025-014",
      "strainName": "Blue Dream",
      "authorizedBy": "Dra. Ana Médica",
      "orderId": 1234
    }
  ],
  "count": 1
}

GET/api/compliance/patient-limit

Límite de pacientes

Retorna la cantidad actual de pacientes y el máximo permitido. El máximo es 150 (Res. 1780/2025).

Response

  • Name
    current
    Type
    number
    Description

    Cantidad actual de pacientes registrados.

  • Name
    maximum
    Type
    number
    Description

    Máximo permitido (150).

Request

GET
/api/compliance/patient-limit
curl https://api.cannahub.tech/api/compliance/patient-limit \
  -H "Authorization: Bearer {token}"

Response

{
  "current": 42,
  "maximum": 150
}

GET/api/compliance/deadlines

Plazos regulatorios

Agrega los plazos de cumplimiento regulatorio y operativo próximos: informe semestral, renovaciones REPROCANN (miembros y cultivos que vencen dentro de 60 días), vencimiento de la matrícula del director médico y renovaciones de variedades INASE RNC. Los plazos se ordenan por fecha ascendente.

Campos de cada plazo

  • Name
    id
    Type
    string
    Description
    Identificador del plazo.
  • Name
    date
    Type
    string
    Description
    Fecha de vencimiento (YYYY-MM-DD).
  • Name
    label
    Type
    string
    Description
    Etiqueta del plazo.
  • Name
    description
    Type
    string
    Description
    Descripción del plazo.
  • Name
    tag
    Type
    string
    Description

    Texto relativo calculado: Vencido, Vence hoy o En {n} días.

  • Name
    urgency
    Type
    enum
    Description

    Urgencia calculada según los días restantes:

    • urgent: 14 días o menos
    • soon: entre 15 y 30 días
    • normal: más de 30 días

Request

GET
/api/compliance/deadlines
curl https://api.cannahub.tech/api/compliance/deadlines \
  -H "Authorization: Bearer {token}"

Response

{
  "deadlines": [
    {
      "id": "reprocann-renewals",
      "date": "2026-07-15",
      "label": "Renovación REPROCANN",
      "description": "7 documentos vencen en los próximos 60 días.",
      "tag": "En 9 días",
      "urgency": "urgent"
    },
    {
      "id": "medical-director-matricula",
      "date": "2026-07-28",
      "label": "Matrícula Director Médico",
      "description": "Vencimiento de la matrícula del director médico designado.",
      "tag": "En 22 días",
      "urgency": "soon"
    },
    {
      "id": "semi-annual-report",
      "date": "2026-12-31",
      "label": "Informe Semestral",
      "description": "Res. 1780/2025 - presentación obligatoria del informe del semestre.",
      "tag": "En 45 días",
      "urgency": "normal"
    }
  ]
}

GET/api/compliance/semi-annual

Informe semestral

Retorna los datos agregados necesarios para el informe semestral REPROCANN. Combina información de miembros, cultivos, cosechas, prescripciones, plantas y organización para el período indicado.

El período se deriva del semester (1 = 1 ene – 30 jun; 2 = 1 jul – 31 dic) y del year. Si semester no es 1 ni 2, la respuesta es un error de validación (400).

Query params opcionales

  • Name
    semester
    Type
    integer
    Description

    Semestre: 1 o 2 (default 1).

  • Name
    year
    Type
    integer
    Description

    Año (default: año actual).

Response

  • Name
    semester
    Type
    number
    Description
    Semestre solicitado.
  • Name
    year
    Type
    number
    Description
    Año solicitado.
  • Name
    from
    Type
    string
    Description
    Inicio del período (YYYY-MM-DD).
  • Name
    to
    Type
    string
    Description
    Fin del período (YYYY-MM-DD).
  • Name
    members
    Type
    array
    Description

    Miembros con su ficha médica (reprocannCode, reprocannExpiration, cannabisUses, etc.).

  • Name
    harvests
    Type
    array
    Description

    Cosechas del período con cannabinoides y análisis de laboratorio.

  • Name
    prescriptions
    Type
    array
    Description

    Prescripciones (patientId + products).

  • Name
    plants
    Type
    array
    Description

    Plantas con su estado.

  • Name
    crops
    Type
    array
    Description

    Cultivos con datos de cepa (incl. inaseRegistrationNumber).

  • Name
    organization
    Type
    object
    Description

    Datos de la organización, incluyendo director médico y responsable técnico.

Request

GET
/api/compliance/semi-annual
curl -G https://api.cannahub.tech/api/compliance/semi-annual \
  -H "Authorization: Bearer {token}" \
  -d semester=1 \
  -d year=2025

Response

{
  "semester": 1,
  "year": 2025,
  "from": "2025-01-01",
  "to": "2025-06-30",
  "members": [
    {
      "id": "usr_01HQ8XYZABC123",
      "firstName": "María",
      "lastName": "González",
      "document": "35123456",
      "medicalRecord": {
        "reprocannCode": "REPRO-2024-AR-001234",
        "reprocannExpiration": "2025-01-15",
        "cannabisUses": ["Manejo de ansiedad"]
      }
    }
  ],
  "harvests": [
    {
      "id": "harv_01",
      "name": "Cosecha Sala A - Q1",
      "batchNumber": "B-2025-014",
      "harvestedAt": "2025-03-20",
      "strainName": "Charlotte Web",
      "cannabinoids": { "thc": 0.5, "cbd": 14.2 },
      "labAnalysis": {
        "labName": "Laboratorio Cannábico Nacional",
        "analysisDate": "2025-03-28"
      }
    }
  ],
  "prescriptions": [],
  "plants": [
    { "id": "p1", "status": "FLOWERING" },
    { "id": "p2", "status": "VEGETATING" }
  ],
  "crops": [
    {
      "id": "c1",
      "name": "Cultivo 1",
      "strain": { "name": "Charlotte Web", "type": "CBD" }
    }
  ],
  "organization": {
    "name": "Medicann Demo",
    "medicalDirector": { "name": "Dr. Mock", "matricula": "12345" }
  }
}

GET/api/compliance/summary

Resumen de cumplimiento

Agrega datos de cumplimiento desde múltiples fuentes (miembros, plantas, cultivos, cosechas, espacios, staff, órdenes y productos) para ofrecer una vista general del estado regulatorio de la organización. Base del dashboard de compliance.

Response

  • Name
    members
    Type
    object
    Description

    Resumen de miembros.

    • Name
      total
      Type
      number
      Description
      Total de miembros.
    • Name
      withActiveReprocann
      Type
      number
      Description
      Con REPROCANN vigente.
    • Name
      withExpiredReprocann
      Type
      number
      Description
      Con REPROCANN vencido.
    • Name
      withInformedConsent
      Type
      number
      Description
      Con consentimiento informado.
    • Name
      list
      Type
      array
      Description

      Lista de miembros (id, name, dni, reprocannCode, reprocannExpiration, initials, avatarTone, hasInformedConsent).

  • Name
    plants
    Type
    object
    Description

    Conteo de plantas por estado (total, flowering, vegetative, other).

  • Name
    crops
    Type
    object
    Description

    Cultivos (total, withInaseRegisteredStrain, withoutInaseRegisteredStrain).

  • Name
    harvests
    Type
    object
    Description

    Cosechas (total, withCannabinoids, withLabAnalysis, withBatchNumber, batchesPendingAnalysis).

  • Name
    spaces
    Type
    object
    Description

    Espacios (total, withGeolocation).

  • Name
    organization
    Type
    object
    Description

    Organización (name, hasMedicalDirector, hasTechnicalManager, patientsMax, locationsMax).

  • Name
    orders
    Type
    object
    Description

    Órdenes (total, toRegisteredPatients).

  • Name
    products
    Type
    object
    Description

    Productos (total, withCannabinoidLabel).

  • Name
    lastSyncedAt
    Type
    string
    Description

    Timestamp de la agregación (ISO).

Request

GET
/api/compliance/summary
curl https://api.cannahub.tech/api/compliance/summary \
  -H "Authorization: Bearer {token}"

Response

{
  "members": {
    "total": 42,
    "withActiveReprocann": 38,
    "withExpiredReprocann": 3,
    "withInformedConsent": 40,
    "list": [
      {
        "id": "mock-mem-1",
        "name": "Lucía Fernández",
        "dni": "32145678",
        "reprocannCode": "RC-00012",
        "reprocannExpiration": "2026-11-12",
        "initials": "LF",
        "avatarTone": "a",
        "hasInformedConsent": true
      }
    ]
  },
  "plants": { "total": 180, "flowering": 45, "vegetative": 90, "other": 45 },
  "crops": { "total": 8, "withInaseRegisteredStrain": 5, "withoutInaseRegisteredStrain": 3 },
  "harvests": {
    "total": 12,
    "withCannabinoids": 9,
    "withLabAnalysis": 6,
    "withBatchNumber": 11,
    "batchesPendingAnalysis": ["B-2026-007", "B-2026-009", "B-2026-011"]
  },
  "spaces": { "total": 3, "withGeolocation": 1 },
  "organization": {
    "name": "Medicann Demo",
    "hasMedicalDirector": true,
    "hasTechnicalManager": false,
    "patientsMax": 150,
    "locationsMax": 3
  },
  "orders": { "total": 85, "toRegisteredPatients": 82 },
  "products": { "total": 15, "withCannabinoidLabel": 12 },
  "lastSyncedAt": "2026-06-17T18:00:00.000Z"
}

Was this page helpful?