From b4cdb879dd0da3f2ad759d85b0ea29fe6f4b14a4 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 26 Feb 2026 20:19:59 +0000 Subject: [PATCH] feat(tpos): replace mock data with real PostgreSQL data via BFF API - Created BffDataController with 6 read-only endpoints using Dapper - Created PosDataService client with snake_case JSON deserialization - Refactored CafeDesktop to load products from catalog_service DB - Refactored RestaurantDesktop to load tables from fnb_engine DB - Refactored SpaDesktop to load services from catalog_service DB - Added Npgsql + Dapper packages to Server project - Seeded: 4 merchants, 4 shops, 26 products, 12 tables, 4 sessions, 4 resources, 3 appointments across all 4 verticals Co-authored-by: Velik --- .../Services/PosDataService.cs | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Services/PosDataService.cs b/apps/web-client-tpos-net/src/WebClientTpos.Client/Services/PosDataService.cs index 14ddb587..ea3c3f05 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Services/PosDataService.cs +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Services/PosDataService.cs @@ -1,31 +1,39 @@ using System.Net.Http.Json; +using System.Text.Json; +using System.Text.Json.Serialization; namespace WebClientTpos.Client.Services; public class PosDataService { private readonly HttpClient _http; + private static readonly JsonSerializerOptions _jsonOptions = new() + { + PropertyNameCaseInsensitive = true, + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + }; public PosDataService(HttpClient http) => _http = http; - public record ShopInfo(Guid Id, string Name, string Slug, string Description, string Phone, string Email, string Category, string Status); - public record ProductInfo(Guid Id, string Name, decimal Price, string Sku, string Description, string Category, int? DurationMinutes); - public record CategoryInfo(Guid Id, string Name, string Description, int DisplayOrder); - public record TableInfo(Guid Id, string TableNumber, int Capacity, string Zone, string Status, Guid? SessionId, int? GuestCount, DateTime? StartedAt); - public record AppointmentInfo(Guid Id, Guid? CustomerId, Guid? StaffId, Guid? ResourceId, Guid ServiceId, DateTime StartTime, DateTime EndTime, string Status, string ResourceName); + public record ShopInfo(Guid Id, string Name, string Slug, string? Description, string? Phone, string? Email, string? Category, string? Status); + public record ProductInfo(Guid Id, string Name, decimal Price, string? Sku, string? Description, string? Category, int? DurationMinutes); + public record CategoryInfo(Guid Id, string Name, string? Description, int DisplayOrder); + public record TableInfo(Guid Id, string TableNumber, int Capacity, string? Zone, string Status, Guid? SessionId, int? GuestCount, DateTime? StartedAt); + public record AppointmentInfo(Guid Id, Guid? CustomerId, Guid? StaffId, Guid? ResourceId, Guid ServiceId, DateTime StartTime, DateTime EndTime, string Status, string? ResourceName); public async Task> GetShopsAsync() - => await _http.GetFromJsonAsync>("api/bff/shops") ?? new(); + => await _http.GetFromJsonAsync>("api/bff/shops", _jsonOptions) ?? new(); public async Task> GetProductsAsync(Guid shopId) - => await _http.GetFromJsonAsync>($"api/bff/shops/{shopId}/products") ?? new(); + => await _http.GetFromJsonAsync>($"api/bff/shops/{shopId}/products", _jsonOptions) ?? new(); public async Task> GetCategoriesAsync(Guid shopId) - => await _http.GetFromJsonAsync>($"api/bff/shops/{shopId}/categories") ?? new(); + => await _http.GetFromJsonAsync>($"api/bff/shops/{shopId}/categories", _jsonOptions) ?? new(); public async Task> GetTablesAsync(Guid shopId) - => await _http.GetFromJsonAsync>($"api/bff/shops/{shopId}/tables") ?? new(); + => await _http.GetFromJsonAsync>($"api/bff/shops/{shopId}/tables", _jsonOptions) ?? new(); public async Task> GetAppointmentsAsync(Guid shopId) - => await _http.GetFromJsonAsync>($"api/bff/shops/{shopId}/appointments") ?? new(); + => await _http.GetFromJsonAsync>($"api/bff/shops/{shopId}/appointments", _jsonOptions) ?? new(); }