← راهنمای طراح

هنداف توسعه‌دهنده

معماری، مدل داده، قراردادها، جدول‌های خودکار از روی کد، امنیت، یکپارچگی‌ها و مسیر انتشار. آنچه «خودکار» است از همین کد ساخته می‌شود و هرگز با پروژه ناهمگام نمی‌ماند.

پارامتر قابل‌ویرایش
۶۴
ماژول مدیریت
۳۲
نقش مدیریتی
۸
مجوز
۴۱
ردیف فهرست طراحی
۲۷۰

هنداف دولوپر

ابعاد فنی پروژه، معماری، مدل داده، قراردادها، تست، امنیت و مسیر رسیدن از نمونه‌ی تعاملی به محصول واقعی.

خلاصه‌ی فنی

موردمقدار
چارچوبNext.js 16 (App Router، خروجی استاتیک `output: export`)، React 19، TypeScript
استایلTailwind CSS v4 با توکن‌های `@theme inline` در `src/app/globals.css`؛ فونت Vazirmatn
نقشهLeaflet + کاشی‌های OpenStreetMap (قابل تعویض با `NEXT_PUBLIC_TILE_URL`)
آیکنlucide-react (فقط SVG)
حالتیک State واحد در IndexedDB (`kamionet/kv/state-v3`)، BroadcastChannel بین تب‌ها، `act(fn)` برای تغییر هم‌زمان با ذخیره‌ی debounce شده
پشتیبان آیندهSupabase/Postgres 16: مایگریشن‌ها در `supabase/migrations` (۳ فایل) و تست در `supabase/tests`
تست`npm run test:ledger` (ثابت‌های دفتر کل) + e2e با Playwright در `tests/e2e/*.mjs`
حجم کدحدود ۳٬۵۰۰ خط موتور (`src/lib/engine`) + صدها کامپوننت؛ سید دترمینیستیک ~۷۰۰ سفارش (~۶ مگابایت)

ساختار پوشه‌ها

مسیرنقش
src/appمسیرها: `/`, `/login`, `/app/*` (صاحب بار), `/driver/*` (راننده), `/admin/[[...m]]` (کنسول ۳۰ ماژولی), `/track`, `/waybill`, `/certificate`, `/blog`, `/handoff`
src/lib/engineمنطق کسب‌وکار خالص (بدون UI): core, orders, pay, payout, finance, trust, admin, kyc, profiles, pro, avail, radar, drivers, stats, demo
src/lib/ledger.tsدفتر کل دوبل با ریال صحیح؛ `post()`, `bal()`, `trialBalance()`, `checkInvariants()`
src/lib/store.tsذخیره‌ساز، نشست‌ها (هر پورتال جدا)، `useStore`, `act`, `startViewAs` (نمایش به‌جای کاربر، فقط‌خواندنی)
src/lib/config.tsجدول پارامترهای قابل‌ویرایش (`CONFIG_DEFS`) و `cv(state, key)`
src/lib/mask.tsمرز دید: `viewOrder()` سه سطح guest / public / full (معادل RPC/View در Postgres)
src/lib/seedسید دترمینیستیک که موتور واقعی را اجرا می‌کند (نه داده‌ی دستی)
src/componentsui.tsx (اتم‌ها)، molecules، portal/Shells، admin/{DataTable,kit,charts,modules}، driver، order، wizard، landing
tests/e2eسناریوهای مرورگری؛ سرو `out/` روی پورت ۴۱۷۳

قراردادهای معماری که نباید شکسته شوند

  • همه‌ی منطق پول فقط از `ledger.post()` عبور می‌کند؛ هیچ UI یا سید مستقیم موجودی را تغییر نمی‌دهد.
  • ریال صحیح؛ هیچ اعشاری در پول. تبدیل به تومان فقط در نمایش (`fmtToman`).
  • هر تراکنش دفتر کل متوازن است و هیچ کیف پولی منفی نمی‌شود (`checkInvariants`).
  • هر نمایش سفارش از `viewOrder()` می‌گذرد؛ فیلد حساس هرگز به UI سطح پایین‌تر نمی‌رسد.
  • هر اقدام ادمین از `guard(perm)` می‌گذرد و در ممیزی ثبت می‌شود؛ مبلغ بالاتر از سقف نقش → `requestApproval` (تأیید دو نفره).
  • عدد کسب‌وکاری هاردکد نشود؛ در `CONFIG_DEFS` اضافه و با `cv()` خوانده شود. قابلیت‌های روشن/خاموش با `feature.*` و `applyFlags` اعمال می‌شوند.
  • اپ بدون سرور اجرا می‌شود (static export)؛ هر `fetch` آینده باید پشت یک لایه‌ی داده (Repository) بیاید تا سید/IndexedDB قابل تعویض بماند.
  • UI فقط خوانندگی `useStore()` و اجرای `act(s => engine(...))` است.

مدل داده‌ی اصلی (src/lib/types.ts)

موجودیتکلیدها / نکته
Person / ShipperProfile / DriverProfile / AdminUserهر Person یک شماره دارد؛ پروفایل نقش‌ها جدا. DriverProfile: kyc, docs (DocFile با notes), vehicle (make/model/year/thermo), pro, clean, controls, strikes, declaredTrips
Orderstatus (۱۷ حالت)، events[] (لاگ زمان‌دار)، waybills[] (نسخه‌ها)، officialDoc، insurance، paid، settlement، consignee{token,otp}، mismatchId
Payment / TransferReceipt / Payout / PayoutBatch / Refund / Debt / Invoice / Coupon / Incentiveهمه به دفتر کل با `ref` وصل‌اند (orderId, personId, …)
LedgerEntrytxId, account, amount (بدهکار +، بستانکار −)، ref؛ حساب‌ها: BANK, GATEWAY, SUSPENSE, ESCROW:{order}, W:S:{id}, W:D:{id}:{pending|avail|hold}, REV:*, EXP:*
Availabilityاعلام یکپارچه‌ی آزادی/مسیر راننده: مبدأ، مقصدها، بازه، بازه‌ی قیمت، بازه‌ی وزن، نوع بار، شرایط پرداخت، انحراف مجاز، کمک در بارگیری، انتظار، پذیرش خودکار
Ticket / Review / RuleDoc / Notification / SmsLog / AuditEntry / Approval / RiskFlagپشتیبانی و حاکمیت
Chat / CallLog / Complaintگفتگوی دو طرف هر سفارش (`orderId`)، تماس شبیه‌سازی‌شده با وضعیت RINGING/ACTIVE/ENDED/MISSED/DECLINED، شکایت با وضعیت OPEN/ANSWERED/RESOLVED/ESCALATED و لینک به Ticket
ConfigStatevalues + history + scheduled (اعمال از فردا)

نگاشت به Postgres/Supabase (مسیر محصول واقعی)

  • جداول مایگریشن فعلی: `app_config, profiles, driver_profiles, orders, order_private, order_events, order_media, rate_table` + RPC `claim_order`, `cancel_order`؛ تست با `bash supabase/tests/run.sh` (نیازمند Postgres 16 محلی).
  • RLS: دید guest/public/full با View و RPC پیاده می‌شود؛ `order_private` آدرس/تلفن را تا بعد از بیعانه پنهان نگه می‌دارد.
  • دفتر کل: جدول `ledger_entries` با constraint مجموع هر tx = ۰ (trigger deferred) و ایندکس روی (account, at)؛ هرگز UPDATE/DELETE.
  • ایدمپوتنسی پرداخت: کلید یکتا روی `idem_key` (در نمونه `txKeys`).
  • موتور (engine) باید به توابع/ترنزاکشن سمت سرور منتقل شود؛ کلاینت فقط RPC صدا بزند. ترتیب پیشنهادی: auth → orders/claim → payments+ledger → payouts → admin.
  • Realtime: کانال برای وضعیت سفارش، تلمتری و اعلان‌ها؛ جایگزین BroadcastChannel/polling فعلی.
  • فایل‌ها (عکس مدارک، حواله‌ی رسمی): Storage خصوصی با لینک امضاشده؛ در نمونه data URL است.

قراردادهای API پیشنهادی (از روی توابع موتور)

عملتابع نمونهورودی → خروجی
ثبت سفارشcreateOrdersOrderInput → {ids}
رزرو / تأیید رانندهclaimOrder / confirmAssignorderId → status
پرداختpay{purpose, amount, method, orderId} → Payment
اجرای سفرstartToPickup / arrivePickup / startTrip / arriveDelivery / deliverمدیا + کد گیرنده
مغایرتreportMismatch / respondMismatch / resolveMismatch—
آزادی رانندهannounce / suggestFree / loadsForMe / requestFreeDriver—
گفتگو و تماسsendChat / startCall / answerCall / endCall (در production: WebSocket + VoIP/ماسک شماره)فقط دو طرف سفارش
شکایتfileComplaint / replyComplaint / resolveComplaint / escalateComplaint / adminResolveComplaintارجاع خودکار بعد از مهلت
رادارradarLoads (کلاینت) → در آینده `GET /loads/near?lat&lng&radius` یا `route`فقط وقتی خودرو خالی است
حواله‌ی رسمیuploadOfficialDocorderId + فایل + شماره
مالی ادمینpayoutAction / createBatch / batchAction / createRefund / dailyClose / lockPeriodبا guard و approval

متغیرهای محیطی و دستورها

نامکاربرد
NEXT_PUBLIC_BASE_PATHمسیر پایه برای GitHub Pages (مثلاً /Kamionet_test)
NEXT_PUBLIC_DEMO_MODE۰ = حذف حساب‌های دمو و کارگردان دمو؛ پیش‌فرض روشن
NEXT_PUBLIC_TILE_URLآدرس کاشی نقشه‌ی فارسی (نشان/Map.ir)
NEXT_PUBLIC_SITE_URLدامنه برای sitemap و canonical
npm run dev / buildتوسعه / خروجی استاتیک در `out/`
npm run test:ledgerتست ثابت‌های دفتر کل روی سید کامل
node tests/e2e/<name>.mjse2e؛ نیازمند `npx serve out -l 4173` و CHROMIUM_PATH
node scripts/gen-trucks.mjsساخت دارایی تصاویر خودرو

تست و کیفیت

  • e2e فعلی: auth, landing, shipper, driver, m4 (مغایرت/رهگیری/گواهی), admin, m6 — همه باید قبل از هر انتشار سبز باشند.
  • تست ثابت دفتر کل پس از سید و پس از مسیرهای UI اجرا می‌شود.
  • پیشنهاد: افزودن تست واحد برای engine (vitest) و تست تصویری (Playwright snapshots) برای Design System.
  • لینت/فرمت هنوز پیکربندی نشده؛ `tsc --noEmit` شرط ادغام است.

امنیت و حریم خصوصی

  • نمونه: هر داده‌ای در مرورگر است؛ برای محصول واقعی همه‌ی قوانین دید باید سمت سرور (RLS) اعمال شود.
  • کد تحویل گیرنده و آدرس دقیق هرگز در پاسخ API نقش‌های غیرمجاز نباشد (در نمونه فقط با mask.ts پنهان می‌شود، نه امن).
  • OTP ورود: در نمونه ثابت ۱۲۳۴۵ است؛ باید با ارائه‌دهنده‌ی پیامک، نرخ‌محدودیت و قفل جایگزین شود.
  • احراز کد ملی/سیم‌کارت (شاهکار) و تطبیق شبا در حالت تست شل‌اند؛ برای production اجباری است.
  • ذخیره‌ی مدارک: رمزنگاری در سکون، دسترسی با نقش `drivers.kyc`، ممیزی هر مشاهده.
  • نقش‌ها و سقف تأیید در `ROLE_PERMS` و `CEILINGS`؛ تغییر آن‌ها حساس است.
  • ۲FA ادمین در داده هست ولی اعمال نشده؛ باید فعال شود.
  • قوانین و متن‌های حقوقی نیازمند بازبینی حقوقی‌اند.

کارایی و بودجه

  • بار اولیه: سید در IndexedDB ساخته می‌شود (~۶ مگابایت)؛ بعدی‌ها فوری.
  • جدول‌های ادمین: صفحه‌بندی ۲۵ ردیفی؛ برای دیتای واقعی صفحه‌بندی سمت سرور لازم است.
  • نقشه با dynamic import و بدون SSR؛ خوشه‌بندی مارکر برای بیش از ۲۰ بار.
  • پیشنهاد بودجه: LCP < ۲٫۵s روی ۴G، JS اولیه < ۲۰۰KB gz در صفحه‌ی لندینگ.

رصد و رخدادها

  • رخدادهای پیشنهادی: order_started/step/submitted، deposit_paid/expired، claim, availability_created, radar_alert_shown/clicked, kyc_step_completed, sensor_linked, support_opened, official_doc_ready.
  • ممیزی (`audit`) محل ثبت اقدام‌های ادمین/سیستم است و باید به Log پایدار منتقل شود.
  • خطاهای کلاینت: Sentry یا مشابه؛ برای صف آپلود آفلاین لاگ ویژه.

بدهی‌های فنی و محدودیت‌های شناخته‌شده

  • همه‌ی سرویس‌های بیرونی شبیه‌سازی‌اند (درگاه، پیامک، شاهکار، شبا، GPS/سنسور، بیمه‌گر).
  • حواله‌ی رسمی/عکس‌ها data URL هستند و حجم state را بالا می‌برند.
  • مدل/سال خودرو توسط راننده تایپ می‌شود و تطبیق خودکار ندارد.
  • رادار: موقعیت با geolocation مرورگر؛ در اپ بومی باید با سرویس پس‌زمینه‌ی مجاز و صرفه‌جویی باتری بازنویسی شود.
  • نقشه: کاشی OSM برای production مناسب نیست؛ ارائه‌دهنده‌ی فارسی لازم است.
  • ESLint/Prettier پیکربندی نشده؛ تست واحد ندارد.