fix: resolve 12 critical/high issues from code review across backend, frontend, and infra
Backend (7 fixes):
- wallet-service: remove conflicting EF Ignore() calls for mapped backing fields
- fnb-engine: remove KitchenTicket short constructor that set productId=orderItemId
- fnb-engine: replace fire-and-forget Task.Run with direct await for inventory deduction
- TenantMiddleware: implement PostgreSQL RLS SET LOCAL in 4 services (wallet, fnb, inventory, catalog)
- order-service: fix SQL injection pattern in TenantMiddleware with Guid.ToString("D")
- order-service: add ValidateShopAccess() authorization check in SignalR PosHub
- 4 services: register IDbConnection (NpgsqlConnection) in DI for RLS middleware
Frontend (3 fixes):
- PosDataService: return Success=false (not true) when PayOrder response parsing fails
- QrPayment: add _disposed guard to prevent timer race condition after component disposal
- BFF OrderController: add [Authorize] attribute to require JWT for all endpoints
Infrastructure (3 fixes):
- docker-compose: upgrade PostgreSQL 15-alpine to 16-alpine per project spec
- init-databases.sh: add 4 missing marketing service databases (mkt_*)
- Traefik routes: add wallet, catalog, booking routers and /api/v1/stock path
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -130,6 +130,7 @@ else
|
||||
private bool _isLoading = true;
|
||||
private bool _isProcessing;
|
||||
private string? _errorMessage;
|
||||
private bool _disposed = false;
|
||||
|
||||
// EN: QR providers / VI: Nhà cung cấp QR
|
||||
private readonly string[] _providers = { "VietQR", "MoMo", "ZaloPay" };
|
||||
@@ -160,7 +161,7 @@ else
|
||||
{
|
||||
_countdownTimer = new Timer(_ =>
|
||||
{
|
||||
if (_timerSeconds > 0)
|
||||
if (!_disposed && _timerSeconds > 0)
|
||||
{
|
||||
_timerSeconds--;
|
||||
InvokeAsync(StateHasChanged);
|
||||
@@ -227,5 +228,9 @@ else
|
||||
NavigationManager.NavigateTo($"/pos/{ShopId}/payment/method-select?orderId={_resolvedOrderId}");
|
||||
}
|
||||
|
||||
public void Dispose() => _countdownTimer?.Dispose();
|
||||
public void Dispose()
|
||||
{
|
||||
_disposed = true;
|
||||
_countdownTimer?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,7 +806,7 @@ public class PosDataService
|
||||
}
|
||||
return System.Text.Json.JsonSerializer.Deserialize<PayOrderResponse>(json, _jsonOptions);
|
||||
}
|
||||
catch { return new PayOrderResponse(true, null, null, null, null, null); }
|
||||
catch { return new PayOrderResponse(false, null, null, null, null, "Không thể xử lý phản hồi từ máy chủ"); }
|
||||
}
|
||||
return new PayOrderResponse(false, null, null, null, null, "Payment failed");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using WebClientTpos.Server.Infrastructure;
|
||||
using WebClientTpos.Server.Models;
|
||||
@@ -10,6 +11,7 @@ namespace WebClientTpos.Server.Controllers;
|
||||
/// VI: Controller đơn hàng — proxy đến OrderService cho đơn hàng, POS thanh toán, dashboard.
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/bff")]
|
||||
public class OrderController : ControllerBase
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user