Files
octopus/myproject/customers/urls.py
Andrey Smakotin b1855cc9f0 Рефакторинг системы кошелька клиентов
Основные изменения:
- Переход от денормализованного поля wallet_balance к вычисляемому балансу
- Баланс теперь вычисляется как SUM(signed_amount) транзакций
- Добавлено кеширование баланса для производительности (5 минут)
- Новая модель WalletTransaction с полем signed_amount (может быть +/-)
- WalletService для всех операций с кошельком (deposit, spend, adjustment)
- Защита от отрицательного баланса и race conditions через select_for_update
- Добавлен balance_after в каждую транзакцию для аудита
- Обновлены миграции для переноса данных из старой схемы

Улучшения безопасности:
- Атомарные транзакции для всех операций с балансом
- Блокировка строк при модификации баланса
- Валидация недостаточности средств
- Обязательное описание для корректировок баланса

UI/UX изменения:
- Обновлён вывод баланса кошелька в деталях клиента
- Добавлена история транзакций с типами и описаниями
- Цветовая индикация положительных транзакций (зелёный)

Техническая документация:
- Добавлены docstrings для всех методов WalletService
- Комментарии к критичным участкам кода
- Примеры использования в docstrings
2025-12-28 00:02:09 +03:00

24 lines
1.1 KiB
Python

from django.urls import path
from . import views
app_name = 'customers'
urlpatterns = [
path('', views.customer_list, name='customer-list'),
path('create/', views.customer_create, name='customer-create'),
path('import/', views.customer_import, name='customer-import'),
path('export/', views.customer_export, name='customer-export'),
path('<int:pk>/', views.customer_detail, name='customer-detail'),
path('<int:pk>/edit/', views.customer_update, name='customer-update'),
path('<int:pk>/delete/', views.customer_delete, name='customer-delete'),
path('<int:pk>/wallet/deposit/', views.wallet_deposit, name='wallet-deposit'),
path('<int:pk>/wallet/withdraw/', views.wallet_withdraw, name='wallet-withdraw'),
# Contact channels
path('<int:customer_pk>/channels/add/', views.add_contact_channel, name='add-contact-channel'),
path('channels/<int:pk>/delete/', views.delete_contact_channel, name='delete-contact-channel'),
# AJAX API endpoints
path('api/search/', views.api_search_customers, name='api-search-customers'),
path('api/create/', views.api_create_customer, name='api-create-customer'),
]