Sari la conținut

Context de sistem

Această pagină descrie componentele deployabile ale ASYDATA și fluxul de date dintre ele — vederea „din avion” peste sistem, înainte de a intra în straturi de cod (Clean Architecture) sau în detaliile event-driven (Flux event-driven).

ASYDATA este un modular monolith .NET 10 (un singur proces WebApi care găzduiește toate modulele de business), plus un proces worker separat pentru consumul de evenimente și integrarea cu Telegram. Restul componentelor sunt servicii de infrastructură (date, mesagerie, search, fișiere) și integrări externe specifice Moldovei.

┌──────────────────────────────────────────────┐
Browser (SPA) ─────► │ Caddy (reverse proxy) │
│ / → wwwroot (React SPA) │
│ /api/* → Kestrel (Asy.WebApi) │
└───────────────┬──────────────────────────────┘
│
┌──────────────▼───────────────┐
│ Asy.WebApi (.NET 10) │
│ modular monolith + OutboxRelay│
└──┬─────┬──────┬─────┬─────────┘
│ │ │ │
┌───────────▼┐ ┌──▼───┐ ┌▼────┐ ▼ (HTTP) ──► SFS e-Factură
│ Postgres │ │ Elastic│ MinIO│ ──► MSign (Prasada)
│ (RLS) │ │ search │ (S3) │ ──► Google OAuth
└─────┬──────┘ └────────┘ └─────┘
│
│ outbox_events ─► Kafka topic `firm.events`
▼
┌──────────────────────────────────┐
│ Asy.Workers.Telegram (worker) │
│ FirmEventsConsumer (telegram) │ ──► Telegram Bot API
│ WebPushConsumer (webpush) │ ──► Browser Web Push
│ TelegramPollerService │
│ ContractInvoiceGenerator │
└──────────────────────────────────┘
ComponentăRolTehnologie
Frontend SPAUI pentru contabili: clienți, facturi, taskuri, dashboardReact 19 + Vite + TanStack
CaddyReverse proxy: servește SPA + rutează /api/* la backendCaddy
Asy.WebApiAPI-ul principal, modular monolith + relay outbox.NET 10, Minimal API
PostgresBaza de date pooled multi-tenant (RLS pe firm_id)PostgreSQL
ElasticsearchFull-text search peste clienți, facturi, operațiuniElasticsearch 9
MinIOStocare fișiere (PDF oferte/contracte, atașamente e-Factură)MinIO (S3)
KafkaMagistrala de evenimente (firm.events)Confluent.Kafka
Asy.Workers.TelegramProces worker: consumeri Kafka + bot Telegram.NET 10 worker

Aplicația de browser (React 19 + Vite + TanStack Router/Query + Tailwind). În producție build-ul static este copiat în wwwroot/ și servit de Caddy, care rutează:

  • / și restul căilor → index.html (routing client-side TanStack);
  • /api/* → Kestrel (Asy.WebApi).

Same-origin în producție → sesiunea pe cookie e suficientă (vezi Autentificare). În dev, SPA rulează pe :5173/:5174 și backend-ul activează CORS cu AllowCredentials pentru aceste origini.

Procesul principal .NET 10. Conține:

  • modulele de business descoperite la startup (assembly scan Odoo-style — vezi asydata-app-backend-dotnet/src/Asy.WebApi/Program.cs și Clean Architecture + module);
  • TenantContextMiddleware care rezolvă tenantul din header X-Firm-Id / claim firm_id (asydata-app-backend-dotnet/src/Asy.Platform/Tenancy/TenantContextMiddleware.cs);
  • OutboxRelayService — un BackgroundService care publică evenimentele din outbox_events în Kafka (asydata-app-backend-dotnet/src/Asy.Infrastructure/Persistence/Outbox/OutboxRelayService.cs);
  • alte workere periodice in-process (generare facturi recurente, remindere, poll e-Factură).

Comunică sincron cu Postgres (EF Core), Elasticsearch și MinIO; sincron prin HTTP cu serviciile externe (SFS, MSign, Google); și asincron prin Kafka cu worker-ul.

Un singur Postgres partajat de toate firmele (pooled multi-tenant). Tabelele operaționale au coloana firm_id; izolarea este planificată prin Postgres Row-Level Security cu un GUC app.firm_id setat per request, peste filtrul explicit din cod (defense-in-depth). Detalii în Multi-tenancy și RLS. Tot aici stau și tabelele ASP.NET Core Identity (AspNetUsers, …) și tabela outbox_events.

  • Elasticsearch — full-text search multi-câmp și multilingv (RO/RU/EN) peste clienți, facturi e-Factură, operațiuni. Filtru obligatoriu pe firm_id în fiecare query.
  • MinIO — stocare S3-compatibilă pentru PDF-uri (oferte, contracte), atașamente la facturi și alte fișiere.

Magistrala de evenimente. WebApi publică pe topicul firm.events (cheie de partiție = firm_id, header event-type = numele CLR complet al evenimentului). Mai mulți consumeri independenți, în grupuri separate, primesc fiecare toate evenimentele. Vezi Flux event-driven.

Proces separat (asydata-app-backend-dotnet/src/Workers/Asy.Workers.Telegram/Program.cs) care reutilizează aceeași infrastructură ca WebApi (același DbContext, aceleași chei de criptare — fără drift). Găzduiește:

ServiciuRol
FirmEventsConsumerConsumă firm.events (grup telegram-worker) → mesaje/carduri Telegram
WebPushConsumerConsumă firm.events (grup webpush-worker) → notificări browser Web Push
TelegramPollerServiceLong-polling pentru update-uri inbound de la Telegram
ContractInvoiceGeneratorGenerator periodic: contracte recurente → facturi
Sistem externDirecțieScopPagină
SFS e-FacturăWebApi → SFS (HTTP)Sincronizare facturi primite/emiseSFS e-Factură
MSign (Prasada)WebApi → MSign (HTTP)Semnătură electronică guvernamentalăMSign
Telegram Bot APIWorker ↔ TelegramNotificări + acțiuni (aprobări facturi)Telegram bot
Google OAuthWebApi ↔ GoogleLogin (identitate)Autentificare
Browser Web PushWorker → browserNotificări in-appNotificări și Web Push
  • Browser ↔ WebApi — JSON peste HTTPS; sesiunea pe cookie asy.session (HttpOnly).
  • WebApi ↔ Postgres — interogări EF Core; fiecare request poartă firm_id pentru izolare.
  • WebApi → Kafka → Worker — evenimente de domeniu serializate JSON pe firm.events (ex. InvoiceReceivedEvent, PermissionRequestedEvent).
  • Worker → Telegram / Web Push — mesaje formatate (RO) către contabili.
  • WebApi → SFS / MSign — apeluri HTTP autentificate cu credențialele firmei (criptate în DB).

Pentru mecanica completă a fluxului asincron, continuă cu Flux event-driven. Pentru stratificarea internă a WebApi, vezi Clean Architecture + module.