Appearance
Backend Modules
Each module lives in MedRegia.API/Modules/[ModuleName]/ and follows the same four-layer structure.
Module Layer Pattern
[ModuleName]/
├── Domain/ ← Pure POCO models — no logic, no annotations
│ ├── [Entity].cs
│ └── Enums/[EnumName].cs
├── Data/ ← SQL only — no business logic
│ ├── Interfaces/I[Entity]Repository.cs
│ └── Repositories/[Entity]Repository.cs
├── Business/ ← All business logic lives here
│ ├── DTOs/
│ ├── Interfaces/I[Entity]Service.cs
│ ├── Profiles/[Entity]Profile.cs (AutoMapper)
│ └── Services/[Entity]Service.cs
└── Controller/ ← HTTP layer — maps DTOs, calls services, returns ActionResults
└── [Entity]Controller.csIdentity Module
Route prefix: /api/auth, /api/users, /api/roles, /api/permissions, /api/policies
Handles authentication, user accounts, and the entire RBAC system.
Entities
| Entity | Key Fields |
|---|---|
User | id, firstName, lastName, email, passwordHash, roleId, isActive |
Role | id, name, description, isSystem, isActive |
Permission | id, collection, action, description |
Policy | id, name, description, isActive |
Controllers
| Controller | Description |
|---|---|
AuthController | POST /api/auth/login — issues a signed JWT |
UsersController | CRUD for user accounts, GET /api/users/me/permissions |
RolesController | CRUD for roles; system roles cannot be deleted |
PermissionsController | Read-only list of all defined permissions |
PoliciesController | CRUD for policies; assign/remove permissions to a policy |
VendorManagement Module
Route prefix: /api/vendors, /api/invoices, /api/transactions
The core business domain — manages the full vendor payment lifecycle.
Entities
| Entity | Key Fields | Computed Fields |
|---|---|---|
Vendor | id, name, address, phone, email, vendorType, drugLicenseNumber1, drugLicenseNumber2, isActive | outstandingBalance, totalInvoiceValue, totalPaidAmount |
Invoice | id, vendorId, invoiceNumber, amount, invoiceDate, dueDate, isActive | paidAmount, pendingAmount, status |
Transaction | id, invoiceId, amount, transactionDate, transactionType, isActive | — |
Enums
| Enum | Values |
|---|---|
VendorType | Manufacturer, Wholesaler, Agency, Dealer, Pharmacy, OwnPharmacy |
InvoiceStatus | PartiallyPaid, FullyPaid, Overdue, Canceled (computed, not stored) |
TransactionType | UPI, Cash, NetBanking |
Invoice Status Logic
Invoice status is computed in C# — it is never stored in the database:
Canceled → isActive == false
FullyPaid → pendingAmount <= 0
Overdue → dueDate.Date < today
Otherwise → PartiallyPaidControllers
| Controller | Description |
|---|---|
VendorsController | Full CRUD + paginated/filtered list + export |
InvoicesController | Full CRUD + rich filtering (date range, amount range, status, vendor) |
TransactionsController | Full CRUD + filtering by invoice, date range, payment type |
Settings Module
Route prefix: /api/settings
Manages application-wide configuration key-value pairs. Settings are pre-seeded — they can only be updated through the API, never created or deleted.
Known Settings
| Key | Description |
|---|---|
Currency | Display currency symbol (e.g. ₹, $) |
Dashboard Module
Route prefix: /api/dashboard
Read-only aggregate queries that power the dashboard overview cards. Intentionally has no service layer — the controller queries repositories directly (documented exception to the standard pattern for cross-module aggregation).
Endpoints
| Endpoint | Description |
|---|---|
GET /api/dashboard/summary | KPIs: totalVendors, totalInvoices, totalDue, totalPaid, recentTransactions |
GET /api/dashboard/top-vendors | Top vendors by outstanding balance |
GET /api/dashboard/recent-invoices | Most recent invoices |
GET /api/dashboard/monthly-transactions | Transaction amounts grouped by month |
Reports Module
Route prefix: /api/reports
Generates downloadable .xlsx Excel files using ClosedXML. No service layer beyond IReportService.
| Endpoint | File |
|---|---|
GET /api/reports/vendors | vendors_YYYYMMDD.xlsx |
GET /api/reports/invoices | invoices_YYYYMMDD.xlsx |
GET /api/reports/transactions | transactions_YYYYMMDD.xlsx |
Onboarding Module
Route prefix: /api/onboarding
Handles the one-time first-run setup. All endpoints are intentionally public (no [Authorize]) so setup can be completed before any user exists.
| Endpoint | Description |
|---|---|
GET /api/onboarding/status | Returns isOnboarded: true/false |
POST /api/onboarding/setup | Creates the pharmacy vendor + admin user in one atomic operation |
UserProfile Module
Route prefix: /api/profile
Allows authenticated users to view and update their own profile and change their password. No admin permission required — users always have access to their own profile.