@consilioweb/payload-support 0.16.0 β 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +347 -435
- package/dist/components/TicketConversation/RewriteDropdown.cjs +98 -0
- package/dist/components/TicketConversation/RewriteDropdown.js +93 -0
- package/dist/components/TicketConversation/SkeletonText.cjs +21 -0
- package/dist/components/TicketConversation/SkeletonText.js +20 -0
- package/dist/components/TicketConversation/constants.cjs +27 -0
- package/dist/components/TicketConversation/constants.js +26 -1
- package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.cjs +20 -0
- package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.js +19 -0
- package/dist/components/TicketConversation/index.cjs +10 -147
- package/dist/components/TicketConversation/index.js +4 -141
- package/dist/index.cjs +1604 -671
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1602 -671
- package/dist/views/BillingView/client.cjs +40 -54
- package/dist/views/BillingView/client.js +40 -54
- package/dist/views/ChatView/client.cjs +4 -3
- package/dist/views/ChatView/client.js +4 -3
- package/dist/views/CrmView/client.cjs +7 -7
- package/dist/views/CrmView/client.js +7 -7
- package/dist/views/EmailTrackingView/client.cjs +6 -5
- package/dist/views/EmailTrackingView/client.js +6 -5
- package/dist/views/ImportConversationView/client.cjs +4 -4
- package/dist/views/ImportConversationView/client.js +4 -4
- package/dist/views/LogsView/client.cjs +3 -2
- package/dist/views/LogsView/client.js +3 -2
- package/dist/views/NewTicketView/client.cjs +1 -1
- package/dist/views/NewTicketView/client.js +1 -1
- package/dist/views/PendingEmailsView/client.cjs +7 -6
- package/dist/views/PendingEmailsView/client.js +7 -6
- package/dist/views/SupportDashboardView/client.cjs +19 -22
- package/dist/views/SupportDashboardView/client.js +19 -22
- package/dist/views/TicketDetailView/NextActionItem.cjs +40 -0
- package/dist/views/TicketDetailView/NextActionItem.js +34 -0
- package/dist/views/TicketDetailView/RewriteDropdown.cjs +80 -0
- package/dist/views/TicketDetailView/RewriteDropdown.js +78 -0
- package/dist/views/TicketDetailView/client.cjs +59 -190
- package/dist/views/TicketDetailView/client.js +52 -183
- package/dist/views/TicketDetailView/constants.cjs +20 -0
- package/dist/views/TicketDetailView/constants.js +16 -0
- package/dist/views/TicketDetailView/helpers.cjs +23 -0
- package/dist/views/TicketDetailView/helpers.js +20 -0
- package/dist/views/TicketDetailView/types.cjs +2 -0
- package/dist/views/TicketDetailView/types.js +1 -0
- package/dist/views/TicketInboxView/client.cjs +14 -10
- package/dist/views/TicketInboxView/client.js +14 -10
- package/dist/views/TicketingSettingsView/client.cjs +101 -96
- package/dist/views/TicketingSettingsView/client.js +92 -88
- package/dist/views/TimeDashboardView/client.cjs +2 -2
- package/dist/views/TimeDashboardView/client.js +2 -2
- package/dist/views/shared/StatusPill.cjs +23 -12
- package/dist/views/shared/StatusPill.js +23 -12
- package/dist/views/shared/dateLocale.cjs +5 -0
- package/dist/views/shared/dateLocale.js +3 -0
- package/package.json +23 -15
- package/src/__tests__/generateTrackingToken.test.ts +53 -0
- package/src/__tests__/integration/ai-agent.test.ts +46 -0
- package/src/__tests__/integration/auth.test.ts +43 -0
- package/src/__tests__/integration/automation-rules.test.ts +68 -0
- package/src/__tests__/integration/buildTestPayload.ts +52 -0
- package/src/__tests__/integration/channels.test.ts +52 -0
- package/src/__tests__/integration/core-behaviors.test.ts +58 -0
- package/src/__tests__/integration/dashboard-volume.test.ts +31 -0
- package/src/__tests__/integration/digest.test.ts +48 -0
- package/src/__tests__/integration/invoice-pdf.test.ts +30 -0
- package/src/__tests__/integration/isolation.test.ts +81 -0
- package/src/__tests__/integration/mentions-invoice.test.ts +50 -0
- package/src/__tests__/integration/nps.test.ts +37 -0
- package/src/__tests__/integration/sanitization.test.ts +35 -0
- package/src/__tests__/integration/sla-pause.test.ts +39 -0
- package/src/__tests__/integration/smoke.test.ts +26 -0
- package/src/__tests__/integration/snooze.test.ts +68 -0
- package/src/__tests__/integration/teams.test.ts +38 -0
- package/src/__tests__/rateLimiter.test.ts +89 -0
- package/src/__tests__/sanitizeHtml.test.ts +165 -0
- package/src/__tests__/sla.test.ts +258 -0
- package/src/collections/AutomationRules.ts +66 -0
- package/src/collections/NotificationQueue.ts +30 -0
- package/src/collections/SatisfactionSurveys.ts +11 -2
- package/src/collections/SupportClients.ts +58 -1
- package/src/collections/SupportTeam.ts +27 -0
- package/src/collections/TicketActivityLog.ts +9 -4
- package/src/collections/TicketMessages.ts +129 -31
- package/src/collections/Tickets.ts +31 -73
- package/src/collections/index.ts +3 -0
- package/src/components/TicketConversation/RewriteDropdown.tsx +86 -0
- package/src/components/TicketConversation/SkeletonText.tsx +23 -0
- package/src/components/TicketConversation/constants.ts +29 -0
- package/src/components/TicketConversation/hooks/useDocumentIdFromUrl.ts +21 -0
- package/src/components/TicketConversation/index.tsx +4 -152
- package/src/endpoints/admin-chat-stream.ts +3 -4
- package/src/endpoints/admin-chat.ts +11 -20
- package/src/endpoints/admin-stats.ts +70 -32
- package/src/endpoints/ai-agent.ts +36 -0
- package/src/endpoints/apply-macro.ts +8 -14
- package/src/endpoints/auth-2fa.ts +12 -12
- package/src/endpoints/auto-close.ts +6 -10
- package/src/endpoints/billing.ts +17 -4
- package/src/endpoints/bulk-action.ts +7 -12
- package/src/endpoints/channels.ts +89 -0
- package/src/endpoints/chat-stream.ts +3 -4
- package/src/endpoints/chat.ts +7 -12
- package/src/endpoints/chatbot.ts +2 -2
- package/src/endpoints/client-intelligence.ts +4 -4
- package/src/endpoints/delete-account.ts +9 -16
- package/src/endpoints/email-stats.ts +2 -2
- package/src/endpoints/escalate.ts +2 -2
- package/src/endpoints/export-csv.ts +2 -2
- package/src/endpoints/export-data.ts +5 -8
- package/src/endpoints/import-conversation.ts +6 -10
- package/src/endpoints/index.ts +18 -1
- package/src/endpoints/invite-collaborator.ts +30 -15
- package/src/endpoints/invoice.ts +127 -0
- package/src/endpoints/kb-search.ts +2 -2
- package/src/endpoints/login.ts +12 -4
- package/src/endpoints/merge-clients.ts +14 -19
- package/src/endpoints/merge-tickets.ts +11 -18
- package/src/endpoints/oauth-google.ts +86 -39
- package/src/endpoints/pending-emails-process.ts +15 -25
- package/src/endpoints/process-digests.ts +93 -0
- package/src/endpoints/process-scheduled.ts +6 -10
- package/src/endpoints/process-snooze.ts +78 -0
- package/src/endpoints/purge-logs.ts +2 -2
- package/src/endpoints/resend-notification.ts +3 -4
- package/src/endpoints/round-robin-config.ts +3 -4
- package/src/endpoints/satisfaction.ts +21 -14
- package/src/endpoints/search.ts +5 -8
- package/src/endpoints/seed-kb.ts +3 -4
- package/src/endpoints/send-reminder.ts +6 -9
- package/src/endpoints/settings.ts +5 -2
- package/src/endpoints/signature.ts +3 -4
- package/src/endpoints/sla-check.ts +2 -2
- package/src/endpoints/split-ticket.ts +7 -12
- package/src/endpoints/statuses.ts +2 -2
- package/src/endpoints/ticket-feedback.ts +4 -6
- package/src/endpoints/ticket-synthesis.ts +2 -2
- package/src/endpoints/track-open.ts +16 -28
- package/src/endpoints/transfer-ticket.ts +21 -9
- package/src/endpoints/user-prefs.ts +3 -4
- package/src/hooks/automationRules.ts +84 -0
- package/src/hooks/checkSLA.ts +48 -16
- package/src/plugin.ts +6 -0
- package/src/portal/LiveChat.tsx +2 -63
- package/src/portal/auth/tickets/detail/CloseTicketButton.tsx +10 -0
- package/src/portal/auth/tickets/detail/MarkSolutionButton.tsx +14 -2
- package/src/portal/auth/tickets/detail/MessageActions.tsx +37 -18
- package/src/portal/auth/tickets/detail/ReopenTicketButton.tsx +10 -0
- package/src/portal/auth/tickets/detail/TransferAndInviteActions.tsx +3 -2
- package/src/portal/auth/tickets/detail/page.tsx +2 -2
- package/src/portal/helpers.ts +46 -0
- package/src/portal/login/page.tsx +3 -8
- package/src/portal/types.ts +15 -0
- package/src/types/lucide-react.d.ts +34 -0
- package/src/types/payload-config.d.ts +10 -0
- package/src/utils/adminNotification.ts +2 -2
- package/src/utils/aiAgent.ts +147 -0
- package/src/utils/auth.ts +5 -4
- package/src/utils/channels.ts +36 -0
- package/src/utils/db.ts +73 -0
- package/src/utils/emailTemplate.ts +8 -1
- package/src/utils/fireWebhooks.ts +4 -6
- package/src/utils/generateTicketSynthesis.ts +7 -12
- package/src/utils/invoicePdf.ts +88 -0
- package/src/utils/notificationQueue.ts +36 -0
- package/src/utils/readSettings.ts +22 -6
- package/src/utils/sanitizeHtml.ts +57 -0
- package/src/utils/slugs.ts +6 -0
- package/src/utils/teamAccess.ts +27 -0
- package/src/utils/ticketAccess.ts +53 -0
- package/src/utils/webhookDispatcher.ts +4 -6
- package/src/views/BillingView/client.tsx +49 -37
- package/src/views/ChatView/client.tsx +4 -3
- package/src/views/CrmView/client.tsx +7 -7
- package/src/views/EmailTrackingView/client.tsx +7 -6
- package/src/views/ImportConversationView/client.tsx +4 -4
- package/src/views/LogsView/client.tsx +3 -2
- package/src/views/NewTicketView/client.tsx +1 -1
- package/src/views/PendingEmailsView/client.tsx +7 -6
- package/src/views/SupportDashboardView/client.tsx +21 -21
- package/src/views/TicketDetailView/NextActionItem.tsx +30 -0
- package/src/views/TicketDetailView/RewriteDropdown.tsx +63 -0
- package/src/views/TicketDetailView/client.tsx +54 -179
- package/src/views/TicketDetailView/constants.ts +23 -0
- package/src/views/TicketDetailView/helpers.ts +17 -0
- package/src/views/TicketDetailView/types.ts +10 -0
- package/src/views/TicketInboxView/client.tsx +16 -10
- package/src/views/TicketingSettingsView/client.tsx +90 -87
- package/src/views/TimeDashboardView/client.tsx +2 -2
- package/src/views/shared/StatusPill.tsx +24 -12
- package/src/views/shared/dateLocale.ts +5 -0
- package/src/views/shared/locales/en.json +708 -0
- package/src/views/shared/locales/fr.json +708 -0
package/README.md
CHANGED
|
@@ -1,525 +1,437 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center" style="background: linear-gradient(135deg, #1f8a5b 0%, #16a34a 50%, #0d9488 100%); padding: 50px 40px; border-radius: 12px; color: white; margin-bottom: 40px;">
|
|
2
|
+
<h1 style="margin: 0 0 15px 0; font-size: 42px; font-weight: 700; letter-spacing: -0.5px;">payload-support</h1>
|
|
3
|
+
<p style="margin: 0 auto; font-size: 18px; opacity: 0.95; max-width: 640px; line-height: 1.6;">A complete, self-hosted support & ticketing system for Payload CMS 3 + Next.js β tickets, SLA, AI assists and an autonomous AI agent, live chat, a full client portal, time tracking & invoicing, and a visual automation-rules engine. No third-party support SaaS required.</p>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
2
6
|
<div align="center">
|
|
3
7
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](package.json)
|
|
10
|
+
[](https://nodejs.org)
|
|
11
|
+
[](https://payloadcms.com)
|
|
12
|
+
[](src/__tests__)
|
|
13
|
+
[](https://www.typescriptlang.org)
|
|
7
14
|
|
|
8
|
-
|
|
15
|
+
</div>
|
|
9
16
|
|
|
10
|
-
|
|
11
|
-
<img src="https://img.shields.io/badge/version-0.2.0-blue?style=for-the-badge" alt="version">
|
|
12
|
-
<img src="https://img.shields.io/badge/Payload%20CMS-3.x-0F172A?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTIgMkw0IDdWMTdMMTIgMjJMMjAgMTdWN0wxMiAyWiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4=&logoColor=white" alt="Payload CMS 3">
|
|
13
|
-
<img src="https://img.shields.io/badge/AI-Anthropic%20%7C%20OpenAI%20%7C%20Ollama-10B981?style=for-the-badge" alt="AI">
|
|
14
|
-
<img src="https://img.shields.io/badge/i18n-FR%20%7C%20EN-F59E0B?style=for-the-badge&logo=translate&logoColor=white" alt="i18n FR | EN">
|
|
15
|
-
<a href="https://github.com/pOwn3d/payload-support/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-7C3AED?style=for-the-badge" alt="MIT License"></a>
|
|
16
|
-
<img src="https://img.shields.io/badge/TypeScript-5.x-3178C6?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript">
|
|
17
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
## π Table of Contents
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
> transpilePackages: ['@consilioweb/payload-seo-analyzer', '@consilioweb/payload-admin-nav', /* ...other @consilioweb packages */],
|
|
41
|
-
> ```
|
|
42
|
-
>
|
|
43
|
-
> β
**Next.js 15** works without any workaround.
|
|
44
|
-
|
|
45
|
-
## About
|
|
46
|
-
|
|
47
|
-
> **@consilioweb/payload-support** β A complete, production-ready support & ticketing system for Payload CMS 3. Comparable to Freshdesk, HelpScout, and Crisp β but free, open-source, and fully integrated into Payload's admin panel.
|
|
21
|
+
- [Features](#-features)
|
|
22
|
+
- [Quick Start](#-quick-start)
|
|
23
|
+
- [Installation](#-installation)
|
|
24
|
+
- [Usage](#-usage)
|
|
25
|
+
- [API Reference](#-api-reference)
|
|
26
|
+
- [Configuration](#-configuration)
|
|
27
|
+
- [Performance](#-performance)
|
|
28
|
+
- [Examples](#-examples)
|
|
29
|
+
- [FAQ](#-faq)
|
|
30
|
+
- [Troubleshooting](#-troubleshooting)
|
|
31
|
+
- [Security](#-security)
|
|
32
|
+
- [Contributing](#-contributing)
|
|
33
|
+
- [Changelog](#-changelog)
|
|
34
|
+
- [Roadmap](#-roadmap)
|
|
35
|
+
- [Support](#-support)
|
|
36
|
+
- [License](#-license)
|
|
37
|
+
|
|
38
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
39
|
+
|
|
40
|
+
## β¨ Features
|
|
48
41
|
|
|
49
42
|
<table>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<b>Ticketing</b><br>
|
|
53
|
-
<sub>Auto-increment, SLA, priorities, categories</sub>
|
|
54
|
-
</td>
|
|
55
|
-
<td align="center" width="20%">
|
|
56
|
-
<b>AI-Powered</b><br>
|
|
57
|
-
<sub>Sentiment, synthesis, suggestions, rewrite</sub>
|
|
58
|
-
</td>
|
|
59
|
-
<td align="center" width="20%">
|
|
60
|
-
<b>Time Tracking</b><br>
|
|
61
|
-
<sub>Timer, entries, billing dashboard</sub>
|
|
62
|
-
</td>
|
|
63
|
-
<td align="center" width="20%">
|
|
64
|
-
<b>Live Chat</b><br>
|
|
65
|
-
<sub>Real-time, chat-to-ticket conversion</sub>
|
|
66
|
-
</td>
|
|
67
|
-
<td align="center" width="20%">
|
|
68
|
-
<b>Modular</b><br>
|
|
69
|
-
<sub>25+ feature flags, enable what you need</sub>
|
|
70
|
-
</td>
|
|
71
|
-
</tr>
|
|
72
|
-
</table>
|
|
43
|
+
<tr>
|
|
44
|
+
<td width="50%">
|
|
73
45
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
## Features
|
|
77
|
-
|
|
78
|
-
### Core Ticketing
|
|
79
|
-
- Auto-increment ticket numbers (TK-0001, TK-0002...)
|
|
80
|
-
- Statuses, priorities, categories, tags
|
|
81
|
-
- Multi-agent assignment with round-robin distribution
|
|
82
|
-
- Ticket merge, split, snooze
|
|
83
|
-
- Scheduled replies
|
|
84
|
-
- Bulk actions on multiple tickets
|
|
85
|
-
- Command palette (βK) for instant search
|
|
86
|
-
|
|
87
|
-
### AI Integration
|
|
88
|
-
- **Sentiment analysis** β detect client mood from messages
|
|
89
|
-
- **AI summary** β generate conversation synthesis
|
|
90
|
-
- **Smart reply** β suggest contextual responses
|
|
91
|
-
- **Rewrite** β rephrase messages professionally
|
|
92
|
-
- Multi-provider: Anthropic Claude, OpenAI, Ollama, custom endpoint
|
|
93
|
-
- AI chatbot for first-line self-service
|
|
94
|
-
|
|
95
|
-
### SLA & Compliance
|
|
96
|
-
- Response & resolution time targets per priority
|
|
97
|
-
- Business hours support
|
|
98
|
-
- SLA breach alerts on dashboard
|
|
99
|
-
- Webhook dispatch on `sla_breached` events
|
|
100
|
-
|
|
101
|
-
### Time Tracking & Billing
|
|
102
|
-
- Built-in timer with pause/resume
|
|
103
|
-
- Manual time entries per ticket
|
|
104
|
-
- Time dashboard with analytics
|
|
105
|
-
- Billing/invoicing foundation
|
|
106
|
-
- Facturable toggle per ticket
|
|
107
|
-
|
|
108
|
-
### Live Chat
|
|
109
|
-
- Real-time chat sessions via **Server-Sent Events (SSE)** (v0.2.0)
|
|
110
|
-
- Automatic **SSE to polling fallback** when EventSource unavailable (v0.2.0)
|
|
111
|
-
- Typing indicators
|
|
112
|
-
- Chat-to-ticket conversion
|
|
113
|
-
- Agent presence/collision detection
|
|
114
|
-
|
|
115
|
-
### Email Integration
|
|
116
|
-
- Inbound email β ticket/message (via webhook)
|
|
117
|
-
- Pending email queue with client matching
|
|
118
|
-
- Email pixel tracking (opens)
|
|
119
|
-
- Per-agent email signatures
|
|
120
|
-
- Email log viewer with purge
|
|
121
|
-
|
|
122
|
-
### Client Management (CRM)
|
|
123
|
-
- Client profiles with history
|
|
124
|
-
- Impersonation (view as client)
|
|
125
|
-
- Client merge
|
|
126
|
-
- Satisfaction surveys (CSAT 1-5)
|
|
127
|
-
- Knowledge base / FAQ
|
|
128
|
-
- Client portal (separate auth)
|
|
129
|
-
|
|
130
|
-
### Automation
|
|
131
|
-
- Auto-close inactive tickets
|
|
132
|
-
- Canned responses with template variables
|
|
133
|
-
- Macros (multi-action shortcuts)
|
|
134
|
-
- Webhooks (HMAC-SHA256 signed) with dispatch on ticket events (v0.2.0)
|
|
135
|
-
- **Scheduled replies** processing endpoint (v0.2.0)
|
|
136
|
-
- Activity log (full audit trail)
|
|
137
|
-
|
|
138
|
-
### Security (v0.2.0)
|
|
139
|
-
- **XSS prevention** β escapeHtml on all email template dynamic fields
|
|
140
|
-
- **2FA codes** hashed with HMAC-SHA256 before storage
|
|
141
|
-
- **Tracking pixels** signed with HMAC
|
|
142
|
-
- **OAuth Google** β `allowedEmailDomains` option for domain restriction
|
|
143
|
-
- **Rate limiting** β unified RateLimiter class on all public endpoints
|
|
144
|
-
- **Collection injection protection** β validates collection parameters against whitelist
|
|
145
|
-
- **Password generation** β uses crypto.randomBytes (not Math.random)
|
|
146
|
-
|
|
147
|
-
### Internationalization
|
|
148
|
-
- Full FR/EN support
|
|
149
|
-
- Locale toggle in settings
|
|
150
|
-
- Extensible translation system
|
|
151
|
-
|
|
152
|
-
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="line">
|
|
153
|
-
|
|
154
|
-
## Architecture
|
|
155
|
-
|
|
156
|
-
### Collections (15)
|
|
157
|
-
|
|
158
|
-
| Collection | Description |
|
|
159
|
-
|------------|-------------|
|
|
160
|
-
| `tickets` | Core ticket with auto-increment, SLA, activity hooks |
|
|
161
|
-
| `ticket-messages` | Conversation messages with author type, attachments |
|
|
162
|
-
| `support-clients` | Client auth collection (email/password) |
|
|
163
|
-
| `time-entries` | Time tracking per ticket |
|
|
164
|
-
| `canned-responses` | Quick reply templates with variables |
|
|
165
|
-
| `ticket-activity-log` | Immutable audit trail |
|
|
166
|
-
| `satisfaction-surveys` | CSAT ratings (1-5) |
|
|
167
|
-
| `knowledge-base` | FAQ articles with rich text |
|
|
168
|
-
| `chat-messages` | Live chat sessions |
|
|
169
|
-
| `pending-emails` | Inbound email queue |
|
|
170
|
-
| `email-logs` | Email delivery audit |
|
|
171
|
-
| `auth-logs` | Authentication audit |
|
|
172
|
-
| `webhook-endpoints` | Outbound webhook config |
|
|
173
|
-
| `sla-policies` | SLA rules per priority |
|
|
174
|
-
| `macros` | Multi-action shortcuts |
|
|
175
|
-
| `ticket-statuses` | Custom configurable statuses |
|
|
176
|
-
|
|
177
|
-
### API Endpoints (34)
|
|
178
|
-
|
|
179
|
-
| Category | Endpoints |
|
|
180
|
-
|----------|-----------|
|
|
181
|
-
| **Tickets** | search, bulk-action, merge-tickets, split-ticket, export-csv, export-data |
|
|
182
|
-
| **AI** | ai (sentiment/synthesis/suggest/rewrite), chatbot |
|
|
183
|
-
| **Chat** | chat, admin-chat, typing, presence |
|
|
184
|
-
| **Email** | pending-emails/process, resend-notification, track-open, email-stats |
|
|
185
|
-
| **Config** | settings, signature, round-robin-config, statuses, sla-check, auto-close |
|
|
186
|
-
| **Auth** | login, 2fa, oauth/google, delete-account |
|
|
187
|
-
| **SSE** | client-stream, admin-stream (v0.2.0) |
|
|
188
|
-
| **Scheduled** | process-scheduled (v0.2.0) |
|
|
189
|
-
| **Misc** | apply-macro, purge-logs, seed-kb, admin-stats, billing, import-conversation, merge-clients, satisfaction |
|
|
190
|
-
|
|
191
|
-
### Admin Views (12)
|
|
192
|
-
|
|
193
|
-
| View | Path | Description |
|
|
194
|
-
|------|------|-------------|
|
|
195
|
-
| Inbox | `/support/inbox` | Superhuman-style ticket list with keyboard nav |
|
|
196
|
-
| Dashboard | `/support/dashboard` | KPIs, SLA metrics, active tickets |
|
|
197
|
-
| Ticket Detail | `/support/ticket?id=X` | Full conversation with sidebar panels |
|
|
198
|
-
| New Ticket | `/support/new-ticket` | Create ticket with client search |
|
|
199
|
-
| Settings | `/support/settings` | Feature flags, AI, SLA, auto-close config |
|
|
200
|
-
| CRM | `/support/crm` | Client list and profiles |
|
|
201
|
-
| Chat | `/support/chat` | Live chat sessions |
|
|
202
|
-
| Pending Emails | `/support/emails` | Inbound email queue |
|
|
203
|
-
| Email Tracking | `/support/tracking` | Open/delivery tracking |
|
|
204
|
-
| Time Dashboard | `/support/time` | Time entries analytics |
|
|
205
|
-
| Logs | `/support/logs` | Email & auth audit logs |
|
|
206
|
-
| Billing | `/support/billing` | Invoice management |
|
|
207
|
-
|
|
208
|
-
### Client Portal (30 files)
|
|
209
|
-
|
|
210
|
-
Full-featured client-facing support portal with its own auth system:
|
|
211
|
-
|
|
212
|
-
| Page | Description |
|
|
213
|
-
|------|-------------|
|
|
214
|
-
| Login / Register | Email + password auth, Google OAuth |
|
|
215
|
-
| Forgot / Reset password | Email-based password recovery |
|
|
216
|
-
| Dashboard | Ticket stats, recent activity, quick actions |
|
|
217
|
-
| Ticket List | Filterable, sortable ticket list |
|
|
218
|
-
| Ticket Detail | Conversation thread, reply form, file attachments, satisfaction survey |
|
|
219
|
-
| New Ticket | Category selection, priority, file upload |
|
|
220
|
-
| FAQ | Knowledge base with search |
|
|
221
|
-
| Profile | Edit name, company, email, password, notification prefs, 2FA, delete account |
|
|
222
|
-
| Chat Widget | Real-time live chat with agent |
|
|
223
|
-
| Chatbot | AI-powered self-service from knowledge base |
|
|
224
|
-
|
|
225
|
-
### Email Template System
|
|
226
|
-
|
|
227
|
-
Configurable, responsive HTML email templates:
|
|
46
|
+
**π« Complete ticketing**
|
|
228
47
|
|
|
229
|
-
|
|
230
|
-
import { createEmailTemplateFactory } from '@consilioweb/payload-support'
|
|
231
|
-
|
|
232
|
-
const emails = createEmailTemplateFactory({
|
|
233
|
-
brandName: 'My Company',
|
|
234
|
-
brandColor: '#2563eb',
|
|
235
|
-
logoUrl: 'https://example.com/logo.png',
|
|
236
|
-
supportEmail: 'support@example.com',
|
|
237
|
-
websiteUrl: 'https://example.com',
|
|
238
|
-
})
|
|
48
|
+
Statuses, priorities, categories, tags, merge/split, snooze, scheduled replies, internal notes, an immutable activity log and a keyboard-driven Superhuman-style inbox.
|
|
239
49
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
emails.paragraph('Hello <strong>John</strong>,'),
|
|
243
|
-
emails.button('Open Dashboard', 'https://example.com/dashboard'),
|
|
244
|
-
].join(''))
|
|
245
|
-
```
|
|
50
|
+
</td>
|
|
51
|
+
<td width="50%">
|
|
246
52
|
|
|
247
|
-
|
|
53
|
+
**β±οΈ SLA & automation**
|
|
248
54
|
|
|
249
|
-
|
|
55
|
+
SLA policies (business hours + pause-on-hold), escalation, macros, round-robin, and a **visual automation-rules engine** (conditions β actions).
|
|
250
56
|
|
|
251
|
-
|
|
57
|
+
</td>
|
|
58
|
+
</tr>
|
|
59
|
+
<tr>
|
|
60
|
+
<td width="50%">
|
|
252
61
|
|
|
253
|
-
|
|
254
|
-
pnpm add @consilioweb/payload-support
|
|
255
|
-
```
|
|
62
|
+
**π€ Built-in AI**
|
|
256
63
|
|
|
257
|
-
|
|
64
|
+
Sentiment, reply suggestions, multi-style rewriting, cached synthesis, a KB chatbot, and an **autonomous AI agent** that answers or escalates. Anthropic, OpenAI or self-hosted Ollama.
|
|
258
65
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
66
|
+
</td>
|
|
67
|
+
<td width="50%">
|
|
68
|
+
|
|
69
|
+
**π¬ Omnichannel & portal**
|
|
70
|
+
|
|
71
|
+
Inbound/outbound email, live chat (SSE), widget, a full **client portal** (auth, 2FA, Google OAuth), knowledge base and deflection.
|
|
263
72
|
|
|
264
|
-
|
|
73
|
+
</td>
|
|
74
|
+
</tr>
|
|
75
|
+
<tr>
|
|
76
|
+
<td width="50%">
|
|
265
77
|
|
|
266
|
-
|
|
267
|
-
|---------|---------|----------|
|
|
268
|
-
| `payload` | `^3.0.0` | **Yes** |
|
|
269
|
-
| `@payloadcms/next` | `^3.0.0` | Optional (admin views) |
|
|
270
|
-
| `@payloadcms/ui` | `^3.0.0` | Optional (admin UI) |
|
|
271
|
-
| `next` | `^14.0.0 \|\| ^15.0.0 \|\| ^16.0.0` | Optional (admin UI) |
|
|
272
|
-
| `react` | `^18.0.0 \|\| ^19.0.0` | Optional (admin UI) |
|
|
78
|
+
**πΆ Time tracking & billing**
|
|
273
79
|
|
|
274
|
-
|
|
80
|
+
Timer, manual entries, time dashboard, per-project pre-billing and a **print-ready invoice** (HTML β PDF).
|
|
275
81
|
|
|
276
|
-
|
|
82
|
+
</td>
|
|
83
|
+
<td width="50%">
|
|
84
|
+
|
|
85
|
+
**π Reporting & privacy**
|
|
86
|
+
|
|
87
|
+
Real-time dashboard, **CSAT + NPS**, email tracking, HMAC-signed webhooks, notification digests, CSV exports. 100% self-hostable.
|
|
88
|
+
|
|
89
|
+
</td>
|
|
90
|
+
</tr>
|
|
91
|
+
</table>
|
|
92
|
+
|
|
93
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
94
|
+
|
|
95
|
+
## π Quick Start
|
|
277
96
|
|
|
278
97
|
```ts
|
|
98
|
+
// payload.config.ts
|
|
279
99
|
import { buildConfig } from 'payload'
|
|
280
100
|
import { supportPlugin } from '@consilioweb/payload-support'
|
|
281
101
|
|
|
282
102
|
export default buildConfig({
|
|
283
|
-
// ... your existing config
|
|
284
103
|
plugins: [
|
|
285
104
|
supportPlugin({
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
chat: false, // disable live chat
|
|
289
|
-
billing: false, // disable billing
|
|
290
|
-
roundRobin: true, // enable round-robin (off by default)
|
|
291
|
-
},
|
|
292
|
-
|
|
293
|
-
// AI provider (optional)
|
|
294
|
-
ai: {
|
|
295
|
-
provider: 'anthropic',
|
|
296
|
-
model: 'claude-haiku-4-5-20251001',
|
|
297
|
-
},
|
|
298
|
-
|
|
299
|
-
// Locale
|
|
105
|
+
features: { ai: true, sla: true, timeTracking: true, chat: true },
|
|
106
|
+
ai: { provider: 'anthropic', model: 'claude-haiku-4-5-20251001' },
|
|
300
107
|
locale: 'fr',
|
|
301
|
-
|
|
302
|
-
// Email
|
|
303
|
-
email: {
|
|
304
|
-
fromAddress: 'support@example.com',
|
|
305
|
-
fromName: 'Support Team',
|
|
306
|
-
},
|
|
307
108
|
}),
|
|
308
109
|
],
|
|
309
110
|
})
|
|
310
111
|
```
|
|
311
112
|
|
|
312
|
-
|
|
113
|
+
```bash
|
|
114
|
+
pnpm payload generate:importmap
|
|
115
|
+
pnpm dev
|
|
116
|
+
```
|
|
313
117
|
|
|
314
|
-
|
|
118
|
+
Open `/admin/support/inbox` for the agent inbox, or `/support` for the client portal. The plugin injects collections, API endpoints and admin views automatically β no external SaaS.
|
|
315
119
|
|
|
316
|
-
|
|
317
|
-
// next.config.mjs
|
|
318
|
-
import { withPayload } from '@payloadcms/next/withPayload'
|
|
120
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
319
121
|
|
|
320
|
-
|
|
321
|
-
const nextConfig = {
|
|
322
|
-
transpilePackages: ['@consilioweb/payload-support'],
|
|
323
|
-
}
|
|
122
|
+
## π¦ Installation
|
|
324
123
|
|
|
325
|
-
|
|
124
|
+
### npm
|
|
125
|
+
```bash
|
|
126
|
+
npm install @consilioweb/payload-support
|
|
326
127
|
```
|
|
327
128
|
|
|
328
|
-
|
|
129
|
+
### yarn
|
|
130
|
+
```bash
|
|
131
|
+
yarn add @consilioweb/payload-support
|
|
132
|
+
```
|
|
329
133
|
|
|
134
|
+
### pnpm
|
|
330
135
|
```bash
|
|
331
|
-
pnpm
|
|
136
|
+
pnpm add @consilioweb/payload-support
|
|
332
137
|
```
|
|
333
138
|
|
|
334
|
-
|
|
139
|
+
**Peer dependencies:** `payload@^3`, `react@^18 || ^19`, `react-dom@^18 || ^19`, `next@^14 || ^15 || ^16`. `lucide-react` and the `@payloadcms/*` packages are optional depending on the features you enable. After adding admin components, run `pnpm payload generate:importmap`.
|
|
335
140
|
|
|
336
|
-
|
|
141
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
337
142
|
|
|
338
|
-
|
|
143
|
+
## π» Usage
|
|
144
|
+
|
|
145
|
+
### Basic
|
|
339
146
|
|
|
340
147
|
```ts
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
ai: { provider, apiKey, model }, // AI provider config
|
|
344
|
-
email: { fromAddress, fromName, replyTo },
|
|
345
|
-
locale: 'fr', // 'fr' | 'en'
|
|
346
|
-
navGroup: 'Support', // Sidebar group label
|
|
347
|
-
basePath: '/support', // Admin view base path
|
|
348
|
-
userCollectionSlug: 'users', // Agent collection slug
|
|
349
|
-
collectionSlugs: { // Override any collection slug
|
|
350
|
-
tickets: 'my-tickets',
|
|
351
|
-
ticketMessages: 'my-messages',
|
|
352
|
-
// ...
|
|
353
|
-
},
|
|
354
|
-
|
|
355
|
-
// v0.2.0 β Webhook dispatch
|
|
356
|
-
webhooks: {
|
|
357
|
-
url: 'https://hooks.slack.com/services/...',
|
|
358
|
-
secret: process.env.WEBHOOK_SECRET,
|
|
359
|
-
events: ['ticket.created', 'ticket.resolved', 'ticket.assigned', 'ticket.replied'],
|
|
360
|
-
},
|
|
361
|
-
|
|
362
|
-
// v0.2.0 β OAuth restrictions
|
|
363
|
-
allowedEmailDomains: ['mycompany.com', 'partner.com'],
|
|
364
|
-
})
|
|
148
|
+
// All features are on by default β turn off what you don't need:
|
|
149
|
+
supportPlugin({ features: { chat: false, pendingEmails: false }, locale: 'en' })
|
|
365
150
|
```
|
|
366
151
|
|
|
367
|
-
###
|
|
368
|
-
|
|
369
|
-
All features are **enabled by default** except `roundRobin` and `customStatuses`.
|
|
370
|
-
|
|
371
|
-
| Flag | Default | Description |
|
|
372
|
-
|------|---------|-------------|
|
|
373
|
-
| `timeTracking` | `true` | Timer, manual entries, billing |
|
|
374
|
-
| `ai` | `true` | Sentiment, synthesis, suggestion, rewrite |
|
|
375
|
-
| `satisfaction` | `true` | CSAT surveys after resolution |
|
|
376
|
-
| `chat` | `true` | Live chat sessions |
|
|
377
|
-
| `emailTracking` | `true` | Pixel tracking, open status |
|
|
378
|
-
| `canned` | `true` | Quick reply templates |
|
|
379
|
-
| `merge` | `true` | Merge two tickets |
|
|
380
|
-
| `snooze` | `true` | Temporarily hide ticket |
|
|
381
|
-
| `externalMessages` | `true` | Add external messages |
|
|
382
|
-
| `clientHistory` | `true` | Past tickets sidebar |
|
|
383
|
-
| `activityLog` | `true` | Audit trail |
|
|
384
|
-
| `splitTicket` | `true` | Extract message to new ticket |
|
|
385
|
-
| `scheduledReplies` | `true` | Future message sending |
|
|
386
|
-
| `autoClose` | `true` | Close inactive tickets |
|
|
387
|
-
| `autoCloseDays` | `7` | Days before auto-close |
|
|
388
|
-
| `roundRobin` | `false` | Distribute tickets to agents |
|
|
389
|
-
| `sla` | `true` | SLA policies & alerts |
|
|
390
|
-
| `webhooks` | `true` | Outbound HTTP hooks |
|
|
391
|
-
| `macros` | `true` | Multi-action shortcuts |
|
|
392
|
-
| `customStatuses` | `false` | Configurable ticket statuses |
|
|
393
|
-
| `collisionDetection` | `true` | Multi-agent collision warning |
|
|
394
|
-
| `signatures` | `true` | Per-agent email signatures |
|
|
395
|
-
| `chatbot` | `true` | AI self-service chatbot |
|
|
396
|
-
| `bulkActions` | `true` | Bulk ticket operations |
|
|
397
|
-
| `commandPalette` | `true` | βK search |
|
|
398
|
-
| `knowledgeBase` | `true` | FAQ / knowledge base |
|
|
399
|
-
| `pendingEmails` | `true` | Inbound email queue |
|
|
400
|
-
| `authLogs` | `true` | Authentication audit logs (v0.2.0) |
|
|
401
|
-
|
|
402
|
-
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="line">
|
|
403
|
-
|
|
404
|
-
## AI Providers
|
|
405
|
-
|
|
406
|
-
### Anthropic (Claude)
|
|
152
|
+
### Advanced
|
|
407
153
|
|
|
408
154
|
```ts
|
|
409
155
|
supportPlugin({
|
|
410
|
-
ai:
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
},
|
|
156
|
+
features: { ai: true, sla: true, roundRobin: true, webhooks: true, snooze: true },
|
|
157
|
+
ai: { provider: 'ollama', model: 'qwen2.5', baseUrl: process.env.OLLAMA_API_URL },
|
|
158
|
+
email: { fromName: 'Support ACME', fromAddress: 'support@acme.com', replyTo: 'support@acme.com' },
|
|
159
|
+
allowedEmailDomains: ['acme.com'], // restrict OAuth auto-registration
|
|
160
|
+
collectionSlugs: { tickets: 'support-tickets' }, // slug overrides
|
|
161
|
+
navGroup: 'Support',
|
|
162
|
+
basePath: '/support',
|
|
415
163
|
})
|
|
416
164
|
```
|
|
417
165
|
|
|
418
|
-
###
|
|
166
|
+
### Run the AI agent on a ticket
|
|
419
167
|
|
|
420
168
|
```ts
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
model: 'gpt-4o-mini',
|
|
426
|
-
},
|
|
169
|
+
await fetch('/api/support/ai-agent', {
|
|
170
|
+
method: 'POST',
|
|
171
|
+
headers: { 'Content-Type': 'application/json' },
|
|
172
|
+
body: JSON.stringify({ ticketId, confidenceThreshold: 0.7 }),
|
|
427
173
|
})
|
|
428
174
|
```
|
|
429
175
|
|
|
430
|
-
|
|
176
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
431
177
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
178
|
+
## π API Reference
|
|
179
|
+
|
|
180
|
+
### `supportPlugin(config)`
|
|
181
|
+
|
|
182
|
+
The Payload plugin. Adds collections, admin views, editor components and API endpoints.
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
supportPlugin(config?: SupportPluginConfig): Plugin
|
|
440
186
|
```
|
|
441
187
|
|
|
442
|
-
|
|
188
|
+
### Exports
|
|
443
189
|
|
|
444
|
-
|
|
190
|
+
```typescript
|
|
191
|
+
import { supportPlugin, generateTicketSynthesis, dispatchWebhook } from '@consilioweb/payload-support'
|
|
192
|
+
import type { SupportPluginConfig, SupportFeatures } from '@consilioweb/payload-support'
|
|
193
|
+
```
|
|
445
194
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
195
|
+
### Key HTTP endpoints (under `/api/support`)
|
|
196
|
+
|
|
197
|
+
| Method | Path | Purpose |
|
|
198
|
+
|---|---|---|
|
|
199
|
+
| `POST` | `/ai` | Sentiment, reply suggestion, rewrite, synthesis (admin). |
|
|
200
|
+
| `POST` | `/ai-agent` | **Autonomous AI agent** β answers from the KB or escalates. |
|
|
201
|
+
| `POST` | `/login`, `/2fa`, `/oauth/google` | Client portal auth (password, 2FA, OAuth). |
|
|
202
|
+
| `GET` | `/admin-stats` | Dashboard KPIs (real volume series, CSAT, NPS). |
|
|
203
|
+
| `GET` | `/billing`, `/billing/invoice` | Pre-billing + print-ready invoice. |
|
|
204
|
+
| `POST` | `/process-snooze`, `/process-digests`, `/process-scheduled`, `/auto-close` | Cron jobs (guarded by `x-cron-secret`). |
|
|
205
|
+
|
|
206
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
207
|
+
|
|
208
|
+
## βοΈ Configuration
|
|
209
|
+
|
|
210
|
+
| Option | Type | Default | Description |
|
|
211
|
+
|--------|------|---------|-------------|
|
|
212
|
+
| `features` | `SupportFeatures` | all `true` | Toggle each feature on/off. |
|
|
213
|
+
| `ai` | `AIProviderConfig` | `anthropic` | AI provider: `anthropic` \| `openai` \| `ollama` \| `custom`. |
|
|
214
|
+
| `email` | `EmailConfig` | β | `fromName`, `fromAddress`, `replyTo`. |
|
|
215
|
+
| `locale` | `'fr' \| 'en'` | `'fr'` | Admin/portal language. |
|
|
216
|
+
| `basePath` | `string` | `'/support'` | Admin views prefix. |
|
|
217
|
+
| `userCollectionSlug` | `string` | `'users'` | Agents collection. |
|
|
218
|
+
| `allowedEmailDomains` | `string[]` | β | Domains allowed for OAuth auto-registration. |
|
|
219
|
+
| `collectionSlugs` | `object` | β | Collection slug overrides. |
|
|
220
|
+
| `skipCollections` / `skipViews` / `skipEndpoints` | `boolean` | `false` | Skip injecting that part. |
|
|
221
|
+
|
|
222
|
+
### Environment variables
|
|
223
|
+
|
|
224
|
+
| Env var | Required | Description |
|
|
225
|
+
|---------|----------|-------------|
|
|
226
|
+
| `PAYLOAD_SECRET` | β
| Payload secret (also signs 2FA & tracking). |
|
|
227
|
+
| `NEXT_PUBLIC_SERVER_URL` | β
| Public URL (email/portal links). |
|
|
228
|
+
| `CRON_SECRET` | for crons | `x-cron-secret` header for the cron endpoints. |
|
|
229
|
+
| `ANTHROPIC_API_KEY` / `OLLAMA_API_URL` | if AI | AI provider keys/URL. |
|
|
230
|
+
| `GOOGLE_OAUTH_CLIENT_ID` / `_SECRET` | if OAuth | Portal Google sign-in. |
|
|
231
|
+
| `SUPPORT_EMAIL` / `SUPPORT_REPLY_TO` | optional | From/reply-to addresses. |
|
|
232
|
+
|
|
233
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
234
|
+
|
|
235
|
+
## β‘ Performance
|
|
236
|
+
|
|
237
|
+
Engineered to stay fast under load (no fabricated benchmarks β figures depend on your volume and host):
|
|
238
|
+
|
|
239
|
+
| Concern | Approach |
|
|
240
|
+
|---------|----------|
|
|
241
|
+
| Settings reads | In-process cache (TTL + invalidation) β avoids ~8 redundant DB reads per ticket mutation. |
|
|
242
|
+
| List queries | SQLite indexes on filtered fields β inbox/dashboard/SLA in `O(index)` instead of full scans. |
|
|
243
|
+
| Email sends | Fire-and-forget β the response no longer waits on the SMTP round-trip (β200-500 ms). |
|
|
244
|
+
| Stats & billing | Paginated aggregation + bounded `select` β never loads all tickets in memory. |
|
|
245
|
+
| AI synthesis | Cached per ticket β no LLM recompute on every view. |
|
|
246
|
+
|
|
247
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
248
|
+
|
|
249
|
+
## π Examples
|
|
250
|
+
|
|
251
|
+
### Automation rule (no code)
|
|
252
|
+
|
|
253
|
+
Create a **Automation Rules** entry: `event = ticket_created`, condition `category = bug`, action `set_priority = urgent`. New "bug" tickets become "urgent" automatically.
|
|
254
|
+
|
|
255
|
+
### Wire the cron jobs
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Hourly: auto-close, snooze wake-up, scheduled replies
|
|
259
|
+
curl -X POST https://your-app/api/support/auto-close -H "x-cron-secret: $CRON_SECRET"
|
|
260
|
+
curl -X POST https://your-app/api/support/process-snooze -H "x-cron-secret: $CRON_SECRET"
|
|
261
|
+
# Daily / weekly: notification digests
|
|
262
|
+
curl -X POST https://your-app/api/support/process-digests -H "x-cron-secret: $CRON_SECRET" -d '{"frequency":"daily"}'
|
|
462
263
|
```
|
|
463
264
|
|
|
464
|
-
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="
|
|
265
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
465
266
|
|
|
466
|
-
##
|
|
267
|
+
## β FAQ
|
|
467
268
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
- Billing & invoicing β time-based billing, invoice PDF generation
|
|
471
|
-
- Knowledge base search β client portal FAQ with full-text search
|
|
472
|
-
- Email inbound processing β parse email replies into ticket messages
|
|
473
|
-
- Real-time typing indicators via SSE
|
|
474
|
-
- Canned responses / macros UI β quick reply templates in admin
|
|
475
|
-
- Dashboard analytics β charts, trends, response times, SLA compliance
|
|
476
|
-
- Multi-language client portal β full i18n beyond FR/EN
|
|
477
|
-
- File attachments on ticket messages
|
|
478
|
-
- Ticket tags & custom fields
|
|
269
|
+
<details>
|
|
270
|
+
<summary><b>Which databases are supported?</b></summary>
|
|
479
271
|
|
|
480
|
-
|
|
272
|
+
Built and tested on **SQLite** (`@payloadcms/db-sqlite`) with a sequential seed and `busyTimeout`. It works with any Payload adapter, but indexes and queries were validated on SQLite.
|
|
481
273
|
|
|
482
|
-
|
|
274
|
+
</details>
|
|
483
275
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
- **React** 18.x or 19.x
|
|
487
|
-
- **Database**: Any Payload-supported adapter (SQLite, PostgreSQL, MongoDB)
|
|
276
|
+
<details>
|
|
277
|
+
<summary><b>What Node / Payload versions are supported?</b></summary>
|
|
488
278
|
|
|
489
|
-
|
|
279
|
+
Node.js 18+, Payload 3.x, React 18 or 19.
|
|
490
280
|
|
|
491
|
-
|
|
281
|
+
</details>
|
|
492
282
|
|
|
493
|
-
|
|
283
|
+
<details>
|
|
284
|
+
<summary><b>Is there TypeScript support?</b></summary>
|
|
494
285
|
|
|
495
|
-
|
|
496
|
-
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" width="217" />
|
|
497
|
-
</a>
|
|
286
|
+
Yes β strict TypeScript, with business types exported (`SupportPluginConfig`, `SupportFeatures`, β¦).
|
|
498
287
|
|
|
499
|
-
|
|
288
|
+
</details>
|
|
500
289
|
|
|
501
|
-
|
|
290
|
+
<details>
|
|
291
|
+
<summary><b>Do I need an external AI service?</b></summary>
|
|
502
292
|
|
|
503
|
-
|
|
293
|
+
No. AI features are optional and you can run **self-hosted Ollama** to depend on no cloud (sovereignty/GDPR). Anthropic and OpenAI are also supported.
|
|
504
294
|
|
|
505
|
-
|
|
295
|
+
</details>
|
|
506
296
|
|
|
507
|
-
|
|
297
|
+
<details>
|
|
298
|
+
<summary><b>How do I migrate the schema in production?</b></summary>
|
|
508
299
|
|
|
509
|
-
|
|
300
|
+
In standalone mode the schema isn't auto-migrated: generate/push the schema (new fields and collections) before deploying. See [Troubleshooting](#-troubleshooting).
|
|
510
301
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
302
|
+
</details>
|
|
303
|
+
|
|
304
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
305
|
+
|
|
306
|
+
## π§ Troubleshooting
|
|
307
|
+
|
|
308
|
+
### `useServerFunctions must be used within ServerFunctionsProvider`
|
|
309
|
+
|
|
310
|
+
Use Payload **3.75+** for all `@payloadcms/*` packages (aligned versions).
|
|
311
|
+
|
|
312
|
+
### `SQLITE_BUSY` / database is locked during seed
|
|
313
|
+
|
|
314
|
+
Make the seed **sequential** (no `Promise.all` on inserts) and add `busyTimeout: 10000` to the SQLite adapter.
|
|
315
|
+
|
|
316
|
+
### Admin views don't load
|
|
317
|
+
|
|
318
|
+
Regenerate the import map after adding components: `pnpm payload generate:importmap`. In a plugin/headless context, use `skipViews: true` if you don't mount the admin UI.
|
|
319
|
+
|
|
320
|
+
### New fields/collections missing in production
|
|
321
|
+
|
|
322
|
+
Standalone doesn't run migrations: push the schema for `googleId`, `twoFactorVerifiedAt`, `slaPausedAt`, `nps`, `mentions`, and the `notification-queue` / `automation-rules` collections.
|
|
323
|
+
|
|
324
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
325
|
+
|
|
326
|
+
## π Security
|
|
327
|
+
|
|
328
|
+
Security is a first-class concern β several guardrails are validated by integration tests.
|
|
329
|
+
|
|
330
|
+
- **Cross-client isolation** β a client can never read another's tickets/messages (filtered by owned tickets).
|
|
331
|
+
- **2FA** enforced server-side (`beforeLogin`); **OAuth** verifies the Google email.
|
|
332
|
+
- **Sanitization** of message HTML server-side (stored-XSS protection).
|
|
333
|
+
- **HMAC-signed** webhooks, signed tracking pixel, fail-closed secrets.
|
|
334
|
+
|
|
335
|
+
### Reporting Security Issues
|
|
336
|
+
|
|
337
|
+
Please email **contact@consilioweb.fr** instead of opening a public issue.
|
|
338
|
+
|
|
339
|
+
### Best Practices
|
|
340
|
+
|
|
341
|
+
- β
Set a strong `PAYLOAD_SECRET` (never a default value)
|
|
342
|
+
- β
Set `CRON_SECRET` to protect the cron endpoints
|
|
343
|
+
- β
Restrict read access to the `media` collection to the ticket owner
|
|
344
|
+
- β
Put the app behind a trusted proxy (`x-forwarded-for` header)
|
|
345
|
+
- β
Keep the plugin up-to-date
|
|
346
|
+
|
|
347
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
348
|
+
|
|
349
|
+
## π€ Contributing
|
|
350
|
+
|
|
351
|
+
Contributions are very welcome!
|
|
352
|
+
|
|
353
|
+
1. **Fork** the repository
|
|
354
|
+
2. **Create** a feature branch (`git checkout -b feature/AmazingFeature`)
|
|
355
|
+
3. **Commit** your changes (`git commit -m 'feat: add AmazingFeature'`)
|
|
356
|
+
4. **Push** the branch (`git push origin feature/AmazingFeature`)
|
|
357
|
+
5. **Open** a Pull Request
|
|
358
|
+
|
|
359
|
+
Run the checks before submitting:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
npm run typecheck && npm test && npm run build
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
366
|
+
|
|
367
|
+
## π Changelog
|
|
368
|
+
|
|
369
|
+
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
370
|
+
|
|
371
|
+
### [1.0.0] β 2026-06-25
|
|
372
|
+
|
|
373
|
+
- β¨ Complete ticketing, SLA (+ pause-on-hold), automation & **visual rules engine**.
|
|
374
|
+
- π€ AI (sentiment, suggestion, synthesis, chatbot) + **autonomous AI agent**.
|
|
375
|
+
- π¬ Live chat, client portal (2FA, OAuth), knowledge base.
|
|
376
|
+
- πΆ Time tracking, pre-billing & print-ready invoice.
|
|
377
|
+
- π CSAT + NPS, real volume series, digests, webhooks.
|
|
378
|
+
- π Security hardening (cross-client isolation, anti-XSS, server-side 2FA).
|
|
379
|
+
- β
Integration test harness (Payload + in-memory SQLite), 102 tests.
|
|
380
|
+
|
|
381
|
+
<details>
|
|
382
|
+
<summary><b>Previous versions (0.x)</b></summary>
|
|
383
|
+
|
|
384
|
+
- **0.16.0** β Manual client reminder + auto-close after 24h
|
|
385
|
+
- **0.15.0** β Next 16 compatibility + accumulated features
|
|
386
|
+
- **0.9.0 β 0.9.13** β Enriched views (Client Intelligence, Billing), bundled RichTextEditor, code blocks in emails, inline message editing, enriched pre-billing, per-ticket cached AI synthesis, multi-style rewriting
|
|
387
|
+
- **0.6.0 β 0.6.4** β Split build (`bundle:false`) for Next.js RSC compatibility + barrel exports
|
|
388
|
+
- **0.5.0** β Full i18n across the 13 admin views
|
|
389
|
+
- **0.4.0** β Per-user preferences (locale, signature) vs global settings
|
|
390
|
+
- **0.3.0** β Feature parity with ConsilioWEB + `skipCollections` / `skipViews` / `skipEndpoints`
|
|
391
|
+
- **0.2.0** β 2026-04-08 β Security overhaul, SSE live chat, webhooks, SLA, scheduled replies, client portal
|
|
392
|
+
- **0.1.0** β 2026-04-08 β Initial scaffold: `supportPlugin()`, 15 collections, feature flags, AI provider abstraction
|
|
393
|
+
|
|
394
|
+
</details>
|
|
395
|
+
|
|
396
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
397
|
+
|
|
398
|
+
## πΊοΈ Roadmap
|
|
399
|
+
|
|
400
|
+
- [x] Ticketing, SLA, time tracking & billing
|
|
401
|
+
- [x] AI assists + autonomous AI agent
|
|
402
|
+
- [x] Live chat, client portal, knowledge base
|
|
403
|
+
- [x] Visual automation-rules engine
|
|
404
|
+
- [x] Native binary PDF invoice (alongside the print-ready HTML)
|
|
405
|
+
- [x] Full admin i18n (all views)
|
|
406
|
+
- [x] Social channels (WhatsApp, Messenger)
|
|
407
|
+
- [x] Multi-team / workspaces mode
|
|
408
|
+
- [ ] **Per-team SLA policies & dashboards**
|
|
409
|
+
- [ ] **Native push / browser notifications**
|
|
410
|
+
- [ ] **End-to-end UI test harness** (browser-driven admin)
|
|
411
|
+
|
|
412
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
413
|
+
|
|
414
|
+
## β Support
|
|
415
|
+
|
|
416
|
+
If this plugin saves you time, consider buying me a coffee!
|
|
417
|
+
|
|
418
|
+
<a href="https://buymeacoffee.com/pown3d">
|
|
419
|
+
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" width="217" />
|
|
519
420
|
</a>
|
|
520
421
|
|
|
521
|
-
<
|
|
422
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
423
|
+
|
|
424
|
+
## π License
|
|
425
|
+
|
|
426
|
+
Licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details.
|
|
522
427
|
|
|
523
|
-
<img src="https://
|
|
428
|
+
<img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" width="100%" alt="" />
|
|
524
429
|
|
|
430
|
+
<div align="center" style="padding: 40px 0; color: #666; border-top: 1px solid #e0e0e0; margin-top: 50px;">
|
|
431
|
+
<p style="margin: 10px 0;">Built and maintained by <a href="https://consilioweb.fr" style="color: #1f8a5b; text-decoration: none;">ConsilioWEB</a></p>
|
|
432
|
+
<p style="margin: 10px 0; font-size: 13px;">
|
|
433
|
+
<a href="https://github.com/pOwn3d/payload-support#readme" style="color: #1f8a5b; text-decoration: none; margin: 0 15px;">Documentation</a>
|
|
434
|
+
<a href="https://github.com/pOwn3d/payload-support/issues" style="color: #1f8a5b; text-decoration: none; margin: 0 15px;">Issues</a>
|
|
435
|
+
<a href="https://www.npmjs.com/package/@consilioweb/payload-support" style="color: #1f8a5b; text-decoration: none; margin: 0 15px;">npm</a>
|
|
436
|
+
</p>
|
|
525
437
|
</div>
|