Skip to content

eDOCS Integration

The LDE backend integrates with OpenText eDOCS — the document management system used by Province of Flevoland — to automatically file process documents into project workspaces as part of the RIP Phase 1 workflow.

The integration uses the external task pattern: Operaton polls the LDE backend worker via fetchAndLock rather than the backend calling Operaton. This keeps the coupling loose and makes the integration resilient to temporary eDOCS unavailability.


Architecture

sequenceDiagram
    participant O as Operaton
    participant W as ExternalTaskWorker
    participant E as EdocsService
    participant D as eDOCS REST API

    O->>W: fetchAndLock (topic: rip-edocs-workspace)
    W->>E: ensureWorkspace(projectNumber, projectName)
    E->>D: POST /connect → X-DM-DST token
    E->>D: GET /workspaces?filter=projectNumber
    D-->>E: workspace found / not found
    alt workspace not found
        E->>D: POST /workspaces
        D-->>E: { id: 2993897 }
    end
    E-->>W: { workspaceId, workspaceName, created }
    W->>O: complete task (sets edocsWorkspaceId)

    O->>W: fetchAndLock (topic: rip-edocs-document)
    W->>E: uploadDocument(workspaceId, filename, content, metadata)
    E->>D: POST /documents (with _restapi.ref.id: workspaceId)
    D-->>E: { DOCNUMBER: "2993898" }
    E-->>W: { documentId, documentNumber }
    W->>O: complete task (sets edocsIntakeReportId)

EdocsService

packages/backend/src/services/edocs.service.ts

Wraps the eDOCS REST API with session token caching and automatic re-authentication.

Authentication

The service authenticates once via POST /connect, which returns an X-DM-DST session token. The token is cached in memory and attached to every subsequent request via an Axios request interceptor. On a 401 or 403 response the service re-authenticates once and retries the original request automatically.

Methods

Method Description
ensureWorkspace(projectNumber, projectName) Searches for an existing workspace by projectNumber. Creates one if not found. Returns { workspaceId, workspaceName, created }.
uploadDocument(workspaceId, filename, contentBase64, metadata) Uploads a base64-encoded document to the workspace. Returns { documentId, documentNumber }.
getWorkspaceDocuments(workspaceId) Lists all documents in a workspace. Used for audit and verification.
healthCheck() Returns { status: 'up' | 'down' | 'stub', latencyMs? }.

Workspace naming convention

Workspaces are named <projectNumber> — <projectName>, e.g. 123456789 — N308 Reconstructie. The project number is used as the search key so that re-deploying or restarting the process does not create duplicate workspaces.

Document IDs

eDOCS workspace and document IDs are plain integers (e.g. 2993896). The _restapi.ref.id field in upload requests is passed as an integer — parseInt(workspaceId, 10).


External task worker

packages/backend/src/services/externalTaskWorker.service.ts

Polls Operaton using long-polling (asyncResponseTimeout: 20 000 ms). Two topics are subscribed:

rip-edocs-workspace

Called once per process instance, immediately after the intake form is submitted.

Variables read from Operaton: projectNumber, projectName

Variables written back: edocsWorkspaceId (String), edocsWorkspaceName (String), edocsWorkspaceCreated (Boolean)

rip-edocs-document

Called three times per process instance — once for the intake report, once for the PSU report, and once for the preliminary design principles.

The documentTemplateId and edocsDocumentVariableName are set as camunda:inputParameter elements on each ServiceTask in the BPMN, making this single topic handler reusable across all three document upload steps.

Variables read from Operaton: edocsWorkspaceId, documentTemplateId, edocsDocumentVariableName, plus all template-specific process variables.

Variables written back: <edocsDocumentVariableName> (String) — the eDOCS document number, e.g. edocsIntakeReportId.

Worker lifecycle

The worker is started inside the app.listen() callback in packages/backend/src/index.ts and stopped cleanly in both SIGTERM and SIGINT handlers. It will not start polling until the HTTP server is fully bound.


Stub mode

When EDOCS_STUB_MODE=true (the default), all EdocsService methods return realistic fake responses and log what they would have done. The worker, routes, and BPMN process behave identically — the stub is fully transparent to callers.

This allows the complete RIP Phase 1 process to run end-to-end in development and acceptance environments before a live eDOCS server is available.

To switch to a live server, set EDOCS_STUB_MODE=false and provide real credentials. No code changes are required.


Configuration

Add the following to packages/backend/.env (see .env.example):

EDOCS_BASE_URL=https://your-edocs-server.nl:port/edocsapi/v1.0
EDOCS_LIBRARY=DOCUVITP
EDOCS_USER_ID=your-user-id
EDOCS_PASSWORD=your-password
EDOCS_STUB_MODE=true
Variable Required Description
EDOCS_BASE_URL Yes (live mode) eDOCS REST API base URL
EDOCS_LIBRARY Yes (live mode) eDOCS library name — DOCUVITP for Flevoland
EDOCS_USER_ID Yes (live mode) eDOCS user ID
EDOCS_PASSWORD Yes (live mode) eDOCS password
EDOCS_STUB_MODE No Defaults to true. Set to false to enable live calls.

Warning

Never commit real eDOCS credentials to the repository. Use Azure Key Vault references or environment-specific App Service configuration in production.


Document file format (.DRF)

When eDOCS saves a document it produces a .DRF (Document Reference File) with the format:

Document;<library>;<document_number>;<version>

For example: Document;DOCUVITP;2993896;R

The document number matches the documentNumber field returned by POST /v1/edocs/documents and stored as the process variable (e.g. edocsIntakeReportId).


REST endpoints

See API Reference — eDOCS for full request and response documentation of all four /v1/edocs endpoints.