Skip to content

Project structure

NetForge is a single solution with two projects: an ASP.NET Core API and a React SPA. The layout is deliberately flat and predictable — once you've seen one feature, you've seen them all.

NetForge.sln
├─ NetForge.Server/            # ASP.NET Core 10 API (minimal APIs)
│  ├─ Features/                # one folder per vertical slice
│  │  ├─ {Domain}/             # Endpoints, Models, Validators, EfConfig, Mappings, Permissions
│  │  └─ _Template/            # copy-me scaffolding (ignored by feature discovery)
│  ├─ Platform/                # cross-cutting: errors, auth, audit, settings, jobs, …
│  ├─ Data/                    # AppDbContext + migrations
│  └─ Program.cs               # composition root — you rarely touch this
└─ netforge.client/           # React 19 + Vite + TypeScript SPA
   ├─ src/pages/               # file-system routes (the path tree IS the URL tree)
   ├─ src/components/          # shared UI (incl. shadcn/ui primitives)
   ├─ src/lib/api/             # one typed API module per backend slice
   ├─ src/widgets/             # dashboard widgets
   └─ src/locales/             # i18n message catalogs

Backend: vertical slices

Each feature is a self-contained folder under Features/{Domain}/, typically six files:

FileHolds
Endpoints.csthe minimal-API routes (these are the handlers)
Models.csrequest/response DTOs (records) + entities
Validators.csFluentValidation rules
EfConfig.csthe EF Core entity configuration
Mappings.csentity → DTO mapping (plain static methods)
Permissions.csthe slice's permission constants

Slices auto-register by reflection — a marker interface is discovered at startup — so you never edit Program.cs to add a feature. A folder prefixed with _ (like _Template) is treated as scaffolding and skipped.

Frontend: file-system routes

Screens live under src/pages/, and the folder tree maps directly to URLs:

  • index.tsx is the screen (default export); optional same-file Pending / Catch exports cover loading and error states.
  • _layout.tsx wraps a subtree; meta.ts holds { title, permissions }.
  • Route groups like (app) organize without affecting the URL.
  • Any _-prefixed file or directory is ignored by the router (_layout.tsx, _template/).

Routes are generated automatically by the Vite dev server — there's no route config to maintain.

Cross-cutting concerns: the filter pipeline

Validation, audit logging, performance timing, and transactions are applied as an IEndpointFilter pipeline per slice — not re-implemented per handler. This is why a handler can be a few lines: the cross-cutting work happens around it. See Architecture for the full picture.

Where to start

Copy Features/_Template/ (backend) or src/pages/_template/ (frontend) — the scaffolding is the canonical shape. The Add a feature recipe walks through it end to end.

NetForge Community is MIT-licensed. Pro is a commercial edition.