Skip to main content
Version: 1.2

9.2 App Notification Templates

Controller: AppNotificationTemplateController · Route: api/v1/AppNotificationTemplate · GroupName: notifications · 9 endpoints · Full CRUD for the templates described in Chapter 8.

Standard CRUD action set — see §9.0 conventions for the shared DtParameters/DtResult/DeleteDto shapes reused below.

Verb + routePermissionRequestResponse (data)
POST GetDataTableAppNotificationTemplates.ViewAllDtParametersDtResult<AppNotificationTemplateDto> (unwrapped)
GET GetDetails/{id}AppNotificationTemplates.ViewAppNotificationTemplateDetailsDto
GET GetEdit/{id}AppNotificationTemplates.EditAppNotificationTemplateEditDto
GET GetDropdownList?findBy=&onlyActive=trueAppNotificationTemplates.Viewquery stringAppNotificationTemplateViewListDto[]
POST CreateAppNotificationTemplates.CreateAppNotificationTemplateEditDtoGuid (new ID)
PUT Update/{id}AppNotificationTemplates.EditAppNotificationTemplateEditDtoGuid
DELETE Delete?restore=AppNotificationTemplates.DeleteDeleteDto[]Guid
PUT ActiveAppNotificationTemplates.ActiveDeleteDto[]Guid
PUT DeactiveAppNotificationTemplates.DeactiveDeleteDto[]Guid

Field-level detail — AppNotificationTemplateEditDto

{
"id": "00000000-0000-0000-0000-000000000000",
"isActive": true,
"displayOrder": 0,
"eventKey": "PurchaseInvoicePosted",
"name": "تم اعتماد فاتورة شراء",
"fName": "Purchase invoice posted",
"subjectTemplate": "Invoice {{ invoiceNumber }} has been posted",
"bodyTemplate": "Hello {{ customerName }}, your invoice {{ invoiceNumber }} for {{ totalAmount }} {{ currencyCode }} has been posted.",
"channel": 1,
"languageCode": "en",
"whatsAppTemplateName": null,
"whatsAppLanguageCode": null,
"whatsAppBodyParams": null
}

Validation (AppNotificationTemplateValidator, FluentValidation): EventKey NotEmpty + max 100, Name NotEmpty + max 200, FName max 200, SubjectTemplate max 500 (only when non-null), BodyTemplate NotEmpty, Channel must be a defined enum value. No validation exists today for WhatsAppTemplateName, WhatsAppLanguageCode, or WhatsAppBodyParams — malformed WhatsApp fields are only caught at dispatch time (see §7.3), not at save time. Flag this to template authors.

Example: create a WhatsApp template row for the same event

{
"isActive": true,
"displayOrder": 0,
"eventKey": "PurchaseInvoicePosted",
"name": "تم اعتماد فاتورة شراء - واتساب",
"fName": "Purchase invoice posted - WhatsApp",
"bodyTemplate": "",
"channel": 6,
"languageCode": "en",
"whatsAppTemplateName": "invoice_posted_en",
"whatsAppLanguageCode": "en",
"whatsAppBodyParams": "[\"{{ customerName }}\", \"{{ invoiceNumber }}\", \"{{ totalAmount }}\"]"
}

bodyTemplate is still required by the validator even for WhatsApp rows (NotEmpty) — send an empty string or a human-readable fallback description; it is never rendered for WhatsApp dispatch.

Possible errors: 400 FluentValidation failure (missing EventKey/Name/BodyTemplate, invalid Channel); succeeded:false entity-not-found on GetDetails/GetEdit/Update with a bad id.

Angular: the template management screen should let an author pick Channel first, then conditionally show WhatsApp-only fields (whatsAppTemplateName, whatsAppLanguageCode, whatsAppBodyParams) only when Channel === 6, since the API accepts but ignores them for other channels. Flutter: template authoring is typically a back-office/admin feature — usually not exposed in the end-user mobile app; the mobile client is a template consumer, not editor. Backend: AppNotificationTemplateService — standard _mapper.Map CRUD, wrapped in BeginTransaction/SaveChangesAsync/CommitTransaction per platform convention. Related APIs: Notification Event Configurations (which channels are even attempted for an event), Chapter 8 — Templates.