Add business gallery API and marketplace profile fields.
Expose list/add/remove gallery endpoints via media_attachments, plus profile title, banner, and category tag/nameFa support needed by the marketplace dashboard. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
d68ef2d08a
commit
3aef62c1b8
@@ -0,0 +1,59 @@
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
import {
|
||||
ArrayMaxSize,
|
||||
IsArray,
|
||||
IsInt,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Max,
|
||||
Min,
|
||||
} from 'class-validator';
|
||||
|
||||
function toStringArray(value: unknown): string[] | undefined {
|
||||
if (value == null || value === '') return undefined;
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => String(item)).filter(Boolean);
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) return undefined;
|
||||
try {
|
||||
const parsed = JSON.parse(trimmed) as unknown;
|
||||
if (Array.isArray(parsed)) {
|
||||
return parsed.map((item) => String(item)).filter(Boolean);
|
||||
}
|
||||
} catch {
|
||||
// comma-separated fallback
|
||||
}
|
||||
return trimmed
|
||||
.split(',')
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export class ListGalleryDto {
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
page?: number;
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
@Max(100)
|
||||
pageSize?: number;
|
||||
}
|
||||
|
||||
export class AddGalleryDto {
|
||||
/** Attach existing business media (also accepted as multipart field). */
|
||||
@IsOptional()
|
||||
@Transform(({ value }) => toStringArray(value))
|
||||
@IsArray()
|
||||
@ArrayMaxSize(50)
|
||||
@IsString({ each: true })
|
||||
mediaIds?: string[];
|
||||
}
|
||||
Reference in New Issue
Block a user