FaceKom Flow Engine & Flow Catalog

The flow engine is vuer_oss’s generic, data-driven workflow runner for customer identification / KYC / e-sign processes. A flow is an ordered list of tasks (steps the operator and/or customer complete) with a status lifecycle and a set of possible results. The engine is generic; the concrete flow definitions live as code under customization/flow/<name>/. Each flow is registered into the DB at boot, instantiated per customer/room, and driven through its lifecycle by vuer_oss’s FlowService. See vuer_oss, architecture-overview, customization-architecture, INDEX.

"Self-Service V2" is a PRODUCT FLOW, not a git branch. It is implemented as the self-service-v2-phase-1 / self-service-v2-phase-2 flow definitions (customization/flow/self-service-v2-phase-*/) plus the SelfServiceV2Service orchestrator (server/service/SelfServiceV2Service.js). The customization/* here is the per-partner override tree inside the repo, loaded at boot — not a branch name. (Branches are partner builds like customization/instacash; see customization-branch-catalog.)

Verified against the devel branch via git show devel:<path> (working tree was on a customization branch). All paths are /Users/levander/coding/facekom/vuer_oss.


1. Engine architecture (where it lives)

Core engine = server/flow/ (6 files, git ls-tree devel:server/flow):

FileRole
server/flow/FlowService.jsThe engine. ~3217 lines. Owns flow registration, instantiation, lifecycle (start/finish/abort/hold/reset), task handling, the Flow Editor API, scope/result resolution, auto-clear.
server/flow/FlowHandler.jsBase class for every flow. Reads the flow’s .proto.js + .trans.js, generates DB rows (register()), creates per-customer flow instances (_createFlow), and exposes ~35 overridable lifecycle hooks (onStarted, onFinished, onProgress, getPossibleActions, getResult, …).
server/flow/FlowScopeMap.jsThe 23 boolean scope flags (capabilities/behaviour toggles) a flow can enable.
server/flow/FlowResultOptions.jsMaps flow statuses → allowed resultCodes; validates result-for-status.
server/flow/Flow.trans.jsDefault i18n keys for flow/task labels (loaded before each flow’s own .trans.js).
server/flow/FlowEditor.trans.jsFlow-Editor UI translations.

Supporting services (server/service/):

  • FlowFilterService.js — ACL-aware list filtering (flows.list.any/other/own permissions; _accessFilter).
  • FlowLiveUpdateService.js — pushes flow/task status changes to watching operator sockets (filters: inRoom, watchingFlow, sameUser).
  • ArchiveServices/FlowArchiveService.js — archive/restore flows.

DB models (server/db/model/): flow.js (instance), flowproto.js (the published definition/template), task.js/taskproto.js (instance/template task), flowresult.js (status↔resultCode rows), flowscope.js (enabled scope rows), flowactivity.js (per-flow audit), flowProtoActivity.js (flow-editor audit), flowTranslation.js (per-proto i18n rows). Verified via git ls-tree devel:server/db/model.

Queue/RPC + socket surface:

  • server/queue/rpc_server/FlowDocuments.js → RPC rpc-flow-documents (server.js:406-412).
  • server/queue/rpc_server/FlowAutoClearRPCServer.js → RPC flow-autoclear, action flowAutoClear (server.js:421-422; calls FlowService.flowAutoClear()).
  • server/queue/rpc_server/SelfServiceV2.js → RPC rpc-selfservice-v2 (server.js:399).
  • server/socket/events/flow.js — operator socket events (flow:create, …) gated by auth.doIfHasRoom.
  • server/web/api/admin/flow*.js (~14 endpoints) + server/web/routes/flow*.endpoint.js — operator console flow UI + Flow Editor REST.
  • bin/flow-editor.js — “Flow Editor CLI” (registers handlers dry, lists/exports flow defs).
  • bin/flow-extractor-portable.mjs — extract self-service room flows to file.

2. Data model & vocabulary (source-verified)

FlowProto (flowproto.js:2-86) = the template. Status enum ['published','draft']; DRAFT/PUBLISHED constants; defaults published. Has name, version, taskCount. A new flow instance always uses the latest PUBLISHED version (FlowHandler._createFlow: order: [['version','DESC']], status: PUBLISHED).

Flow (flow.js:3-9) = a running instance for one customer/room. Status enum is exactly:

created → in-progress → { on-hold | finished | aborted }

(allStatuses = ['created','in-progress','on-hold','finished','aborted']). Columns include result, finishedTaskCount, startedAt/finishedAt/lastUpdatedAt, customerId, roomId, selfServiceRoomId, parentFlowId, createdById/startedById/finishedById/updatedById, isArchived, cleared, metadata (JSON). name is validated against config.flow.flows.

Task (task.js:1-6) — instance task. Status enum: ['pending','finished','skipped','idle']. idle = waiting to be started (used with scope task_start_require_action).

Task types (taskproto.js:1-12, task.js:8-19) — the 11 valid type values: info, prompt, confirm, check, select, search, upload, dateTime, file, photo, presentation. Only ['info','prompt','confirm','check','select'] are creatable in the Flow Editor (taskproto.js:14-20 creatableProtoType).

FlowResult (flowresult.js:17-43) — rows of { status, resultCode, protected, filterable, userSelectable, flowProtoId }. FlowResultOptions (FlowResultOptions.js) buckets result codes per status: created, in-progress, on-hold, finished, aborted.

FlowScope (flowscope.js:2-9) — one row per enabled scope name. Hydrated into a FlowScopeMap with these 23 booleans (all default false; constructor this.<name> = false assignments, FlowScopeMap.js, devel). (allow_ordered_task_backsteps is assigned twice — initialised, then re-gated on ordered_task_completion at the end of the constructor — but is a single scope property.):

ScopeMeaning (verbatim intent from source)
creatable_by_systemflow may be created with no creator user (system-initiated)
creatable_on_videochat / listable_on_videochat / editable_on_videochatcreate / list / edit on the videochat screen
listable_on_room_profilelist on room profile
listable_on_selfservice_room_profilelist on self-service room profile
listable_on_customer_profile / creatable_on_customer_profilelist / create on customer profile
listable_on_flow_listappears in the global flow list
editable_on_flow_profileeditable on the flow profile page
editable_customer_data_on_flow_profileallow editing customer data while flow is in-progress
task_skipping_enabledtasks may be skipped
allow_task_updates_when_on_hold / allow_task_updates_when_created / allow_task_updates_when_donepermit task updates in those flow/task states
hold_action_disabled / abort_action_disabled / finish_action_disabledhide/disable those actions for the user
resetableflow may be reset
task_start_require_actiontask → pending only when the customer starts it (else idle)
ordered_task_completiontasks must be completed in order
allow_unordered_task_reopenreopen tasks out of order
allow_ordered_task_backstepsstep back to a previous task (auto-gated: only true if ordered_task_completion also true, FlowScopeMap.js:30)

FlowActivity types (flowactivity.js:4-20) — the audit event vocabulary: flow:create, flow:start, flow:hold, flow:abort, flow:finish, flow:reset, flow:clear, flow:external-update, flow:task:update, flow:task:start, flow:task:idle, flow:task:reopen, flow:task:search, flow:task:data:change, flow:task:upload:create, flow:task:upload:delete, flow:task:photo:create.


3. A flow definition = 3 files per flow

Every flow <name> is a folder customization/flow/<name>/ with exactly:

  • <name>.flow.proto.js — the definition: { flow:{name,version,taskCount}, scopes:{…}, tasks:[…], results:{…} }. (Example: esign-registration.flow.proto.js.)
  • <name>.flow.handler.js — a class extends FlowHandler that wires lifecycle hooks (e.g. abort-on-room-close) and overrides behaviour (onProgress, getResult, getNextTask, …).
  • <name>.flow.trans.js — i18n keys for flow name/description, task names/instructions, result labels.

Task definition shape (from protos): { order, name, type, protected?, optional?, input?:{required,pattern,maxLength,…}, options?:{…}, file?:{mime,extension,maxCount,minCount,…}, search? }. For self-service-v2, each task carries an options.step object (see §6).

Boot: registration → instantiation

  1. Registration (proto → DB), once per boot. customization/customization.js:208 calls serviceContainer.service.flow.registerFlowHandlers() (after requiring ./flow/flowStatProviders). FlowService constructor (FlowService.js:20-29) iterates config.flow.flows and require()s each customization/flow/<type>/<type>.flow.handler. registerFlowHandlers news up each handler and calls handler.register() (FlowHandler.register, FlowHandler.js): if a FlowProto with that name+version doesn’t exist, it generates FlowProto + TaskProtos + FlowScopes + FlowResults + FlowTranslations in a transaction. Bumping a proto’s version creates a new published proto; old instances keep their old version. background.js:88 and bin/flow-editor.js register with dry = true (no DB writes). FlowService is instantiated in both server.js:174 and background.js:88.
  2. Instantiation (per customer/room). FlowHandler registers a hook flow:<name>:create (FlowHandler.js:21-23) → _createFlow(customerId, roomId, userId, parentFlowId, selfServiceRoomId). It loads the latest published proto withTasks, builds a Flow + its Task rows in a transaction, applies scope-driven initial task statuses (ordered_task_completion/task_start_require_action → first task pending, rest idle), runs onBeforeCreate*/onCreated hooks, writes a flow:create activity, and emits flow:status:updated. Public entry: FlowService.createFlow(...) (and the operator socket flow:create in server/socket/events/flow.js).

4. Lifecycle (FlowService methods — verified)

Status transitions are guarded and emit events + run handler hooks via _signalBeforeLifecycleChange / _signalLifecycleChange (FlowService.js:1393-1456):

FlowService methodEffectHandler hooks fired
startFlow(flowId,userId,roomId,options,selfServiceRoomId)created/on-holdin-progress; sets startedAt/startedById; resource-locked to prevent double-start by another user (FlowService.js:1735-1795).onBeforeStart then onStarted; hook flow:<name>:before:in-progress / flow:<name>:in-progress
holdFlow(...)on-holdonBeforeHalt/onHalted
finishFlow(flowId,userId,roomId,comment,result,options,…)finished; computes result via handler.getResult, checks getPossibleActions().finish + finish_action_disabled scope, validates result-for-status (FlowService.js:2173+).onBeforeFinish/onFinished
abortFlow(...)aborted (sets result, e.g. 'failed').onBeforeAbort/onAborted
resetFlow(...)reset (requires resetable scope).onReset
updateResult(...)change a flow’s result code.

_signalBeforeLifecycleChange returning false (handler hook veto) cancels the transition. Each status maps to its handler callbacks in a switch (FlowService.js:1400-1410, 1431-1441).

Task-level methods (FlowService.js): updateTask, updateTaskData, startTask, idleTask, reopenTask, submitTaskSearch, submitTaskUpload, submitTaskPhoto, submitTaskRecognition, handleTaskRecognitionOptions, deleteTaskFile, getNextTask/getPreviousTask (order-based, FlowHandler.js). Task completion drives onProgress(flow, task) and _updateTaskCount.

FlowHandler overridable hooks (FlowHandler.js, all no-ops by default): onPersonalizeScopes, onBeforeCreate(Tasks/Task), onCreated, onExternalUpdate, onBeforeStart/onStarted, onBeforeFinish/onFinished, onBeforeHalt/onHalted, onBeforeAbort/onAborted, onReset, onBeforeUpdateTask, onProgress, onTaskStart/Idle/Reopen, onTaskSearchSubmit, onBeforeTaskUpload/onTaskUploadSubmit, onTaskPhotoSubmit, onBeforeTaskRecognition/onTaskRecognitionSubmit, plus calc hooks getPossibleActions(flow,prevStatus,prevResult), getTaskActions(task), getResult(flow,result), getRelatedFlows(flow,filters), getNextTask/getPreviousTask. Utility helpers: removeTask, switchTasks (conditionally drop tasks at create time).

Access control. FlowService.checkViewAccess (FlowService.js:72-99) honours flows.view.any/own/other ACL permissions; FlowFilterService honours flows.list.any/other/own. (Permission strings live in config/roles.json.)

Auto-clear. config.flow.autoClear.schedule (cron, e.g. "0 8 * * *" in config/dev.json:85-87) → flow-autoclear RPC → FlowService.flowAutoClear()collectClearableFlowsclearFlows (sets cleared, writes flow:clear activity).

Flow Editor (gated by config.features.flowEditor). FlowService methods generateDraft, resetDraft, publishFlow, updateFlowProto, createFlowResult/updateFlowResult/deleteFlowResult, createFlowTask/updateFlowTask/deleteFlowTask let operators clone a published proto into a draft, edit tasks/results/scopes/translations, and re-publish (version+1). Every edit writes a FlowProtoActivity row.


5. Flow catalog — EVERY flow (from customization/flow/*/*.flow.proto.js, devel)

config.flow.flows enables 13 flows on the devel base config (config/dev.json:88-102): customer-data-change-test, online-verification-phase-1, online-verification-phase-2, automated-test-1..5, esign-registration, self-service-phase-1, self-service-phase-2, self-service-v2-phase-1, self-service-v2-phase-2.

config.flow.flows is branch-specific. The 13-flow list above is config/dev.json on devel. Partner/customization branches replace it wholesale: e.g. on the working-tree branch update/customization/instacash-2026-05-27, config/dev.json:107-127 instead lists 19 ic-* flows (ic-customer-verification-1/2, ic-loan-confirmation, ic-self-service-v2-phase-1/2, ic-mfl-verification-1..4, ic-online-verification-1/2, ic-contract, …). Always read the config for the branch you care about.

A 14th definition, automated-test-6, exists on disk (customization/flow/automated-test-6/) but is NOT in config/dev.json's flows list, so it is not registered in that config. Its proto is identical to automated-test-5. The full 13+1 = 14 named set (the 13 above plus automated-test-6) is the list registered by the test config test/testconfigs/test-config.json:54-69 on devel (there is no config/test-config.json).

5.1 online-verification-phase-1 — operator-led video KYC, phase 1

  • Purpose: the operator’s “phase 1” script during a live video identification call (greeting → legal → prep → screenshots → 2FA → consents). Created on the videochat screen.
  • Definition: customization/flow/online-verification-phase-1/online-verification-phase-1.flow.proto.js — version 24, 7 tasks.
  • Tasks (type): greeting(info), legal_coverage(info), preparations(info), screenshots(info), two_fact_auth(info), ttny(confirm), pep(confirm).
  • Scopes: creatable_by_system, listable/editable/creatable_on_videochat, listable_on_room_profile, listable_on_customer_profile, listable_on_flow_list.
  • Results: success→finished, failed→aborted.

5.2 online-verification-phase-2 — operator-led video KYC, phase 2 (review/approval)

  • Purpose: the operator’s “phase 2” control/review checklist (confirm tasks); not creatable on videochat, editable on the flow profile (post-call decision). Carries the girinfo_control GIRINFO check.
  • Definition: …/online-verification-phase-2.flow.proto.js — version 25, 6 tasks.
  • Tasks (all confirm): video_quality_control, consent_to_recording, consent_to_cdd, screenshots_control, ttny_pep, girinfo_control.
  • Scopes: creatable_by_system, listable_on_videochat, listable_on_room_profile, listable_on_customer_profile, listable_on_flow_list, editable_on_flow_profile.
  • Results: success→finished, failed→aborted.

5.3 esign-registration — e-sign account registration

  • Purpose: guide an operator through registering the customer into the e-sign / mobile-app service (collect phone, upload data, start app, SMS token, set credentials, approve). Handler (esign-registration.flow.handler.js) on onProgress drives the eSign integration (esign_oss) and aborts the flow on videochat:close.
  • Definition: …/esign-registration.flow.proto.js — version 10, 10 tasks.
  • Tasks: bank_process_info(info), customer_confirm(confirm), check_phone_number(info), upload_customer_data(info), download_and_start_app(info), instruct_new_registration(info), send_registration_sms(info), prompt_sms_token(info), set_username_password(info), approve_customer(confirm).
  • Scopes: creatable_by_system, listable/editable/creatable_on_videochat, listable_on_room_profile, listable_on_customer_profile, listable_on_flow_list.
  • Results: success→finished, failed→aborted.
  • Gotcha: onProgress warns and no-ops if config.esign.active is false.

5.4 self-service-phase-1 — Self-Service V1, customer photo capture

  • Purpose: the legacy (“V1”) unattended self-service capture flow — customer photographs themself + ID documents. System-created (no operator). Ordered, with back-steps and out-of-order reopen.
  • Definition: …/self-service-phase-1.flow.proto.js — version 23, declared taskCount:4 (proto lists 7 photo tasks; an 8th id-recaptcha is commented out).
  • Tasks (all photo, input.required:true): customer-photo, id-front-photo, id-back-photo, dl-front-photo, dl-back-photo, pa-front-photo, address-card-photo. Each has options.screenshotCategory, camChangeOptions.facingMode, photoInstructions.{validationType,overlayType}, and recognitionOptions (recipe e.g. built-in-face-detection, built-in-id-card-front, MRZ hu-id-2016-back/hu-passport, compareFaceWith:'customer-photo').
  • Scopes: creatable_by_system, listable/editable_on_videochat (not creatable_on_videochat), listable_on_room_profile, listable_on_selfservice_room_profile, listable_on_customer_profile, listable_on_flow_list, ordered_task_completion, allow_ordered_task_backsteps, allow_unordered_task_reopen.
  • Results: success→finished, failed→aborted.

5.5 self-service-phase-2 — Self-Service V1, operator review/decision

  • Purpose: operator review of the V1 self-service capture; rich set of abort reason codes (AML/KYC rejection reasons). Editable on the flow profile.
  • Definition: …/self-service-phase-2.flow.proto.js — version 7, 5 tasks.
  • Tasks (all info): screenshot_face, screenshot_id, screenshot_comparison, screenshot_address_card, ttny_pep.
  • Scopes: creatable_by_system, listable_on_videochat, listable_on_room_profile, listable_on_selfservice_room_profile, listable_on_customer_profile, listable_on_flow_list, editable_on_flow_profile.
  • Results: success→finished, plus 14 aborted reason codes: missing_contribution, data_doesnot_match, id_cannot_be_read, deviation_in_the_id_process, presence_of_another_person, id_number_incorrect, id_card_expired, person_mismatch, influenced_person, high_risk_customer, bad_video_conditions, prominent_public_actor, person_mandated_by_the_owner, expired_unattended (last one userSelectable:false — set by the system on expiry).

5.6 self-service-v2-phase-1Self-Service V2 capture (the product flow)

  • Purpose: the current unattended Self-Service V2 customer journey — the full set of identity-capture steps (2FA, consents, portrait, liveness, ID/DL/passport front+back, hologram, eMRTD NFC chip read, proof-of-address, data confirmation, Client Gate). Driven entirely by SelfServiceV2Service (§6). See docs/features/self-service-v2/ for the operator-facing manuals.
  • Definition: customization/flow/self-service-v2-phase-1/self-service-v2-phase-1.flow.proto.js — version 30, taskCount:16.
  • Handler: …/self-service-v2-phase-1.flow.handler.js — class SelfServiceV2PhaseOne extends FlowHandler. Hooks: self-service:v2:created→creates the flow; self-service:v2:aborted|failed|expiredabortFlowForRoom. onProgressadvanceSelfServiceProgress. onBeforeCreateTasks prunes tasks per device/SDK capability (drops steps unsupported by the customer’s browser/mobile SDK via taskCompatibility + CustomerEnvData.supportedSteps) and renumbers order.
  • Tasks (16; each has options.step.type): 2-factor(info), consent-pep(info), consent-ttny(info), customer-portrait(photo, step customer-portrait), liveness-check-v1(photo, step liveness-check-v1, optional), id-front-photo(photo, step id-front idTypes id-card), dl-front-photo(photo, step id-front idTypes driving-licence), pa-front-photo(photo, step id-front idTypes passport, recipe built-in-self-service-v2-passport), hologram(info, step hologram, optional), hologram-id-card(info, step hologram-v2 id-card, optional), id-back-photo(photo, step id-back id-card, recipe built-in-self-service-v2-id-card-back), dl-back-photo(photo, step id-back driving-licence), emrtd(info, step emrtd, optional, idTypes id-card+passport, dataGroups DG1,DG2,DG7,DG11,DG12,DG14), address-card-photo(photo, step proof-of-address), data-confirmation(info, step data-confirmation), client-gate(info, step client-gate).
    • hologram-driving-licence/hologram-passport step variants are present but commented out in the proto ("nem működik" = "does not work").

  • Scopes: creatable_by_system, listable_on_videochat, listable_on_room_profile, listable_on_selfservice_room_profile, listable_on_customer_profile, listable_on_flow_list, ordered_task_completion, allow_ordered_task_backsteps, allow_unordered_task_reopen, task_skipping_enabled.
  • Results: success→finished, failed→aborted.

5.7 self-service-v2-phase-2Self-Service V2 operator review/decision

  • Purpose: operator review of the V2 capture, mirroring phase-1’s steps as info tasks; same AML reason-code result set as V1 phase-2. Editable on the flow profile.
  • Definition: …/self-service-v2-phase-2.flow.proto.js — version 6, 15 tasks.
  • Tasks (all info), one per phase-1 step: 2-factor, consent-pep, consent-ttny, customer-portrait, liveness-check, id-front-photo, dl-front-photo, pa-front-photo, hologram, id-back-photo, dl-back-photo, emrtd, address-card-photo, data-confirmation, client-gate.
  • Scopes: creatable_by_system, listable_on_videochat, listable_on_room_profile, listable_on_selfservice_room_profile, listable_on_customer_profile, listable_on_flow_list, editable_on_flow_profile.
  • Results: identical to §5.5 — success→finished plus the same 14 aborted reason codes (incl. expired_unattended userSelectable:false).

5.8 customer-data-change-test — customer data-change (no tasks)

  • Purpose: a 0-task flow that exists to edit customer data on the flow profile (a record/approval wrapper rather than a step sequence). Created on the customer profile.
  • Definition: …/customer-data-change-test.flow.proto.js — version 2, taskCount:0, tasks:[]. Handler is an empty extends FlowHandler.
  • Scopes: creatable_on_customer_profile, listable_on_customer_profile, editable_on_flow_profile, editable_customer_data_on_flow_profile.
  • Results: success→finished only.

5.9 Automated-test flows (automated-test-1-6) — engine test fixtures

These exercise specific engine features (task types, scopes) and back the Playwright/unit suites; not customer-facing products. All: success→finished, failed→aborted (test-3/test-4 same).

Flowver / tasksTasks (type)Notable scopes / feature under test
automated-test-11 / 6video_quality_control,consent_to_recording,consent_to_cdd,screenshots_control,ttny_pep,girinfo_control (all confirm)task_start_require_action (idle→pending on start)
automated-test-21 / 4trigger_videochat:customerData:update,test_task_1..3 (confirm)ordered_task_completion, allow_ordered_task_backsteps
automated-test-31 / 3info-task(info), upload-task(upload, pdf), search-task(search)resetable, task_skipping_enabled, editable_customer_data_on_flow_profile; types upload/search
automated-test-41 / 2test-prompt(prompt), test-select(select, options ['1','2'])prompt + select task types
automated-test-53 / 4upload(upload, pdf), sign-ltv(info), timestamp(info), delete(info)upload + eSign/LTV/timestamp sequence
automated-test-61 / 4identical to automated-test-5(not in config/dev.json flows list)

6. Self-Service V2 orchestration (SelfServiceV2Service)

server/service/SelfServiceV2Service.js (~2411 lines) extends SelfServiceRoomService and is the runtime driver of the Self-Service V2 product flow. It treats the self-service-v2-phase-1 flow’s tasks as customer-facing steps: each task’s options.step object ({type, required?, idTypes?, dataGroups?, …}) is the step. getStepsForCustomer (SelfServiceV2Service.js:159-173) maps flow.tasks → step objects; getCurrentStep (:175-198) returns the current step from the pending task and checks task.name === selfServiceRoom.serviceProgress; getNextStepName/advanceSelfServiceProgress walk the ordered tasks (preparation → step[0] … → wrapup).

The phase-1/phase-2 flow names are not hardcoded in the service — they come from hooks resolved at runtime:

  • getFirstPhaseFlowName()callOnlyHook('self-service:v2:get-first-phase-flow-name') → returns 'self-service-v2-phase-1' (provided by customization/listeners/self-service-v2.js:12-14).
  • getSecondPhaseFlowName() → hook self-service:v2:get-second-phase-flow-name'self-service-v2-phase-2' (self-service-v2.js:16-18).

Room lifecycle hooks (in customization/listeners/self-service-v2.js): self-service:v2:create creates a SelfServiceRoom (serviceProgress:'preparation'), records a config-state activity (generate-config-state hook → faceComparison + hologram settings), emits self-service:v2:created (→ flow created via the phase-1 handler hook), then FlowService.startFlow(...). The service’s start/finish/abort/fail/expire map to flow startFlow/finishFlow/abortFlow; FINAL_STEPS = ['finished','aborted','failed','expired'] (SelfServiceV2Service.js:19-23).

Per-step handlers in the service (verified method names): verifySmsToken (2-factor), handleConsentResult (consent-pep/ttny), photoCandidate/photoFinalize (portrait & doc photos), handleLivenessCheck/getLivenessType (liveness), handleHologram/hologramScreenshot/getHologramClientSettings (hologram), emrtdInfo/handleEmrtdCustomerPortrait/getBacHash/getDataGroups (eMRTD NFC), getMrzRecognitionAttempts/getIdType (ID), dataConfirmationChange/dataConfirmationAccept (data-confirmation), getClientGateURL/clientGateDemoLogin (client-gate), plus CV plumbing (mergeRecognitions, handleActionTask, handleDocumentTask, handleSpeechTask) talking to vuer_cv via VuerCVSession. Customer transport is over RPC rpc-selfservice-v2 (server/queue/rpc_server/SelfServiceV2.js) + queue server/queue/queue_server/SelfServiceV2.js, with vuer_css as the CSS-side client (server/queue/queue_client/SelfServiceV2Css.js).

CV recognition recipes referenced by self-service tasks (built-in-face-detection, built-in-id-card-front, built-in-self-service-v2-passport, built-in-self-service-v2-id-card-back, built-in-driving-licence-back, build-in-address-card) are CV instruction bundles under customization/cv/instructions/… and orchestrated by server/cv/. See vuer_cv.


7. Config knobs (docs/config/schemas/flow.schema.json)

config.flow:

  • flows: string[]which flow definitions to register (the catalog gate).
  • autoClear.schedule: string — cron for auto-clearing flows.
  • settings.preventTaskDataUpdateWhenFinished (bool), restrictUpdateToCreator, restrictUpdateToStarter, displayRelatedDocuments.{fromCustomer,fromParentFlow,fromRoom,fromTaskUpload}, search.{startedBy,finishedBy}.
  • (Observed in config/dev.json but not in the schema head: settings.copyTaskTextToChat.)
  • Flow Editor is separately gated by config.features.flowEditor (checked throughout FlowService).

Unverified / gaps

  • FlowService.js (3217 lines): read the constructor, registration, full lifecycle method list, and the bodies of startFlow/finishFlow + the lifecycle-signal switches; did not read every line of the Flow-Editor CRUD bodies (updateFlowTask/updateFlowResult internals) — their purpose is summarized from method shape + activity-log fields.
  • SelfServiceV2Service.js (2411 lines): read the head, helpers, step-resolution and the full method list; did not read every per-step handler body (e.g. mergeRecognitions, hologramScreenshot internals).
  • Flow handler .handler.js bodies: read full for self-service-v2-phase-1, esign-registration (head), customer-data-change-test (full); did not read the other handlers’ bodies (online-verification, self-service-phase-1/2, automated-test-*). Their proto definitions were read in full.
  • .flow.trans.js files: not read (i18n strings only).
  • Exact getPossibleActions/getResult logic per flow is handler-specific and not exhaustively read.
  • Whether each partner customization/<branch> overrides this catalog: out of scope here — see customization-branch-catalog.

Sources

Read via git show devel:<path> / git ls-tree devel:

  • Engine: server/flow/FlowService.js, server/flow/FlowHandler.js, server/flow/FlowScopeMap.js, server/flow/FlowResultOptions.js; git ls-tree devel:server/flow.
  • Models: server/db/model/flow.js, flowproto.js, task.js, taskproto.js, flowresult.js, flowscope.js, flowactivity.js; git ls-tree devel:server/db/model.
  • Flow definitions (proto, full): customization/flow/{esign-registration,self-service-phase-1,self-service-phase-2,self-service-v2-phase-1,self-service-v2-phase-2,online-verification-phase-1,online-verification-phase-2,customer-data-change-test,automated-test-1,automated-test-2,automated-test-3,automated-test-4,automated-test-5,automated-test-6}/*.flow.proto.js.
  • Handlers: customization/flow/self-service-v2-phase-1/*.flow.handler.js (full), customization/flow/esign-registration/*.flow.handler.js (head), customization/flow/customer-data-change-test/*.flow.handler.js (full).
  • Orchestration: server/service/SelfServiceV2Service.js (head + method list), customization/listeners/self-service-v2.js (head), server/service/FlowFilterService.js (head), server/service/FlowLiveUpdateService.js (head).
  • Wiring: server.js (FlowService instantiation :174, flow RPCs :399-422), background.js (:45,:88), customization/customization.js:208, customization/background-customization.js:73, bin/flow-editor.js (head), server/socket/events/flow.js (head), server/queue/rpc_server/FlowAutoClearRPCServer.js.
  • Config: docs/config/schemas/flow.schema.json, config/dev.json (flow block :68-103).
  • git ls-tree -r devel filtered for *.flow.handler.js, customization/flow/*, self-service-v2*.