Paperless
Plataforma multi-tenant de digitalización y OCR de documentos.
Cada cliente (organización) opera aislado dentro de la misma base, el equipo interno de Paperless administra a todos, y el trabajo se organiza en Órdenes de Servicio (OS) con pasos y evidencia.
Stack: API y worker en Go (api/), SPA en React/TypeScript/Tailwind
(web/), Postgres con RLS para el aislamiento por tenant, Keycloak para identidad/OIDC y
S3 para los archivos. Corre en AWS (mx-central-1) por Docker Compose.
Secciones
- Guía de uso — entrar (con MFA), dar de alta clientes y su admin, invitar equipo, subir documentos y operar una OS de principio a fin.
- Documentación técnica — arquitectura, seguridad/multi-tenant, auth/MFA y deploy.
- Integración & API — autenticación OIDC, tenant efectivo y endpoints.
Guía de uso
Todo lo que necesitas para operar Paperless día a día, seas del equipo Paperless o administrador de un cliente.
Quién usa Paperless
Hay dos grandes grupos de usuarios: el equipo Paperless (staff, que administra a todos los clientes) y las organizaciones cliente (que ven solo su propia información). Tu rol define qué módulos ves y qué puedes hacer.
Equipo Paperless (staff)
| Rol | Quién es |
|---|---|
| admin | Administración Paperless — acceso total; administra clientes, equipos y configuración. |
| coordinador | Coordinación de operaciones — gestiona órdenes, rutas y bodega. |
| atencion_cliente | Atención a clientes — da de alta clientes y administra sus equipos. |
| operador_bodega | Operación de bodega — recepción, fotos y relocalización de cajas. |
| capturista_bd | Control de inventario — captura y auditoría de inventario. |
| supervisor | Supervisión — seguimiento y control de calidad. |
| auditor_externo | Auditor externo — acceso de auditoría/lectura. |
Organizaciones cliente
| Rol | Quién es |
|---|---|
| cliente_admin | Administrador del cliente — administra su organización y su equipo, ve toda la información de su empresa. |
| cliente_usuario | Usuario — consulta y trabaja con los documentos y órdenes de su empresa. |
| partner_admin | Socio coworking — administra su espacio y sus sub-clientes. |
Entrar y configurar MFA
Paperless usa Paperless ID (Keycloak) para el acceso. Entra en app.78-12-50-254.sslip.io.
Primer acceso del equipo Paperless (staff)
El personal de Paperless entra siempre con segundo factor. La primera vez:
- Entra con tu correo y la contraseña temporal que te dieron.
- El sistema te pide fijar una contraseña nueva.
- Luego te pide configurar TOTP: escanea el código QR con una app autenticadora (Google Authenticator, Microsoft Authenticator, 1Password, etc.) y escribe el código de 6 dígitos para confirmar.
- Desde ahí, cada login pide tu contraseña y el código de 6 dígitos que muestra tu app.
Guarda el acceso a tu app autenticadora. Si cambias de teléfono sin migrarla, un administrador tendrá que reiniciar tu TOTP para que vuelvas a configurarlo.
Primer acceso de un cliente
Los usuarios de un cliente (cliente_admin, cliente_usuario) solo
fijan su contraseña en el primer login; no se les pide MFA.
Cambiar de organización (staff)
El equipo Paperless puede trabajar en nombre de una organización cliente. Usa el selector “Actuar como organización” en la parte superior: al elegir un cliente, todo lo que hagas (crear órdenes, invitar equipo, ver documentos) aplica a esa organización.
Mientras actúas como una organización, los cambios quedan registrados a tu nombre pero dentro de la empresa seleccionada. Cambia de regreso a Paperless cuando termines.
Dar de alta un cliente y su administrador
Solo el equipo Paperless (roles admin, coordinador,
atencion_cliente) puede crear organizaciones cliente.
Cliente nuevo
- Ve a Clientes → “Nueva organización”.
- Captura el nombre de la empresa y los datos de su primer administrador (nombre y
correo). Se crea la organización y su
cliente_adminen un solo paso. - El administrador del cliente recibe acceso y fija su contraseña en el primer login.
Darle un administrador a un cliente existente
- Usa “Actuar como organización” y elige el cliente.
- Ve a Equipo → Invitar e invita a la persona con el rol Administrador
(
cliente_admin).
Administrar tu equipo
Los administradores (cliente_admin / partner_admin, y el staff actuando como la
organización) administran a los miembros desde Equipo.
- Invitar: Equipo → Invitar; captura nombre, correo y rol.
- Cambiar el rol de un miembro (por ejemplo, de Usuario a Administrador).
- Desactivar a quien ya no debe tener acceso — deja de poder entrar sin borrar su historial.
Subir y encontrar documentos
Subir
- Entra a Documentos (si eres staff, primero “Actuar como organización” del cliente correcto).
- Arrastra o selecciona los archivos. Quedan asociados a la organización activa.
- El OCR se procesa en segundo plano; cuando termina, el texto es buscable.
Buscar y abrir
- Usa el Buscador para encontrar documentos por nombre o por su contenido (gracias al OCR).
- Abre un documento para verlo; usa Descargar para obtener el archivo original.
Cada quien ve solo los documentos de su propia organización. El aislamiento es a nivel de base de datos: nadie puede ver los documentos de otro cliente.
Órdenes de Servicio de principio a fin
El trabajo operativo se organiza en Órdenes de Servicio (OS). Cada servicio tiene su propia secuencia de pasos, y cada paso guarda su evidencia.
- Crear la OS: en Servicios, crea una nueva orden eligiendo el tipo de servicio y el cliente.
- Paso 1 — Validar: valida la solicitud y la autorización. Aquí puedes subir el archivo de formato (.pdf / .png / .jpg) con el botón de formato; queda adjunto a la orden como evidencia.
- Pasos siguientes: avanza por el flujo del servicio. Cada paso puede pedir evidencia (notas, fotos, condiciones) que queda registrada.
- Timeline: en la orden ves la línea de tiempo con cada paso y su evidencia. El formato aparece como “📎 Abrir formato” para descargarlo.
Acciones sobre una orden
- Reabrir un paso si hay que corregir algo ya registrado.
- Registrar una excepción cuando algo no sale según lo esperado, y luego resolverla.
- Autorizar, cancelar o cobrar la orden según el flujo y tu rol.
Preguntas frecuentes
Me dice “mfa required” aunque ya configuré el MFA
Cierra la sesión y vuelve a entrar en una ventana limpia (o incógnito), escribiendo contraseña y el código de 6 dígitos. Si persiste, avisa al equipo técnico: es un problema de configuración del lado del servidor, no tuyo.
Olvidé mi contraseña
Las contraseñas las administra Paperless ID. Pide a un administrador que te genere una contraseña temporal; la cambiarás al entrar.
No veo un módulo que otra persona sí ve
Los módulos dependen de tu rol. Si necesitas acceso a algo, pídele a tu administrador que revise tu rol.
Soy staff y no puedo “actuar como” un cliente
Actuar como organización requiere tener el segundo factor (MFA) activo y un rol de staff con permiso. Verifica que entraste con tu código de 6 dígitos.
Documentación técnica
Arquitectura, seguridad, autenticación y deploy.
Arquitectura
La SPA habla solo con la API; la API valida la sesión OIDC de Keycloak, aplica permisos server-side
(s.can()) y accede a los datos del tenant siempre a través de db.Scoped sobre
Postgres con RLS. Los archivos viven en S3; el worker procesa el OCR de forma asíncrona.
Comandos de la app (api/cmd/api): serve (HTTP),
worker (OCR), migrate (esquema + roles), idp-setup (configura
MFA/amr en Keycloak), bootstrap-admin (siembra el primer admin).
seed es solo local.
Seguridad y multi-tenant
El aislamiento por tenant va antes que las features. Reglas no negociables:
- Toda tabla con datos de tenant lleva
org_id+ RLSENABLE+FORCE+ una políticatenantsobrecurrent_org().TestEveryTenantTableHasRLSfalla si no. - Los datos de tenant se acceden solo por
db.Scoped(s.tx(r, ...)): el tenant viene de la sesión, nunca del body o query. - Las FK ignoran RLS: antes de enlazar un id foráneo (box, documento, orden, usuario) hay que verificar que existe dentro del tenant.
- Las lecturas cross-tenant de staff van solo por
db.StaffDirectory, que nunca expone documentos. - Cada acción que cambia estado escribe
audit(r, tx, ...)en la misma transacción. - Permisos server-side con
s.can("<perm>"); la UI solo los refleja. - Validar toda entrada en el borde (longitudes, enums, UUID con
validUUID);decoderechaza campos desconocidos. - Proveedores externos tras un adapter con fake marcado. Los secretos solo por env, nunca commiteados.
Autenticación y MFA
Keycloak 26.1 (realm paperless) maneja identidad por OIDC. Dos clientes:
paperless-web (login, confidential, standard flow) y paperless-admin
(service account que usa la API para administrar usuarios).
- Login: la SPA redirige a Keycloak; la API lee el ID token en el callback
(
auth.go) y abre la sesión. - MFA de staff:
REQUIRE_STAFF_MFA=true. Todo usuario del grupostaffdebe configurar TOTP en su primer login. - El claim
amr: la API leeamrdel ID token; si traeotp/mfa/hwk/swk, la sesión cuenta con segundo factor. - Para que
amrllegue al token hacen falta DOS cosas, ambas configuradas poridp-setup(idempotente): (1) las authenticator reference configspwd/otpen el flowpaperless-browser, y (2) el protocol mapperoidc-amr-mapperen el clientepaperless-web.
Sin eloidc-amr-mapper,amrsale vacío y todo login de staff se rechaza como “mfa required” aunque el TOTP esté bien. Fue la causa raíz del bug de login en el box (oct 2026);idp-setupahora crea el mapper automáticamente.
Modelo de onboarding
organizations:is_internal(bool) +kindenum (client/partner/internal) sincronizado por el triggerorg_kind_sync.memberships: UNIQUE(identity_uid, org_id);identity_uid=subde Keycloak;activedefault true.- Alta de cliente:
POST /api/admin/orgscrea la org cliente + su primercliente_admin. - Invitar equipo:
POST /api/teamcontra la org actual; staff usa el headerX-Act-As-Org. - Primer admin: el comando
bootstrap-adminsiembra la org interna Paperless + el primer staff admin.
Flujo de Órdenes de Servicio (modelo)
- Cada servicio define una secuencia de pasos; el Paso 1 siempre es
validar(laneatencion). - La evidencia de cada paso se guarda como JSON en
os_events.evidence. - El Paso 1 acepta subir un archivo de formato opcional:
formato_doc_idapunta a un documento ya existente (se valida contradocuments, no borrado).
Deploy en AWS
Corre en AWS (mx-central-1): box EC2 (ubuntu@78.12.50.254, llave
deploy/aws/paperless.pem), RDS Postgres, S3, todo por Docker Compose.
Deploy (hoy manual) — el runner self-hosted de GitHub Actions aún no está instalado:
rsyncdel working tree al box (excluir.env,.pem,._*).- En
~/paperless/deploy/aws:sudo docker compose build app && docker compose run --rm migrate && docker compose up -d.
Wiki (docs): sitio estático en deploy/aws/docs/ servido por Caddy
(DOCS_HOST); deploy = rsync de docs/ + docker compose up -d caddy.
Primera puesta en marcha: deploy/aws/box-setup.sh hace swap, .env,
realm + clientes de Keycloak por kcadm, grupo staff, migrate,
idp-setup y up.
Cutover DNS (pendiente): apuntar paperless.com.mx (2 A records →
78.12.50.254), editar los hosts en .env, reiniciar caddy + app y actualizar el
redirect URI en Keycloak.
Operación
URLs vivas:
- App: app.78-12-50-254.sslip.io
- Auth: auth.78-12-50-254.sslip.io/realms/paperless
- Wiki: docs.78-12-50-254.sslip.io
Contraseñas: nunca pasan por la app; Keycloak es dueño de las credenciales. Se fija una
temporal con kcadm en el box:
kcadm.sh set-password -r paperless --username <email> --new-password '<temp>' --temporary
Cuentas sembradas (2026-10-21):
| Usuario | Rol | Organización | MFA |
|---|---|---|---|
| developer1@paperless.com.mx | admin (staff) | Paperless (interna) | TOTP obligatorio |
| demo-cliente@paperless.com.mx | cliente_admin | Cliente Demo | No |
Pendientes
- Instalar el runner self-hosted de GitHub Actions para self-deploy (hoy el deploy es manual).
- Cutover de DNS a
paperless.com.mxcuando haya acceso al DNS. - Resto del backlog de WhatsApp (oct 20) — mayormente sin empezar.
Integración & API
Cómo se habla con la API de Paperless.
Autenticación
- La API se consume desde la SPA con la sesión OIDC de Keycloak (cookie de sesión),
no con tokens armados a mano. El flujo de login es el estándar de
paperless-web. - Server-to-server: el service account
paperless-admin(client credentials) — hoy lo usa la propia API contra el Admin REST de Keycloak.
El tenant efectivo (actuar como organización)
El tenant siempre sale de la sesión, nunca del body. El staff puede actuar sobre una org cliente de dos formas (ambas requieren MFA y son solo para staff):
POST /api/session/org{"org_id": "..."}— fija la org activa en la sesión (el selector “Actuar como organización”).- Header
X-Act-As-Org: <org_id>— fija la org por request. Un cliente que lo mande recibe 403.
Endpoints principales
| Método y ruta | Qué hace |
|---|---|
GET /api/me, GET /api/me/orgs | Identidad y organizaciones del usuario |
POST /api/session/org | Actuar como una organización (staff) |
POST /api/admin/orgs | Crea org cliente + su primer cliente_admin |
GET / POST / PATCH /api/team | Lista, invita y edita miembros de la org actual |
GET / POST /api/documents | Lista y sube documentos (multipart, campo files) |
POST /api/documents/{id}/download | Devuelve una URL firmada de descarga |
GET / POST /api/os | Lista y crea Órdenes de Servicio |
POST /api/os/{id}/steps/{key} | Avanza un paso de la OS con su evidencia |
Subir archivos por cliente
- Entra como el
cliente_adminde esa org, o (staff) usa “Actuar como organización”. - Sube por Documentos, o directo a
POST /api/documents(multipart, campofiles). - En el Paso 1 de una OS, el archivo de formato viaja como
formato_doc_id(el id de un documento ya subido) enPOST /api/os/{id}/steps/{key}.
Pendiente
- Webhooks / API pública con tokens propios: aún no definido.