diff --git a/packages/types/src/common/index.ts b/packages/types/src/common/index.ts index 317898d80..21158afe3 100644 --- a/packages/types/src/common/index.ts +++ b/packages/types/src/common/index.ts @@ -1,5 +1,6 @@ export * from "./payments"; export * from "./payment-messaging"; +export * from "./support-attachments"; export interface BaseEntity { id: string; diff --git a/packages/types/src/common/support-attachments.ts b/packages/types/src/common/support-attachments.ts new file mode 100644 index 000000000..1f6a1b376 --- /dev/null +++ b/packages/types/src/common/support-attachments.ts @@ -0,0 +1,73 @@ +/** + * Rules shared by the freight and passenger support-chat attachment flows. + * + * The two chat backends are independent implementations (freight: TypeORM + + * polymorphic `FileRecord`; passenger: Prisma + `SupportAttachment`), but the + * *contract* a client codes against — what may be uploaded, how large, how the + * preview URL behaves — must not drift between them. Keep the limits here so + * both APIs validate identically and all four web apps can render one consistent + * "file too large / type not allowed" message. + */ + +/** `FileRecord.resource` discriminator for freight chat attachments. */ +export const SUPPORT_ATTACHMENT_RESOURCE = "support_message"; + +/** Per-file ceiling. Enforced server-side; the UI pre-checks to fail fast. */ +export const SUPPORT_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024; + +/** Max files on a single message. */ +export const SUPPORT_ATTACHMENT_MAX_PER_MESSAGE = 10; + +/** + * How long a minted preview URL stays valid. Long enough that an open thread + * doesn't rot mid-read, short enough that a leaked URL isn't a durable grant. + */ +export const SUPPORT_ATTACHMENT_URL_TTL_SECONDS = 60 * 60; + +/** + * Types accepted on a chat message. + * + * Deliberately NARROWER than `FilesService.ALLOWED_UPLOAD_MIME` (which also + * serves generated PDFs and scanned business documents at 25MB). Chat is + * user-to-user, so the blast radius of a bad file is another human clicking it. + * + * `image/svg+xml` is excluded on purpose and must stay excluded: an SVG is + * executable markup, and previewing one inline (`` is safe, but an + * `