diff --git a/apps/api/src/organizations/dto.ts b/apps/api/src/organizations/dto.ts index ff15960..8e5e3d6 100644 --- a/apps/api/src/organizations/dto.ts +++ b/apps/api/src/organizations/dto.ts @@ -2,12 +2,14 @@ import { ArrayMinSize, IsArray, IsIn, + IsISO8601, IsNumber, IsOptional, IsString, MaxLength, Min, MinLength, + ValidateIf, ValidateNested, } from 'class-validator'; import { Type } from 'class-transformer'; @@ -72,5 +74,8 @@ export class UpdateOrganizationDto { export class UpdatePriorArchiveCutoffDto implements UpdatePriorArchiveCutoffRequest { + /** بدون دکوراتور، whitelist پایپ Nest فیلد را حذف می‌کرد و ذخیره همیشه خطا می‌داد. */ + @ValidateIf((_, value) => value !== null) + @IsISO8601() cutoffAt!: string | null; } diff --git a/apps/web/src/components/TeamsSettingsPanel.vue b/apps/web/src/components/TeamsSettingsPanel.vue index b91ee53..b1d84db 100644 --- a/apps/web/src/components/TeamsSettingsPanel.vue +++ b/apps/web/src/components/TeamsSettingsPanel.vue @@ -95,16 +95,23 @@ async function setPriorArchive(userId: string, enabled: boolean) { function cutoffPayload(value: string): UpdatePriorArchiveCutoffRequest { const parsed = parseLocalInput(value); - return { cutoffAt: parsed ? parsed.toISOString() : null }; + if (!parsed) return { cutoffAt: null }; + // پایان همان روز محلی تا ایمپورت همان روز هم قبل از تاریخ قطع شمرده شود + parsed.setHours(23, 59, 59, 999); + return { cutoffAt: parsed.toISOString() }; +} + +function applyCutoffFromOrg(org: Pick) { + cutoffLocal.value = org.priorArchiveCutoffAt + ? formatLocalDateInput(new Date(org.priorArchiveCutoffAt)) + : ''; } async function loadPriorArchiveCutoff() { cutoffLoading.value = true; try { const { data } = await api.get('/organizations/current'); - cutoffLocal.value = data.priorArchiveCutoffAt - ? formatLocalDateInput(new Date(data.priorArchiveCutoffAt)) - : ''; + applyCutoffFromOrg(data); } catch (e) { error.value = axios.isAxiosError(e) ? String((e.response?.data as { message?: string })?.message ?? 'بارگذاری تاریخ بایگانی ناموفق بود.') @@ -120,7 +127,11 @@ async function onCutoffChange(value: string) { error.value = ''; ok.value = ''; try { - await api.patch('/organizations/current/prior-archive-cutoff', cutoffPayload(value)); + const { data } = await api.patch( + '/organizations/current/prior-archive-cutoff', + cutoffPayload(value), + ); + applyCutoffFromOrg(data); ok.value = value ? 'تاریخ بایگانی اطلاعات قبل ذخیره شد.' : 'تاریخ بایگانی اطلاعات قبل پاک شد.'; await auth.hydrate(); } catch (e) {