Improve the app-passport-scan (AppPassportScanComponent) flow so that after the user chooses a file or takes a picture, the UI immediately shows the image in the MRZ crop experience (crop to MRZ lines + tilt / slider), and only then the user runs OCR via a single clear action ( Extract or Scan MRZ — same meaning; align copy).
Problem (UX)
Today the first primary button is labeled “Extract” (or “Extract + Store” / “Store Only”), but in extract modes that button does not run OCR first — it only opens the next step. That feels misleading: users think they are “extracting” when they are really just advancing to selection/crop. The real extraction happens only after crop (and related controls), often described as “Scan MRZ” in the crop UI — so the mental model is: Extract → (nothing extracted yet) → adjust → Scan MRZ.
requestScan() currently sets showCrop.set(true) for non-store modes; it is the entry to <app-mrz-crop>.
Camera capturePhoto() already sets showCrop to true for extract / extract-store (see passport-scan.component.ts — blob callback after toBlob).
File onFileSelected() only sets selectedFile and does not set showCrop — so upload still requires the user to press the primary Extract-labeled button, which is the inconsistency the ticket addresses.
Acceptance (proposed):
On file pick (valid image), if intake mode is extract or extract-store, automatically set showCrop = true (equivalent to calling the same path as requestScan() for that branch), or refactor so a single enterCropUi() is invoked from both file select and capture.
Ensure tilt / slider and crop are available before any OCR.
Unify or clarify labels: final OCR action can be “Scan MRZ” or “Extract” but not two confusing steps that both sound like “run OCR now.”
Store-only mode may stay different (no crop if product requires).
## Summary
Improve the **app-passport-scan** (`AppPassportScanComponent`) flow so that after the user **chooses a file** or **takes a picture**, the UI **immediately** shows the image in the **MRZ crop** experience (crop to MRZ lines + tilt / slider), and only **then** the user runs **OCR** via a single clear action ( **Extract** or **Scan MRZ** — same meaning; align copy).
## Problem (UX)
Today the first primary button is labeled **“Extract”** (or “Extract + Store” / “Store Only”), but **in extract modes that button does not run OCR first** — it only opens the next step. That feels misleading: users think they are “extracting” when they are really just **advancing to selection/crop**. The real extraction happens only after **crop** (and related controls), often described as **“Scan MRZ”** in the crop UI — so the mental model is: *Extract → (nothing extracted yet) → adjust → Scan MRZ*.
**Desired model:** *Choose image / capture → immediately see preview + **crop MRZ** + **tilt** → then **Extract / Scan MRZ** (OCR).*
## Scope / component
- **Component:** `app-passport-scan`
- **Path:** `spikersoft-angular/projects/spikersoft/src/app/_components/employment/application-dialog/passport-scan/`
- **Crop sub-component:** `app-mrz-crop` (`MrzCropComponent`)
## Implementation notes (for devs)
- **`requestScan()`** currently sets `showCrop.set(true)` for non-store modes; it is the entry to `<app-mrz-crop>`.
- **Camera `capturePhoto()`** already sets `showCrop` to `true` for extract / extract-store (see `passport-scan.component.ts` — blob callback after `toBlob`).
- **File `onFileSelected()`** only sets `selectedFile` and does **not** set `showCrop` — so upload still requires the user to press the primary **Extract**-labeled button, which is the inconsistency the ticket addresses.
- **Acceptance (proposed):**
1. On file pick (valid image), if intake mode is **extract** or **extract-store**, automatically set **`showCrop = true`** (equivalent to calling the same path as `requestScan()` for that branch), or refactor so a single `enterCropUi()` is invoked from both file select and capture.
2. Ensure **tilt / slider** and crop are available **before** any OCR.
3. Unify or clarify labels: final OCR action can be **“Scan MRZ”** or **“Extract”** but not two confusing steps that both sound like “run OCR now.”
4. **Store-only** mode may stay different (no crop if product requires).
## Type
**Enhancement** (UX + flow; no production incident).
---
*Labels (optional):* `enhancement`, `frontend`, `ux`, `passport` / `application-dialog`
Verified the current state of AppPassportScanComponent; every acceptance item is in place. Closing as done.
Acceptance checklist
Auto-enter crop UI on file pick — onFileSelected() now calls enterCropUi() when needsExtraction is true (extract / extract-store), so upload no longer requires the user to press an Extract-labeled button just to advance to the crop step.
Tilt + crop available before any OCR — runClientOcr() only fires from onCropped() / onCropSkipped() (i.e. after <app-mrz-crop> emits), never directly from upload or capture.
Single OCR action label — the in-crop "Scan MRZ" button is the sole OCR trigger; the prior double-Extract step is gone. The enterCropUi() doc-comment explicitly narrates this design intent.
Store-only mode unchanged — requestScan() short-circuits to emitStore(file) for store mode, and onIntakeModeChange() hides the crop UI if the user flips to store after picking a file.
Implementation
New private helper enterCropUi() is the single entry-point invoked from all three intake paths (file upload, camera capture, manual requestScan) so the crop experience is identical regardless of source.
onFileSelected (lines 71–79), capturePhoto (lines 144–146), and requestScan (line 200) all funnel through it.
Bonus polish (not in original ticket): onIntakeModeChange() keeps the crop UI in sync with mode flips when a file is already chosen.
## Closing — already implemented
Verified the current state of `AppPassportScanComponent`; every acceptance item is in place. Closing as **done**.
### Acceptance checklist
- [x] **Auto-enter crop UI on file pick** — `onFileSelected()` now calls `enterCropUi()` when `needsExtraction` is true (extract / extract-store), so upload no longer requires the user to press an Extract-labeled button just to advance to the crop step.
- [x] **Tilt + crop available before any OCR** — `runClientOcr()` only fires from `onCropped()` / `onCropSkipped()` (i.e. after `<app-mrz-crop>` emits), never directly from upload or capture.
- [x] **Single OCR action label** — the in-crop "Scan MRZ" button is the sole OCR trigger; the prior double-Extract step is gone. The `enterCropUi()` doc-comment explicitly narrates this design intent.
- [x] **Store-only mode unchanged** — `requestScan()` short-circuits to `emitStore(file)` for store mode, and `onIntakeModeChange()` hides the crop UI if the user flips to store after picking a file.
### Implementation
- New private helper `enterCropUi()` is the single entry-point invoked from all three intake paths (file upload, camera capture, manual `requestScan`) so the crop experience is identical regardless of source.
- `onFileSelected` (lines 71–79), `capturePhoto` (lines 144–146), and `requestScan` (line 200) all funnel through it.
- Bonus polish (not in original ticket): `onIntakeModeChange()` keeps the crop UI in sync with mode flips when a file is already chosen.
### File
`spikersoft-angular/projects/spikersoft/src/app/_components/employment/application-dialog/passport-scan/passport-scan.component.ts`
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Improve the app-passport-scan (
AppPassportScanComponent) flow so that after the user chooses a file or takes a picture, the UI immediately shows the image in the MRZ crop experience (crop to MRZ lines + tilt / slider), and only then the user runs OCR via a single clear action ( Extract or Scan MRZ — same meaning; align copy).Problem (UX)
Today the first primary button is labeled “Extract” (or “Extract + Store” / “Store Only”), but in extract modes that button does not run OCR first — it only opens the next step. That feels misleading: users think they are “extracting” when they are really just advancing to selection/crop. The real extraction happens only after crop (and related controls), often described as “Scan MRZ” in the crop UI — so the mental model is: Extract → (nothing extracted yet) → adjust → Scan MRZ.
Desired model: Choose image / capture → immediately see preview + crop MRZ + tilt → then Extract / Scan MRZ (OCR).
Scope / component
app-passport-scanspikersoft-angular/projects/spikersoft/src/app/_components/employment/application-dialog/passport-scan/app-mrz-crop(MrzCropComponent)Implementation notes (for devs)
requestScan()currently setsshowCrop.set(true)for non-store modes; it is the entry to<app-mrz-crop>.capturePhoto()already setsshowCroptotruefor extract / extract-store (seepassport-scan.component.ts— blob callback aftertoBlob).onFileSelected()only setsselectedFileand does not setshowCrop— so upload still requires the user to press the primary Extract-labeled button, which is the inconsistency the ticket addresses.showCrop = true(equivalent to calling the same path asrequestScan()for that branch), or refactor so a singleenterCropUi()is invoked from both file select and capture.Type
Enhancement (UX + flow; no production incident).
Labels (optional):
enhancement,frontend,ux,passport/application-dialogClosing — already implemented
Verified the current state of
AppPassportScanComponent; every acceptance item is in place. Closing as done.Acceptance checklist
onFileSelected()now callsenterCropUi()whenneedsExtractionis true (extract / extract-store), so upload no longer requires the user to press an Extract-labeled button just to advance to the crop step.runClientOcr()only fires fromonCropped()/onCropSkipped()(i.e. after<app-mrz-crop>emits), never directly from upload or capture.enterCropUi()doc-comment explicitly narrates this design intent.requestScan()short-circuits toemitStore(file)for store mode, andonIntakeModeChange()hides the crop UI if the user flips to store after picking a file.Implementation
enterCropUi()is the single entry-point invoked from all three intake paths (file upload, camera capture, manualrequestScan) so the crop experience is identical regardless of source.onFileSelected(lines 71–79),capturePhoto(lines 144–146), andrequestScan(line 200) all funnel through it.onIntakeModeChange()keeps the crop UI in sync with mode flips when a file is already chosen.File
spikersoft-angular/projects/spikersoft/src/app/_components/employment/application-dialog/passport-scan/passport-scan.component.ts