chore: commit pending admin-panel, api auth and parity doc changes

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
s.esmaeili
2026-10-14 04:33:24 +03:30
co-authored by Claude Haiku 5.5
parent 55856cac89
commit cf014e1f6c
41 changed files with 3471 additions and 969 deletions
+92
View File
@@ -1343,3 +1343,95 @@ apps depend on and the method had no test at all. ⚠️ Nothing click-tested: t
cart re-sync and the favourites screen are the two worth a manual pass.
_No data was deleted in this entry._
---
## 2026-10-14 — Owner request (not parity) — add/edit product UI/UX redesign
- **What:** redesigned the Add/Edit Product page (`AddProduct.vue` / `EditProduct.vue`)
with a modern e-commerce dashboard architecture. Introduced a 2-column layout
(content/variants in primary 1fr column; publication status and media uploaders
in dedicated 340px sidebar); added a top page header with breadcrumb navigation,
accounting-sync indicators, and dual fast-save actions; redesigned the variants
table with badge columns, inline actions, empty states, and clean weight/wage
formatting; streamlined the variant modal; unified the gallery slots with clean
site/mobile segmented tabs and compact upload grids; strictly preserved the
PROTECTED §B variant gallery image picker (64x64 grid with `.is-on` selection).
All schemas, fields, accounting locks (D27), permissions, and payloads preserved.
- **Why:** owner requested professional, efficient, high-end SaaS UI/UX overhaul
for Add Product.
- **Reference:** n/a (visual layer overhaul; all fields, validations, and logic preserved)
- **Target:** `apps/admin-panel/src/views/apps/product/AddProduct.vue`
- **Matrix row:** n/a
_No schema change, no data deleted._
---
## 2026-10-14 — Owner request (not parity) — add/edit customer UI/UX redesign
- **What:** redesigned the Add Person (`/customer/add`) page and its wholesale
(`bulkCustomer.vue`), sales expert (`ReagentCustomer.vue`), and retail
(`singleCustomer.vue`) forms. Replaced nested double/triple card boxes with
semantic `.form-section` panels featuring clean icon badges, titles, and
descriptions; improved input grid rhythm (3-column responsive layout with
clear required asterisks and placeholders); redesigned document upload blocks
as dedicated dash-bordered upload cards; upgraded the sales-expert avatar
slot; added a top page header with back navigation; unified the action bar
with loading indicators and explicit cancel/back buttons. Both full-page and
modal forms (`asModal`) upgraded.
- **Why:** owner requested professional SaaS-grade UI/UX overhaul starting with
the Add Person forms.
- **Reference:** n/a (visual layer overhaul; all fields, validations, and logic preserved)
- **Target:** `apps/admin-panel/src/views/apps/customer/AddCustomer.vue`,
`apps/admin-panel/src/views/apps/customer/bulkCustomer.vue`,
`apps/admin-panel/src/views/apps/customer/ReagentCustomer.vue`,
`apps/admin-panel/src/views/apps/customer/singleCustomer.vue`
- **Matrix row:** n/a
_No schema change, no data deleted._
---
## 2026-10-14 — Owner request (not parity) — admin dashboard visual unify
- **What:** unified dashboard chrome with the rest of the admin panel — removed
radial wash / Mentzer badge / gold period chips / multi-shadow cards / KPI lift
hover and coloured side bars; muted period text; flat navy KPI icons; equal
sales-summary cells. Same data, block order, charts, sorts, and API.
- **Why:** owner asked for a principled restyle; PROTECTED §A chrome updated with
approval.
- **Reference:** n/a (target-only dashboard; reference dashboards were demo husks)
- **Target:** `apps/admin-panel/src/views/Dashboard.vue`,
`apps/admin-panel/src/components/statistics-cards/StatisticsCardLine.vue`,
`docs/parity/PROTECTED.md` §A,
`docs/superpowers/specs/2026-10-14-admin-dashboard-visual-unify-design.md`
- **Matrix row:** n/a
_No schema change, no data deleted._
---
## 2026-10-14 — Owner request (not parity) — super-admin-only admin features (D30)
- **What:** retail customers, bankers, walk-in shopkeepers, branches and
workshops, the «مشتری تک» tab, trays («سینی ها», product field + Const tab),
retail orders (create + list), retail promotions (add/edit/delete) and wallet
management are reserved to the 09128081392 account — hidden in the menu and
pages, blocked by route, 403 from the API, and removed from the permission tree
for everyone else.
- **Why:** owner ruling D30. Deliberately not reference behaviour.
- **Reference:** n/a
- **Target:** API — `auth/super-admin.ts` (new), `auth/guards.ts`
(`@SuperAdminOnly`, multi-rid `@RequirePermission`), `auth/jwt.strategy.ts`,
`auth/auth.service.ts` (`is_super_admin`), and the branches, workshops,
customers, orders, documents, categories and products controllers. Panel —
`utils/superAdmin.ts` (new), `stores/users.ts`, `stores/auth.ts`,
`router/index.ts`, `router/admin.ts` (16 routes), `layouts/navMenuItems.ts`,
`NavMenuNode.vue`, `VerticalNavMenu.vue`, `AddCustomer.vue`, `AddProduct.vue`,
`Const.vue`, `promotion_list.vue`, `Permission.vue`.
- **Tests:** `auth/guards.spec.ts` (new, 8 cases). api 342/342 across 31
suites; api `tsc` and admin-panel `vue-tsc` clean. ⚠️ Not click-tested.
- **Matrix row:** n/a
_No schema change, no data deleted._
+37
View File
@@ -1513,3 +1513,40 @@ act-as را پاک می‌کند و او را از سیستم بیرون نمی
(در مرجع این مسئله وجود نداشت چون کل نشست با توکن عوض می‌شد.)
ثبت شده در `ISSUES.md` به‌عنوان EXP-01.
## D30 — بخش‌های «فقط سوپر ادمین» در پنل مدیریت (۲۰۲۶/۱۰/۱۴)
**خواسته مالک:** این بخش‌ها فقط به سوپر ادمین (۰۹۱۲۸۰۸۱۳۹۲) نشان داده شوند و در
سطح دسترسی‌ها هم نباشند: لیست مشتریان تک، لیست بنکداران، لیست مغازه‌داران حضوری،
شعب و کارگاه، تب «مشتری تک» در افزودن شخص، فیلد «سینی ها» در فرم محصول، ثبت
سفارش تک و لیست سفارش‌های تک، «افزودن تخفیف تک»، و «مدیریت کیف پول».
**پاسخ‌های مالک:**
- سوپر ادمین = **فقط حساب با موبایل ۰۹۱۲۸۰۸۱۳۹۲**، نه هر ادمینی که نقش `SUPER_ADMIN` دارد.
- اعمال **کامل**: مخفی در پنل + بستن آدرس مستقیم صفحه + ۴۰۳ از API.
- «سینی ها» در **هر دو جا**: فیلد فرم محصول و تب «مدیریت ثابت ها».
- تخفیف تک: **افزودن + ویرایش + حذف**، و هر سه از سطح دسترسی‌ها حذف.
**سازوکار.** `@SuperAdminOnly()` در `apps/api/src/modules/auth/guards.ts`، که
`PermissionsGuard` سراسری آن را اعمال می‌کند؛ شماره و فهرست rid ها در
`auth/super-admin.ts`. به سوپر ادمین rid های این بخش‌ها همیشه داده می‌شود
(`withSuperAdminRids`) تا با ذخیره‌ی دوباره‌ی سطح دسترسی‌اش از دست نروند. در پنل:
`users.isSuperAdmin` (از `is_super_admin` در login و `users/show`)، `superAdminOnly`
روی منو و route، و حذف این rid ها از درخت صفحه دسترسی‌ها برای غیر سوپر ادمین.
**تصمیم‌های جانبی (برای نشکستن چیزهای دیگر):**
- **پنل شعبه** همان endpoint های مشتری تک و سفارش تک را صدا می‌زند؛ این endpoint ها
برای ادمینِ دارای `branchId` هم باز ماند (`allowBranch`). بدون این، کارکنان شعبه
قفل می‌شدند. پیامد: ادمینی که شعبه دارد از API به این چهار endpoint دسترسی دارد.
- **سوپر ادمین در درخت دسترسی‌ها همه را می‌بیند** تا بتواند این rid ها را به سطح
دسترسی کارکنان شعبه بدهد. دیگران آن‌ها را نمی‌بینند، و rid هایی که سطح از قبل
دارد هنگام ذخیره توسط آن‌ها **حفظ** می‌شود (حذف بی‌صدا نمی‌شود).
- `admin/orders/:id`، `status` و `status-options` بین سفارش تک، عمده و تامین مشترک‌اند
و `order.list` می‌خواستند؛ حالا هر کدام از `order.list` / `order.omde` / `order.tamin`
کافی است (`RequirePermission` چند rid می‌پذیرد).
- لیست کارگاه‌ها (`admin/workshops/list`) **باز ماند**: انتخاب کارگاه در «سفارش های
ساختنی» از آن است. بقیه‌ی endpoint های کارگاه و همه‌ی شعب بسته شدند.
- **تخفیف تک فقط در پنل بسته شد، نه در API**: API تک و عمده را از هم تشخیص نمی‌دهد
(PROMO-TAK-01).
- بنکداران/مغازه‌داران و سینی‌ها rid مشترک با بخش‌های دیگر دارند (`persons.list.client.omde`،
`collection.*`)؛ پس از درخت حذف نشدند و با `@SuperAdminOnly` / `isSuperAdmin` بسته شدند.
+8
View File
@@ -291,3 +291,11 @@ wrong and both are right here. Its one real gap was that nothing ever went
stale — no TTL, and `force` used only by pull-to-refresh — which READ-01/02 fix
at the point that matters: opening the screen. The policy is now written at the
top of `queryCache.ts` so the next person does not re-introduce a TTL.
## Super-admin-only features — found while building D30 (2026-10-14)
| ID | Severity | Where | Description | Status |
|---|---|---|---|---|
| **PROMO-TAK-01** | Medium | TGT `admin-promotions.service.ts:147`, `PromotionForm.vue:67` | `type_customer` (1 = تک, 2 = عمده) is not stored; it is derived from the scope — CUSTOMER scope gives 1, any other gives 2. The «تک» form hides the customer scope, so everything it creates comes back as عمده, while the عمده form *can* pick the customer scope and produce a «تک» row. The API also never checks the `.tak` rids and deletes on `offers.list.edit`. Consequence for D30: retail promotions can only be restricted in the panel, not in the API. | Open — logged, not fixed |
| **CINY-01** | Low | TGT `admin-products.service.ts` `update()` | `create()` saves `ciny_ids` (trays), `update()` ignores them, so changing a product's trays on edit is silently lost. | Open — logged, not fixed |
+12 -7
View File
@@ -16,8 +16,9 @@ discovered in Phase 0, proposed for protection · **[?]** = needs your ruling.
## A. Admin panel — Dashboard · **[brief]**
**Location:** `apps/admin-panel/src/views/Dashboard.vue` (327 lines) — one file
serving both `/dashboard/ecommerce` and `/dashboard/analytics`.
**Location:** `apps/admin-panel/src/views/Dashboard.vue` — one file serving both
`/dashboard/ecommerce` and `/dashboard/analytics`. KPI chrome lives in
`components/statistics-cards/StatisticsCardLine.vue`.
**Gate:** rid `dashboard.view`; lacking it redirects to `my-data` (not a 403 page).
**Data:** a single `GET admin/dashboard/overview` on mount, then client-side sorts
(`reagent` desc by `grams_sell`; `lastOrder` desc by `w`).
@@ -31,18 +32,22 @@ Contents, in render order:
4. 2 donuts — وضعیت سفارشات (8-entry colour array) · تفکیک عمده/تک
5. Horizontal bar + an always-rendered agent table (کارشناس فروش / میزان فروش گرم / تعداد سفارش)
6. Vertical bar «محصولات پرفروش» with an `a-empty` fallback
7. `a-descriptions` «میزان فروش» — 3 columns incl. a computed average
7. Sales summary «میزان فروش» — 3 equal cells incl. a computed average
8. Table «سفارشات هفته جاری» — `pageSize` 10, `sts_str` as a coloured `a-tag`, `caj` via `jdate`
Fixed palette `#1c2d56 / #28c76f / #ff9f43 / #ea5455`. **No filters, no date range,
no export, no refresh** — that is the intended design, not a gap.
**Chrome (owner-approved 2026-10-14):** panel-unified look — plain layout background,
simple page header (no brand badge), bordered ant cards, muted period labels (not gold
pills), flat KPI tiles (soft navy icon well, no lift hover / side accent bar), equal
sales-summary cells. Chart series palette stays `#1c2d56 / #28c76f / #ff9f43 / #ea5455`.
**No filters, no date range, no export, no refresh** — that is the intended design, not a gap.
Spec: `docs/superpowers/specs/2026-10-14-admin-dashboard-visual-unify-design.md`.
> Why this matters for parity: the reference's two dashboards
> (`DashboardECommerce.vue`, `DashboardAnalytics.vue`) were found in the earlier
> port to be **mostly commented-out Vuexy demo markup**, with ApexCharts imported
> but never used in live markup (`docs/CHANGELOG-PORT-HISTORY.md`). So there is
> essentially nothing to port *into* this dashboard. Phase 1 will confirm and
> record that, and will not touch this file.
> essentially nothing to port *into* this dashboard. Visual chrome may change only
> with explicit owner approval (this section).
---
@@ -0,0 +1,43 @@
# Admin dashboard visual unify — design spec
**Date:** 2026-10-14
**Status:** Approved (owner)
**Scope:** Visual chrome only on the admin dashboard
## Goal
Make the admin dashboard look like the rest of the admin panel: calm, bordered cards, brand navy, even spacing. Remove marketing-style gradients, gold chips, lift hover, and multi-colour KPI accents that made the page feel scattered.
## Decisions
| Decision | Choice |
|---|---|
| Content / API | Unchanged — same fields, sorts, charts, `GET dashboard/overview` |
| Approach | Unify with panel chrome (not a new IA, not polish-only) |
| Filters / refresh / export | Out of scope (PROTECTED §A) |
## Visual rules
1. **Page background** — no radial gold/navy wash; no negative margin on the dashboard container.
2. **Header** — title «نمای کلی» + muted subtitle «آمار ۳۰ روز گذشته · به‌روز از سرور»; remove «منتزر» badge.
3. **Chart/table cards** — light border / default ant Card look; drop heavy multi-layer shadows.
4. **Period labels** — muted text next to the title (not gold pills).
5. **KPI cards** — flat; soft grey icon well + `#1c2d56` icon/value; no side accent bar; no translateY hover.
6. **Sales summary** — three equal cells; no gold accent on the average.
7. **Spacing** — ~16px gap between blocks.
8. **Chart series colours** — keep `#1c2d56 / #28c76f / #ff9f43 / #ea5455` and −45° x-label rotation.
## Files
- `apps/admin-panel/src/views/Dashboard.vue`
- `apps/admin-panel/src/components/statistics-cards/StatisticsCardLine.vue`
- `docs/parity/PROTECTED.md` §A (document chrome change)
- `docs/parity/CHANGELOG.md`
## States
Loading (`a-spin`), empty product chart (`a-empty`), tables, and fetch error handling stay as today.
## Done when
Same stats and charts render; page reads as part of the admin shell (no gradient / gold chip / card lift); desktop and mobile grids still work.