chore: init project

This commit is contained in:
cesnimda
2026-06-30 15:53:32 +02:00
commit f43ef5f945
94 changed files with 4405 additions and 0 deletions
@@ -0,0 +1,59 @@
using InboxIntel.Application.Abstractions;
using InboxIntel.Application.Common;
using InboxIntel.Application.DTOs;
using InboxIntel.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
namespace InboxIntel.Infrastructure.Search;
/// <summary>
/// Structured + full-text search. Structured filters compose as SQL WHERE
/// clauses; free text uses PostgreSQL FTS via the generated SearchVector column
/// (EF.Functions.ToTsVector/Matches translate to @@ / to_tsquery).
/// </summary>
public class SearchService : ISearchService
{
private readonly AppDbContext _db;
public SearchService(AppDbContext db) => _db = db;
public async Task<PagedResult<EmailSummaryDto>> SearchAsync(Guid userId, SearchRequestDto r, CancellationToken ct = default)
{
var q = _db.Emails.AsNoTracking().Where(e => e.UserId == userId);
if (!string.IsNullOrWhiteSpace(r.Sender))
q = q.Where(e => e.Sender!.Address.Contains(r.Sender) || e.Sender.DisplayName!.Contains(r.Sender));
if (!string.IsNullOrWhiteSpace(r.Domain))
q = q.Where(e => e.Sender!.Domain!.Name == r.Domain);
if (r.From is { } from)
q = q.Where(e => e.SentAtUtc >= new DateTimeOffset(from.ToDateTime(TimeOnly.MinValue), TimeSpan.Zero));
if (r.To is { } to)
q = q.Where(e => e.SentAtUtc <= new DateTimeOffset(to.ToDateTime(TimeOnly.MaxValue), TimeSpan.Zero));
if (r.IsUnread is { } unread)
q = q.Where(e => e.IsUnread == unread);
if (r.HasAttachments is { } att)
q = q.Where(e => e.HasAttachments == att);
if (!string.IsNullOrWhiteSpace(r.Query))
{
// PostgreSQL full-text match against the generated tsvector.
var term = r.Query.Trim();
q = q.Where(e => e.SearchVector!.Matches(EF.Functions.PlainToTsQuery("english", term)));
}
var total = await q.CountAsync(ct);
var items = await q
.OrderByDescending(e => e.SentAtUtc)
.Skip((r.Page - 1) * r.PageSize)
.Take(r.PageSize)
.Select(e => new EmailSummaryDto(
e.Id, e.GmailMessageId, e.Subject, e.Snippet,
e.Sender!.Address, e.Sender.DisplayName, e.SentAtUtc,
e.IsUnread, e.HasAttachments, e.SizeEstimateBytes, e.Category))
.ToListAsync(ct);
return new PagedResult<EmailSummaryDto>
{
Items = items, Page = r.Page, PageSize = r.PageSize, TotalCount = total
};
}
}