Skip to main content

Core Module Development

The Core module is where your business logic lives. Unlike standard modules (AuthProxy, TrexWallet, Chat, CRM), the Core module is written by the project team for each customer.

Architecture

Internet → AuthProxy (reverse proxy + auth)

├─→ Core Module (your code)
│ ├── REST API controllers
│ ├── Admin pages (Razor)
│ └── Business logic

├─→ TrexWallet (optional)
├─→ Chat (optional)
└─→ CRM (optional)

AuthProxy handles authentication and proxies requests to your Core module. Your Core module receives authenticated requests with user context in HTTP headers.

Request Headers

Every request proxied by AuthProxy includes these headers (only those relevant to the route are added):

HeaderWire formatDescription
X-Crmstring of long (TimeTick) — read as string in TS / JSONUser's CRM ID (universal identifier). Platform int64 ids stay as string end-to-end; never Number(...) them.
X-Projectnumeric stringProject number (Config.Project).
X-KeyTypenumeric string of LoginMethod enumAuthentication method (Cookie, Fido2Key, UserKey, AppLogin, Mcp*, etc.).
X-Scopescomma-separated listList of route paths the user is allowed to call (used by RouteFlags.ScopeCheck).
X-AppIdnumeric stringValidated application identifier when the route has CheckAppId and an app_id is supplied.
X-MCP-App-Idnumeric stringApplication bound to an MCP session.
X-Pkey-Crmnumeric stringCRM resolved from the public key (header pkey) when the route has CheckPubKey.
X-CountryISO country codeGeo enrichment from the GeoIp cache when the route has GeoEnrich.
X-SignResultvalid (only when set)Signature on the request body was verified by AuthProxy (paired with X-Signature on the inbound side).
X-API-Keyshared secretInternal API key for private endpoints (route flag InternalApi).

There is no X-User-Id or X-UserId header — read identity from X-Crm.

Project Setup

1. Create ASP.NET Core project

Create a standard ASP.NET Core project for your customer Core module.

2. Add ItBuild.Shared

Add the shared ItBuild project reference. This gives you access to all platform infrastructure: ApiResponse, DbCore, TimeTick, inter-module clients, etc.

3. Configure Startup

Core startup should load ItBuild configuration, register logging and telemetry, enable controllers/Razor Pages, configure Swagger for development, enable the standard API error envelope, and protect private module endpoints.

4. Configure Runtime Settings

The generated settings include service identity, database connection strings, module URLs, private API key, and observability options. Keep environment-specific values outside the repository and deploy them with the project configuration.

API Development

Controller Pattern

Core APIs are ordinary ASP.NET controllers under the project API prefix. They receive authenticated identity from AuthProxy headers, call platform services through shared module services, and return the standard platform API envelope.

ApiResponse Pattern

All API responses use the ApiResponse<T> wrapper. Success data and structured errors use the same envelope so PWA clients can handle responses consistently.

Response format:

// Success
{ "result": { "id": "123", "name": "John" } }

// Error
{ "error": { "code": -1100, "message": "Account not found" } }

Null Semantics (Updates)

When updating records, null fields are skipped — they don't overwrite the existing value:

Use the platform update helpers so null fields are skipped instead of clearing existing values. This is especially important for partial profile, settings, and admin edits.

Database

Conventions

ConventionRule
Table/column nameslowercase_snake_case
Primary keytimetick BIGINT (TimeTick ID)
No NULLsAll columns NOT NULL with DEFAULT
Model classlowercase matching table name

Example Table

Tables follow the platform conventions: TimeTick primary key, lowercase snake_case columns, no nullable database columns, and default values for every column.

Example Model

Entity classes mirror the table naming convention. Keep entities internal to Core and expose DTOs from public APIs.

Database Operations

Use DbCore helpers for create/read/update/delete operations and reserve raw SQL for cases where a query shape genuinely needs it. Keep mutations behind service methods so business rules stay in one place.

Using Platform Modules

TrexWallet (Payments)

Use the TrexWallet client for balances, payment orders, transfers, and exchange rates. Core should pass business intent; TrexWallet remains the source of truth for wallet state and settlement.

Chat (Messaging)

Use the shared message service for SMS, email, and chat notifications. Keep message templates and user-facing text in the project layer.

CRM (User Data)

Use the CRM client for profile and contact data. Do not duplicate identity data inside Core unless it is project-specific business state.

Admin Pages

Create Razor Pages in Pages/ for the admin interface:

Admin pages should check admin scopes before rendering data, use shared admin UI helpers, and call Core services rather than embedding business logic directly in the page.

Admin pages are accessible through AuthProxy at /adm/ (configured in route map).

Deployment

The Core module is deployed as a Docker container alongside other modules:

services:
core:
image: mcr.microsoft.com/dotnet/aspnet:10.0-alpine
container_name: project-core
volumes:
- ./Core/1.0.0:/app
- ./configs/core.json:/app/appsettings.json
entrypoint: ["dotnet", "Core.dll"]
networks:
- project-network

AuthProxy routes requests to Core based on the route_map configuration.