Commit1d3847ddeleted the entire tree (2584 files) and added nothing, so main was empty. This restores main todc43a6a(the PR 22 merge) exactly. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
5.5 KiB
Claude native handoff: Echo setup named possible values
Source-verified contract (core qqq-wt-native-provider-logout)
- operationId
searchProcessPossibleValues:POST /qqq/v1/processes/{processName}/possibleValues/{fieldName}(UiApiOperationIds,ProcessPossibleValuesSpecV1, openapi.yaml ~12440). Server advertises featurepossibleValuesonGET /version. - Request:
application/json{ "values": {other form values}, "processValues": {...}, "useCase": "form", "searchTerm"?, "ids"? }(PossibleValuesSpecUtils). Not multipart. Same session cookie,X-QQQ-Clientand device headers as other native calls (shared Retrofit client). - Response
PossibleValuesResponseV1:{ "options": [{ "id", "label", ... }], "hasMore"? };optionsis omitted when empty. - Field metadata (FieldMetaData v1):
possibleValueSourceName, and for contingent fieldspossibleValueSourceDependsOn: [names]andpossibleValueSourceDependencyBehavior: DISABLE_UNTIL_SET | SHOW_ALL_UNTIL_SET(docs/CONTINGENT-POSSIBLE-VALUES.md). - Frontend rules (same doc): re-query when a dependency changes, clear a selection that no longer fits (transitively), disable with a hint until dependencies are set (default), ignore stale responses.
A previous revision of this work invented the multipart shape from memory; it has been replaced entirely by the above. The route path happened to match; the body did not.
Root cause (unchanged, source inference)
Echo setup declares printerId/mediaId with named PVS (media dependsOn printerId); fixture uses ENUM PVS. The client rendered only inline choices, so Printer became a free-text "Printer *" field and submission was blocked as unsupported. That init is a synchronous COMPLETE (not ASYNC) is inferred from sources and the operations log; the native E2E remains the authority. The fixture is NOT changed to inline choices.
Implementation
- core:
QQQApiService.processPossibleValues;QQQRepository.processPossibleValues(process, field, values, processValues)(default throws Unsupported so other fakes compile);NetworkQQQRepositorybuilds the JSON body and decodes options (scalar ids kept);QFieldMetaDatagainspossibleValueSourceDependsOn/possibleValueSourceDependencyBehavior. - mobileapp
ProcessViewModel:loadRemoteOptions,remoteOptionsBlockedReason(DISABLE_UNTIL_SET -> "Choose Printer first." and no request),fieldChanged(dependents drop selection immediately, transitively, and re-query), per-field generation token so only the newest request publishes (a late reply for an old parent cannot restore options or a selection), post-load prune of a choice no longer offered,fieldResetsso the control follows a VM-cleared value. Load failures are shown with "Retry choices", cancel the superseded job, never set client-work, so Cancel/Leave stay available.reset()clears all of it. ProcessComponentEditForm: select for named PVS (label text unchanged: "Printer", "Paper or label size", button "Choose a value"), disabled with a hint while blocked.SemanticProcess.unsupportedaccepts named PVS in EDIT_FORM only (widget INPUT_FIELD remains unsupported).- E2E test: literal
waitFor("Printer")unchanged (diagnostic text dump retained on timeout); added a readiness wait for the enabled media control before clicking it, since media is contingent. No assertion weakened. - docs/UI-API.md updated.
Tests added/updated
NetworkQQQRepositoryTest.processPossibleValuesUsesThePublishedJsonOperation: method/path/JSON body/use case, response with options, and the omitted-optionsempty response.ProcessSubmissionTest.namedPossibleValueSourcesLoadWithDependentValuesAndReportFailures: blocked dependent not searched; parent value sent; dependent selection cleared on parent change; late old-parent reply ignored; failure reported, no client-work block, retry succeeds.SemanticProcessTest: named PVS in EDIT_FORM supported; UNKNOWN type and widget PVS still unsupported. Note: server response bodies in tests are minimal shapes taken fromPossibleValuesResponseV1/ProcessPossibleValuesSpecV1Test(options[].id/label), not captured from a live server.
Commands for root (Java 21, wrapper)
./gradlew :qqq:android:core:testDebugUnitTest :qqq:android:mobileapp:testDebugUnitTest :scanner-host:testDebugUnitTest :scanner-host:lintDebug :scanner-host:assembleE2e :scanner-host:assembleE2eAndroidTest
node --test scripts/ci/scanner-echo-guards.test.mjs
Then re-approve rebuilt APK hashes and run the root native Echo helper.
Known gaps / risks
- Nothing compiled or run (no shell). Expect possible small compile fixes (Compose state/
mutableIntStateOfdelegate, imports). possibleValuesis not added to the client's REQUIRED_FEATURES (all existing fixtures advertise only six features); a server lacking it fails the search with a visible error + Retry rather than at startup.- Pre-existing and untested: decoding inline
inlinePossibleValueSourceids typedjava.io.Serializablevia kotlinx. - Whether the real Echo metadata publishes
possibleValueSourceDependsOnfor media is inferred fromwithPossibleValueSourceDependsOn(List.of("printerId"))in the producer; unverified against a live/metaData/process/echoPrintresponse. - Untracked
native.mdat the repo root is an obsolete earlier handoff (a pointer to this file); delete it.
Coordinator verification:169JVMtests pass; lint0errors/0warnings; E2EAPKs assemble; all8guards/sourcegate236pass. RealTC22 Echo native scenario completes all5stages with86/86documented semanticrequests,2accepted synthetic scans andsuccessfulcleanup. Printing remains simulated.