Skip to content

Architecture — Project Structure

The solution NKO.Main/ERP-System.sln contains five projects, all targeting net6.0. One is the web application; the rest are class libraries.

Dependency graph

flowchart TD
    MAIN["NKO.Main<br/>web application"]
    SHARED["NKO.Shared<br/>shared BAL, controllers, views"]
    DATA["NKO.DataAccess<br/>core EF model"]
    WARE["NKO.Warehouse.DataAccess<br/>warehouse EF model"]
    HELP["NKO.Helpers<br/>validation attributes"]

    MAIN --> DATA
    MAIN --> SHARED
    MAIN --> WARE
    SHARED --> DATA
    SHARED --> WARE
    DATA --> HELP

NKO.Helpers and NKO.Warehouse.DataAccess are leaves. Note that the folder layout does not match the dependency direction: NKO.Helpers sits physically under NKO.Main/ even though it is the lowest-level library in the graph.

The five projects

Project Path .cs files Role
NKO.Main NKO.Main/NKO.Main/ 149 The deployable web application — controllers, business logic, views, static assets
NKO.Shared NKO.Lib/NKO.Shared/ 131 Cross-cutting library: identity controllers, shared BAL, the permission engine, helpers, shared views
NKO.DataAccess NKO.Lib/NKO.DataAccess/ 183 Core EF model — 140 entities, NKO_DBEntities1, 18 migrations
NKO.Warehouse.DataAccess NKO.Lib/NKO.Warehouse.DataAccess/ 33 Warehouse EF model — 21 entities, WarehouseDBContext, 5 migrations
NKO.Helpers NKO.Main/NKO.Helpers/ 1 A single custom validation attribute

NKO.Main — the web application

NKO.Main/NKO.Main/
├── Controllers/            29 core controllers  (+ inner view-model classes)
├── WarehouseControllers/   10 warehouse controllers
├── BAL/                    32 business-logic classes — the core rules
├── WareBAL/                 8 warehouse business-logic classes
├── ViewModels/             view models grouped by feature
├── Views/                  Razor views, one folder per controller
├── Helpers/                OperationConstants and app-specific helpers
├── Infrastructure/         IHostedService jobs + AddScheduledJobsExtention
├── ScheduledTasks/         Quartz IJob implementations
├── Resources/              .resx localisation (en / ar / tr)
├── wwwroot/                css, js, images, Rotativa binaries
├── Program.cs              host builder + Quartz registration
└── Startup.cs              DI container and middleware pipeline

Where the rules live. BAL/ and WareBAL/ hold everything that matters. The largest classes are BAsset (4 206 lines), BStock (4 024), BRFQ (3 844), BLeave (2 704) and BJobs (2 690). Controllers are thin by comparison — they resolve the user, call a BAL method and pick a view.

Warehouse code is separated by folder, not by project. WarehouseControllers/ and WareBAL/ live inside NKO.Main but talk to a different database. There is no compile-time boundary stopping core code from touching warehouse code or vice versa.

NKO.Shared — the cross-cutting library

NKO.Lib/NKO.Shared/
├── Controllers/     AccountController, CommonController, FilesController,
│                    CultureController, and the sidebar/topbar view components
├── BAL/             7 shared business classes (BSign, Bsettings, BCalendar,
│                    SharedBAL, AttenadancesHandler, BArchiveFile,
│                    Permissionchecker)
├── Helpers/         Sec/ (ClaimRequirementFilter, PermissionsHandler,
│                    HasPermission, BCryptPasswordHasher), NextUserHelper,
│                    EmailManager, ExportHelper, CommonConstants,
│                    BNotification, and **BUser** (1 909 ln — the largest
│                    shared class, and not under BAL/ despite its name)
├── Configs/         BaseAppSettings, StorageConfigs, SiteSettings
├── Contracts/       IAttendancesHandler, DayTypeSummary, MissingAttendance
│                    (IS3ServiceHandler and CurrentRequestData are in Helpers/Contracts/)
├── Models/          ApplicationUser and identity models
├── ViewModels/      shared view models, including the status enums
├── Attributes/      custom MVC attributes
├── Hangfire/        despite the name: the SignalR hub (RealTime), RealTimeNotifier and
│                    CustomUserIdProvider — Hangfire itself is set up in Startup (R8-2)
└── Views/           shared Razor views, served as embedded resources

This project is why authentication and permissions are available to both the core and the warehouse side: both reference it, and its views are embedded in the assembly and surfaced through EmbeddedFileProvider.

A trap to remember

NKO.Shared/ViewModels/Training/TrainingStatus.cs does not only hold training statuses — it defines seven status enums, including LeaveStatus, AdvanceStatus, OvertimeStatus and UpgradeStatus. See R7-15 in Recommendations.

The two data-access projects

NKO.Lib/NKO.DataAccess/                NKO.Lib/NKO.Warehouse.DataAccess/
├── DbModel/    140 entities           ├── DbModel/    15 entities
│   └── (+ NKO_DBEntities1.cs)         │   └── Assets/  6 more entities
└── Migrations/ 18 migrations          │   └── (+ WarehouseDBContext.cs)
                                       └── Migrations/ 5 migrations

Counting migrations

Migrations/ holds 37 files for the core model, but that is 18 migrations × 2 files (<name>.cs + <name>.Designer.cs) plus one NKO_DBEntities1ModelSnapshot.cs. The real count is 18, spanning 20241002070209_snapshot to 20260730200327_finSODRemoved. The warehouse folder likewise holds 11 files for 5 migrations. Entity counts are DbSet<> properties on each context: 140 core, 21 warehouse.

Two independent models with no cross-database foreign keys. The warehouse DbModel/Assets/ sub-folder is easy to miss — it holds Asset, AssetDetail, AssetPendingAmount, AssetsReturn, Computer and GRNReport, which is why the entity count is 21, not 15.

Repository layout

E:\NKO_Project-main\
├── NKO.Main/          the web app + NKO.Helpers + the .sln
├── NKO.Lib/           the three libraries
├── docs/              this documentation site
├── mkdocs.yml         site configuration
├── requirements-docs.txt
└── .gitignore

site/ (generated MkDocs output) and any local duplicate of the solution are excluded from version control.

Conventions

Pattern Convention
Business class B<Entity> (BPayroll, BLeave) or <Feature>Handler (AllocationHandler)
Workflow method Set<Role><Outcome> — SetManagerAccepted, SetHRRefused
Visibility query GetMy<Things>(userId) applies data scoping; GetAll does not
Permission key <Area><Action> — PurchaseOrderDetails, StockSRR
Constants core in NKO.Shared/Helpers/CommonConstants.cs, warehouse in NKO.Main/Helpers/OperationConstants.cs

Two source files are named with a trailing space before .cs (AdvanceController .cs, TrainingController .cs) — R7-14.