@consilioweb/payload-support 5.0.0 → 6.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 +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/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 +6 -2
- package/scripts/uninstall-data.mjs +178 -0
- package/scripts/uninstall.mjs +184 -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.cjs
CHANGED
|
@@ -81,6 +81,11 @@ var DEFAULT_SLUGS = {
|
|
|
81
81
|
users: "users",
|
|
82
82
|
media: "media"
|
|
83
83
|
};
|
|
84
|
+
var FIXED_SLUGS = {
|
|
85
|
+
clientSummaries: "client-summaries",
|
|
86
|
+
ticketCollaborators: "ticket-collaborators",
|
|
87
|
+
ticketFeedback: "ticket-feedback"
|
|
88
|
+
};
|
|
84
89
|
function resolveSlugs(overrides) {
|
|
85
90
|
return { ...DEFAULT_SLUGS, ...overrides };
|
|
86
91
|
}
|
|
@@ -2997,6 +3002,51 @@ function createApplyMacroEndpoint(slugs) {
|
|
|
2997
3002
|
};
|
|
2998
3003
|
}
|
|
2999
3004
|
|
|
3005
|
+
// src/utils/retention.ts
|
|
3006
|
+
var DEFAULT_RETENTION = {
|
|
3007
|
+
authLogsDays: 180,
|
|
3008
|
+
emailLogsDays: 365,
|
|
3009
|
+
cron: "0 30 3 * * *",
|
|
3010
|
+
queue: "default"
|
|
3011
|
+
};
|
|
3012
|
+
var PURGE_LOGS_TASK_SLUG = "support-purge-logs";
|
|
3013
|
+
function purgeableCollections(slugs) {
|
|
3014
|
+
return {
|
|
3015
|
+
"email-logs": slugs.emailLogs,
|
|
3016
|
+
"auth-logs": slugs.authLogs
|
|
3017
|
+
};
|
|
3018
|
+
}
|
|
3019
|
+
async function purgeOlderThan(payload, slug, days, req) {
|
|
3020
|
+
const cutoff = days > 0 ? new Date(Date.now() - days * 864e5).toISOString() : null;
|
|
3021
|
+
const result = await dbDelete(payload, slug, {
|
|
3022
|
+
where: cutoff ? { createdAt: { less_than: cutoff } } : { id: { exists: true } },
|
|
3023
|
+
overrideAccess: true,
|
|
3024
|
+
...req ? { req } : {}
|
|
3025
|
+
});
|
|
3026
|
+
return Array.isArray(result?.docs) ? result.docs.length : 0;
|
|
3027
|
+
}
|
|
3028
|
+
async function runScheduledPurge(payload, slugs, retention, req) {
|
|
3029
|
+
if (retention === false) return { purged: {}, skipped: ["auth-logs", "email-logs"] };
|
|
3030
|
+
const plan = [
|
|
3031
|
+
["auth-logs", slugs.authLogs, retention?.authLogsDays ?? DEFAULT_RETENTION.authLogsDays],
|
|
3032
|
+
["email-logs", slugs.emailLogs, retention?.emailLogsDays ?? DEFAULT_RETENTION.emailLogsDays]
|
|
3033
|
+
];
|
|
3034
|
+
const purged = {};
|
|
3035
|
+
const skipped = [];
|
|
3036
|
+
for (const [name, slug, days] of plan) {
|
|
3037
|
+
if (!Number.isFinite(days) || days <= 0) {
|
|
3038
|
+
skipped.push(name);
|
|
3039
|
+
continue;
|
|
3040
|
+
}
|
|
3041
|
+
if (!payload.collections?.[slug]) {
|
|
3042
|
+
skipped.push(name);
|
|
3043
|
+
continue;
|
|
3044
|
+
}
|
|
3045
|
+
purged[name] = await purgeOlderThan(payload, slug, days, req);
|
|
3046
|
+
}
|
|
3047
|
+
return { purged, skipped };
|
|
3048
|
+
}
|
|
3049
|
+
|
|
3000
3050
|
// src/endpoints/purge-logs.ts
|
|
3001
3051
|
function createPurgeLogsEndpoint(slugs) {
|
|
3002
3052
|
return {
|
|
@@ -3009,19 +3059,11 @@ function createPurgeLogsEndpoint(slugs) {
|
|
|
3009
3059
|
const url = new URL(req.url);
|
|
3010
3060
|
const collection = url.searchParams.get("collection");
|
|
3011
3061
|
const days = Number(url.searchParams.get("days") || "0");
|
|
3012
|
-
const allowedCollections =
|
|
3013
|
-
"email-logs": slugs.emailLogs,
|
|
3014
|
-
"auth-logs": slugs.authLogs
|
|
3015
|
-
};
|
|
3062
|
+
const allowedCollections = purgeableCollections(slugs);
|
|
3016
3063
|
if (!collection || !allowedCollections[collection]) {
|
|
3017
3064
|
return Response.json({ error: "Invalid collection. Use email-logs or auth-logs." }, { status: 400 });
|
|
3018
3065
|
}
|
|
3019
|
-
const
|
|
3020
|
-
const result = await dbDelete(payload, allowedCollections[collection], {
|
|
3021
|
-
where: cutoff ? { createdAt: { less_than: cutoff } } : { id: { exists: true } },
|
|
3022
|
-
overrideAccess: true
|
|
3023
|
-
});
|
|
3024
|
-
const count = Array.isArray(result.docs) ? result.docs.length : 0;
|
|
3066
|
+
const count = await purgeOlderThan(payload, allowedCollections[collection], days, req);
|
|
3025
3067
|
return Response.json({
|
|
3026
3068
|
purged: count,
|
|
3027
3069
|
collection,
|
|
@@ -4744,6 +4786,7 @@ function createExportCsvEndpoint(slugs) {
|
|
|
4744
4786
|
}
|
|
4745
4787
|
|
|
4746
4788
|
// src/endpoints/export-data.ts
|
|
4789
|
+
var EMPTY = { docs: [] };
|
|
4747
4790
|
function createExportDataEndpoint(slugs) {
|
|
4748
4791
|
return {
|
|
4749
4792
|
path: "/support/export-data",
|
|
@@ -4752,7 +4795,16 @@ function createExportDataEndpoint(slugs) {
|
|
|
4752
4795
|
try {
|
|
4753
4796
|
const payload = req.payload;
|
|
4754
4797
|
requireClient(req, slugs);
|
|
4755
|
-
const
|
|
4798
|
+
const isRegistered = (slug) => Boolean(payload.collections?.[slug]);
|
|
4799
|
+
const [
|
|
4800
|
+
clientData,
|
|
4801
|
+
ticketsResult,
|
|
4802
|
+
messagesResult,
|
|
4803
|
+
surveysResult,
|
|
4804
|
+
chatResult,
|
|
4805
|
+
feedbackResult,
|
|
4806
|
+
summariesResult
|
|
4807
|
+
] = await Promise.all([
|
|
4756
4808
|
dbFindByID(payload, slugs.supportClients, {
|
|
4757
4809
|
id: req.user.id,
|
|
4758
4810
|
depth: 0,
|
|
@@ -4778,12 +4830,35 @@ function createExportDataEndpoint(slugs) {
|
|
|
4778
4830
|
limit: 500,
|
|
4779
4831
|
depth: 0,
|
|
4780
4832
|
overrideAccess: true
|
|
4781
|
-
})
|
|
4833
|
+
}),
|
|
4834
|
+
isRegistered(slugs.chatMessages) ? dbFind(payload, slugs.chatMessages, {
|
|
4835
|
+
where: { client: { equals: req.user.id } },
|
|
4836
|
+
limit: 5e3,
|
|
4837
|
+
depth: 0,
|
|
4838
|
+
overrideAccess: true
|
|
4839
|
+
}) : EMPTY,
|
|
4840
|
+
isRegistered(FIXED_SLUGS.ticketFeedback) ? dbFind(payload, FIXED_SLUGS.ticketFeedback, {
|
|
4841
|
+
where: { client: { equals: req.user.id } },
|
|
4842
|
+
limit: 500,
|
|
4843
|
+
depth: 0,
|
|
4844
|
+
overrideAccess: true
|
|
4845
|
+
}) : EMPTY,
|
|
4846
|
+
isRegistered(FIXED_SLUGS.clientSummaries) ? dbFind(payload, FIXED_SLUGS.clientSummaries, {
|
|
4847
|
+
where: { client: { equals: req.user.id } },
|
|
4848
|
+
limit: 100,
|
|
4849
|
+
depth: 0,
|
|
4850
|
+
overrideAccess: true
|
|
4851
|
+
}) : EMPTY
|
|
4782
4852
|
]);
|
|
4853
|
+
const ticketIds = ticketsResult.docs.map((t) => t.id);
|
|
4854
|
+
const timeResult = ticketIds.length > 0 && isRegistered(slugs.timeEntries) ? await dbFind(payload, slugs.timeEntries, {
|
|
4855
|
+
where: { ticket: { in: ticketIds } },
|
|
4856
|
+
limit: 5e3,
|
|
4857
|
+
depth: 0,
|
|
4858
|
+
overrideAccess: true
|
|
4859
|
+
}) : EMPTY;
|
|
4783
4860
|
const c = clientData;
|
|
4784
|
-
const
|
|
4785
|
-
exportDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4786
|
-
exportType: "RGPD - Export des donn\xE9es personnelles",
|
|
4861
|
+
const providedByYou = {
|
|
4787
4862
|
profile: {
|
|
4788
4863
|
email: c.email,
|
|
4789
4864
|
firstName: c.firstName,
|
|
@@ -4812,8 +4887,50 @@ function createExportDataEndpoint(slugs) {
|
|
|
4812
4887
|
rating: s.rating,
|
|
4813
4888
|
comment: s.comment,
|
|
4814
4889
|
createdAt: s.createdAt
|
|
4890
|
+
})),
|
|
4891
|
+
feedback: feedbackResult.docs.map((f) => ({
|
|
4892
|
+
ticketId: f.ticket,
|
|
4893
|
+
rating: f.rating,
|
|
4894
|
+
comment: f.comment,
|
|
4895
|
+
submittedFrom: f.submittedFrom,
|
|
4896
|
+
createdAt: f.createdAt
|
|
4897
|
+
})),
|
|
4898
|
+
chatMessages: chatResult.docs.map((m) => ({
|
|
4899
|
+
session: m.session,
|
|
4900
|
+
senderType: m.senderType,
|
|
4901
|
+
message: m.message,
|
|
4902
|
+
createdAt: m.createdAt
|
|
4903
|
+
})),
|
|
4904
|
+
timeEntries: timeResult.docs.map((e) => ({
|
|
4905
|
+
ticketId: e.ticket,
|
|
4906
|
+
duration: e.duration,
|
|
4907
|
+
date: e.date,
|
|
4908
|
+
description: e.description,
|
|
4909
|
+
billable: e.billable
|
|
4815
4910
|
}))
|
|
4816
4911
|
};
|
|
4912
|
+
const exportData = {
|
|
4913
|
+
exportDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4914
|
+
exportType: "RGPD - Export des donn\xE9es personnelles",
|
|
4915
|
+
providedByYou: {
|
|
4916
|
+
legalBasis: "Art. 20 RGPD - droit \xE0 la portabilit\xE9",
|
|
4917
|
+
...providedByYou
|
|
4918
|
+
},
|
|
4919
|
+
derivedData: {
|
|
4920
|
+
legalBasis: "Art. 15 RGPD - droit d'acc\xE8s (donn\xE9es d\xE9riv\xE9es, hors portabilit\xE9)",
|
|
4921
|
+
clientSummaries: summariesResult.docs.map((s) => ({
|
|
4922
|
+
summary: s.summary,
|
|
4923
|
+
recurringTopics: s.recurringTopics,
|
|
4924
|
+
patterns: s.patterns,
|
|
4925
|
+
keyFacts: s.keyFacts,
|
|
4926
|
+
ticketCount: s.ticketCount,
|
|
4927
|
+
messageCount: s.messageCount,
|
|
4928
|
+
averageSatisfaction: s.averageSatisfaction,
|
|
4929
|
+
generatedAt: s.generatedAt,
|
|
4930
|
+
aiModel: s.aiModel
|
|
4931
|
+
}))
|
|
4932
|
+
}
|
|
4933
|
+
};
|
|
4817
4934
|
const json = JSON.stringify(exportData, null, 2);
|
|
4818
4935
|
return new Response(json, {
|
|
4819
4936
|
status: 200,
|
|
@@ -5727,15 +5844,22 @@ function createOAuthGoogleEndpoint(slugs, options) {
|
|
|
5727
5844
|
}
|
|
5728
5845
|
};
|
|
5729
5846
|
}
|
|
5730
|
-
|
|
5731
|
-
|
|
5847
|
+
function collectAttachmentIds(docs, into) {
|
|
5848
|
+
for (const doc of docs) {
|
|
5849
|
+
for (const attachment of doc.attachments ?? []) {
|
|
5850
|
+
const file = attachment?.file;
|
|
5851
|
+
const id = file != null && typeof file === "object" ? file.id : file;
|
|
5852
|
+
if (id != null) into.add(id);
|
|
5853
|
+
}
|
|
5854
|
+
}
|
|
5855
|
+
}
|
|
5732
5856
|
function createDeleteAccountEndpoint(slugs) {
|
|
5733
5857
|
return {
|
|
5734
5858
|
path: "/support/delete-account",
|
|
5735
5859
|
method: "post",
|
|
5736
5860
|
handler: async (req) => {
|
|
5737
5861
|
try {
|
|
5738
|
-
const payload = req.payload;
|
|
5862
|
+
const payload$1 = req.payload;
|
|
5739
5863
|
requireClient(req, slugs);
|
|
5740
5864
|
const body = await req.json();
|
|
5741
5865
|
const { confirmPassword } = body;
|
|
@@ -5746,7 +5870,7 @@ function createDeleteAccountEndpoint(slugs) {
|
|
|
5746
5870
|
);
|
|
5747
5871
|
}
|
|
5748
5872
|
try {
|
|
5749
|
-
await payload.login({
|
|
5873
|
+
await payload$1.login({
|
|
5750
5874
|
collection: slugs.supportClients,
|
|
5751
5875
|
data: { email: req.user.email, password: confirmPassword }
|
|
5752
5876
|
});
|
|
@@ -5757,44 +5881,135 @@ function createDeleteAccountEndpoint(slugs) {
|
|
|
5757
5881
|
);
|
|
5758
5882
|
}
|
|
5759
5883
|
const clientId = req.user.id;
|
|
5760
|
-
const
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
select: { id: true }
|
|
5766
|
-
});
|
|
5767
|
-
const ticketIds = tickets.docs.map((t) => t.id);
|
|
5768
|
-
if (ticketIds.length > 0) {
|
|
5769
|
-
await dbDelete(payload, slugs.ticketMessages, {
|
|
5770
|
-
where: { ticket: { in: ticketIds } },
|
|
5771
|
-
overrideAccess: true
|
|
5772
|
-
});
|
|
5773
|
-
await dbDelete(payload, slugs.ticketActivityLog, {
|
|
5774
|
-
where: { ticket: { in: ticketIds } },
|
|
5775
|
-
overrideAccess: true
|
|
5776
|
-
});
|
|
5777
|
-
await dbDelete(payload, slugs.timeEntries, {
|
|
5778
|
-
where: { ticket: { in: ticketIds } },
|
|
5779
|
-
overrideAccess: true
|
|
5780
|
-
});
|
|
5781
|
-
await dbDelete(payload, slugs.tickets, {
|
|
5884
|
+
const clientEmail = req.user.email;
|
|
5885
|
+
const isRegistered = (slug) => Boolean(payload$1.collections?.[slug]);
|
|
5886
|
+
const startedTransaction = await payload.initTransaction(req);
|
|
5887
|
+
try {
|
|
5888
|
+
const tickets = await dbFind(payload$1, slugs.tickets, {
|
|
5782
5889
|
where: { client: { equals: clientId } },
|
|
5783
|
-
|
|
5890
|
+
limit: 1e4,
|
|
5891
|
+
depth: 0,
|
|
5892
|
+
overrideAccess: true,
|
|
5893
|
+
select: { id: true },
|
|
5894
|
+
req
|
|
5895
|
+
});
|
|
5896
|
+
const ticketIds = tickets.docs.map((t) => t.id);
|
|
5897
|
+
const attachmentIds = /* @__PURE__ */ new Set();
|
|
5898
|
+
if (ticketIds.length > 0) {
|
|
5899
|
+
const messages = await dbFind(
|
|
5900
|
+
payload$1,
|
|
5901
|
+
slugs.ticketMessages,
|
|
5902
|
+
{
|
|
5903
|
+
where: { ticket: { in: ticketIds } },
|
|
5904
|
+
limit: 1e4,
|
|
5905
|
+
depth: 0,
|
|
5906
|
+
overrideAccess: true,
|
|
5907
|
+
req
|
|
5908
|
+
}
|
|
5909
|
+
);
|
|
5910
|
+
collectAttachmentIds(messages.docs, attachmentIds);
|
|
5911
|
+
}
|
|
5912
|
+
if (isRegistered(slugs.pendingEmails)) {
|
|
5913
|
+
const pendingEmails = await dbFind(
|
|
5914
|
+
payload$1,
|
|
5915
|
+
slugs.pendingEmails,
|
|
5916
|
+
{
|
|
5917
|
+
where: { client: { equals: clientId } },
|
|
5918
|
+
limit: 1e4,
|
|
5919
|
+
depth: 0,
|
|
5920
|
+
overrideAccess: true,
|
|
5921
|
+
req
|
|
5922
|
+
}
|
|
5923
|
+
);
|
|
5924
|
+
collectAttachmentIds(pendingEmails.docs, attachmentIds);
|
|
5925
|
+
}
|
|
5926
|
+
if (ticketIds.length > 0) {
|
|
5927
|
+
for (const slug of [FIXED_SLUGS.ticketFeedback, FIXED_SLUGS.ticketCollaborators]) {
|
|
5928
|
+
if (!isRegistered(slug)) continue;
|
|
5929
|
+
await dbDelete(payload$1, slug, {
|
|
5930
|
+
where: {
|
|
5931
|
+
or: [
|
|
5932
|
+
{ ticket: { in: ticketIds } },
|
|
5933
|
+
{ client: { equals: clientId } }
|
|
5934
|
+
]
|
|
5935
|
+
},
|
|
5936
|
+
overrideAccess: true,
|
|
5937
|
+
req
|
|
5938
|
+
});
|
|
5939
|
+
}
|
|
5940
|
+
}
|
|
5941
|
+
if (ticketIds.length > 0) {
|
|
5942
|
+
await dbDelete(payload$1, slugs.tickets, {
|
|
5943
|
+
where: { client: { equals: clientId } },
|
|
5944
|
+
overrideAccess: true,
|
|
5945
|
+
req
|
|
5946
|
+
});
|
|
5947
|
+
}
|
|
5948
|
+
for (const slug of [
|
|
5949
|
+
slugs.satisfactionSurveys,
|
|
5950
|
+
slugs.chatMessages,
|
|
5951
|
+
slugs.notificationQueue,
|
|
5952
|
+
slugs.pendingEmails,
|
|
5953
|
+
FIXED_SLUGS.clientSummaries,
|
|
5954
|
+
FIXED_SLUGS.ticketFeedback
|
|
5955
|
+
]) {
|
|
5956
|
+
if (!isRegistered(slug)) continue;
|
|
5957
|
+
await dbDelete(payload$1, slug, {
|
|
5958
|
+
where: { client: { equals: clientId } },
|
|
5959
|
+
overrideAccess: true,
|
|
5960
|
+
req
|
|
5961
|
+
});
|
|
5962
|
+
}
|
|
5963
|
+
if (isRegistered(FIXED_SLUGS.ticketCollaborators)) {
|
|
5964
|
+
await dbDelete(payload$1, FIXED_SLUGS.ticketCollaborators, {
|
|
5965
|
+
where: {
|
|
5966
|
+
or: [
|
|
5967
|
+
{ client: { equals: clientId } },
|
|
5968
|
+
...clientEmail ? [{ email: { equals: clientEmail } }] : []
|
|
5969
|
+
]
|
|
5970
|
+
},
|
|
5971
|
+
overrideAccess: true,
|
|
5972
|
+
req
|
|
5973
|
+
});
|
|
5974
|
+
}
|
|
5975
|
+
if (clientEmail) {
|
|
5976
|
+
if (isRegistered(slugs.authLogs)) {
|
|
5977
|
+
await dbDelete(payload$1, slugs.authLogs, {
|
|
5978
|
+
where: { email: { equals: clientEmail } },
|
|
5979
|
+
overrideAccess: true,
|
|
5980
|
+
req
|
|
5981
|
+
});
|
|
5982
|
+
}
|
|
5983
|
+
if (isRegistered(slugs.emailLogs)) {
|
|
5984
|
+
await dbDelete(payload$1, slugs.emailLogs, {
|
|
5985
|
+
where: {
|
|
5986
|
+
or: [
|
|
5987
|
+
{ senderEmail: { equals: clientEmail } },
|
|
5988
|
+
{ recipientEmail: { equals: clientEmail } }
|
|
5989
|
+
]
|
|
5990
|
+
},
|
|
5991
|
+
overrideAccess: true,
|
|
5992
|
+
req
|
|
5993
|
+
});
|
|
5994
|
+
}
|
|
5995
|
+
}
|
|
5996
|
+
for (const id of isRegistered(slugs.media) ? attachmentIds : []) {
|
|
5997
|
+
await dbDelete(payload$1, slugs.media, {
|
|
5998
|
+
id,
|
|
5999
|
+
overrideAccess: true,
|
|
6000
|
+
req
|
|
6001
|
+
});
|
|
6002
|
+
}
|
|
6003
|
+
await dbDelete(payload$1, slugs.supportClients, {
|
|
6004
|
+
id: clientId,
|
|
6005
|
+
overrideAccess: true,
|
|
6006
|
+
req
|
|
5784
6007
|
});
|
|
6008
|
+
if (startedTransaction) await payload.commitTransaction(req);
|
|
6009
|
+
} catch (err) {
|
|
6010
|
+
if (startedTransaction) await payload.killTransaction(req);
|
|
6011
|
+
throw err;
|
|
5785
6012
|
}
|
|
5786
|
-
await dbDelete(payload, slugs.satisfactionSurveys, {
|
|
5787
|
-
where: { client: { equals: clientId } },
|
|
5788
|
-
overrideAccess: true
|
|
5789
|
-
});
|
|
5790
|
-
await dbDelete(payload, slugs.chatMessages, {
|
|
5791
|
-
where: { client: { equals: clientId } },
|
|
5792
|
-
overrideAccess: true
|
|
5793
|
-
});
|
|
5794
|
-
await dbDelete(payload, slugs.supportClients, {
|
|
5795
|
-
id: clientId,
|
|
5796
|
-
overrideAccess: true
|
|
5797
|
-
});
|
|
5798
6013
|
const headers = new Headers({ "Content-Type": "application/json" });
|
|
5799
6014
|
const secure = process.env.NODE_ENV === "production";
|
|
5800
6015
|
headers.append(
|
|
@@ -8437,9 +8652,11 @@ function createCascadeDelete(slugs) {
|
|
|
8437
8652
|
return async ({ id, req }) => {
|
|
8438
8653
|
const collections = [slugs.ticketMessages, slugs.ticketActivityLog, slugs.timeEntries, slugs.satisfactionSurveys];
|
|
8439
8654
|
for (const slug of collections) {
|
|
8655
|
+
if (!req.payload.collections?.[slug]) continue;
|
|
8440
8656
|
await dbDelete(req.payload, slug, {
|
|
8441
8657
|
where: { ticket: { equals: id } },
|
|
8442
|
-
overrideAccess: true
|
|
8658
|
+
overrideAccess: true,
|
|
8659
|
+
req
|
|
8443
8660
|
});
|
|
8444
8661
|
}
|
|
8445
8662
|
};
|
|
@@ -9927,7 +10144,7 @@ function createSupportClientsCollection(slugs, options) {
|
|
|
9927
10144
|
}
|
|
9928
10145
|
|
|
9929
10146
|
// src/collections/TimeEntries.ts
|
|
9930
|
-
async function recalculateTicketTime(payload, slugs, ticketId) {
|
|
10147
|
+
async function recalculateTicketTime(payload, slugs, ticketId, req) {
|
|
9931
10148
|
let totalMinutes = 0;
|
|
9932
10149
|
let page = 1;
|
|
9933
10150
|
let hasMore = true;
|
|
@@ -9939,7 +10156,8 @@ async function recalculateTicketTime(payload, slugs, ticketId) {
|
|
|
9939
10156
|
page,
|
|
9940
10157
|
depth: 0,
|
|
9941
10158
|
overrideAccess: true,
|
|
9942
|
-
select: { duration: true }
|
|
10159
|
+
select: { duration: true },
|
|
10160
|
+
req
|
|
9943
10161
|
});
|
|
9944
10162
|
for (const entry of entries.docs) {
|
|
9945
10163
|
totalMinutes += entry.duration || 0;
|
|
@@ -9951,14 +10169,15 @@ async function recalculateTicketTime(payload, slugs, ticketId) {
|
|
|
9951
10169
|
collection: slugs.tickets,
|
|
9952
10170
|
id: ticketId,
|
|
9953
10171
|
data: { totalTimeMinutes: totalMinutes },
|
|
9954
|
-
overrideAccess: true
|
|
10172
|
+
overrideAccess: true,
|
|
10173
|
+
req
|
|
9955
10174
|
});
|
|
9956
10175
|
}
|
|
9957
10176
|
function createRecalculateTicketTime(slugs) {
|
|
9958
10177
|
return async ({ doc, req }) => {
|
|
9959
10178
|
if (!doc.ticket) return;
|
|
9960
10179
|
const ticketId = typeof doc.ticket === "object" ? doc.ticket.id : doc.ticket;
|
|
9961
|
-
await recalculateTicketTime(req.payload, slugs, ticketId);
|
|
10180
|
+
await recalculateTicketTime(req.payload, slugs, ticketId, req);
|
|
9962
10181
|
};
|
|
9963
10182
|
}
|
|
9964
10183
|
function createRecalculateTicketTimeOnDelete(slugs) {
|
|
@@ -9966,7 +10185,7 @@ function createRecalculateTicketTimeOnDelete(slugs) {
|
|
|
9966
10185
|
if (!doc?.ticket) return;
|
|
9967
10186
|
const ticketId = typeof doc.ticket === "object" ? doc.ticket.id : doc.ticket;
|
|
9968
10187
|
try {
|
|
9969
|
-
await recalculateTicketTime(req.payload, slugs, ticketId);
|
|
10188
|
+
await recalculateTicketTime(req.payload, slugs, ticketId, req);
|
|
9970
10189
|
} catch (err) {
|
|
9971
10190
|
console.error("[support] Failed to recalculate ticket time after delete:", err);
|
|
9972
10191
|
}
|
|
@@ -11837,8 +12056,30 @@ function supportPlugin(config) {
|
|
|
11837
12056
|
rateLimitStore,
|
|
11838
12057
|
capabilities: config?.capabilities
|
|
11839
12058
|
});
|
|
12059
|
+
const retention = config?.retention === false ? void 0 : config?.retention;
|
|
12060
|
+
const retentionEnabled = Boolean(retention);
|
|
12061
|
+
const purgeTask = {
|
|
12062
|
+
slug: PURGE_LOGS_TASK_SLUG,
|
|
12063
|
+
label: "Support \u2014 purge des journaux",
|
|
12064
|
+
schedule: [
|
|
12065
|
+
{
|
|
12066
|
+
cron: retention?.cron ?? DEFAULT_RETENTION.cron,
|
|
12067
|
+
queue: retention?.queue ?? DEFAULT_RETENTION.queue
|
|
12068
|
+
}
|
|
12069
|
+
],
|
|
12070
|
+
handler: async ({ req }) => {
|
|
12071
|
+
const result = await runScheduledPurge(req.payload, slugs, retention, req);
|
|
12072
|
+
return { output: result };
|
|
12073
|
+
}
|
|
12074
|
+
};
|
|
12075
|
+
const existingJobs = incomingConfig.jobs;
|
|
12076
|
+
const jobs = retentionEnabled ? {
|
|
12077
|
+
...existingJobs,
|
|
12078
|
+
tasks: [...existingJobs?.tasks ?? [], purgeTask]
|
|
12079
|
+
} : existingJobs;
|
|
11840
12080
|
return {
|
|
11841
12081
|
...incomingConfig,
|
|
12082
|
+
jobs,
|
|
11842
12083
|
// Publish the resolved staff collection so the server-side readers share
|
|
11843
12084
|
// ONE source of truth with the writers. `requireAdmin` compares against
|
|
11844
12085
|
// `slugs.users`; the `payload-preferences` reads used to scope themselves
|
|
@@ -11865,11 +12106,13 @@ function supportPlugin(config) {
|
|
|
11865
12106
|
|
|
11866
12107
|
exports.DEFAULT_FEATURES = DEFAULT_FEATURES;
|
|
11867
12108
|
exports.DEFAULT_INBOUND_EMAIL_LIMITS = DEFAULT_INBOUND_EMAIL_LIMITS;
|
|
12109
|
+
exports.DEFAULT_RETENTION = DEFAULT_RETENTION;
|
|
11868
12110
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
|
11869
12111
|
exports.DEFAULT_SLUGS = DEFAULT_SLUGS;
|
|
11870
12112
|
exports.DEFAULT_TICKETING_FEATURES = DEFAULT_TICKETING_FEATURES;
|
|
11871
12113
|
exports.DEFAULT_USER_PREFS = DEFAULT_USER_PREFS;
|
|
11872
12114
|
exports.MemoryRateLimitStore = MemoryRateLimitStore;
|
|
12115
|
+
exports.PURGE_LOGS_TASK_SLUG = PURGE_LOGS_TASK_SLUG;
|
|
11873
12116
|
exports.PayloadRateLimitStore = PayloadRateLimitStore;
|
|
11874
12117
|
exports.RateLimiter = RateLimiter;
|
|
11875
12118
|
exports.calculateBusinessHoursDeadline = calculateBusinessHoursDeadline;
|
|
@@ -11902,10 +12145,13 @@ exports.dispatchWebhook = dispatchWebhook;
|
|
|
11902
12145
|
exports.generateTicketSynthesis = generateTicketSynthesis;
|
|
11903
12146
|
exports.normalizeFeatures = normalizeFeatures;
|
|
11904
12147
|
exports.projectAutoClose = projectAutoClose;
|
|
12148
|
+
exports.purgeOlderThan = purgeOlderThan;
|
|
12149
|
+
exports.purgeableCollections = purgeableCollections;
|
|
11905
12150
|
exports.readSupportSettings = readSupportSettings;
|
|
11906
12151
|
exports.readSupportSettingsState = readSupportSettingsState;
|
|
11907
12152
|
exports.readUserPrefs = readUserPrefs;
|
|
11908
12153
|
exports.resolveSlugs = resolveSlugs;
|
|
12154
|
+
exports.runScheduledPurge = runScheduledPurge;
|
|
11909
12155
|
exports.stripProjectedFeatures = stripProjectedFeatures;
|
|
11910
12156
|
exports.supportPlugin = supportPlugin;
|
|
11911
12157
|
exports.validateInboundEmailPayload = validateInboundEmailPayload;
|
package/dist/index.d.cts
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 };
|