Files
tehran_taj/apps/user-app-v2/dist/assets/ProductCard-Ccapyn--.js
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
2.1 KiB
JavaScript

import{d as D,k as F,f as t,c as a,F as P,b as o,u as e,w as S,l as p,I as h,a4 as z,i as N,e as c,t as _,D as V,s as I,j as E,g as O,_ as U}from"./index-D7u32dbn.js";import{a as $,S as j}from"./SingleProduct-BYO4_Jip.js";import{u as q}from"./cartStore-B3Iy7abs.js";import{D as L}from"./index-CGMkzVe8.js";const M={class:"pc__art"},T=["alt"],A={key:1,class:"pc__artEmpty","aria-hidden":"true"},G=["aria-label"],H={key:2,class:"pc__flag"},J={key:3,class:"pc__flag pc__flag--soft"},K={class:"pc__title"},Q={class:"pc__weight"},R={key:0,class:"pc__meta"},W={key:0,class:"pc__wageOld"},X={class:"pc__wage"},Y=D({__name:"ProductCard",props:{value:{},wageBefore:{}},setup(d){const w=d,r=$(),{image:v,id:i,title:f,min_gram:y,wage:m,is_exist:k,qty:b,isPreOrder:x}=q(w.value),l=O(!1);function C(){l.value=!0}function g(n){return n%1===0?String(n):n.toFixed(2)}return(n,s)=>{const B=F("lazy");return t(),a(P,null,[o("article",{class:"pc",onClick:C},[o("div",M,[e(v)?S((t(),a("img",{key:0,alt:e(f)},null,8,T)),[[B,e(v)]]):(t(),a("div",A,[p(h,{icon:"vuesax-linear:diamonds",size:"26"})])),o("button",{type:"button",class:N(["pc__fav",{"is-on":e(r).isFavorite(e(i))}]),"aria-label":e(r).isFavorite(e(i))?"حذف از علاقه‌مندی":"افزودن به علاقه‌مندی",onClick:s[0]||(s[0]=z(u=>e(r).toggle(e(i)),["stop"]))},[p(h,{icon:e(r).isFavorite(e(i))?"vuesax-linear:heart-fill":"vuesax-linear:heart",size:"16"},null,8,["icon"])],10,G),e(k)?e(x)&&e(b)===0?(t(),a("span",J,"پیش‌سفارش")):c("",!0):(t(),a("span",H,"ناموجود"))]),o("h3",K,_(e(f)),1),o("p",Q,[V(_(e(y))+" ",1),s[3]||(s[3]=o("span",{class:"pc__weightUnit"},"گرم",-1))]),e(m)!=null?(t(),a("div",R,[d.wageBefore!=null?(t(),a("span",W,"اجرت "+_(g(d.wageBefore))+"٪",1)):c("",!0),o("span",X,_(g(e(m)))+"٪ اجرت",1)])):c("",!0)]),p(e(L),{visible:l.value,"onUpdate:visible":s[2]||(s[2]=u=>l.value=u),placement:"bottom",closable:!1,class:"rtl",height:"100vh",bodyStyle:{padding:0,position:"relative"}},{default:I(()=>[l.value?(t(),E(j,{id:e(i),key:e(i),onCloseDrawer:s[1]||(s[1]=u=>l.value=!1)},null,8,["id"])):c("",!0)]),_:1},8,["visible"])],64)}}}),ae=U(Y,[["__scopeId","data-v-ed785ed2"]]);export{ae as P};