Messenger/packages/core/src/schemas/conversation.ts
Заид Омар Медхат | Zaid Omar Medhat db5c1610b3 Phase 6: media messages + avatars via MinIO presigned uploads
- Media (voice/video/image/file): private bucket, presigned PUT upload,
  reference-only publish, membership-gated presigned GET for viewing
- Avatars: public bucket, presigned PUT + direct public URL, profile.update event
- messages.media_key + media_meta (migration 1720000000005_media)
- Explicit MinIO region on presigning client (avoids getBucketRegion network call)
- Event type values sourced from EventType constants (no raw string literals)
- Web: attach button, MediaView renderer, avatar upload in topbar

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BFRyKxkKEjfAgpXygzoNiD
2026-07-10 18:11:25 +05:00

67 lines
2 KiB
TypeScript

import type { FromSchema } from 'json-schema-to-ts';
import { mediaRefSchema } from './media';
const USERNAME_PATTERN = '^[a-zA-Z0-9_]{3,32}$';
export const createDirectBodySchema = {
type: 'object',
additionalProperties: false,
required: ['username'],
properties: {
username: { type: 'string', pattern: USERNAME_PATTERN },
},
} as const;
export const createGroupBodySchema = {
type: 'object',
additionalProperties: false,
required: ['title'],
properties: {
title: { type: 'string', minLength: 1, maxLength: 100 },
members: {
type: 'array',
maxItems: 200,
items: { type: 'string', pattern: USERNAME_PATTERN },
},
},
} as const;
export const addMemberBodySchema = {
type: 'object',
additionalProperties: false,
required: ['username'],
properties: {
username: { type: 'string', pattern: USERNAME_PATTERN },
},
} as const;
export const sendMessageBodySchema = {
type: 'object',
additionalProperties: false,
required: ['clientMsgId'],
properties: {
// Caption; may be empty for a media-only message.
content: { type: 'string', maxLength: 16000 },
clientMsgId: { type: 'string', minLength: 1, maxLength: 64 },
contentType: { type: 'string', enum: ['text', 'text/ciphertext'] },
encryption: { type: ['string', 'null'] },
// Object key returned by the media upload URL + its metadata.
mediaKey: { type: 'string', minLength: 1, maxLength: 255 },
media: mediaRefSchema,
},
} as const;
export const addContactBodySchema = {
type: 'object',
additionalProperties: false,
required: ['username'],
properties: {
username: { type: 'string', pattern: USERNAME_PATTERN },
},
} as const;
export type CreateDirectBody = FromSchema<typeof createDirectBodySchema>;
export type CreateGroupBody = FromSchema<typeof createGroupBodySchema>;
export type AddMemberBody = FromSchema<typeof addMemberBodySchema>;
export type SendMessageBody = FromSchema<typeof sendMessageBodySchema>;
export type AddContactBody = FromSchema<typeof addContactBodySchema>;