Is

1POST /test/ HTTP/1.1 

actually a part of the request body?

If so, it's invalid json and you need to remove it from request body. What does

do httpRequest.EntityBody.OutputToDevice()

shows right before  sending the request?

Other thought, iin property should be passed as string, not as number. To do that:

1. Create a class

Class MyApp.Request Extends %RegisteredObject {

Property iin As %String;

... other properties ...

}

2. After that instead of %ZEN.proxyObject use this object as a request body.

Note that %ZEN.Auxiliary.jsonProvider:%WriteJSONStreamFromObject method has a pFormat argument, which defaults to aceloqtw in %ObjectToJSON method. One of the flags, q  means  output numeric values unquoted even when they come from a non-numeric property and you don't need that.

So your code should look something like this:

Set Object = ##class(MyApp.Request).%New()
Set Object.iin="123132132"
Set Object.firstName=name
Set Object.lastName=surname
Set Object.middleName=middlename
Set Object.birthDate=birthDate
Set Object.contractType="Z001"
Set sc = ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(httpRequest.EntityBody, Object, , , , "aelotw")
Set sc = httpRequest.Post("", 2)

Minor note, you don't need this line, remove it (it may be causing your error):

set sc = ##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(Object)

"Corrupt body: json: cannot unmarshal number into Go struct field CheckContractRequest.iin of type string". 

Where you get this error? This looks like an error you get from the server you send your request to.

Can you get output from

Set sc = httpRequest.Post("", 1) 

Set sc = httpRequest.Post("", 2)

And post it here.

I believe it's enough to have [Final] keyword set in deployed mode to give a developer a hint that this class should not be extended.

Well, it's mainly for developers who can't take a hint.

If you want to enforce this behaviour, I would add a check into each method as a first line , something like

if $this.%ClassName(1)'="My.Class" quit $$$ERROR(50000,"don't extend this class")

Good idea.

You can also try to add a method-generator, I believe when you have a deployed class with method generator it will not be able to compile a subclass without method generator's source (though I'm not sure).

At first it didn't work - method generator by default works while deployed. Then I added a class check to generator.  Compilation was now failing, but other methods were actually compiled so I was able to call them. Finally I worked out this solution:

Class Package.Final [ Final ]
{

ClassMethod ANoExtend() [ CodeMode = objectgenerator, Final, ForceGenerate, Private ]
{
    quit:%class.Name="Package.Final" $$$OK
    quit $$$ERROR($$$GeneralError, "No extending")
}

ClassMethod ProtectedMethod() As %Status [ Private, ForceGenerate, GenerateAfter = ANoExtend ]
{
        // code
    quit $$$OK
}
}

This way each protected method should be recompiled but only after method-generator which always fails in subclasses. This way no code gets generated.

Username would be _Ensemble because Ensemble switches users.

Tried OnInit, available context is not enough there:

Method OnInit() As %Status
{
    break
}

And here's the break:

break
 ^
<BREAK>zOnInit+1^Demo.Workflow.WFMetric.1
ENSDEMO 7e1>zw
 
%Ensemble("ArchiveFlags")=""
%Ensemble("ArchiveFlags","Demo.Workflow.WFMetric")=""
%Ensemble("ArchiveFlags","Demo.Workflow.WFMetric","iCfg")=0
%Ensemble("Config","%ModIndexFlag")=1
%Ensemble("ConfigName")="Demo.Workflow.WFMetric"
%Ensemble("Debug","TraceCat","My Terminal Output")=0
%Ensemble("Debug","TraceCat","My Terminal Output","user")=1
%Ensemble("Debug","TraceCat","user")=1
%Ensemble("DoTrace")=2
%Ensemble("JobKey")=10548
%Ensemble("LogSystemTrace")=0
<Private variables>

Thought about $zparent but it didn't help too:

ENSDEMO 7e1>w $system.Process.UserName($zparent)
CSP Gateway

You can to change default file I/O from GB18030 to UTF8.

To do that, execute do ^NLS and choose:

2) Select defaults
2) I/O tables
4) File

And choose UTF8 there. After that, your I/O table should look like that:

I/O table              Current default
---------------------  --------------------
....
4) File                UTF8 (*)

After that, restart Cache and delete/reimport faulty files in Atelier

Note that this action (changing NLS defaults) can be disruptive to existing Cache applications.

If you're sure that your id bigger ids are generated later, you can only get the first id from index and after that iterate the data global directly:

set FromDateH = (+$h-1)
set id = ^TestI("StartDateIDX",FromDateH,id)
for {
    set id=$order(^TestD(id),1,dat)
    quit:id=""
    //dat=$lb("a","b","c","d","e")
}

Also you can use three-argument form of $order to iterate and get data in one command.

Finally, consider checking work-heavy system with %SYS.MONLBL to verify what lines consume more  time.