mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-10-01 16:23:12 +00:00
- Structured manual site entry with 5 separate address fields - Site search via Autocomplete with server-side filtering - Added PO number field to proposal form and AddPoNumber migration - Added Other to ServiceCategory enum with custom category text input - Label consistency: "Work Order #" → "Work Order Number", "PO Number" - Top row reflow to 3-column layout (4/4/4) - Dev PDF generation script for local testing
52 lines
1.5 KiB
C#
52 lines
1.5 KiB
C#
using Amazon.DynamoDBv2;
|
|
using Amazon.DynamoDBv2.Model;
|
|
using ProposalSystem.Application.DTOs;
|
|
using ProposalSystem.Application.Interfaces;
|
|
|
|
namespace ProposalSystem.Infrastructure.Services;
|
|
|
|
public class SiteService : ISiteService
|
|
{
|
|
private readonly IAmazonDynamoDB _dynamo;
|
|
private const string TableName = "verified-sites";
|
|
|
|
public SiteService(IAmazonDynamoDB dynamo)
|
|
{
|
|
_dynamo = dynamo;
|
|
}
|
|
|
|
public async Task<IReadOnlyList<SiteResponse>> SearchAsync(string query, CancellationToken ct = default)
|
|
{
|
|
var upper = query.ToUpper();
|
|
|
|
var request = new ScanRequest
|
|
{
|
|
TableName = TableName,
|
|
FilterExpression = "contains(siteCode, :q)",
|
|
ExpressionAttributeValues = new Dictionary<string, AttributeValue>
|
|
{
|
|
{ ":q", new AttributeValue { S = upper } }
|
|
},
|
|
Limit = 20,
|
|
};
|
|
|
|
var response = await _dynamo.ScanAsync(request, ct);
|
|
|
|
return response.Items
|
|
.Select(item => new SiteResponse(
|
|
GetString(item, "siteCode") ?? "",
|
|
GetString(item, "fullAddress"),
|
|
GetString(item, "address"),
|
|
GetString(item, "city"),
|
|
GetString(item, "state"),
|
|
GetString(item, "zip")
|
|
))
|
|
.OrderBy(s => s.SiteCode)
|
|
.ToList();
|
|
}
|
|
|
|
private static string? GetString(Dictionary<string, AttributeValue> item, string key)
|
|
{
|
|
return item.TryGetValue(key, out var attr) ? attr.S : null;
|
|
}
|
|
}
|