17 KiB
راهنمای پیادهسازی و راهاندازی چهارسو و پرداختها
تاریخ: ۲۰۲۶/۱۰/۰۵
مسیرها و سازگاری
- ورود عادی مشتری و مسیر
/به/chaharsu/هدایت میشوند. لینک داخلی معتبرِ ادامه ورود حفظ میشود؛ لینک خارجی پذیرفته نمیشود. /tickets/همچنان تاریخچه فعلی درخواستهاست./tickets/new/، قالب و منطق ثبت درخواست تغییر نکردهاند.- خانه چهارسو فقط خدمات دارد: ارتباط با کارشناسان، ارسال فیش و شماره حسابها.
- شماره حسابها:
/chaharsu/bank-accounts/؛ فرم فیش:/chaharsu/payment-receipt/؛ سوابق فیش مشتری:/chaharsu/receipts/. - میزکار کارشناسان:
/staff/payments/؛ مدیریت حسابها:/staff/payments/banks/. - PWA از
/شروع میشود تا مشتری به چهارسو و کارشناس به میزکار خودش برسد. رفتار ثبت service worker و URLهای نسخهدار حفظ شدهاند.
ساختار و قواعد مالی
اپ مستقل apps.payments شامل مدلها، سیاست دسترسی، اعتبارسنجی، سرویسهای تراکنشی، خواندن داده، اعلانها و صفحات است. وابستگیهای بیرونی از زیرساخت فعلی کاربران، واحدها، پیامک و سیاست تصویر استفاده میکنند. PaymentReceiptRevision هم اطلاعات نسخه و هم مدرک تصویر را نگه میدارد؛ مدل جداگانه Document لازم نشده است.
- اعلامیه، فیش و تصمیم تأیید مستقلاند. ثبت تصویر یا تأیید یک نفر از دو نفر، پرداخت را نهایی نمیکند.
- مبلغ عدد صحیح ریال است؛ نمایش حروفی تومان در مرورگر با BigInt انجام میشود و مقدار ریال به سرور میرود.
- نمایش تاریخ شمسی و انتخاب سهقسمتی است. سرور با jdatetime روز/ماه/سال را مستقل از JS بررسی و Gregorian را در DateField ذخیره میکند. تاریخ ناقص، غیرواقعی، آینده و خارج از بازه مجاز رد میشود.
- شناسهها، شمارهها و شبا رشتهاند؛ صفر ابتدایی حفظ میشود. شبا و کارت موجود اعتبارسنجی میشوند.
- حساب شناسهدار در صدور اعلامیه الزاماً شناسه میخواهد. در ثبت فیش، شناسه اعلامیه فقط برای همان حساب معتبر است؛ مقصد متفاوت شناسه خودش را لازم دارد.
- حساب فقط فعال در پنل کارشناسان، در زمینه اعلامیه اختصاصی همان مشتری قابل استفاده است؛ در واریز مستقل قابل استفاده نیست. غیرفعال کلی بودن، ثبت جدید را متوقف میکند و سوابق را پنهان نمیکند.
- snapshot حساب و شناسه اعلامیه حفظ میشود؛ ویرایش بانک، شماره تاریخی اعلامیه یا نسخه فیش را تغییر نمیدهد.
- فرم صدور و فرم فیش nonce دارند؛ ارسال تکراری همان داده رکورد یا پیامک جدید ایجاد نمیکند. استفاده مجدد از nonce برای اطلاعات مالی متفاوت رد میشود.
- وضعیت اعلامیه از مبلغ نسخه جاری فیشهای تأییدشده بدون مغایرت مقصد محاسبه میشود؛ پرداخت جزئی و باقیمانده نمایش داده میشوند.
تنظیمات ضروری پیش از استفاده مالی واقعی
۱. migrationها را اجرا کنید:
.venv/Scripts/python.exe manage.py migrate
۲. مدیرعامل فعال، superuser از نوع STAFF یا کارشناس دارای مجوز payments.manage_company_bankaccounts، حسابهای واقعی شرکت را در منوی «بانکها» تعریف کند. اطلاعات واقعی حساب در migration قرار نگرفته است. برای حساب شناسهدار، «شناسه واریز الزامی» را فعال کنید. سه وضعیت فعال کلی، کارشناسان و مشتریان مستقلاند و تغییر جمعی هم دارند. حساب دارای سابقه قابل حذف نیست؛ غیرفعال کنید. فرم ویرایش قدیمی نمیتواند تغییر جدید را بازنویسی کند.
۳. در مدیریت Django /x5admin/، بخش PaymentApprovalPolicy، یک سیاست عمومی یا سیاست واحد بسازید. همه افراد فهرست reviewers باید رأی بدهند؛ یک نفر یعنی تأیید تکنفره، چند نفر یعنی شرط تأیید همه اشخاص تعیینشده. افراد seniors میتوانند با دلیل، تأیید نهایی ارشد انجام دهند.
۴. انتخاب فرد در سیاست بهتنهایی کافی نیست. مجوزهای زیر را به افراد مجاز بدهید؛ مدیر مالی یا نقش FINANCE خودکار تأییدکننده نمیشود:
| مجوز | کاربرد |
|---|---|
payments.approve_paymentreceipt |
رأی عادی فردِ تعیینشده در سیاست |
payments.senior_approve_paymentreceipt |
تأیید ارشد فردِ تعیینشده در seniors |
payments.manage_payment_approval_policy |
مدیریت سیاستها و تخصیص سیاست فعال به چرخه خالی |
payments.manage_company_bankaccounts |
مدیریت حسابها |
payments.manage_payment_access |
تنظیم باز یا محدود بودن مشاهده و ایجاد |
payments.view_all_payments |
مشاهده مالی در همه واحدها |
payments.view_payment_audit |
دسترسی ممیزی مالی در مدیریت |
مجوزهای تأیید میتوانند سراسری، در عضویت فعال واحد یا در مجوزهای واحد فعال باشند. مشاهده همان فیش و تخصیص همان چرخه نیز لازم است. ثبتکننده کارشناس، فیشی را که خودش ثبت کرده تأیید نمیکند. مدیریت Django علاوه بر مجوز مالی، شرایط ورود استاندارد پنل admin را لازم دارد.
۵. نبود سیاست فعال باعث ماندن فیش در انتظار بررسی میشود. تأیید خودکار یا تعیین فرضی مدیرعامل انجام نشده است. پس از تعریف سیاست، مدیر مجاز از جزئیات فیش، «اعمال سیاست فعال تأیید» را برای چرخه خالی بزند. سیاست چرخه دارای تخصیص/رأی بازنویسی نمیشود.
۶. تنظیم پیشفرض PaymentAccessConfiguration مشاهده و ایجاد را برای همه کارشناسان فعال باز میگذارد. برای محدودسازی بعدی این دو گزینه را غیرفعال و مجوزهای view_paymentnotice، view_paymentreceipt و add_paymentnotice را در دامنه موردنظر بدهید. تأیید از ابتدا محدود است.
نسخهها، تأیید و ممیزی
تصمیم در transaction و با قفل فیش و چرخه، تطبیق نسخه جاری و رأی یکتا ثبت میشود. PostgreSQL برای join واحد nullable فقط خود فیش را قفل میکند. ترتیب قفل مشتری/حساب در صدور و ثبت یکسان است. پیامک نهایی فقط با نهاییشدن شرط تأیید صف میشود.
فیش ردشده از صفحه مشتری با تصویر جدید اصلاح میشود. نسخه پیشین، فایل و رأیها باقی میمانند؛ نسخه تازه از ابتدا با سیاست جدید بررسی میشود و رأی قدیمی در تأیید جدید شمرده نمیشود. رد و ارشد دلیل لازم دارند؛ مغایرت مقصد برای تأیید دلیل بررسی لازم دارد. تصویر تکراری روی فیش دیگر به کارشناس هشدار داده میشود.
صدور، ارسال، اصلاح، شروع چرخه، تخصیص، رأی، مشاهده مدرک و تغییر حساب با نام/شناسه عامل، زمان و جزئیات در PaymentAuditEvent ثبت میشوند. تغییرات مجوز مالی در مسیرهای مدیریت User/Group/Unit/Membership/StaffProfile نیز ممیزی میشوند. سیاست و دادههای ممیزی از admin قابل حذف/ویرایش عادی نیستند. تغییر مستقیم دیتابیس خارج از مسیرهای برنامه، نیازمند کنترل عملیاتی و ممیزی مستقل دیتابیس است.
تصاویر و امنیت مرورگر
تصاویر در payments/ رسانه خصوصی ذخیره میشوند و فقط endpoint احراز هویتشده تصویر آنها را ارائه میدهد. مجوز در هر بار مشاهده/دانلود بررسی میشود؛ Magic Link تیکت اجازه مالی نمیدهد. لینک مستقیم /media/payments/ در توسعه و مسیر signed /protected-media/payments/ در nginx مسدودند. پاسخ مالی/تصویر no-store است و service worker داده مالی را cache نمیکند.
اعتبارسنجی تصویر شامل سقف حجم سیاست فعلی، extension، MIME واقعی، decode با Pillow، سقف ابعاد و SHA-256 است. فایل ساختهشده در شکست transaction پاک میشود. دانلود نسخه قبلی همچنان کنترل دسترسی دارد.
فونت، SVG، CSS و JS داخل پروژهاند؛ وابستگی CDN اضافه نشده است. CSS چهارسو scoped است. کپی کامل اطلاعات از snapshot کامل، شامل شرح و فاکتور و تاریخ، ساخته میشود؛ فقط فیلدهای بانکی ضروری کپی تکی دارند. در HTTP شبکه محلی، اگر Clipboard مجاز نباشد، پنجره قابل انتخاب و کپی دستی نمایش داده میشود.
پیامک
دو رویداد دیتابیسی PAYMENT_NOTICE_CREATED و PAYMENT_RECEIPT_APPROVED به SMSTemplate اضافه شدهاند. migration الگوهای عمومی اولیه را ایجاد میکند؛ override واحد در الگوهای پیامک فعلی قابل تنظیم است. تگها:
recipient_name, company_name, notice_number, receipt_number, amount_rial, invoice_number, payment_link
صف فعلی NotificationJob و worker process_notifications به کار میروند. اعلامیه به معنی صفشدن پیامک است؛ دریافت پیامک نیازمند اجرای worker و تنظیم provider است. وضعیت ارسال و دلیوری مستقل از وضعیت مالی است. متن و نسخه الگو در اولین تلاش موفق آمادهسازی snapshot میشود؛ retry همان متن را حفظ میکند. تلاش ناموفقِ آمادهسازی قالب یا ارتباط provider نیز تاریخچه دارد. URL پیامک ورود کامل مشتری را لازم دارد.
در آزمونها provider mock شده است؛ پیامک واقعی برای مشتری ارسال نشده و worker روی صف واقعی توسعه اجرا نشده است.
آزمون و محدودیت محیط
نتایج اجرا (اجرای مجدد را نباید با تعداد آزمونهای یکتا جمع کرد):
- مجموعه کامل سمت سرور: ۳۲۲ موفق، ۴ skipped؛ ۴۶ آزمون مرورگر در این اجرای جدا انتخاب نشدهاند (
chaharsu-backend-final.log). - کنترل مجدد بخشهای مالی، view، مجوز و دامنه: ۱۸۱ موفق (
chaharsu-focused-final.log). - مجموعه کامل مرورگر: ۴۴ موفق، ۲ skipped؛ دو smoke test محیط خارجی بدون تنظیمات آن محیط اجرا نشدهاند (
chaharsu-e2e-final.log). - پس از تکمیل سناریوی ایجاد اعلامیه و ارسال فیش مرتبط: ۵ آزمون مرورگر مالی و یک آزمون مجوز audit موفق (
chaharsu-payments-e2e-final.log). - کنترل نهایی ثبت مقادیر قبل/بعد حساب بانکی، جلوگیری از ویرایش فرم قدیمی و مجوز حساب مقصد: ۳ موفق (
chaharsu-audit-final.log). - آزمون نمونه قبلی ثبت تیکت: ۳ موفق (
chaharsu-prototype-test.log)؛ آزمون JavaScript موجود: ۱ موفق. بررسی syntax هر سه فایل JS جدید نیز موفق بود. - بررسی نهایی Django بدون خطا؛ کنترل صفحه واقعی با نشست مشتری و اندازه ۳۲۰×۵۶۸ موفق: هر سه خدمت کامل بالای نوار پایین دیده میشوند، overflow افقی وجود ندارد و داراییها نسخهدارند (
chaharsu-live-final.log). سرور توسعه روی0.0.0.0:8000فعال است. - Graphify بهروز و روابط معماری بازبینی شد. Ripwire
--test-gateفهرست آزمونها و مسیرهای dispatch فاقد اتصال ایستای آزمون را ارائه کرد (exit 4، به معنای تعهد بررسی، نه شکست pytest). آزمونهای فوق اجرا شدند؛--quality-deltaبا gating=0 و preexisting-worse=0 پایان یافت. برای کد جدید موارد پیچیدگی و callbackهای چارچوب نیز گزارش شدهاند؛ این گزارش جایگزین تست اجرایی نیست.
گزارشهای فوق در graphify-out/ نگهداری میشوند. آزمونهای PostgreSQL در tests/test_payment_concurrency.py از connectionهای جدا استفاده میکنند و در SQLite صریحاً skip میشوند. تست SQLite اثبات صحت قفل PostgreSQL نیست. پیش از انتشار مالی روی production این ۴ آزمون باید روی پایگاه آزمایشی جداگانه PostgreSQL اجرا شوند؛ در این محیط Docker daemon در دسترس نیست و binary قابل اجرای PostgreSQL موجود نیست.
پشتیبان دیتابیس توسعه پیش از migration در مسیر ignoredِ graphify-out/db-pre-chaharsu.sqlite3 تهیه شد. bootstrap_demo اجرا نشده، دسترسی یا حساب واقعی فرضی ایجاد نشده و عملیات git commit/push انجام نشده است.
انتخاب مشتری و میانبر ایجاد اعلامیه
انتخاب مشتری در ایجاد اعلامیه و انتخاب مشتری برای ثبت فیش، جستوجویی است؛ فهرست کامل مشتریان در HTML بارگیری نمیشود. جستوجو با نام، موبایل فارسی/لاتین، سازمان، شماره یا موضوع تیکت انجام میشود. هر پاسخ حداکثر ۲۰ مشتری فعال را همراه سه سابقه اخیر قابل مشاهده برمیگرداند؛ سوابق خصوصی خارج از مجوز کارشناس در نتیجه یا شمارنده دیده نمیشوند. انتخاب خودکار نتیجه اول وجود ندارد. نام، موبایل، سازمان و موقعیت در کارت انتخابشده نمایش داده میشوند و تغییر عبارت جستوجو، انتخاب قبلی را پاک میکند.
دکمه «ایجاد اعلامیه واریز» در باکس مشتری تیکت و کارت مخاطب، فقط برای کارشناس دارای مجوز ایجاد و مشتری فعال نمایش داده میشود. پارامتر customer در لینک، UUID مشتری است؛ GET تنها مشتری فعال را پیشانتخاب میکند و هیچ اعلامیه یا پیامکی ایجاد نمیکند. POST همچنان شناسه مشتری را با queryset فعال فرم و مجوز مالی سرور اعتبارسنجی میکند. پاسخ جستوجو private, no-store است و داده مشتری در حافظه پایدار مرورگر ذخیره نمیشود.