NALU/src/Nalu.Api/Data/Repositories/WebhookEventRepository.cs
Ricardo Carneiro ea6cdb5395 Initial commit — NALU AI web platform
- ASP.NET Core 9 Razor Pages + Minimal API hybrid
- 14 validators (CPF, CEP, CNPJ, email, phone, name, yes-no, birthdate, handoff, cancel-intent, company-name, plate-br, postal-code, validate_reply)
- OAuth login (Google, Microsoft, GitHub) + cookie auth
- MongoDB usage tracking + CEP cache collection
- Stripe checkout with inline PriceData (no Price IDs)
- MCP server for Claude Code / Cursor integration
- Playground (10 calls/IP/day, no auth)
- Docs: Quickstart, API Reference, N8N, MCP, Créditos, Erros, Fluxos
- Credit system: 3 cr standard validators, 5 cr validate_reply
- SmartSuggestion: contextual re-ask via IA when obtained=false
- Per-IP rate limiting + daily cap + shared-IP abuse detection
- Lightbox for comic images
- Validadores page split: Brasileiros / Universais + Em breve

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 16:39:04 -03:00

41 lines
1.2 KiB
C#

using MongoDB.Driver;
using Nalu.Web.Data.Models;
namespace Nalu.Web.Data.Repositories;
public class WebhookEventRepository(MongoDbContext db)
{
/// <summary>
/// Attempts to record a Stripe event for idempotency.
/// Returns true if inserted (first time seen), false if already processed.
/// </summary>
public async Task<bool> TryInsertAsync(string stripeEventId, string eventType, CancellationToken ct = default)
{
if (!db.IsConnected) return true; // fallback: allow processing if DB unavailable
try
{
await db.WebhookEvents.InsertOneAsync(new WebhookEvent
{
StripeEventId = stripeEventId,
EventType = eventType
}, cancellationToken: ct);
return true;
}
catch (MongoWriteException ex) when (ex.WriteError.Category == ServerErrorCategory.DuplicateKey)
{
return false;
}
}
public async Task<bool> ExistsAsync(string stripeEventId, CancellationToken ct = default)
{
if (!db.IsConnected) return false;
return await db.WebhookEvents
.Find(w => w.StripeEventId == stripeEventId)
.AnyAsync(ct);
}
}