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.
Vederea de ansamblu
Secțiune intitulată „Vederea de ansamblu” ┌──────────────────────────────────────────────┐ 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 │ └──────────────────────────────────┘Componente
Secțiune intitulată „Componente”| Componentă | Rol | Tehnologie |
|---|---|---|
| Frontend SPA | UI pentru contabili: clienți, facturi, taskuri, dashboard | React 19 + Vite + TanStack |
| Caddy | Reverse proxy: servește SPA + rutează /api/* la backend | Caddy |
Asy.WebApi | API-ul principal, modular monolith + relay outbox | .NET 10, Minimal API |
| Postgres | Baza de date pooled multi-tenant (RLS pe firm_id) | PostgreSQL |
| Elasticsearch | Full-text search peste clienți, facturi, operațiuni | Elasticsearch 9 |
| MinIO | Stocare fișiere (PDF oferte/contracte, atașamente e-Factură) | MinIO (S3) |
| Kafka | Magistrala de evenimente (firm.events) | Confluent.Kafka |
Asy.Workers.Telegram | Proces worker: consumeri Kafka + bot Telegram | .NET 10 worker |
Frontend React SPA
Secțiune intitulată „Frontend React SPA”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.
Asy.WebApi (modular monolith)
Secțiune intitulată „Asy.WebApi (modular monolith)”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); TenantContextMiddlewarecare rezolvă tenantul din headerX-Firm-Id/ claimfirm_id(asydata-app-backend-dotnet/src/Asy.Platform/Tenancy/TenantContextMiddleware.cs);OutboxRelayService— unBackgroundServicecare publică evenimentele dinoutbox_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.
Postgres (RLS)
Secțiune intitulată „Postgres (RLS)”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 și MinIO
Secțiune intitulată „Elasticsearch și MinIO”- 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.
Kafka — firm.events
Secțiune intitulată „Kafka — firm.events”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.
Worker Asy.Workers.Telegram
Secțiune intitulată „Worker Asy.Workers.Telegram”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:
| Serviciu | Rol |
|---|---|
FirmEventsConsumer | Consumă firm.events (grup telegram-worker) → mesaje/carduri Telegram |
WebPushConsumer | Consumă firm.events (grup webpush-worker) → notificări browser Web Push |
TelegramPollerService | Long-polling pentru update-uri inbound de la Telegram |
ContractInvoiceGenerator | Generator periodic: contracte recurente → facturi |
Servicii externe
Secțiune intitulată „Servicii externe”| Sistem extern | Direcție | Scop | Pagină |
|---|---|---|---|
| SFS e-Factură | WebApi → SFS (HTTP) | Sincronizare facturi primite/emise | SFS e-Factură |
| MSign (Prasada) | WebApi → MSign (HTTP) | Semnătură electronică guvernamentală | MSign |
| Telegram Bot API | Worker ↔ Telegram | Notificări + acțiuni (aprobări facturi) | Telegram bot |
| Google OAuth | WebApi ↔ Google | Login (identitate) | Autentificare |
| Browser Web Push | Worker → browser | Notificări in-app | Notificări și Web Push |
Ce date circulă
Secțiune intitulată „Ce date circulă”- Browser ↔ WebApi — JSON peste HTTPS; sesiunea pe cookie
asy.session(HttpOnly). - WebApi ↔ Postgres — interogări EF Core; fiecare request poartă
firm_idpentru 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.