SAIF.Services.Appworx architecture¶
SAIF.Services.Appworx is a small, single-purpose integration/service library. Despite the SAIF.Services.* naming it is not a hosted service — it is a thin client-side adapter, compiled directly into the LegalMaintenance web application, that translates a "run this batch job" intent into the Appworx enterprise scheduler's Oracle submission contract (the submit_appworx_job stored procedure).
Responsibilities¶
- Translate a "run this batch job with these arguments" intent into the Appworx scheduler's Oracle submission contract (
submit_appworx_job), normalizing argument handling (fixed 20 positional slots, empty-slot suppression, defaults for requestor and printer). - Provide a stateful instance API (
clsRequestAppworxJob) and a stateless shared convenience overload (SubmitBatchJob) that constructs a fresh instance per call. - Reset argument state between submissions (
InitArgs) so a reused instance cannot leak arguments from a previous job. - Optionally redirect submissions to a fixed, hard-coded Appworx-hosting Oracle database/schema (
PRADTonWCISPROD/WCISDEV1) instead of the caller's own data portal, via theinUseWCISDEV1AppworxForAllDevEnvflag.
Component boundaries¶
clsRequestAppworxJob(class,SAIF.Services.Appworx/clsRequestAppworxJob.vb) is the sole hand-written type in the library. It has no base class, implements no interfaces, and takes no part in the BOFOnRetrieve/OnSavebusiness-object lifecycle — it uses the BOF data portal purely as a command channel*.- Instance API: constructor,
DPI,ModuleName,Requestor,Printer,Arg1–Arg20properties,SubmitBatchJob(instance),InitArgs. - Shared convenience overload:
SubmitBatchJob(Shared) — the form actually used by all in-repo callers — which optionally redirects the data portal, constructs the instance, maps only non-Nothingarguments, and submits. - No
IBusinessCriteriaimplementations or nestedCriteriatypes exist; the library performs no application-layer SQL beyond the single stored-procedure call. - The library is a leaf/foundation project with no outbound
<ProjectReference>elements — all collaborators (IDataPortalInfo,clsSmartString,clsMSOracleDataLayer,AppGlobal) come from external SAIF framework packages, not from repo projects.
Interaction model¶
- Application/business → scheduler: application managers in
SAIF.Application.Claim.Legal(clsCreateFileManager,clsMailDateManager,clsRequestManager) call the sharedSubmitBatchJoboverload; from that point the work is asynchronous and out-of-process — the library returns as soon as the job row is accepted and has no visibility into scheduler execution, success, or output. - Library → database: all traffic goes through the BOF data portal (
IDataPortalInfo.ProcessPortalRequest) rather than raw ADO.NET, so connection management, credentials, and provider selection are the framework's concern. - Deliberate escape hatch: the shared overload can bypass the caller's data portal entirely and construct its own
clsMSOracleDataLayer("PRADT", "WCISPROD" | "WCISDEV1"), hard-coding a schema/owner and two database aliases directly into the library rather than relying on configuration. - Statefulness: the instance API is mutable and reusable (
InitArgsallows resetting between submissions), but the shared overload creates a fresh instance per call, so the class is used statelessly by this repository's code. - Error posture: the only failure handling is a
Try/CatcharoundProcessPortalRequestthat rethrows a wrappedApplicationException; there is no logging, retry, or compensating action inside this library.
Architecture diagram¶
The following diagram shows the high-level flow from an application-layer caller through this library to the Appworx scheduler's Oracle stored procedure.
flowchart TD
A[SAIF.Application.Claim.Legal<br>clsCreateFileManager / clsMailDateManager / clsRequestManager] --> B[clsRequestAppworxJob.SubmitBatchJob<br>Shared overload]
B --> C[clsRequestAppworxJob<br>instance: ModuleName, Requestor, Printer, Arg1..Arg20]
C --> D[clsRequestAppworxJob.SubmitBatchJob<br>instance method]
D --> E[IDataPortalInfo.ProcessPortalRequest<br>BOF data portal]
E --> F[submit_appworx_job<br>Oracle stored procedure]
B -.optional redirect.-> G[clsMSOracleDataLayer<br>PRADT / WCISPROD or WCISDEV1]
G --> E
Sequence diagram¶
The following diagram shows the primary submission sequence used by all observed in-repo call sites.
sequenceDiagram
participant Caller as Application manager
participant Shared as SubmitBatchJob (Shared)
participant Instance as clsRequestAppworxJob
participant Portal as IDataPortalInfo
participant Proc as submit_appworx_job
Caller->>Shared: SubmitBatchJob(inDPI, inModule, inRequestor, args...)
Shared->>Instance: New clsRequestAppworxJob(lDPI)
Instance->>Instance: InitArgs()
Shared->>Instance: set ModuleName, Requestor, Printer, ArgN (non-Nothing only)
Shared->>Instance: SubmitBatchJob()
Instance->>Portal: ProcessPortalRequest(PortalRequest)
Portal->>Proc: execute submit_appworx_job(inModule, inrequestor, inprinter, inargN...)
Proc-->>Portal: NonQuery completion (no output)
Portal-->>Instance: result
Instance-->>Caller: returns (or rethrows wrapped ApplicationException)
Design constraints¶
- No validation exists on
ModuleName,Requestor,Printer, or argument content within this library; the receiving procedure also performs no validation**. - Parameter sizes are fixed to the scheduler's contract: module 30, requestor 32, printer 30, each argument 4000 characters.
- The submission is fire-and-forget —
RequestType = DataRequestType.NonQuery, no output parameters are registered, and the unusedvResultlocal is never assigned or read, so callers cannot correlate a submission with a scheduler job instance from this library*. - Only argument slots explicitly set (non-
Nothingon the shared overload, non-emptyclsSmartStringon the instance) are transmitted, so positional argument gaps are possible and expected (observed callers skip arg3). - The differing requestor defaults between the two entry points (
"APPWORX"on the instance field vs."Appworx"on the shared overload's optional parameter) mean the instance-field default is only observable when the class is constructed directly*. - No authorization checks are performed by this library; any caller holding a valid
IDataPortalInfocan submit any Appworx module with any arguments — enforcement is the responsibility of the calling application layer and the database account behind the data portal*.
Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.
Related documentation¶
- Index
- Overview
- Dependencies
- Operations and processes
- Business rules
- Database tables
- SQL catalog
- Procedures
- API reference
Sources¶
SAIF.Services.Appworx/SAIF.Services.Appworx.vbprojSAIF.Services.Appworx/clsRequestAppworxJob.vbSAIF.Services.Appworx/packages.configSAIF.Services.Appworx/App.configSAIF.Services.Appworx/Web.configSAIF.Business.Claim.Legal/SAIF.Business.Claim.Legal.vbprojSAIF.Application.Claim.Legal/SAIF.Application.Claim.Legal.vbprojSAIF.Application.Claim.Legal/LegalNet/clsRequestManager.vbSAIF.Application.Claim.Legal/LegalNet/clsMailDateManager.vbSAIF.Application.Claim.Legal/LegalNet/clsCreateFileManager.vb