@consilioweb/payload-support 5.0.0 → 6.0.1
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 +249 -22
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/components/TicketConversation/RewriteDropdown.js +1 -1
- package/dist/components/TicketConversation/components/AISummaryPanel.js +3 -0
- package/dist/components/TicketConversation/components/ActionPanels.js +13 -8
- package/dist/components/TicketConversation/components/ClientHistory.js +1 -0
- package/dist/components/TicketConversation/components/CodeBlock.js +1 -0
- package/dist/components/TicketConversation/components/CodeBlockInserter.js +1 -1
- package/dist/components/TicketConversation/components/QuickActions.js +10 -8
- package/dist/components/TicketConversation/components/TicketHeader.js +2 -0
- package/dist/components/TicketConversation/components/TimeTrackingPanel.js +15 -9
- package/dist/components/TicketConversation/index.d.ts +10 -0
- package/dist/components/TicketConversation/index.js +25 -7
- package/dist/index.cjs +306 -60
- package/dist/index.d.cts +107 -38
- package/dist/index.d.ts +107 -38
- package/dist/index.js +300 -59
- package/dist/styles/BillingView.module.scss +11 -11
- package/dist/styles/ChatView.module.scss +7 -7
- package/dist/styles/CommandPalette.module.scss +1 -1
- package/dist/styles/CrmView.module.scss +9 -9
- package/dist/styles/EmailTracking.module.scss +6 -6
- package/dist/styles/ImportConversation.module.scss +5 -5
- package/dist/styles/Logs.module.scss +5 -5
- package/dist/styles/NewTicket.module.scss +2 -2
- package/dist/styles/PendingEmails.module.scss +13 -13
- package/dist/styles/SupportDashboard.module.scss +24 -8
- package/dist/styles/TicketDetail.module.scss +20 -20
- package/dist/styles/TicketInbox.module.scss +6 -6
- package/dist/styles/TicketingSettings.module.scss +10 -10
- package/dist/styles/TimeDashboard.module.scss +6 -6
- package/dist/styles/_tokens.scss +3 -1
- package/dist/utils/db.js +20 -0
- package/dist/utils/readSettings.js +150 -0
- package/dist/views/BillingView/client.js +15 -8
- package/dist/views/ChatView/client.js +2 -0
- package/dist/views/CrmView/client.js +2 -0
- package/dist/views/EmailTrackingView/client.js +23 -11
- package/dist/views/ImportConversationView/client.js +1 -0
- package/dist/views/LogsView/client.js +1 -1
- package/dist/views/NewTicketView/client.js +20 -13
- package/dist/views/PendingEmailsView/client.js +9 -3
- package/dist/views/SupportDashboardView/client.js +17 -19
- package/dist/views/TicketDetailView/client.js +23 -11
- package/dist/views/TicketInboxView/client.js +52 -26
- package/dist/views/TicketingSettingsView/TicketingSettings.module.scss +7 -7
- package/dist/views/TicketingSettingsView/client.js +44 -26
- package/dist/views/TimeDashboardView/client.js +10 -7
- package/dist/views/shared/ErrorBoundary.d.ts +36 -1
- package/dist/views/shared/ErrorBoundary.js +59 -28
- package/dist/views/shared/adminTokens.d.ts +15 -5
- package/dist/views/shared/adminTokens.js +23 -7
- package/dist/views/shared/icons.d.ts +49 -0
- package/dist/views/shared/icons.js +92 -0
- package/dist/views/shared/locales/en.json +15 -1
- package/dist/views/shared/locales/fr.json +15 -1
- package/package.json +9 -4
- package/scripts/copy-subpath-types.mjs +103 -0
- package/scripts/uninstall-data.mjs +178 -0
- package/scripts/uninstall.mjs +184 -0
- package/scripts/verify-dist-imports.mjs +84 -0
- package/src/collections/Tickets.ts +7 -0
- package/src/collections/TimeEntries.ts +11 -3
- package/src/components/RichTextEditor/index.tsx +1 -1
- package/src/components/TicketConversation/RewriteDropdown.tsx +1 -1
- package/src/components/TicketConversation/components/AISummaryPanel.tsx +3 -0
- package/src/components/TicketConversation/components/ActionPanels.tsx +13 -8
- package/src/components/TicketConversation/components/ClientHistory.tsx +1 -0
- package/src/components/TicketConversation/components/CodeBlock.tsx +1 -0
- package/src/components/TicketConversation/components/CodeBlockInserter.tsx +1 -1
- package/src/components/TicketConversation/components/QuickActions.tsx +10 -8
- package/src/components/TicketConversation/components/TicketHeader.tsx +2 -0
- package/src/components/TicketConversation/components/TimeTrackingPanel.tsx +17 -9
- package/src/components/TicketConversation/index.tsx +41 -7
- package/src/endpoints/delete-account.ts +191 -47
- package/src/endpoints/export-data.ts +104 -4
- package/src/endpoints/purge-logs.ts +6 -15
- package/src/index.ts +2 -0
- package/src/plugin.ts +51 -1
- package/src/portal/LiveChat.tsx +1 -1
- package/src/portal/auth/profile/page.tsx +3 -2
- package/src/portal/icons.tsx +91 -0
- package/src/styles/BillingView.module.scss +11 -11
- package/src/styles/ChatView.module.scss +7 -7
- package/src/styles/CommandPalette.module.scss +1 -1
- package/src/styles/CrmView.module.scss +9 -9
- package/src/styles/EmailTracking.module.scss +6 -6
- package/src/styles/ImportConversation.module.scss +5 -5
- package/src/styles/Logs.module.scss +5 -5
- package/src/styles/NewTicket.module.scss +2 -2
- package/src/styles/PendingEmails.module.scss +13 -13
- package/src/styles/SupportDashboard.module.scss +24 -8
- package/src/styles/TicketDetail.module.scss +20 -20
- package/src/styles/TicketInbox.module.scss +6 -6
- package/src/styles/TicketingSettings.module.scss +10 -10
- package/src/styles/TimeDashboard.module.scss +6 -6
- package/src/styles/_tokens.scss +3 -1
- package/src/types.ts +20 -0
- package/src/utils/retention.ts +111 -0
- package/src/utils/slugs.ts +15 -0
- package/src/views/BillingView/client.tsx +17 -8
- package/src/views/ChatView/client.tsx +2 -0
- package/src/views/CrmView/client.tsx +2 -0
- package/src/views/EmailTrackingView/client.tsx +18 -7
- package/src/views/ImportConversationView/client.tsx +1 -0
- package/src/views/LogsView/client.tsx +1 -1
- package/src/views/NewTicketView/client.tsx +22 -13
- package/src/views/PendingEmailsView/client.tsx +9 -3
- package/src/views/SupportDashboardView/client.tsx +11 -5
- package/src/views/TicketDetailView/client.tsx +25 -11
- package/src/views/TicketInboxView/client.tsx +47 -7
- package/src/views/TicketingSettingsView/TicketingSettings.module.scss +7 -7
- package/src/views/TicketingSettingsView/client.tsx +201 -144
- package/src/views/TimeDashboardView/client.tsx +10 -7
- package/src/views/shared/ErrorBoundary.tsx +95 -31
- package/src/views/shared/adminTokens.ts +28 -11
- package/src/views/shared/icons.tsx +146 -0
- package/src/views/shared/locales/en.json +15 -1
- package/src/views/shared/locales/fr.json +15 -1
- package/src/types/lucide-react.d.ts +0 -42
package/dist/index.d.ts
CHANGED
|
@@ -65,6 +65,94 @@ declare class RateLimiter {
|
|
|
65
65
|
reset(key: string, context?: unknown): Promise<void>;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Default collection slugs used by the support plugin.
|
|
70
|
+
* All slugs can be overridden via SupportPluginConfig.collectionSlugs.
|
|
71
|
+
*/
|
|
72
|
+
interface CollectionSlugs {
|
|
73
|
+
tickets: string;
|
|
74
|
+
ticketMessages: string;
|
|
75
|
+
supportClients: string;
|
|
76
|
+
timeEntries: string;
|
|
77
|
+
cannedResponses: string;
|
|
78
|
+
ticketActivityLog: string;
|
|
79
|
+
satisfactionSurveys: string;
|
|
80
|
+
knowledgeBase: string;
|
|
81
|
+
chatMessages: string;
|
|
82
|
+
pendingEmails: string;
|
|
83
|
+
emailLogs: string;
|
|
84
|
+
authLogs: string;
|
|
85
|
+
webhookEndpoints: string;
|
|
86
|
+
slaPolicies: string;
|
|
87
|
+
macros: string;
|
|
88
|
+
ticketStatuses: string;
|
|
89
|
+
ticketFeedback: string;
|
|
90
|
+
notificationQueue: string;
|
|
91
|
+
automationRules: string;
|
|
92
|
+
supportTeams: string;
|
|
93
|
+
pushSubscriptions: string;
|
|
94
|
+
rateLimits: string;
|
|
95
|
+
counters: string;
|
|
96
|
+
users: string;
|
|
97
|
+
media: string;
|
|
98
|
+
}
|
|
99
|
+
declare const DEFAULT_SLUGS: CollectionSlugs;
|
|
100
|
+
/**
|
|
101
|
+
* Resolve collection slugs merging user overrides with defaults.
|
|
102
|
+
*/
|
|
103
|
+
declare function resolveSlugs(overrides?: Partial<CollectionSlugs>): CollectionSlugs;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* How long the two journals are kept, in days.
|
|
107
|
+
*
|
|
108
|
+
* Defaults follow the CNIL guidance the README documents: six months would be
|
|
109
|
+
* the floor for connection logs, a year is the ceiling usually accepted, and
|
|
110
|
+
* these two values sit inside that range while staying long enough to
|
|
111
|
+
* investigate an intrusion. Set a value to 0 to disable the automatic purge of
|
|
112
|
+
* that journal — never to mean "delete everything", which is what `days=0`
|
|
113
|
+
* means on the manual endpoint.
|
|
114
|
+
*/
|
|
115
|
+
interface RetentionConfig {
|
|
116
|
+
/** Retention of `auth-logs` in days. `0` disables the scheduled purge. */
|
|
117
|
+
authLogsDays?: number;
|
|
118
|
+
/** Retention of `email-logs` in days. `0` disables the scheduled purge. */
|
|
119
|
+
emailLogsDays?: number;
|
|
120
|
+
/**
|
|
121
|
+
* Cron for the scheduled purge. Payload's cron takes an optional leading
|
|
122
|
+
* seconds field. Default: every day at 03:30.
|
|
123
|
+
*/
|
|
124
|
+
cron?: string;
|
|
125
|
+
/** Queue the scheduled job is pushed to. Default: `default`. */
|
|
126
|
+
queue?: string;
|
|
127
|
+
}
|
|
128
|
+
declare const DEFAULT_RETENTION: {
|
|
129
|
+
readonly authLogsDays: 180;
|
|
130
|
+
readonly emailLogsDays: 365;
|
|
131
|
+
readonly cron: "0 30 3 * * *";
|
|
132
|
+
readonly queue: "default";
|
|
133
|
+
};
|
|
134
|
+
declare const PURGE_LOGS_TASK_SLUG = "support-purge-logs";
|
|
135
|
+
/** Journals the purge is allowed to touch, keyed by their public name. */
|
|
136
|
+
declare function purgeableCollections(slugs: CollectionSlugs): Record<string, string>;
|
|
137
|
+
/**
|
|
138
|
+
* Delete rows of `slug` created more than `days` days ago.
|
|
139
|
+
*
|
|
140
|
+
* `days <= 0` means "everything" and is only reachable from the manual
|
|
141
|
+
* admin-only endpoint. The scheduled task refuses it: a misconfigured cron
|
|
142
|
+
* that wipes the whole security journal every night is a far worse outcome
|
|
143
|
+
* than a journal that grows.
|
|
144
|
+
*/
|
|
145
|
+
declare function purgeOlderThan(payload: Payload, slug: string, days: number, req?: PayloadRequest): Promise<number>;
|
|
146
|
+
interface ScheduledPurgeResult {
|
|
147
|
+
purged: Record<string, number>;
|
|
148
|
+
skipped: string[];
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The scheduled half of the purge. Never accepts `days <= 0`, and silently
|
|
152
|
+
* skips a journal whose collection is not registered (its feature flag is off).
|
|
153
|
+
*/
|
|
154
|
+
declare function runScheduledPurge(payload: Payload, slugs: CollectionSlugs, retention: RetentionConfig | false | undefined, req?: PayloadRequest): Promise<ScheduledPurgeResult>;
|
|
155
|
+
|
|
68
156
|
interface InboundEmailLimits {
|
|
69
157
|
maxRequestBytes: number;
|
|
70
158
|
maxAttachmentBytes: number;
|
|
@@ -228,6 +316,24 @@ interface SupportPluginConfig {
|
|
|
228
316
|
email?: EmailConfig;
|
|
229
317
|
/** Shared rate-limit storage. Defaults to process-local memory. */
|
|
230
318
|
rateLimitStore?: RateLimitStore | 'payload';
|
|
319
|
+
/**
|
|
320
|
+
* Automatic retention of the two journals the plugin writes.
|
|
321
|
+
*
|
|
322
|
+
* The plugin registers a daily Payload Jobs task that deletes rows older
|
|
323
|
+
* than the configured number of days. Set a value to 0 to keep that journal
|
|
324
|
+
* forever (the manual `DELETE /api/support/purge-logs` endpoint stays
|
|
325
|
+
* available either way).
|
|
326
|
+
*
|
|
327
|
+
* Defaults: auth-logs 180 days, email-logs 365 days, cron `0 30 3 * * *`.
|
|
328
|
+
*
|
|
329
|
+
* `false` registers no task at all. That is the ONLY value that changes the
|
|
330
|
+
* schema footprint: registering a task turns Payload's job queue on, which
|
|
331
|
+
* adds the `payload-jobs` collection and the `payload-jobs-stats` global to
|
|
332
|
+
* an app that had no jobs — two tables you would have to migrate. Pass
|
|
333
|
+
* `false` if you would rather purge from your own cron, calling
|
|
334
|
+
* `DELETE /api/support/purge-logs`.
|
|
335
|
+
*/
|
|
336
|
+
retention?: RetentionConfig | false;
|
|
231
337
|
/** Sequential ticket number formatting. */
|
|
232
338
|
ticketNumber?: {
|
|
233
339
|
prefix?: string;
|
|
@@ -376,43 +482,6 @@ declare const DEFAULT_FEATURES: Required<SupportFeatures>;
|
|
|
376
482
|
*/
|
|
377
483
|
declare function supportPlugin(config?: SupportPluginConfig): Plugin;
|
|
378
484
|
|
|
379
|
-
/**
|
|
380
|
-
* Default collection slugs used by the support plugin.
|
|
381
|
-
* All slugs can be overridden via SupportPluginConfig.collectionSlugs.
|
|
382
|
-
*/
|
|
383
|
-
interface CollectionSlugs {
|
|
384
|
-
tickets: string;
|
|
385
|
-
ticketMessages: string;
|
|
386
|
-
supportClients: string;
|
|
387
|
-
timeEntries: string;
|
|
388
|
-
cannedResponses: string;
|
|
389
|
-
ticketActivityLog: string;
|
|
390
|
-
satisfactionSurveys: string;
|
|
391
|
-
knowledgeBase: string;
|
|
392
|
-
chatMessages: string;
|
|
393
|
-
pendingEmails: string;
|
|
394
|
-
emailLogs: string;
|
|
395
|
-
authLogs: string;
|
|
396
|
-
webhookEndpoints: string;
|
|
397
|
-
slaPolicies: string;
|
|
398
|
-
macros: string;
|
|
399
|
-
ticketStatuses: string;
|
|
400
|
-
ticketFeedback: string;
|
|
401
|
-
notificationQueue: string;
|
|
402
|
-
automationRules: string;
|
|
403
|
-
supportTeams: string;
|
|
404
|
-
pushSubscriptions: string;
|
|
405
|
-
rateLimits: string;
|
|
406
|
-
counters: string;
|
|
407
|
-
users: string;
|
|
408
|
-
media: string;
|
|
409
|
-
}
|
|
410
|
-
declare const DEFAULT_SLUGS: CollectionSlugs;
|
|
411
|
-
/**
|
|
412
|
-
* Resolve collection slugs merging user overrides with defaults.
|
|
413
|
-
*/
|
|
414
|
-
declare function resolveSlugs(overrides?: Partial<CollectionSlugs>): CollectionSlugs;
|
|
415
|
-
|
|
416
485
|
/**
|
|
417
486
|
* Ticketing feature flags — single source of truth (client + server).
|
|
418
487
|
*
|
|
@@ -710,4 +779,4 @@ declare function createTicketStatusesCollection(slugs: CollectionSlugs): Collect
|
|
|
710
779
|
*/
|
|
711
780
|
declare function createTicketCollaboratorsCollection(slugs: CollectionSlugs): CollectionConfig;
|
|
712
781
|
|
|
713
|
-
export { type AIProviderConfig, type ActivityEntryData, type CannedResponseData, type ClientData, type CollectionSlugs, DEFAULT_FEATURES, DEFAULT_INBOUND_EMAIL_LIMITS, DEFAULT_SETTINGS, DEFAULT_SLUGS, DEFAULT_TICKETING_FEATURES, DEFAULT_USER_PREFS, type EmailConfig, type InboundEmailInput, type InboundEmailLimits, type InboundEmailValidationError, MemoryRateLimitStore, type MessageData, PayloadRateLimitStore, type RateLimitEntry, type RateLimitStore, RateLimiter, type SatisfactionSurveyData, type SupportFeatures, type SupportPluginConfig, type SupportSettings, type SupportSettingsState, type TicketData, type TicketSynthesisResult, type TicketingFeatures, type TimeEntryData, type UserPrefs, calculateBusinessHoursDeadline, createAdminNotification, createAssignSlaDeadlines, createAuthLogsCollection, createCannedResponsesCollection, createChatMessagesCollection, createCheckSlaOnReply, createCheckSlaOnResolve, createEmailLogsCollection, createKnowledgeBaseCollection, createLoginEndpoint, createMacrosCollection, createOAuthGoogleEndpoint, createPendingEmailsCollection, createSatisfactionSurveysCollection, createSlaPoliciesCollection, createSupportClientsCollection, createTicketActivityLogCollection, createTicketCollaboratorsCollection, createTicketMessagesCollection, createTicketStatusEmail, createTicketStatusesCollection, createTicketsCollection, createTimeEntriesCollection, createTrackOpenEndpoint, createWebhookEndpointsCollection, dispatchWebhook, generateTicketSynthesis, normalizeFeatures, projectAutoClose, readSupportSettings, readSupportSettingsState, readUserPrefs, resolveSlugs, stripProjectedFeatures, supportPlugin, validateInboundEmailPayload, verifySecret };
|
|
782
|
+
export { type AIProviderConfig, type ActivityEntryData, type CannedResponseData, type ClientData, type CollectionSlugs, DEFAULT_FEATURES, DEFAULT_INBOUND_EMAIL_LIMITS, DEFAULT_RETENTION, DEFAULT_SETTINGS, DEFAULT_SLUGS, DEFAULT_TICKETING_FEATURES, DEFAULT_USER_PREFS, type EmailConfig, type InboundEmailInput, type InboundEmailLimits, type InboundEmailValidationError, MemoryRateLimitStore, type MessageData, PURGE_LOGS_TASK_SLUG, PayloadRateLimitStore, type RateLimitEntry, type RateLimitStore, RateLimiter, type RetentionConfig, type SatisfactionSurveyData, type ScheduledPurgeResult, type SupportFeatures, type SupportPluginConfig, type SupportSettings, type SupportSettingsState, type TicketData, type TicketSynthesisResult, type TicketingFeatures, type TimeEntryData, type UserPrefs, calculateBusinessHoursDeadline, createAdminNotification, createAssignSlaDeadlines, createAuthLogsCollection, createCannedResponsesCollection, createChatMessagesCollection, createCheckSlaOnReply, createCheckSlaOnResolve, createEmailLogsCollection, createKnowledgeBaseCollection, createLoginEndpoint, createMacrosCollection, createOAuthGoogleEndpoint, createPendingEmailsCollection, createSatisfactionSurveysCollection, createSlaPoliciesCollection, createSupportClientsCollection, createTicketActivityLogCollection, createTicketCollaboratorsCollection, createTicketMessagesCollection, createTicketStatusEmail, createTicketStatusesCollection, createTicketsCollection, createTimeEntriesCollection, createTrackOpenEndpoint, createWebhookEndpointsCollection, dispatchWebhook, generateTicketSynthesis, normalizeFeatures, projectAutoClose, purgeOlderThan, purgeableCollections, readSupportSettings, readSupportSettingsState, readUserPrefs, resolveSlugs, runScheduledPurge, stripProjectedFeatures, supportPlugin, validateInboundEmailPayload, verifySecret };
|
package/dist/index.js
CHANGED
|
@@ -72,6 +72,11 @@ var DEFAULT_SLUGS = {
|
|
|
72
72
|
users: "users",
|
|
73
73
|
media: "media"
|
|
74
74
|
};
|
|
75
|
+
var FIXED_SLUGS = {
|
|
76
|
+
clientSummaries: "client-summaries",
|
|
77
|
+
ticketCollaborators: "ticket-collaborators",
|
|
78
|
+
ticketFeedback: "ticket-feedback"
|
|
79
|
+
};
|
|
75
80
|
function resolveSlugs(overrides) {
|
|
76
81
|
return { ...DEFAULT_SLUGS, ...overrides };
|
|
77
82
|
}
|
|
@@ -2988,6 +2993,51 @@ function createApplyMacroEndpoint(slugs) {
|
|
|
2988
2993
|
};
|
|
2989
2994
|
}
|
|
2990
2995
|
|
|
2996
|
+
// src/utils/retention.ts
|
|
2997
|
+
var DEFAULT_RETENTION = {
|
|
2998
|
+
authLogsDays: 180,
|
|
2999
|
+
emailLogsDays: 365,
|
|
3000
|
+
cron: "0 30 3 * * *",
|
|
3001
|
+
queue: "default"
|
|
3002
|
+
};
|
|
3003
|
+
var PURGE_LOGS_TASK_SLUG = "support-purge-logs";
|
|
3004
|
+
function purgeableCollections(slugs) {
|
|
3005
|
+
return {
|
|
3006
|
+
"email-logs": slugs.emailLogs,
|
|
3007
|
+
"auth-logs": slugs.authLogs
|
|
3008
|
+
};
|
|
3009
|
+
}
|
|
3010
|
+
async function purgeOlderThan(payload, slug, days, req) {
|
|
3011
|
+
const cutoff = days > 0 ? new Date(Date.now() - days * 864e5).toISOString() : null;
|
|
3012
|
+
const result = await dbDelete(payload, slug, {
|
|
3013
|
+
where: cutoff ? { createdAt: { less_than: cutoff } } : { id: { exists: true } },
|
|
3014
|
+
overrideAccess: true,
|
|
3015
|
+
...req ? { req } : {}
|
|
3016
|
+
});
|
|
3017
|
+
return Array.isArray(result?.docs) ? result.docs.length : 0;
|
|
3018
|
+
}
|
|
3019
|
+
async function runScheduledPurge(payload, slugs, retention, req) {
|
|
3020
|
+
if (retention === false) return { purged: {}, skipped: ["auth-logs", "email-logs"] };
|
|
3021
|
+
const plan = [
|
|
3022
|
+
["auth-logs", slugs.authLogs, retention?.authLogsDays ?? DEFAULT_RETENTION.authLogsDays],
|
|
3023
|
+
["email-logs", slugs.emailLogs, retention?.emailLogsDays ?? DEFAULT_RETENTION.emailLogsDays]
|
|
3024
|
+
];
|
|
3025
|
+
const purged = {};
|
|
3026
|
+
const skipped = [];
|
|
3027
|
+
for (const [name, slug, days] of plan) {
|
|
3028
|
+
if (!Number.isFinite(days) || days <= 0) {
|
|
3029
|
+
skipped.push(name);
|
|
3030
|
+
continue;
|
|
3031
|
+
}
|
|
3032
|
+
if (!payload.collections?.[slug]) {
|
|
3033
|
+
skipped.push(name);
|
|
3034
|
+
continue;
|
|
3035
|
+
}
|
|
3036
|
+
purged[name] = await purgeOlderThan(payload, slug, days, req);
|
|
3037
|
+
}
|
|
3038
|
+
return { purged, skipped };
|
|
3039
|
+
}
|
|
3040
|
+
|
|
2991
3041
|
// src/endpoints/purge-logs.ts
|
|
2992
3042
|
function createPurgeLogsEndpoint(slugs) {
|
|
2993
3043
|
return {
|
|
@@ -3000,19 +3050,11 @@ function createPurgeLogsEndpoint(slugs) {
|
|
|
3000
3050
|
const url = new URL(req.url);
|
|
3001
3051
|
const collection = url.searchParams.get("collection");
|
|
3002
3052
|
const days = Number(url.searchParams.get("days") || "0");
|
|
3003
|
-
const allowedCollections =
|
|
3004
|
-
"email-logs": slugs.emailLogs,
|
|
3005
|
-
"auth-logs": slugs.authLogs
|
|
3006
|
-
};
|
|
3053
|
+
const allowedCollections = purgeableCollections(slugs);
|
|
3007
3054
|
if (!collection || !allowedCollections[collection]) {
|
|
3008
3055
|
return Response.json({ error: "Invalid collection. Use email-logs or auth-logs." }, { status: 400 });
|
|
3009
3056
|
}
|
|
3010
|
-
const
|
|
3011
|
-
const result = await dbDelete(payload, allowedCollections[collection], {
|
|
3012
|
-
where: cutoff ? { createdAt: { less_than: cutoff } } : { id: { exists: true } },
|
|
3013
|
-
overrideAccess: true
|
|
3014
|
-
});
|
|
3015
|
-
const count = Array.isArray(result.docs) ? result.docs.length : 0;
|
|
3057
|
+
const count = await purgeOlderThan(payload, allowedCollections[collection], days, req);
|
|
3016
3058
|
return Response.json({
|
|
3017
3059
|
purged: count,
|
|
3018
3060
|
collection,
|
|
@@ -4735,6 +4777,7 @@ function createExportCsvEndpoint(slugs) {
|
|
|
4735
4777
|
}
|
|
4736
4778
|
|
|
4737
4779
|
// src/endpoints/export-data.ts
|
|
4780
|
+
var EMPTY = { docs: [] };
|
|
4738
4781
|
function createExportDataEndpoint(slugs) {
|
|
4739
4782
|
return {
|
|
4740
4783
|
path: "/support/export-data",
|
|
@@ -4743,7 +4786,16 @@ function createExportDataEndpoint(slugs) {
|
|
|
4743
4786
|
try {
|
|
4744
4787
|
const payload = req.payload;
|
|
4745
4788
|
requireClient(req, slugs);
|
|
4746
|
-
const
|
|
4789
|
+
const isRegistered = (slug) => Boolean(payload.collections?.[slug]);
|
|
4790
|
+
const [
|
|
4791
|
+
clientData,
|
|
4792
|
+
ticketsResult,
|
|
4793
|
+
messagesResult,
|
|
4794
|
+
surveysResult,
|
|
4795
|
+
chatResult,
|
|
4796
|
+
feedbackResult,
|
|
4797
|
+
summariesResult
|
|
4798
|
+
] = await Promise.all([
|
|
4747
4799
|
dbFindByID(payload, slugs.supportClients, {
|
|
4748
4800
|
id: req.user.id,
|
|
4749
4801
|
depth: 0,
|
|
@@ -4769,12 +4821,35 @@ function createExportDataEndpoint(slugs) {
|
|
|
4769
4821
|
limit: 500,
|
|
4770
4822
|
depth: 0,
|
|
4771
4823
|
overrideAccess: true
|
|
4772
|
-
})
|
|
4824
|
+
}),
|
|
4825
|
+
isRegistered(slugs.chatMessages) ? dbFind(payload, slugs.chatMessages, {
|
|
4826
|
+
where: { client: { equals: req.user.id } },
|
|
4827
|
+
limit: 5e3,
|
|
4828
|
+
depth: 0,
|
|
4829
|
+
overrideAccess: true
|
|
4830
|
+
}) : EMPTY,
|
|
4831
|
+
isRegistered(FIXED_SLUGS.ticketFeedback) ? dbFind(payload, FIXED_SLUGS.ticketFeedback, {
|
|
4832
|
+
where: { client: { equals: req.user.id } },
|
|
4833
|
+
limit: 500,
|
|
4834
|
+
depth: 0,
|
|
4835
|
+
overrideAccess: true
|
|
4836
|
+
}) : EMPTY,
|
|
4837
|
+
isRegistered(FIXED_SLUGS.clientSummaries) ? dbFind(payload, FIXED_SLUGS.clientSummaries, {
|
|
4838
|
+
where: { client: { equals: req.user.id } },
|
|
4839
|
+
limit: 100,
|
|
4840
|
+
depth: 0,
|
|
4841
|
+
overrideAccess: true
|
|
4842
|
+
}) : EMPTY
|
|
4773
4843
|
]);
|
|
4844
|
+
const ticketIds = ticketsResult.docs.map((t) => t.id);
|
|
4845
|
+
const timeResult = ticketIds.length > 0 && isRegistered(slugs.timeEntries) ? await dbFind(payload, slugs.timeEntries, {
|
|
4846
|
+
where: { ticket: { in: ticketIds } },
|
|
4847
|
+
limit: 5e3,
|
|
4848
|
+
depth: 0,
|
|
4849
|
+
overrideAccess: true
|
|
4850
|
+
}) : EMPTY;
|
|
4774
4851
|
const c = clientData;
|
|
4775
|
-
const
|
|
4776
|
-
exportDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4777
|
-
exportType: "RGPD - Export des donn\xE9es personnelles",
|
|
4852
|
+
const providedByYou = {
|
|
4778
4853
|
profile: {
|
|
4779
4854
|
email: c.email,
|
|
4780
4855
|
firstName: c.firstName,
|
|
@@ -4803,8 +4878,50 @@ function createExportDataEndpoint(slugs) {
|
|
|
4803
4878
|
rating: s.rating,
|
|
4804
4879
|
comment: s.comment,
|
|
4805
4880
|
createdAt: s.createdAt
|
|
4881
|
+
})),
|
|
4882
|
+
feedback: feedbackResult.docs.map((f) => ({
|
|
4883
|
+
ticketId: f.ticket,
|
|
4884
|
+
rating: f.rating,
|
|
4885
|
+
comment: f.comment,
|
|
4886
|
+
submittedFrom: f.submittedFrom,
|
|
4887
|
+
createdAt: f.createdAt
|
|
4888
|
+
})),
|
|
4889
|
+
chatMessages: chatResult.docs.map((m) => ({
|
|
4890
|
+
session: m.session,
|
|
4891
|
+
senderType: m.senderType,
|
|
4892
|
+
message: m.message,
|
|
4893
|
+
createdAt: m.createdAt
|
|
4894
|
+
})),
|
|
4895
|
+
timeEntries: timeResult.docs.map((e) => ({
|
|
4896
|
+
ticketId: e.ticket,
|
|
4897
|
+
duration: e.duration,
|
|
4898
|
+
date: e.date,
|
|
4899
|
+
description: e.description,
|
|
4900
|
+
billable: e.billable
|
|
4806
4901
|
}))
|
|
4807
4902
|
};
|
|
4903
|
+
const exportData = {
|
|
4904
|
+
exportDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4905
|
+
exportType: "RGPD - Export des donn\xE9es personnelles",
|
|
4906
|
+
providedByYou: {
|
|
4907
|
+
legalBasis: "Art. 20 RGPD - droit \xE0 la portabilit\xE9",
|
|
4908
|
+
...providedByYou
|
|
4909
|
+
},
|
|
4910
|
+
derivedData: {
|
|
4911
|
+
legalBasis: "Art. 15 RGPD - droit d'acc\xE8s (donn\xE9es d\xE9riv\xE9es, hors portabilit\xE9)",
|
|
4912
|
+
clientSummaries: summariesResult.docs.map((s) => ({
|
|
4913
|
+
summary: s.summary,
|
|
4914
|
+
recurringTopics: s.recurringTopics,
|
|
4915
|
+
patterns: s.patterns,
|
|
4916
|
+
keyFacts: s.keyFacts,
|
|
4917
|
+
ticketCount: s.ticketCount,
|
|
4918
|
+
messageCount: s.messageCount,
|
|
4919
|
+
averageSatisfaction: s.averageSatisfaction,
|
|
4920
|
+
generatedAt: s.generatedAt,
|
|
4921
|
+
aiModel: s.aiModel
|
|
4922
|
+
}))
|
|
4923
|
+
}
|
|
4924
|
+
};
|
|
4808
4925
|
const json = JSON.stringify(exportData, null, 2);
|
|
4809
4926
|
return new Response(json, {
|
|
4810
4927
|
status: 200,
|
|
@@ -5718,8 +5835,15 @@ function createOAuthGoogleEndpoint(slugs, options) {
|
|
|
5718
5835
|
}
|
|
5719
5836
|
};
|
|
5720
5837
|
}
|
|
5721
|
-
|
|
5722
|
-
|
|
5838
|
+
function collectAttachmentIds(docs, into) {
|
|
5839
|
+
for (const doc of docs) {
|
|
5840
|
+
for (const attachment of doc.attachments ?? []) {
|
|
5841
|
+
const file = attachment?.file;
|
|
5842
|
+
const id = file != null && typeof file === "object" ? file.id : file;
|
|
5843
|
+
if (id != null) into.add(id);
|
|
5844
|
+
}
|
|
5845
|
+
}
|
|
5846
|
+
}
|
|
5723
5847
|
function createDeleteAccountEndpoint(slugs) {
|
|
5724
5848
|
return {
|
|
5725
5849
|
path: "/support/delete-account",
|
|
@@ -5748,44 +5872,135 @@ function createDeleteAccountEndpoint(slugs) {
|
|
|
5748
5872
|
);
|
|
5749
5873
|
}
|
|
5750
5874
|
const clientId = req.user.id;
|
|
5751
|
-
const
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
select: { id: true }
|
|
5757
|
-
});
|
|
5758
|
-
const ticketIds = tickets.docs.map((t) => t.id);
|
|
5759
|
-
if (ticketIds.length > 0) {
|
|
5760
|
-
await dbDelete(payload, slugs.ticketMessages, {
|
|
5761
|
-
where: { ticket: { in: ticketIds } },
|
|
5762
|
-
overrideAccess: true
|
|
5763
|
-
});
|
|
5764
|
-
await dbDelete(payload, slugs.ticketActivityLog, {
|
|
5765
|
-
where: { ticket: { in: ticketIds } },
|
|
5766
|
-
overrideAccess: true
|
|
5767
|
-
});
|
|
5768
|
-
await dbDelete(payload, slugs.timeEntries, {
|
|
5769
|
-
where: { ticket: { in: ticketIds } },
|
|
5770
|
-
overrideAccess: true
|
|
5771
|
-
});
|
|
5772
|
-
await dbDelete(payload, slugs.tickets, {
|
|
5875
|
+
const clientEmail = req.user.email;
|
|
5876
|
+
const isRegistered = (slug) => Boolean(payload.collections?.[slug]);
|
|
5877
|
+
const startedTransaction = await initTransaction(req);
|
|
5878
|
+
try {
|
|
5879
|
+
const tickets = await dbFind(payload, slugs.tickets, {
|
|
5773
5880
|
where: { client: { equals: clientId } },
|
|
5774
|
-
|
|
5881
|
+
limit: 1e4,
|
|
5882
|
+
depth: 0,
|
|
5883
|
+
overrideAccess: true,
|
|
5884
|
+
select: { id: true },
|
|
5885
|
+
req
|
|
5775
5886
|
});
|
|
5887
|
+
const ticketIds = tickets.docs.map((t) => t.id);
|
|
5888
|
+
const attachmentIds = /* @__PURE__ */ new Set();
|
|
5889
|
+
if (ticketIds.length > 0) {
|
|
5890
|
+
const messages = await dbFind(
|
|
5891
|
+
payload,
|
|
5892
|
+
slugs.ticketMessages,
|
|
5893
|
+
{
|
|
5894
|
+
where: { ticket: { in: ticketIds } },
|
|
5895
|
+
limit: 1e4,
|
|
5896
|
+
depth: 0,
|
|
5897
|
+
overrideAccess: true,
|
|
5898
|
+
req
|
|
5899
|
+
}
|
|
5900
|
+
);
|
|
5901
|
+
collectAttachmentIds(messages.docs, attachmentIds);
|
|
5902
|
+
}
|
|
5903
|
+
if (isRegistered(slugs.pendingEmails)) {
|
|
5904
|
+
const pendingEmails = await dbFind(
|
|
5905
|
+
payload,
|
|
5906
|
+
slugs.pendingEmails,
|
|
5907
|
+
{
|
|
5908
|
+
where: { client: { equals: clientId } },
|
|
5909
|
+
limit: 1e4,
|
|
5910
|
+
depth: 0,
|
|
5911
|
+
overrideAccess: true,
|
|
5912
|
+
req
|
|
5913
|
+
}
|
|
5914
|
+
);
|
|
5915
|
+
collectAttachmentIds(pendingEmails.docs, attachmentIds);
|
|
5916
|
+
}
|
|
5917
|
+
if (ticketIds.length > 0) {
|
|
5918
|
+
for (const slug of [FIXED_SLUGS.ticketFeedback, FIXED_SLUGS.ticketCollaborators]) {
|
|
5919
|
+
if (!isRegistered(slug)) continue;
|
|
5920
|
+
await dbDelete(payload, slug, {
|
|
5921
|
+
where: {
|
|
5922
|
+
or: [
|
|
5923
|
+
{ ticket: { in: ticketIds } },
|
|
5924
|
+
{ client: { equals: clientId } }
|
|
5925
|
+
]
|
|
5926
|
+
},
|
|
5927
|
+
overrideAccess: true,
|
|
5928
|
+
req
|
|
5929
|
+
});
|
|
5930
|
+
}
|
|
5931
|
+
}
|
|
5932
|
+
if (ticketIds.length > 0) {
|
|
5933
|
+
await dbDelete(payload, slugs.tickets, {
|
|
5934
|
+
where: { client: { equals: clientId } },
|
|
5935
|
+
overrideAccess: true,
|
|
5936
|
+
req
|
|
5937
|
+
});
|
|
5938
|
+
}
|
|
5939
|
+
for (const slug of [
|
|
5940
|
+
slugs.satisfactionSurveys,
|
|
5941
|
+
slugs.chatMessages,
|
|
5942
|
+
slugs.notificationQueue,
|
|
5943
|
+
slugs.pendingEmails,
|
|
5944
|
+
FIXED_SLUGS.clientSummaries,
|
|
5945
|
+
FIXED_SLUGS.ticketFeedback
|
|
5946
|
+
]) {
|
|
5947
|
+
if (!isRegistered(slug)) continue;
|
|
5948
|
+
await dbDelete(payload, slug, {
|
|
5949
|
+
where: { client: { equals: clientId } },
|
|
5950
|
+
overrideAccess: true,
|
|
5951
|
+
req
|
|
5952
|
+
});
|
|
5953
|
+
}
|
|
5954
|
+
if (isRegistered(FIXED_SLUGS.ticketCollaborators)) {
|
|
5955
|
+
await dbDelete(payload, FIXED_SLUGS.ticketCollaborators, {
|
|
5956
|
+
where: {
|
|
5957
|
+
or: [
|
|
5958
|
+
{ client: { equals: clientId } },
|
|
5959
|
+
...clientEmail ? [{ email: { equals: clientEmail } }] : []
|
|
5960
|
+
]
|
|
5961
|
+
},
|
|
5962
|
+
overrideAccess: true,
|
|
5963
|
+
req
|
|
5964
|
+
});
|
|
5965
|
+
}
|
|
5966
|
+
if (clientEmail) {
|
|
5967
|
+
if (isRegistered(slugs.authLogs)) {
|
|
5968
|
+
await dbDelete(payload, slugs.authLogs, {
|
|
5969
|
+
where: { email: { equals: clientEmail } },
|
|
5970
|
+
overrideAccess: true,
|
|
5971
|
+
req
|
|
5972
|
+
});
|
|
5973
|
+
}
|
|
5974
|
+
if (isRegistered(slugs.emailLogs)) {
|
|
5975
|
+
await dbDelete(payload, slugs.emailLogs, {
|
|
5976
|
+
where: {
|
|
5977
|
+
or: [
|
|
5978
|
+
{ senderEmail: { equals: clientEmail } },
|
|
5979
|
+
{ recipientEmail: { equals: clientEmail } }
|
|
5980
|
+
]
|
|
5981
|
+
},
|
|
5982
|
+
overrideAccess: true,
|
|
5983
|
+
req
|
|
5984
|
+
});
|
|
5985
|
+
}
|
|
5986
|
+
}
|
|
5987
|
+
for (const id of isRegistered(slugs.media) ? attachmentIds : []) {
|
|
5988
|
+
await dbDelete(payload, slugs.media, {
|
|
5989
|
+
id,
|
|
5990
|
+
overrideAccess: true,
|
|
5991
|
+
req
|
|
5992
|
+
});
|
|
5993
|
+
}
|
|
5994
|
+
await dbDelete(payload, slugs.supportClients, {
|
|
5995
|
+
id: clientId,
|
|
5996
|
+
overrideAccess: true,
|
|
5997
|
+
req
|
|
5998
|
+
});
|
|
5999
|
+
if (startedTransaction) await commitTransaction(req);
|
|
6000
|
+
} catch (err) {
|
|
6001
|
+
if (startedTransaction) await killTransaction(req);
|
|
6002
|
+
throw err;
|
|
5776
6003
|
}
|
|
5777
|
-
await dbDelete(payload, slugs.satisfactionSurveys, {
|
|
5778
|
-
where: { client: { equals: clientId } },
|
|
5779
|
-
overrideAccess: true
|
|
5780
|
-
});
|
|
5781
|
-
await dbDelete(payload, slugs.chatMessages, {
|
|
5782
|
-
where: { client: { equals: clientId } },
|
|
5783
|
-
overrideAccess: true
|
|
5784
|
-
});
|
|
5785
|
-
await dbDelete(payload, slugs.supportClients, {
|
|
5786
|
-
id: clientId,
|
|
5787
|
-
overrideAccess: true
|
|
5788
|
-
});
|
|
5789
6004
|
const headers = new Headers({ "Content-Type": "application/json" });
|
|
5790
6005
|
const secure = process.env.NODE_ENV === "production";
|
|
5791
6006
|
headers.append(
|
|
@@ -8428,9 +8643,11 @@ function createCascadeDelete(slugs) {
|
|
|
8428
8643
|
return async ({ id, req }) => {
|
|
8429
8644
|
const collections = [slugs.ticketMessages, slugs.ticketActivityLog, slugs.timeEntries, slugs.satisfactionSurveys];
|
|
8430
8645
|
for (const slug of collections) {
|
|
8646
|
+
if (!req.payload.collections?.[slug]) continue;
|
|
8431
8647
|
await dbDelete(req.payload, slug, {
|
|
8432
8648
|
where: { ticket: { equals: id } },
|
|
8433
|
-
overrideAccess: true
|
|
8649
|
+
overrideAccess: true,
|
|
8650
|
+
req
|
|
8434
8651
|
});
|
|
8435
8652
|
}
|
|
8436
8653
|
};
|
|
@@ -9918,7 +10135,7 @@ function createSupportClientsCollection(slugs, options) {
|
|
|
9918
10135
|
}
|
|
9919
10136
|
|
|
9920
10137
|
// src/collections/TimeEntries.ts
|
|
9921
|
-
async function recalculateTicketTime(payload, slugs, ticketId) {
|
|
10138
|
+
async function recalculateTicketTime(payload, slugs, ticketId, req) {
|
|
9922
10139
|
let totalMinutes = 0;
|
|
9923
10140
|
let page = 1;
|
|
9924
10141
|
let hasMore = true;
|
|
@@ -9930,7 +10147,8 @@ async function recalculateTicketTime(payload, slugs, ticketId) {
|
|
|
9930
10147
|
page,
|
|
9931
10148
|
depth: 0,
|
|
9932
10149
|
overrideAccess: true,
|
|
9933
|
-
select: { duration: true }
|
|
10150
|
+
select: { duration: true },
|
|
10151
|
+
req
|
|
9934
10152
|
});
|
|
9935
10153
|
for (const entry of entries.docs) {
|
|
9936
10154
|
totalMinutes += entry.duration || 0;
|
|
@@ -9942,14 +10160,15 @@ async function recalculateTicketTime(payload, slugs, ticketId) {
|
|
|
9942
10160
|
collection: slugs.tickets,
|
|
9943
10161
|
id: ticketId,
|
|
9944
10162
|
data: { totalTimeMinutes: totalMinutes },
|
|
9945
|
-
overrideAccess: true
|
|
10163
|
+
overrideAccess: true,
|
|
10164
|
+
req
|
|
9946
10165
|
});
|
|
9947
10166
|
}
|
|
9948
10167
|
function createRecalculateTicketTime(slugs) {
|
|
9949
10168
|
return async ({ doc, req }) => {
|
|
9950
10169
|
if (!doc.ticket) return;
|
|
9951
10170
|
const ticketId = typeof doc.ticket === "object" ? doc.ticket.id : doc.ticket;
|
|
9952
|
-
await recalculateTicketTime(req.payload, slugs, ticketId);
|
|
10171
|
+
await recalculateTicketTime(req.payload, slugs, ticketId, req);
|
|
9953
10172
|
};
|
|
9954
10173
|
}
|
|
9955
10174
|
function createRecalculateTicketTimeOnDelete(slugs) {
|
|
@@ -9957,7 +10176,7 @@ function createRecalculateTicketTimeOnDelete(slugs) {
|
|
|
9957
10176
|
if (!doc?.ticket) return;
|
|
9958
10177
|
const ticketId = typeof doc.ticket === "object" ? doc.ticket.id : doc.ticket;
|
|
9959
10178
|
try {
|
|
9960
|
-
await recalculateTicketTime(req.payload, slugs, ticketId);
|
|
10179
|
+
await recalculateTicketTime(req.payload, slugs, ticketId, req);
|
|
9961
10180
|
} catch (err) {
|
|
9962
10181
|
console.error("[support] Failed to recalculate ticket time after delete:", err);
|
|
9963
10182
|
}
|
|
@@ -11828,8 +12047,30 @@ function supportPlugin(config) {
|
|
|
11828
12047
|
rateLimitStore,
|
|
11829
12048
|
capabilities: config?.capabilities
|
|
11830
12049
|
});
|
|
12050
|
+
const retention = config?.retention === false ? void 0 : config?.retention;
|
|
12051
|
+
const retentionEnabled = Boolean(retention);
|
|
12052
|
+
const purgeTask = {
|
|
12053
|
+
slug: PURGE_LOGS_TASK_SLUG,
|
|
12054
|
+
label: "Support \u2014 purge des journaux",
|
|
12055
|
+
schedule: [
|
|
12056
|
+
{
|
|
12057
|
+
cron: retention?.cron ?? DEFAULT_RETENTION.cron,
|
|
12058
|
+
queue: retention?.queue ?? DEFAULT_RETENTION.queue
|
|
12059
|
+
}
|
|
12060
|
+
],
|
|
12061
|
+
handler: async ({ req }) => {
|
|
12062
|
+
const result = await runScheduledPurge(req.payload, slugs, retention, req);
|
|
12063
|
+
return { output: result };
|
|
12064
|
+
}
|
|
12065
|
+
};
|
|
12066
|
+
const existingJobs = incomingConfig.jobs;
|
|
12067
|
+
const jobs = retentionEnabled ? {
|
|
12068
|
+
...existingJobs,
|
|
12069
|
+
tasks: [...existingJobs?.tasks ?? [], purgeTask]
|
|
12070
|
+
} : existingJobs;
|
|
11831
12071
|
return {
|
|
11832
12072
|
...incomingConfig,
|
|
12073
|
+
jobs,
|
|
11833
12074
|
// Publish the resolved staff collection so the server-side readers share
|
|
11834
12075
|
// ONE source of truth with the writers. `requireAdmin` compares against
|
|
11835
12076
|
// `slugs.users`; the `payload-preferences` reads used to scope themselves
|
|
@@ -11854,4 +12095,4 @@ function supportPlugin(config) {
|
|
|
11854
12095
|
};
|
|
11855
12096
|
}
|
|
11856
12097
|
|
|
11857
|
-
export { DEFAULT_FEATURES, DEFAULT_INBOUND_EMAIL_LIMITS, DEFAULT_SETTINGS, DEFAULT_SLUGS, DEFAULT_TICKETING_FEATURES, DEFAULT_USER_PREFS, MemoryRateLimitStore, PayloadRateLimitStore, RateLimiter, calculateBusinessHoursDeadline, createAdminNotification, createAssignSlaDeadlines, createAuthLogsCollection, createCannedResponsesCollection, createChatMessagesCollection, createCheckSlaOnReply, createCheckSlaOnResolve, createEmailLogsCollection, createKnowledgeBaseCollection, createLoginEndpoint, createMacrosCollection, createOAuthGoogleEndpoint, createPendingEmailsCollection, createSatisfactionSurveysCollection, createSlaPoliciesCollection, createSupportClientsCollection, createTicketActivityLogCollection, createTicketCollaboratorsCollection, createTicketMessagesCollection, createTicketStatusEmail, createTicketStatusesCollection, createTicketsCollection, createTimeEntriesCollection, createTrackOpenEndpoint, createWebhookEndpointsCollection, dispatchWebhook, generateTicketSynthesis, normalizeFeatures, projectAutoClose, readSupportSettings, readSupportSettingsState, readUserPrefs, resolveSlugs, stripProjectedFeatures, supportPlugin, validateInboundEmailPayload, verifySecret };
|
|
12098
|
+
export { DEFAULT_FEATURES, DEFAULT_INBOUND_EMAIL_LIMITS, DEFAULT_RETENTION, DEFAULT_SETTINGS, DEFAULT_SLUGS, DEFAULT_TICKETING_FEATURES, DEFAULT_USER_PREFS, MemoryRateLimitStore, PURGE_LOGS_TASK_SLUG, PayloadRateLimitStore, RateLimiter, calculateBusinessHoursDeadline, createAdminNotification, createAssignSlaDeadlines, createAuthLogsCollection, createCannedResponsesCollection, createChatMessagesCollection, createCheckSlaOnReply, createCheckSlaOnResolve, createEmailLogsCollection, createKnowledgeBaseCollection, createLoginEndpoint, createMacrosCollection, createOAuthGoogleEndpoint, createPendingEmailsCollection, createSatisfactionSurveysCollection, createSlaPoliciesCollection, createSupportClientsCollection, createTicketActivityLogCollection, createTicketCollaboratorsCollection, createTicketMessagesCollection, createTicketStatusEmail, createTicketStatusesCollection, createTicketsCollection, createTimeEntriesCollection, createTrackOpenEndpoint, createWebhookEndpointsCollection, dispatchWebhook, generateTicketSynthesis, normalizeFeatures, projectAutoClose, purgeOlderThan, purgeableCollections, readSupportSettings, readSupportSettingsState, readUserPrefs, resolveSlugs, runScheduledPurge, stripProjectedFeatures, supportPlugin, validateInboundEmailPayload, verifySecret };
|