profileShare

rasmusjy / splitapp-backend-clean-onion

Read-only snapshot

No repository description.

main default branch 429 files Expires Sep 13, 2026, 9:06 AM
arhitektuur.md 11,794 bytes

SplitApp Onion Arhitektuur — joonis ja võrdlus TalTech-i loenguga

1. Sibula-joonis (ringid seestpoolt väljapoole)

                    ┌─────────────────────────────────────────────────┐
                    │              WebApp (Presentation)              │
                    │   MVC Controllers · API Controllers (v1)        │
                    │   Areas/Admin · Areas/Identity · Views          │
                    │   ViewModels · Program.cs (DI Composition Root) │
                    │  ┌───────────────────────────────────────────┐  │
                    │  │        App.BLL (Application Services)     │  │
                    │  │   TripService · ExpenseService ·          │  │
                    │  │   SettlementService · AdminServices       │  │
                    │  │   (kasutab IAppUnitOfWork liidese kaudu)  │  │
                    │  │  ┌─────────────────────────────────────┐  │  │
                    │  │  │       App.Domain (Core / Süda)      │  │  │
                    │  │  │   Entities: Trip, Expense, ...      │  │  │
                    │  │  │   Enums, AppUser, AppRole           │  │  │
                    │  │  │   Contracts: IAppUnitOfWork,        │  │  │
                    │  │  │             ITripRepository, ...    │  │  │
                    │  │  │  ┌───────────────────────────────┐  │  │  │
                    │  │  │  │ Base.Domain · Base.Contracts  │  │  │  │
                    │  │  │  │ BaseEntity · IBaseRepository  │  │  │  │
                    │  │  │  │ IUnitOfWork · LangStr         │  │  │  │
                    │  │  │  └───────────────────────────────┘  │  │  │
                    │  │  └─────────────────────────────────────┘  │  │
                    │  └───────────────────────────────────────────┘  │
                    └─────────────────────────────────────────────────┘
      ▲                                                                 ▲
      │                                                                 │
      │    ┌────────────────────────────────────┐                       │
      │    │  App.DAL.EF (Infrastructure)       │                       │
      │    │  AppDbContext · AppUnitOfWork      │─── implementeerib ───┘
      │    │  Repositories · Migrations         │      IAppUnitOfWork,
      │    │  Seeding · ServiceCollectionExt    │      ITripRepository
      │    └────────────────────────────────────┘
      │                  ▲
      │                  │ plugitav (saab vahetada nt Dapperi vastu)
      │
      │    ┌────────────────────────────────────┐
      └────│  App.DTO · App.Resources           │
           │  v1 DTOs · Mappers · .resx         │
           └────────────────────────────────────┘

Tähtis: Infrastructure (DAL.EF) on väljaspool sibulat ja osutab sissepoole — just nagu TalTech-i loengus: "Infrastructure -> Domain <- Application <- Web".


2. Sõltuvuste graaf (nooled = ProjectReference)

  Base.Domain ◄──── Base.Contracts
        ▲                 ▲
        │                 │
        └──── App.Domain ─┤
                  ▲       │
         ┌────────┼───────┴─────────┐
         │        │                 │
     App.DTO   App.BLL          App.DAL.EF
         ▲        ▲                 ▲
         │        │                 │
         └────────┴──── WebApp ─────┘
                (Composition Root)

Tähelepanu: App.BLL ei viita App.DAL.EF-le. BLL näeb ainult liideseid (IAppUnitOfWork), mis elavad Domain-is. See ongi Onion-i "Dependency Inversion" — täpselt nagu loengus kirjeldatud.


3. Võrdlus TalTech-i loengu nõuetega

TalTech-i Clean/Onion nõue SplitApp teostus Vastab?
"Who owns the interfaces" → liidesed elavad Domain-is IAppUnitOfWork, ITripRepository jt asuvad App.Domain/Contracts/ Jah
Entities in Domain (mitte DAL-is) Kõik entiteedid App.Domain/, POCO, ilma EF-atribuutideta Jah
Infrastructure → Domain (pöördsuund) App.DAL.EF viitab App.Domain-le, mitte vastupidi Jah
Application ← Web, Application → Domain WebApp → App.BLL → App.Domain Jah
Infrastructure pluginatav BLL kasutab ainult liideseid; EF-i saaks teoreetiliselt Dapperi vastu vahetada Jah
Repository pattern BaseRepository.cs + spetsiifilised repod Jah
Unit of Work (SaveChangesAsync() atomic commit) AppUnitOfWork.cs, lazy-load repod Jah
DTOs ("dumb objects, no logic") App.DTO/v1/ + Mappers Jah
Mappers entiteet↔DTO Staatilised mapper-klassid App.DTO/Mappers/ Jah
Dependency Injection (konstruktori kaudu) Teenused AddScoped-ina Program.cs-is, konstruktori-injection Jah
DI Composition Root välimises ringis Ainult Program.cs teab konkreetseid implementatsioone Jah
SOLID → DIP: kõrgemad kihid sõltuvad abstraktsioonidest BLL sõltub IAppUnitOfWork-ist, mitte AppUnitOfWork-ist Jah
ViewModelid (mitte entiteedid vaadetes) WebApp/Models/ sisaldab ViewModel-eid Jah

4. Lisaväärtused üle loengu miinimumi

  • Versioneeritud API ([ApiVersion("1.0")], api/v{version}/...) — Asp.Versioning
  • JWT + Cookie hübriid-autentimine — MVC ja REST samaaegselt
  • Admin Area eraldi teenustega (12 AdminService-t)
  • Lokaliseerimine läbi LangStr (Domain-is) + .resx (App.Resources/)
  • DataProtection võtmed DB-s (PersistKeysToDbContext)
  • PostgreSQL + Docker tootmiseks
  • Swagger versioonidega (ConfigureSwaggerOptions.cs)

5. Projektide detailne kirjeldus

Sisemine südamik

Base.DomainBaseEntity (Guid Id, CreatedAt, UpdatedAt), LangStr (mitmekeelne string, implitsiitne cast string ↔ LangStr).

Base.Contracts — generic abstraktsioonid:

  • IBaseRepository<T> — CRUD (GetAllAsync, GetByIdAsync, Add, Update, RemoveAsync, ExistsAsync)
  • IUnitOfWorkSaveChangesAsync()
  • IBaseEntity

App.Domain — puhas äridomeen, POCO entiteedid:

  • Trip, Expense, ExpenseSplit — reisid ja kulud
  • TripParticipant, TripInvitation — osavõtjad ja kutsed
  • SettlementPlan, SettlementPayment — arveldused
  • TripPoll, TripPollOption, TripPollVote — küsitlused
  • TripWishlistItem, TripWishlistVote — sooviste nimekiri
  • BudgetCategory, Currency, SplitPreset — abi-entiteedid
  • Identity/AppUser, AppRole
  • Contracts/IAppUnitOfWork + repo-liidesed (ITripRepository jne)
  • Enumid: ETripStatus, EParticipantRole, ESplitMethod, ESettlementStatus, EPaymentStatus, EInvitationStatus, EWishlistPriority, EWishlistCategory

Infrastructure — DAL

App.DAL.EF — EF Core + PostgreSQL (Npgsql):

  • AppDbContext.csIdentityDbContext<AppUser, AppRole, Guid>, ~13 DbSet, UTC DateTime converter, unique indexid, DeleteBehavior.Restrict, LangStr JSON-seerimine.
  • AppUnitOfWork.cs — lazy-load repod, generic GetRepository<T>().
  • Repositories/BaseRepository<T> + spetsiifilised (nt TripRepository GetUserTripsAsync, GetByIdWithDetailsAsync).
  • Migrations/ — EF Core migreeringud.
  • Seeding/InitialData.cs, AppDataInit.cs.
  • ServiceCollectionExtensions.csAddDalServices() DI registreerimine, NoTrackingWithIdentityResolution, SplitQuery käitumine.

Application Layer — BLL

App.BLL — ärieteenused, sõltub ainult Domain-ist (mitte DAL-ist otse):

  • Services: TripService, ExpenseService, SettlementService, InvitationService, PollService, WishlistService, BudgetCategoryService, SplitPresetService
  • Admin services — 12 eraldi admin teenust (BudgetCategoryAdminService, CurrencyAdminService jne)
  • Helpers/CurrencyConverter jt

DTO kiht

App.DTO — API- ja teenuste-tasemel andmeobjektid:

  • v1/ — versioneeritud API DTO-d (TripDto, TripCreateDto, TripUpdateDto, ExpenseDto, SettlementPlanDto, BudgetCategoryDto)
  • v1/Identity/LoginInfo, RegisterInfo, JWTResponse, TokenRefreshInfo
  • Mappers/ — staatilised mapper-klassid (TripMapper jt)

Presentation — WebApp

MVC Controllers Controllers/ — Razor Views: TripsController, ExpensesController, BudgetController, MembersController, PollsClientController, WishlistClientController, SettlementController

API Controllers ApiControllers/ — REST API:

  • [ApiVersion("1.0")] + api/v{version:apiVersion}/[controller]
  • JWT Bearer autentimine

Areas:

  • Admin — 13 admin-controllerit (Users, Currencies, Trips, Expenses, Polls, Wishlist, SettlementPlans jne)
  • Identity — Razor Pages (Register jne)

Models/ViewModelid (õppejõu nõue, mitte ViewBag/ViewData)

Program.cs — DI konfig:

  • Identity (AppUser, AppRole)
  • JWT Bearer + Cookie autentimine (SlidingExpiration)
  • AddDataProtection().PersistKeysToDbContext<AppDbContext>()
  • Request localization
  • Swagger + API versioning
  • InvariantDecimalModelBinderProvider — kümnendkoha parser

Kokkuvõte

SplitApp on korrektne Clean/Onion Architecture täpselt nii, nagu TalTech-i loeng "architecture1" kirjeldab:

"The entire difference between N-tier and Clean Architecture is who owns the interfaces."

Meie projektis liidesed kuuluvad Domain-ile (App.Domain.Contracts), Infrastructure (App.DAL.EF) asub välimises ringis ja osutab sissepoole, mistõttu BLL-i äriloogika ei tea midagi EF Core-ist ega PostgreSQL-ist. See on just see "pööratud sõltuvus", mida Onion nõuab.