Pokaż spis treści

Tasko

Architektura i granice modułów

Architektura Tasko ma postać modułowego monolitu opartego o Clean Architecture. Warstwy Presentation, Application, Domain i Infrastructure oddzielają kontrakty HTTP, przypadki użycia, reguły domenowe, dostęp do danych i integracje.

Zakres odpowiedzialności

Backend składa się z WebAPI jako composition root, App.Control dla danych globalnych oraz modułów biznesowych Core, Settings, Chat, RecurringTasks i Mcp. Frontend obejmuje Tasko.Client dla użytkowników firmowych oraz Tasko.Platform dla administratorów platformy.

Warstwa Application zawiera use case, komendy, zapytania, walidatory i porty repozytoriów. Domain utrzymuje model biznesowy bez zależności od EF Core i ASP.NET Core.

Przebieg systemowy

Przetworzenie żądania: Tasko.Client albo Tasko.Platform wysyła żądanie do WebAPI. Minimal API mapuje kontrakt HTTP, Application wykonuje przypadek użycia, Domain egzekwuje reguły, a Infrastructure zapisuje lub odczytuje dane z właściwej bazy.

Dodanie funkcji biznesowej: nowa funkcja powinna otrzymać własny use case, kontrakt, walidację i endpoint w odpowiednim module. Warstwa Domain nie przyjmuje zależności od EF Core ani ASP.NET Core, więc logika pozostaje testowalna poza transportem HTTP.

Obsługa modułu opcjonalnego: Presentation może oznaczyć endpoint przez RequireModule. To pozwala WebAPI odrzucić żądanie dla tenanta, który nie ma włączonej funkcji, bez rozpraszania warunku po komponentach UI.

Przepływ procesu

flowchart LR
  A[Tasko.Client] --> C[WebAPI]
  B[Tasko.Platform] --> C
  C --> D[App.Control]
  C --> E[App.Modules.Core]
  C --> F[App.Modules.Settings]
  C --> G[App.Modules.Chat]
  C --> H[App.Modules.RecurringTasks]
  C --> I[App.Modules.Mcp]
  D --> J[(Control DB)]
  E --> K[(Baza tenanta)]
  F --> K
  G --> K
  H --> K

Reguły techniczne

Dozwolony kierunek zależności to Presentation -> Application -> Domain oraz Infrastructure -> Application -> Domain. Domain nie zależy od pozostałych warstw.

Każdy moduł ma osobną granicę odpowiedzialności i może oznaczać endpointy przez RequireModule, dzięki czemu przełączniki tenantowe nie mieszają się z logiką UI.