Files
tehran_tala/apps/user-app-v2/dist/assets/CompleteProfileView-SiN9Fsb5.css
T
s.esmaeiliandClaude Opus 5 5ad1083aee parity(apps+api): complete_profile in both apps [ref: henza_server Major/CustomerController::complete]
Ports "تکمیل پروفایل" end to end (D22).

API
- POST customer/me/complete-profile — three required document ids, the
  customer taken from the token, verification step set to the reference's
  LIVE value (approved outright; its `= 1` line is commented out at :83 in
  favour of `= 2` at :85). Both SMS messages byte-identical and non-blocking
  per D20.
- POST customer/me/documents — the reference let the app upload through the
  same file/create the admin used, inside its auth:api-customer group
  (routes/api.php:95); the target's copy is admin-guarded, so the page could
  not have uploaded at all. Reuses AdminUploadsService unchanged, so both
  paths share one size limit, MIME whitelist and naming scheme (UPL-01).
- PROFILE_ADMIN_MOBILES replaces the reference's four hardcoded personal
  numbers; blank means nobody is notified and the upload still succeeds.

Three reference behaviours deliberately NOT ported, all in ISSUES.md:
- SEC-14: `$customer->update($request->all())` mass-assigned the whole request
  body, letting the app write its own credit limit, making charge, gold debt,
  active flag or mobile. Replaced with a three-field whitelist.
- SEC-15: four real personal mobiles hardcoded in the source.
- APP-03: refresh()'s unterminated setInterval page reload.

Apps (both, template+script byte-identical, per-app styling only)
- CompleteProfileView + SingleImageUploader
- route /complete_profile, redirecting home once the documents are in, as the
  reference's guard did (router/index.ts:266)
- the entry point on the profile screen, shown only while they are missing
  (profile.vue:96-102)

Also (D23): JWT_CUSTOMER_SECRET now warns loudly at boot when unset. It falls
back to JWT_SECRET, which signs app and admin tokens with the same key and
leaves the `typ` check as the only barrier — and an expert's app token carries
their AdminUser id in `sub`. Warn rather than refuse to boot (D19, lowest
risk); DELIVERY.md lists it as the first pre-release step (REL-03).

Verified: build 5/5 · jest 45/45 · complete-profile 38/38 (new) ·
expert login 36/36 · apps smoke 43/43 · admin smoke 43/43 ·
B2B scan 34 ok/0 broken · typecheck clean on all four apps.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 01:42:07 +03:30

2 lines
1.8 KiB
CSS

.siu__input[data-v-61170337]{display:none}.siu__box[data-v-61170337]{position:relative;width:100%;padding:18px 2px;display:flex;flex-direction:row-reverse;align-items:center;justify-content:flex-end;gap:12px;border:none;border-bottom:1px solid #ECEDEF;background:transparent;font-family:inherit;text-align:right;cursor:pointer;overflow:hidden}.siu__box[data-v-61170337]:disabled{cursor:progress}.siu__box[data-v-61170337]:active{opacity:.75}.is-done .siu__box[data-v-61170337]{border-bottom-color:#16a34a}.is-error .siu__box[data-v-61170337]{border-bottom-color:#dc2626}.siu__preview[data-v-61170337]{width:46px;height:46px;flex:0 0 auto;-o-object-fit:cover;object-fit:cover;border-radius:12px;order:-1}.siu__icon[data-v-61170337]{display:flex;flex:0 0 auto;align-items:center;justify-content:center;width:46px;height:46px;border-radius:12px;background:#fafafa;color:#5b616e;order:-1}.siu__text[data-v-61170337]{flex:1;font-size:13.5px;font-weight:600;color:#14161a}.siu__badge[data-v-61170337]{flex:0 0 auto;display:flex;color:#16a34a}.siu__error[data-v-61170337]{margin:7px 2px 0;font-size:12px;color:#dc2626}.cpf__body[data-v-c1854a08]{padding-top:84px;padding-bottom:110px}.cpf__lead[data-v-c1854a08]{margin:4px 0 6px;font-size:13px;color:#5b616e}.cpf__form[data-v-c1854a08]{display:flex;flex-direction:column}.cpf__error[data-v-c1854a08]{margin:12px 2px 0;font-size:12.5px;color:#dc2626}.cpf__submit[data-v-c1854a08]{position:fixed;left:16px;right:16px;bottom:20px;z-index:20;max-width:736px;margin:0 auto;padding:15px;border:none;border-radius:999px;background:#7a1b33;color:#fff;font-family:inherit;font-size:15px;font-weight:700;cursor:pointer}.cpf__submit[data-v-c1854a08]:disabled{opacity:.6;cursor:progress}.cpf__dialogText[data-v-c1854a08]{padding:20px;line-height:1.9;text-align:justify;font-size:14px}.cpf__dialogBtn[data-v-c1854a08]{text-align:center;cursor:pointer}