Tmavý režim
Notifikace — interní API (/internal)
Endpointy pro odesílání notifikací z backend aplikací. Vyžadují x-internal-api-key header — bez JWT tokenu.
POST /internal/notifications — odeslání notifikace
Odešle jednu notifikaci uživateli (email + push, dle preferencí).
http
POST /api/internal/notifications
x-internal-api-key: <api-key>
Content-Type: application/jsonRequest body
json
{
"recipientEmail": "uzivatel@firma.cz",
"appCode": "crm",
"type": "new_task",
"data": {
"taskTitle": "Zavolat zákazníkovi",
"dueDate": "2024-01-25",
"assignedBy": "Jana Nováková"
},
"locale": "cs"
}| Pole | Typ | Povinné | Popis |
|---|---|---|---|
recipientEmail | string | ✓ | Email příjemce |
appCode | string | ✓ | Kód aplikace |
type | string | ✓ | Kód notifikačního typu |
data | object | ✗ | Data pro šablonu (Mustache proměnné) |
locale | string | ✗ | Locale pro šablonu (výchozí: profil uživatele nebo "cs") |
Response
json
{
"success": true,
"data": {
"id": 123,
"status": "sent",
"statusReason": null
}
}| Stav | Popis |
|---|---|
sent | Notifikace úspěšně odeslána |
failed | Odeslání selhalo (chyba SMTP/Push) |
skipped | Přeskočeno — uživatel má vypnuté notifikace nebo typ neexistuje |
Příklad — odeslání e-mailové notifikace
bash
curl -X POST http://localhost:3001/api/internal/notifications \
-H "x-internal-api-key: muj-tajny-klic" \
-H "Content-Type: application/json" \
-d '{
"recipientEmail": "jan.novak@firma.cz",
"appCode": "crm",
"type": "task_assigned",
"data": {
"taskTitle": "Připravit nabídku",
"projectName": "Projekt Alfa"
}
}'POST /internal/notifications/bulk — hromadné odeslání
Odešle více notifikací najednou (max 100 v jednom requestu).
http
POST /api/internal/notifications/bulk
x-internal-api-key: <api-key>
Content-Type: application/jsonRequest body
json
{
"notifications": [
{
"recipientEmail": "jan.novak@firma.cz",
"appCode": "crm",
"type": "daily_report",
"data": { "reportDate": "2024-01-20" }
},
{
"recipientEmail": "petra.kratka@firma.cz",
"appCode": "crm",
"type": "daily_report",
"data": { "reportDate": "2024-01-20" }
}
]
}Response
json
{
"success": true,
"data": [
{ "id": 124, "status": "sent" },
{ "id": 125, "status": "skipped", "statusReason": "notifications disabled" }
]
}GET /internal/notifications/types — typy notifikací
http
GET /api/internal/notifications/types?appCode=crm
x-internal-api-key: <api-key>Response
json
{
"success": true,
"data": [
{
"id": 1,
"code": "new_task",
"name": "Nový úkol",
"description": "Oznámení o přiřazení nového úkolu",
"emailEnabled": true,
"pushEnabled": true,
"userCanDisable": true,
"defaultEmail": true,
"defaultPush": false
}
]
}GET /internal/notifications/log/:email — log příjemce
Audit log odeslaných notifikací pro konkrétního uživatele.
http
GET /api/internal/notifications/log/jan.novak@firma.cz
x-internal-api-key: <api-key>Response
json
{
"success": true,
"data": [
{
"id": 123,
"recipientEmail": "jan.novak@firma.cz",
"appCode": "crm",
"type": "new_task",
"subject": "Nový úkol: Připravit nabídku",
"status": "sent",
"locale": "cs",
"createdAt": "2024-01-20T10:30:00.000Z"
}
]
}GET /internal/notifications/log/app/:appCode — log aplikace
http
GET /api/internal/notifications/log/app/crm
x-internal-api-key: <api-key>Správa šablon
GET /internal/notifications/templates/:appCode
http
GET /api/internal/notifications/templates/crm
x-internal-api-key: <api-key>POST /internal/notifications/templates/:appCode — vytvoření šablony
http
POST /api/internal/notifications/templates/crm
x-internal-api-key: <api-key>
Content-Type: application/jsonjson
{
"type": "new_task",
"locale": "cs",
"subjectTemplate": "Nový úkol: {{taskTitle}}",
"bodyTemplate": "<h1>Byl vám přiřazen nový úkol</h1><p>{{taskTitle}}</p><p>Projekt: {{projectName}}</p>",
"description": "Šablona pro notifikaci o novém úkolu"
}| Pole | Typ | Povinné | Popis |
|---|---|---|---|
type | string | ✓ | Kód notifikačního typu |
locale | string | ✓ | Locale šablony (cs, en, ...) |
subjectTemplate | string | ✓ | Předmět emailu (Mustache) |
bodyTemplate | string | ✓ | HTML tělo emailu (Mustache) |
description | string | ✗ | Popis šablony |
GET /internal/notifications/templates/detail/:id
http
GET /api/internal/notifications/templates/detail/5
x-internal-api-key: <api-key>PUT /internal/notifications/templates/detail/:id
http
PUT /api/internal/notifications/templates/detail/5
x-internal-api-key: <api-key>
Content-Type: application/jsonjson
{
"subjectTemplate": "Aktualizovaný předmět: {{taskTitle}}",
"bodyTemplate": "<p>Nový obsah šablony</p>"
}DELETE /internal/notifications/templates/detail/:id
http
DELETE /api/internal/notifications/templates/detail/5
x-internal-api-key: <api-key>Mustache šablony
Šablony používají Mustache-style syntaxi pro vkládání proměnných:
html
<!-- subjectTemplate -->
Nový úkol: {{taskTitle}}
<!-- bodyTemplate (HTML) -->
<h1>Byl vám přiřazen nový úkol</h1>
<p><strong>Úkol:</strong> {{taskTitle}}</p>
<p><strong>Projekt:</strong> {{projectName}}</p>
<p><strong>Přiřadil/a:</strong> {{assignedBy}}</p>
<p><strong>Termín:</strong> {{dueDate}}</p>Proměnné se předávají v poli data při odesílání notifikace.
Speciální proměnné (automaticky dostupné)
| Proměnná | Obsah |
|---|---|
| Email příjemce |
| Jméno aplikace |
| Název brandu |
| Aktuální rok |
Jak notifikace funguje — flow
POST /internal/notifications
│
├─ Existuje notifikační typ? NE → status: "skipped"
│
├─ Má uživatel profil? NE → vytvoří se lazy
│
├─ Jsou notifikace povoleny?
│ (userAppPreference.notificationsEnabled)
│ NE → status: "skipped"
│
├─ Preference uživatele pro typ?
│ (userNotificationPreference.email + .push)
│
├─ Email povolen?
│ ├─ Načti šablonu pro locale uživatele
│ ├─ Renderuj šablonu s data
│ └─ Odešli email (SMTP + DKIM)
│
├─ Push povolen?
│ ├─ Načti všechny push subscripce uživatele
│ └─ Odešli Web Push na každé zařízení
│
└─ Ulož záznam do audit logu (notifications tabulka)Viz Notifikační systém pro kompletní dokumentaci.