Configuration
All configuration is in appsettings.json. For local development, override with appsettings.dv.json (gitignored). For production on IIS, use appsettings.Production.json next to the executable or set environment variables on the IIS app pool.
Connection strings
"ConnectionStrings": {
"DefaultConnection": "Data Source=customstuf.db",
"TarbelConnection": "Data Source=tarbel.db"
}
tarbel.db is the Belgian customs TARIC reference database (~550 MB), managed entirely by the application. The app checks the minfin portal every 12 hours for new extractions and notifies admins via a banner when an update is available. Admins upload the ZIP from the minfin portal via /Admin/Tarbel; the TarbelImportWorker background service processes it and writes GoodsNomenclature, GeographicalArea, MeasureType, AdditionalCode, Certificate, Measure, and related tables into tarbel.db. Both database files must live outside the versioned deploy folder in production — see deployment.md.
Auth
Set Auth:Provider to select the authentication backend:
| Value | Backend |
|---|---|
EntraId |
Microsoft Entra ID (Azure AD) |
Authentik |
Self-hosted Authentik OIDC |
| (empty) | No auth — all pages accessible (dev only) |
Entra ID
"Auth": {
"Provider": "EntraId",
"EntraId": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "",
"ClientId": "",
"ClientSecret": "",
"CallbackPath": "/signin-oidc",
"CertificateThumbprint": "" // optional — use cert instead of secret
}
}
Authentik
"Auth": {
"Provider": "Authentik",
"Authentik": {
"Authority": "https://auth.example.com/application/o/customstuf/",
"ClientId": "",
"ClientSecret": "",
"CallbackPath": "/signin-authentik",
"AdminGroup": "TUF Admins",
"HoofdgebruikerGroup": "TUF Users"
}
}
Roles (AdminGroup / HoofdgebruikerGroup) map to the Beheerder and Hoofdgebruiker claims used throughout the app.
AI provider
Set AI:Provider to select the extraction backend:
| Value | Backend |
|---|---|
AzureOpenAI |
Azure OpenAI (managed, always considered available) |
OpenAI |
OpenAI-compatible endpoint (e.g. LiteLLM proxy) |
LiteLLM / OpenAI-compatible proxy
"AI": {
"Provider": "OpenAI",
"OpenAI": {
"BaseUrl": "http://litellm:4000",
"ApiKey": "your-key",
"Model": "gpt-4o-mini"
}
}
If BaseUrl is set, the app does an availability pre-check (GET BaseUrl) before attempting PDF conversion. If the endpoint is unreachable, the dossier is set to Failed immediately rather than burning time on PDF rendering.
Azure OpenAI
"AI": {
"Provider": "AzureOpenAI",
"AzureOpenAI": {
"Endpoint": "https://your-resource.openai.azure.com/",
"DeploymentName": "gpt-4o",
"UseKeylessAuth": true, // true = Managed Identity / workload identity
"ApiKey": "", // set if UseKeylessAuth = false
"TenantId": "", // for workload identity
"ClientId": "",
"ClientSecret": ""
}
}
Storage
"Storage": {
"UploadFolder": "./uploads",
"OutputFolder": "./generated_xml",
"MaxFileSizeBytes": 52428800
}
UploadFolder — where uploaded PDFs/XLSXes are stored for processing. OutputFolder — where the XML generator writes CC415 files; can be a UNC path (e.g. \\fileserver\customstuf\xml_out) so output lands directly on a network share for pickup. In production both should be absolute paths outside the versioned deploy folder — see deployment.md.
Processing
PdfDpi controls the resolution at which PDFs are rasterised before being sent to the AI vision model. 300 DPI is recommended — lower values cause digit misreads.
Country aliases
The AI sometimes returns country names that differ from the Tarbel database entries (e.g. TURKIYE instead of TURKEY, USA instead of UNITED STATES). Add aliases here without a rebuild:
Keys are case-insensitive. Values must be valid ISO 3166-1 alpha-2 codes. When the AI returns a name not in the Tarbel GeographicalArea table, the resolution order is:
- Already a 2-letter ISO2 code → pass through
CountryAliaseslookup (this section)- Exact match on
DescriptionENorDescriptionNLin Tarbel - Partial / starts-with match in Tarbel
- Log warning, leave as-is
Declarations (company-wide defaults)
Stored in the AppSettings table (editable via /Admin/Settings), not in appsettings.json. Prefix: declarations:.
| Key | Description |
|---|---|
declarations:sender_gln |
GLN of the sender (MessageHeader) |
declarations:declarant_eori |
Declarant / representative EORI |
declarations:auth_c501 |
Authorisation C501 reference |
declarations:auth_c517 |
Authorisation C517 reference |
declarations:auth_c506 |
Authorisation C506 reference |
declarations:supervising_customs_office |
Default supervising customs office ref |
declarations:warehouse |
Default warehouse identifier (H2B) |
declarations:location_of_goods |
Default UN/LOCODE for location of goods |
declarations:contact_phone |
Contact phone number for declarations |
declarations:contact_name |
Contact person name for declarations |
declarations:contact_email |
Contact person email for declarations |