Skip to content

feat(TE-22637): add threshold flags to upload-pdf - #562

Open
shrinishLT wants to merge 4 commits into
LambdaTest:stagefrom
shrinishLT:TE-22637
Open

feat(TE-22637): add threshold flags to upload-pdf#562
shrinishLT wants to merge 4 commits into
LambdaTest:stagefrom
shrinishLT:TE-22637

Conversation

@shrinishLT

@shrinishLT shrinishLT commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

What

upload-pdf gains threshold support with one way in per level:

Level How
build-level (every PDF in the upload) --approvalThreshold <n> / --rejectionThreshold <n>, or the config file
per-PDF the config file only — pdf.thresholds, keyed by resolved PDF name
smartui upload-pdf ./invoices --buildName release-42 --config config.json
{
  "web": { "browsers": ["chrome"], "viewports": [[1920, 1080]] },
  "approvalThreshold": 2,
  "rejectionThreshold": 5,
  "pdf": {
    "approvalThreshold": 1,
    "thresholds": { "invoice.pdf": { "approval": 0, "rejection": 4 } }
  }
}

upload-pdf now accepts -c --config and reads the same config.json exec uses: the existing top-level approvalThreshold/rejectionThreshold apply to PDFs too; the pdf block is new and optional. One file serves web and PDF, which is the shape a Jenkins pipeline with one mixed PDF directory needs.

Resolution — client-side, per file, like the web path

The CLI resolves one final {approval, rejection} per uploaded PDF — pdf.thresholds[name], else the build-level value (flagpdf.* → top-level) — and posts only the complete thresholds map. That mirrors snapshotQueue.ts resolving per snapshot; there is one precedence rule, in one place (src/lib/pdfThresholds.ts). ?? throughout, so an explicit 0 is sent, never dropped. The raw per-call form fields stay on the endpoint for API/SDK callers; the CLI doesn't send them.

Fails before any file is uploaded when a pdf.thresholds key matches no uploaded file (or --pdfNames name), or a flag isn't numeric; the server still validates range, band (rejection > 0 && approval > rejection), and use_default_thresholds as the last line.

Compatibility — strictly additive

pdf joins the schema's anyOf so a PDF-only config is valid for upload-pdf; every other command keeps the "web or mobile required" rule in ctxInit, so an existing file behaves identically for exec. Unknown keys inside pdf are rejected. Verified against the built CLI: web-only, web+thresholds, web+pdf and pdf-only files on both commands; typo and out-of-range values fail with the schema messages.

Behaviour when nothing is set

Unchanged: no flags, no pdf block, no top-level thresholds → nothing new is sent → project settings apply, exactly as today.

Verified on the pdf-thresholds dev env (2026-09-09, 02:21–02:34 IST)

dev-tests/TE-22637/run.sh, DB-verified, against smartui-rendering-service#1264 + dotlapse-event-service#2913:

Case Result
legacy (platform='pdf') and Omni projects, config above rows invoice 0/4, contract 3/5, report 1/5 on both tables — explicit 0 preserved
nothing set rows NULL/NULL
unknown name in pdf.thresholds fails before upload, names it; no build created
--approvalThreshold 6 --rejectionThreshold 5 rejected, inverted band
--approvalThreshold 5 --rejectionThreshold 0 accepted (rejection=0 = never auto-reject)
--approvalThreshold 101 rejected, field named
two uploads, same --buildName, different groups via --pdfNames one build, a1–3 @2/5 and c1–3 @7/9
same names re-uploaded to a build 400 naming the files; build survives

Not in this PR

  • exitOnError: false on this task means a server 400 prints red and exits 0 — same as exec/upload; deliberately unchanged (RFC §7.4).
  • tsc --noEmit fails on the untouched tsconfig.json (TS5110) — pre-existing; tsup is the build and passes.

Server: LambdatestIncPrivate/smartui-rendering-service#1264 · DES: LambdatestIncPrivate/dotlapse-event-service#2913 · RFC: LambdatestIncPrivate/internal-docs#2963 · Ticket: TE-22637

🤖 Generated with Claude Code

https://claude.ai/code/session_01QbnKfTzhr64osinPevTmVG

--approvalThreshold and --rejectionThreshold apply to every pdf in the
upload; --thresholds takes inline JSON or a path to a JSON file with
per-pdf overrides keyed by name, e.g.
{"invoice.pdf":{"approval":2,"rejection":5}}.

Values are forwarded as strings and left to the backend to validate
(range, band, unmatched names, use_default_thresholds), so the CLI
surfaces the server's message rather than a second copy of the rules.
A run with none of the flags sends nothing new.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbnKfTzhr64osinPevTmVG

@sushobhit-lt sushobhit-lt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good news first: this does not repeat the --sync no-op from #558. I traced every read site back to the ctxInit whitelist in src/lib/ctx.ts:292-294 and the keys match exactly; field names, types and the 0-100 range agree with the server parser in smartui-rendering-service#1264, and an explicit 0 survives end to end.

The risk here is error handling rather than wiring — three comments below.

Comment thread src/tasks/uploadPdfs.ts Outdated
Comment thread src/tasks/uploadPdfs.ts Outdated
Comment thread src/lib/httpClient.ts Outdated
shrinishLT and others added 3 commits September 8, 2026 17:17
upload-pdf now accepts --config and reads thresholds from the same file
exec uses, so one config.json serves web and PDF. Top-level
approvalThreshold/rejectionThreshold apply to both; a new optional `pdf`
block carries PDF-specific defaults and a per-file `thresholds` map keyed
by resolved PDF name. Precedence for a PDF: CLI flag, then pdf block,
then top-level config, then the project setting; the per-file map is
taken whole from the first source that sets it.

Strictly additive. `pdf` joins the schema's anyOf so a PDF-only file is
valid for upload-pdf, and ctxInit keeps every other command on the old
rule (web or mobile required) so exec behaves exactly as before. Unknown
keys inside `pdf` are still rejected. Values are carried as strings via
a helper that treats a numeric 0 as set, so an explicit 0 reaches the
backend rather than being dropped.

Verified against the built CLI: web-only, web+thresholds and web+pdf
files authenticate on both commands; pdf-only authenticates on
upload-pdf and is rejected by exec with the existing message; a typo
inside pdf and an out-of-range value fail with the schema messages.

The shared rejection<=approval check in ctxInit now also runs for PDF
configs; that rule is under review separately (LambdaTest#6 on the RFC).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbnKfTzhr64osinPevTmVG
…b path does

The CLI now resolves one final {approval, rejection} per uploaded pdf -
per-file entry, else the build-level value (flag > pdf block > top-level
config) - and posts only the complete `thresholds` map. The raw
approvalThreshold/rejectionThreshold form fields are no longer sent by
the CLI; they remain on the endpoint for raw-API callers.

Mirrors snapshotQueue's per-snapshot resolution so there is one
precedence rule, tested in one place, and every file the backend sees
carries an explicit value. Uses ?? throughout so an explicit 0 is sent.

Also fails fast, before any file goes over the wire: a --thresholds
value that is not inline JSON is treated as a path and must exist; the
JSON must parse to an object; names in the map must match the uploaded
(or --pdfNames) names; a non-numeric flag is rejected. Server-side
validation still runs as the last line.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbnKfTzhr64osinPevTmVG
…e config file only

Two ways to give the same per-pdf map (a flag taking inline JSON or a
path, and the config file's pdf.thresholds block) was one too many and
invited questions about which wins and whether the flag carried
build-level values too. One way in per level now:

  build-level  --approvalThreshold / --rejectionThreshold, or config.json
  per-pdf      config.json  pdf.thresholds  (only)

The resolver is unchanged: per-pdf entry, else build-level (flag > pdf
block > top-level), else the project setting; names in pdf.thresholds
that match no uploaded file still fail before anything is uploaded.
Removes the file/inline parser that only served the flag.

Verified on pdf-thresholds: legacy and Omni rows carry the resolved
values, an unknown name in pdf.thresholds fails fast with no build,
rejection=0 accepted, two uploads into one build keep their own groups.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbnKfTzhr64osinPevTmVG
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants