Commit Graph
9 Commits
Author SHA1 Message Date
mahmoodandClaude Sonnet 5.5 6514b05d18 fix(money,orders): wage/gram-debt parity, atomic document confirm, expert edit, made-to-order, QA fixes
- Rial wage and gram-debt arithmetic matched to the reference; order corrections keep debt in sync
- Document confirm/un-confirm is a compare-and-swap (no double-applied cache under concurrency)
- Settlement document and expert inputs validated (400 instead of 500)
- Expert: edit / activate-deactivate own customers, adjust raw weights only
- Made-to-order flow in the app, PreOrder.quantity migration
- Order grids: customer column, sort keys; panel select search; pre-order quantity save
- Rebuilt release artifacts

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-29 18:09:02 +03:30
s.esmaeiliandCursor afb068c643 feat: paginate customer orders and polish the dashboard hero
Add paged orders API and infinite scroll, short order numbers, and align the guest invite card with the logged-in hero shell.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-17 13:11:42 +03:30
s.esmaeiliandClaude Haiku 5.5 532ceee189 feat: move brand name to one config and redesign the accounting card
اپ: نام برند در همه‌ی صفحه‌ها و پیام‌ها یکسان شده و از یک تنظیم مرکزی خوانده می‌شود.
اپ: کارت حسابداری در صفحه‌ی مشتری بازطراحی شد؛ مانده‌ها و وضعیت لینک واضح‌تر نمایش داده می‌شوند.
پنل: کارت حسابداری در پرونده‌ی مشتری بازطراحی شد؛ مانده‌ها، آخرین ارسال و فرم لینک دستی واضح‌تر شده‌اند.
پنل: ستون «کد» در جدول‌ها به‌طور پیش‌فرض پنهان است و از انتخاب ستون‌ها قابل نمایش است.
پنل: تغییر نمایش ستون‌ها در جدول‌ها بلافاصله اعمال می‌شود.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-14 13:31:20 +03:30
s.esmaeiliandCursor 574fa1b4aa feat: catalog read cache (api + user apps) and clearer Zarrin accounting errors
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-11 14:31:32 +03:30
s.esmaeiliandClaude Opus 5.5 699657e483 feat(pricing): the server prices app orders with legacy's making-charge formula (MON-08)
Legacy: final % = variant % + customer % − the largest active promotion
on the product, its category or its brand; rial charge 0. The apps sent
the variant's own % only, so the new app undercharged by the customer's
percent (usually 3) and ignored promotions, and the server trusted
whatever the app sent.

- pricing/wage-formula.ts: one formula, legacy by default, with
  coefficients, promotion pick, constant, floor/cap and rounding so the
  admin screen can change it; validated
- an app order is priced by it; the app's wage, discount and rial charge
  are ignored; an operator's manual numbers are kept
- POST customer/me/wage-quote; both apps show that figure
- admin/pricing/wage-formula (config.wage): read, preview, approve with
  the sample it was checked on, last 20 versions kept; the setting is
  kept off the generic const routes

Owner approval: 2026-10-08.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 11:26:55 +03:30
s.esmaeili f441ca8289 feat(user-apps): appearance settings (dark mode + reduced motion), product morph, filter sheet
Applies to both user-app and user-app-v2. Logic and structure are shared;
each app keeps its own look.

Appearance settings
- New "تنظیمات ظاهری" page (/settings/appearance), opened from the
  dashboard and available without login. It offers a light/dark/system
  theme and a "fast & light" motion switch.
- appearanceStore saves the choice to localStorage. A small inline boot
  script in index.html applies it before first paint so there is no
  white flash. The "system" option follows OS changes live.
- New ToggleSwitch component.

Dark mode
- Theme LESS tokens now compile to CSS custom properties. Light/dark
  values come from a generated virtual:palette.css (themeConfig/
  appearance.ts, with colors.json + new colors.dark.json).
- New LESS alpha() plugin replaces fade() on theme tokens.
- New semantic tokens: page, onInk, heroSurface, hairlineStrong,
  photoMat, photoStage.
- The dark palette is layered (page < card < panel < border) so
  surfaces separate without shadows.
- Hard-coded colors were replaced by tokens according to their role.
- antd inputs/text get dark overrides; vant uses its own
  .van-theme-dark.
- Light mode looks the same as before.

Reduced motion
- With html.motion-reduced, transitions are capped at 120ms, keyframe
  loops stop, and backdrop blurs and permanent will-change are dropped.
- Spinners and the toast progress bar (which closes the toast) are
  exempt via .keep-motion.
- Carousel autoplay, the v1 Lottie and the product morph honor the
  setting.

Product detail
- Opening a product is now a container-transform morph from the tapped
  card (ProductMorph). It replaces the bottom Drawer and uses composited
  transform/opacity only.
- The detail view is seeded with the card's data, so it no longer
  opens blank and jumps.

Filters and sheets
- Filters are now a full-width bottom sheet. Selections stay a draft
  until applied, so the result list no longer re-renders while
  dragging the slider.
- DropDown collapse animates grid-template-rows instead of a capped
  max-height.
- v2 IslandSheet is restyled to the v2 design language (API unchanged).

Fixes
- filtersStore.reset() shallow-copied shared arrays, so clearing the
  filters never cleared the selected brands.
2026-10-04 16:18:56 +03:30
s.esmaeiliandClaude Sonnet 5 c05352d6fd refactor(ui): replace modal dialogs with toast/sheet components
Remove DialogVant/NotifyVant and add Toast and Sheet components with
useToast, useReveal, and usePageTransition composables. Rework
Navigation, RegisterView, and styles across both apps; rebuild dist assets.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-04 13:57:25 +03:30
s.esmaeiliandClaude Opus 5 024e3dd045 parity(api,apps): close SEC-02 - orders take the customer from the token
The user declined to defer this to Phase 2, correctly: a public POST /orders
with customerId in the body let anyone place an order on any customer's
account, and an order lands on that customer's gold debt and ledger.

POST /orders is now behind CustomerAuth. OrdersService.createOrder takes the
customer id as a separate argument that the controller fills from the token;
the body's customerId is ignored and a mismatch is logged. The field stays
optional in the DTO and in shared-types only so both apps keep validating
while they still send it -- they drop it in Phase 2. The admin builder is
unaffected: it legitimately places orders for a chosen customer and passes
that id explicitly, behind the admin guard.

GET /orders/:id is scoped to the owner. A foreign or nonexistent id both
return 404, never 403, so ids stay unenumerable. Operators read through the
new GET /orders/admin/:id behind rid order.list, declared before the :id
route because Nest matches in declaration order.

Both apps' CartView now gates on session.isLoggedIn rather than a remembered
customerId, which is no longer a credential.

OTP audit (requested): no master code, no bypass, no hardcoded code anywhere;
one code path issues a token and only after bcrypt.compare. No SMS provider is
wired up -- in development the code is logged once, guarded by
NODE_ENV !== 'production'.

Fixed while auditing (SEC-11): deliver() persisted the real message text, code
included, into SmsMessage.body, which the admin SMS grid lists and full-text
searches. Any operator with the sms rid could read live codes, defeating the
hashing of codeHash. The stored row is now a redacted audit line.

Also logged MON-08: wagePercent/discountPercent/flatRialCharge are still taken
from the client on order creation. The reference is worse -- it takes
rash_weight from the client too -- so this is already a partial improvement;
logged rather than changed, per D4.

Tests: auth-smoke.sh now 53 passed, 0 failed, including a spoofed body
customerId being ignored in favour of the token. Typecheck clean on api,
user-app, user-app-v2 and shared-types.

[ref: henza_server ApiMobileController.php:533,536-545,615-632]

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 07:09:33 +03:30
s.esmaeili 53a304b5d5 SearchView: Removed the dynamic collection-tile grid (e.g. "پرفروش‌های این هفته") and the "نتایج / N محصول" section header from the UI. Underlying data/filtering logic untouched.
DashboardView ("میز کار"): Rebuilt from scratch with a new structure, distinct from the old card+grid layout but visually aligned with HomeView (same blurred bar, @ink/@wine palette, staged reveal animation on mount):

Single hero card (ink→wine gradient) showing balance, gold/fiat debt, and identity — no quick-action icons inside it anymore.

Live gold rate folded into a slim inline row at the bottom instead of a titled section.
Iterated shadow/spacing on the hero card per feedback (softer, less clipped).
DialogVant / DialogVantOneButton (shared modal components, used in 7+ call sites: Dashboard, Cart, SingleProduct, Register, App): Replaced Vant's default dialog chrome with the app's own rounded-card language — circular icon badge for the illustration, pill-shaped primary/secondary buttons. No call-site markup changed.

LoginView: Rebuilt from scratch — full-bleed dark hero (brand + step copy) overlapped by a floating white form sheet, animated crossfade transition between the mobile-number and OTP steps, same staged entrance animation as Home/Dashboard. All auth logic (API check, OTP stub, session login) unchanged.
2026-09-18 12:54:45 +03:30