diff --git a/src/Meezi.API/Controllers/SmsController.cs b/src/Meezi.API/Controllers/SmsController.cs
index 6d43313..a765bb3 100644
--- a/src/Meezi.API/Controllers/SmsController.cs
+++ b/src/Meezi.API/Controllers/SmsController.cs
@@ -7,33 +7,64 @@ using Meezi.Shared;
namespace Meezi.API.Controllers;
+///
+/// Marketing SMS — bring-your-own-provider. Each café configures its OWN
+/// Kavenegar API key + sender line; the platform does not sell SMS.
+///
[Route("api/cafes/{cafeId}/sms")]
public class SmsController : CafeApiControllerBase
{
private readonly ISmsMarketingService _smsMarketingService;
- private readonly ISmsService _smsService;
private readonly IValidator _campaignValidator;
public SmsController(
ISmsMarketingService smsMarketingService,
- ISmsService smsService,
IValidator campaignValidator)
{
_smsMarketingService = smsMarketingService;
- _smsService = smsService;
_campaignValidator = campaignValidator;
}
+ [HttpGet("settings")]
+ public async Task GetSettings(string cafeId, ITenantContext tenant, CancellationToken cancellationToken)
+ {
+ if (EnsureCafeAccess(cafeId, tenant) is { } denied) return denied;
+ if (EnsureManager(tenant) is { } forbidden) return forbidden;
+
+ var data = await _smsMarketingService.GetSettingsAsync(cafeId, cancellationToken);
+ return Ok(new ApiResponse(true, data));
+ }
+
+ [HttpPut("settings")]
+ public async Task UpdateSettings(
+ string cafeId,
+ [FromBody] UpdateSmsSettingsRequest request,
+ ITenantContext tenant,
+ CancellationToken cancellationToken)
+ {
+ if (EnsureCafeAccess(cafeId, tenant) is { } denied) return denied;
+ if (EnsureManager(tenant) is { } forbidden) return forbidden;
+
+ var (success, data, code, message) = await _smsMarketingService.UpdateSettingsAsync(
+ cafeId, request, cancellationToken);
+ if (!success)
+ {
+ return code switch
+ {
+ "NOT_FOUND" => NotFound(new ApiResponse