feat: certificates, landing pages, ai tutor, website update, compliance
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import * as z from 'zod';
|
||||
|
||||
/**
|
||||
* Payload for an `emails:send` job that uses a registered `@cio/email`
|
||||
* template id. Field shape is validated again inside the worker via the
|
||||
* template's Zod schema, so we keep the on-the-wire schema permissive.
|
||||
*/
|
||||
export const ZSendTemplateEmailPayload = z.object({
|
||||
kind: z.literal('template'),
|
||||
template: z.string().min(1),
|
||||
to: z.string().email(),
|
||||
fields: z.record(z.string(), z.unknown()).default({}),
|
||||
from: z.string().optional(),
|
||||
replyTo: z.string().optional()
|
||||
});
|
||||
export type TSendTemplateEmailPayload = z.infer<typeof ZSendTemplateEmailPayload>;
|
||||
|
||||
/**
|
||||
* Payload for an `emails:send` job that carries free-form subject + content
|
||||
* (used by the public mail route and submission notifications that don't have
|
||||
* a registered template).
|
||||
*/
|
||||
export const ZSendRawEmailPayload = z.object({
|
||||
kind: z.literal('raw'),
|
||||
to: z.string().email(),
|
||||
subject: z.string().min(1),
|
||||
content: z.string().min(1),
|
||||
from: z.string().optional(),
|
||||
replyTo: z.string().optional()
|
||||
});
|
||||
export type TSendRawEmailPayload = z.infer<typeof ZSendRawEmailPayload>;
|
||||
|
||||
/**
|
||||
* Discriminated union BullMQ workers parse on entry. Adding a new email
|
||||
* delivery shape is a matter of appending another variant here + a branch in
|
||||
* the worker.
|
||||
*/
|
||||
export const ZSendEmailPayload = z.discriminatedUnion('kind', [ZSendTemplateEmailPayload, ZSendRawEmailPayload]);
|
||||
export type TSendEmailPayload = z.infer<typeof ZSendEmailPayload>;
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './media';
|
||||
export * from './emails';
|
||||
export * from './maintenance';
|
||||
@@ -0,0 +1,18 @@
|
||||
import * as z from 'zod';
|
||||
|
||||
export const ZRetentionCompactPayload = z.object({
|
||||
/** Override default retention windows (in days). Optional. */
|
||||
windowDays: z
|
||||
.object({
|
||||
mediaJob: z.number().int().positive().optional(),
|
||||
jobStep: z.number().int().positive().optional(),
|
||||
deadLetterJob: z.number().int().positive().optional()
|
||||
})
|
||||
.optional()
|
||||
});
|
||||
export type TRetentionCompactPayload = z.infer<typeof ZRetentionCompactPayload>;
|
||||
|
||||
export const ZDeadLetterCleanupPayload = z.object({
|
||||
olderThanDays: z.number().int().positive().default(180)
|
||||
});
|
||||
export type TDeadLetterCleanupPayload = z.infer<typeof ZDeadLetterCleanupPayload>;
|
||||
@@ -0,0 +1,65 @@
|
||||
import * as z from 'zod';
|
||||
|
||||
/**
|
||||
* Payloads for the `media` and `media-transcribe` queues.
|
||||
*
|
||||
* Every payload carries the `mediaJobId` (DB run id) and `assetId` so workers
|
||||
* never need to re-derive context. `actorContext` is snapshotted at enqueue
|
||||
* time per the plan's authorization-on-resume rule.
|
||||
*/
|
||||
|
||||
export const ZActorContext = z.object({
|
||||
userId: z.string().uuid().nullable(),
|
||||
organizationId: z.string().uuid(),
|
||||
locale: z.string().optional()
|
||||
});
|
||||
export type TActorContext = z.infer<typeof ZActorContext>;
|
||||
|
||||
export const ZProbeMetadataPayload = z.object({
|
||||
mediaJobId: z.string().uuid(),
|
||||
assetId: z.string().uuid(),
|
||||
storageKey: z.string().min(1),
|
||||
actorContext: ZActorContext
|
||||
});
|
||||
export type TProbeMetadataPayload = z.infer<typeof ZProbeMetadataPayload>;
|
||||
|
||||
export const ZGenerateThumbnailPayload = z.object({
|
||||
mediaJobId: z.string().uuid(),
|
||||
assetId: z.string().uuid(),
|
||||
storageKey: z.string().min(1),
|
||||
actorContext: ZActorContext,
|
||||
/** Seconds into the video to grab. Defaults to 1.0 in the worker. */
|
||||
atSeconds: z.number().nonnegative().optional()
|
||||
});
|
||||
export type TGenerateThumbnailPayload = z.infer<typeof ZGenerateThumbnailPayload>;
|
||||
|
||||
export const ZExtractAudioPayload = z.object({
|
||||
mediaJobId: z.string().uuid(),
|
||||
assetId: z.string().uuid(),
|
||||
storageKey: z.string().min(1),
|
||||
actorContext: ZActorContext
|
||||
});
|
||||
export type TExtractAudioPayload = z.infer<typeof ZExtractAudioPayload>;
|
||||
|
||||
export const ZTranscribeAudioPayload = z.object({
|
||||
mediaJobId: z.string().uuid(),
|
||||
assetId: z.string().uuid(),
|
||||
actorContext: ZActorContext,
|
||||
/** Provider override; defaults to `openai` in the worker. */
|
||||
provider: z.enum(['openai', 'assemblyai', 'deepgram']).optional()
|
||||
});
|
||||
export type TTranscribeAudioPayload = z.infer<typeof ZTranscribeAudioPayload>;
|
||||
|
||||
export const ZCompressVideoPayload = z.object({
|
||||
mediaJobId: z.string().uuid(),
|
||||
assetId: z.string().uuid(),
|
||||
storageKey: z.string().min(1),
|
||||
actorContext: ZActorContext,
|
||||
options: z
|
||||
.object({
|
||||
crf: z.number().int().min(0).max(51).optional(),
|
||||
scale: z.string().optional()
|
||||
})
|
||||
.optional()
|
||||
});
|
||||
export type TCompressVideoPayload = z.infer<typeof ZCompressVideoPayload>;
|
||||
Reference in New Issue
Block a user