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-2flow definitions (customization/flow/self-service-v2-phase-*/) plus theSelfServiceV2Serviceorchestrator (server/service/SelfServiceV2Service.js). Thecustomization/*here is the per-partner override tree inside the repo, loaded at boot — not a branch name. (Branches are partner builds likecustomization/instacash; see customization-branch-catalog.)
Verified against the
develbranch viagit 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):
| File | Role |
|---|---|
server/flow/FlowService.js | The 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.js | Base 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.js | The 23 boolean scope flags (capabilities/behaviour toggles) a flow can enable. |
server/flow/FlowResultOptions.js | Maps flow statuses → allowed resultCodes; validates result-for-status. |
server/flow/Flow.trans.js | Default i18n keys for flow/task labels (loaded before each flow’s own .trans.js). |
server/flow/FlowEditor.trans.js | Flow-Editor UI translations. |
Supporting services (server/service/):
FlowFilterService.js— ACL-aware list filtering (flows.list.any/other/ownpermissions;_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→ RPCrpc-flow-documents(server.js:406-412).server/queue/rpc_server/FlowAutoClearRPCServer.js→ RPCflow-autoclear, actionflowAutoClear(server.js:421-422; callsFlowService.flowAutoClear()).server/queue/rpc_server/SelfServiceV2.js→ RPCrpc-selfservice-v2(server.js:399).server/socket/events/flow.js— operator socket events (flow:create, …) gated byauth.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 handlersdry, 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.):
| Scope | Meaning (verbatim intent from source) |
|---|---|
creatable_by_system | flow may be created with no creator user (system-initiated) |
creatable_on_videochat / listable_on_videochat / editable_on_videochat | create / list / edit on the videochat screen |
listable_on_room_profile | list on room profile |
listable_on_selfservice_room_profile | list on self-service room profile |
listable_on_customer_profile / creatable_on_customer_profile | list / create on customer profile |
listable_on_flow_list | appears in the global flow list |
editable_on_flow_profile | editable on the flow profile page |
editable_customer_data_on_flow_profile | allow editing customer data while flow is in-progress |
task_skipping_enabled | tasks may be skipped |
allow_task_updates_when_on_hold / allow_task_updates_when_created / allow_task_updates_when_done | permit task updates in those flow/task states |
hold_action_disabled / abort_action_disabled / finish_action_disabled | hide/disable those actions for the user |
resetable | flow may be reset |
task_start_require_action | task → pending only when the customer starts it (else idle) |
ordered_task_completion | tasks must be completed in order |
allow_unordered_task_reopen | reopen tasks out of order |
allow_ordered_task_backsteps | step 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 classextends FlowHandlerthat 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
- Registration (proto → DB), once per boot.
customization/customization.js:208callsserviceContainer.service.flow.registerFlowHandlers()(after requiring./flow/flowStatProviders).FlowServiceconstructor (FlowService.js:20-29) iteratesconfig.flow.flowsandrequire()s eachcustomization/flow/<type>/<type>.flow.handler.registerFlowHandlersnews up each handler and callshandler.register()(FlowHandler.register,FlowHandler.js): if a FlowProto with thatname+versiondoesn’t exist, it generates FlowProto + TaskProtos + FlowScopes + FlowResults + FlowTranslations in a transaction. Bumping a proto’sversioncreates a new published proto; old instances keep their old version.background.js:88andbin/flow-editor.jsregister withdry = true(no DB writes).FlowServiceis instantiated in bothserver.js:174andbackground.js:88. - Instantiation (per customer/room).
FlowHandlerregisters a hookflow:<name>:create(FlowHandler.js:21-23) →_createFlow(customerId, roomId, userId, parentFlowId, selfServiceRoomId). It loads the latest published protowithTasks, builds aFlow+ itsTaskrows in a transaction, applies scope-driven initial task statuses (ordered_task_completion/task_start_require_action→ first taskpending, restidle), runsonBeforeCreate*/onCreatedhooks, writes aflow:createactivity, and emitsflow:status:updated. Public entry:FlowService.createFlow(...)(and the operator socketflow:createinserver/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 method | Effect | Handler hooks fired |
|---|---|---|
startFlow(flowId,userId,roomId,options,selfServiceRoomId) | created/on-hold → in-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-hold | onBeforeHalt/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() → collectClearableFlows → clearFlows (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.flowsis branch-specific. The 13-flow list above isconfig/dev.jsonondevel. Partner/customization branches replace it wholesale: e.g. on the working-tree branchupdate/customization/instacash-2026-05-27,config/dev.json:107-127instead lists 19ic-*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 inconfig/dev.json'sflowslist, so it is not registered in that config. Its proto is identical toautomated-test-5. The full 13+1 = 14 named set (the 13 above plusautomated-test-6) is the list registered by the test configtest/testconfigs/test-config.json:54-69ondevel(there is noconfig/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_controlGIRINFO 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) ononProgressdrives the eSign integration (esign_oss) and aborts the flow onvideochat: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:
onProgresswarns and no-ops ifconfig.esign.activeis 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, declaredtaskCount:4(proto lists 7 photo tasks; an 8thid-recaptchais 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 hasoptions.screenshotCategory,camChangeOptions.facingMode,photoInstructions.{validationType,overlayType}, andrecognitionOptions(recipe e.g.built-in-face-detection,built-in-id-card-front, MRZhu-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 oneuserSelectable:false— set by the system on expiry).
5.6 self-service-v2-phase-1 — Self-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). Seedocs/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— classSelfServiceV2PhaseOne extends FlowHandler. Hooks:self-service:v2:created→creates the flow;self-service:v2:aborted|failed|expired→abortFlowForRoom.onProgress→advanceSelfServiceProgress.onBeforeCreateTasksprunes tasks per device/SDK capability (drops steps unsupported by the customer’s browser/mobile SDK viataskCompatibility+CustomerEnvData.supportedSteps) and renumbersorder. - Tasks (16; each has
options.step.type):2-factor(info),consent-pep(info),consent-ttny(info),customer-portrait(photo, stepcustomer-portrait),liveness-check-v1(photo, stepliveness-check-v1, optional),id-front-photo(photo, stepid-frontidTypesid-card),dl-front-photo(photo, stepid-frontidTypesdriving-licence),pa-front-photo(photo, stepid-frontidTypespassport, recipebuilt-in-self-service-v2-passport),hologram(info, stephologram, optional),hologram-id-card(info, stephologram-v2id-card, optional),id-back-photo(photo, stepid-backid-card, recipebuilt-in-self-service-v2-id-card-back),dl-back-photo(photo, stepid-backdriving-licence),emrtd(info, stepemrtd, optional, idTypes id-card+passport, dataGroupsDG1,DG2,DG7,DG11,DG12,DG14),address-card-photo(photo, stepproof-of-address),data-confirmation(info, stepdata-confirmation),client-gate(info, stepclient-gate).-
hologram-driving-licence/hologram-passportstep 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-2 — Self-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_unattendeduserSelectable: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 emptyextends 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).
| Flow | ver / tasks | Tasks (type) | Notable scopes / feature under test |
|---|---|---|---|
automated-test-1 | 1 / 6 | video_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-2 | 1 / 4 | trigger_videochat:customerData:update,test_task_1..3 (confirm) | ordered_task_completion, allow_ordered_task_backsteps |
automated-test-3 | 1 / 3 | info-task(info), upload-task(upload, pdf), search-task(search) | resetable, task_skipping_enabled, editable_customer_data_on_flow_profile; types upload/search |
automated-test-4 | 1 / 2 | test-prompt(prompt), test-select(select, options ['1','2']) | prompt + select task types |
automated-test-5 | 3 / 4 | upload(upload, pdf), sign-ltv(info), timestamp(info), delete(info) | upload + eSign/LTV/timestamp sequence |
automated-test-6 | 1 / 4 | identical 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 bycustomization/listeners/self-service-v2.js:12-14).getSecondPhaseFlowName()→ hookself-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 undercustomization/cv/instructions/…and orchestrated byserver/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.jsonbut not in the schema head:settings.copyTaskTextToChat.) - Flow Editor is separately gated by
config.features.flowEditor(checked throughoutFlowService).
Unverified / gaps
FlowService.js(3217 lines): read the constructor, registration, full lifecycle method list, and the bodies ofstartFlow/finishFlow+ the lifecycle-signal switches; did not read every line of the Flow-Editor CRUD bodies (updateFlowTask/updateFlowResultinternals) — 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,hologramScreenshotinternals).- Flow handler
.handler.jsbodies: read full forself-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.jsfiles: not read (i18n strings only).- Exact
getPossibleActions/getResultlogic 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(flowblock:68-103). git ls-tree -r develfiltered for*.flow.handler.js,customization/flow/*,self-service-v2*.