feat: separate prior records behind an owner switch and count last-period questions

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-15 10:48:30 +03:30
co-authored by Cursor
parent 3a8a684aa4
commit 6bc5e1bec7
29 changed files with 775 additions and 77 deletions
+72
View File
@@ -0,0 +1,72 @@
import type { Prisma } from '@prisma/client';
import type { Actor } from './record-scope';
export const PRIOR_IMPORT_SOURCE = 'didar';
export type PriorLens = 'off' | 'current' | 'archive';
export function actorPriorLens(actor: Pick<Actor, 'priorLens'> | undefined): PriorLens {
return actor?.priorLens ?? 'off';
}
function liveDeal(now: Date): Prisma.DealWhereInput {
return {
importSource: PRIOR_IMPORT_SOURCE,
status: 'open',
expectedCloseAt: { gt: now },
};
}
function liveActivity(now: Date): Prisma.ActivityWhereInput {
return {
importSource: PRIOR_IMPORT_SOURCE,
status: 'open',
dueAt: { gt: now },
};
}
export function personPriorWhere(lens: PriorLens | undefined): Prisma.PersonWhereInput {
if (lens === 'archive') return { importSource: PRIOR_IMPORT_SOURCE };
if (lens === 'current') return { importSource: { not: PRIOR_IMPORT_SOURCE } };
return {};
}
export function companyPriorWhere(lens: PriorLens | undefined): Prisma.CompanyWhereInput {
if (lens === 'archive') return { importSource: PRIOR_IMPORT_SOURCE };
if (lens === 'current') return { importSource: { not: PRIOR_IMPORT_SOURCE } };
return {};
}
export function dealPriorWhere(lens: PriorLens | undefined, now = new Date()): Prisma.DealWhereInput {
if (lens === 'current') {
return { OR: [{ importSource: { not: PRIOR_IMPORT_SOURCE } }, liveDeal(now)] };
}
if (lens === 'archive') {
return { importSource: PRIOR_IMPORT_SOURCE, NOT: liveDeal(now) };
}
return {};
}
export function activityPriorWhere(
lens: PriorLens | undefined,
now = new Date(),
): Prisma.ActivityWhereInput {
if (lens === 'current') {
return { OR: [{ importSource: { not: PRIOR_IMPORT_SOURCE } }, liveActivity(now)] };
}
if (lens === 'archive') {
return { importSource: PRIOR_IMPORT_SOURCE, NOT: liveActivity(now) };
}
return {};
}
/** فهرست شخص/شرکت: در کار جاری، جستجو و فیلتر صریح منبع، قبلی‌ها را هم پیدا می‌کند. */
export function listPriorLens(
lens: PriorLens | undefined,
q: string | undefined,
explicitSource: boolean,
): PriorLens {
if (explicitSource) return 'off';
if (lens === 'current' && q?.trim()) return 'off';
return lens ?? 'off';
}
+2
View File
@@ -20,6 +20,8 @@ export type Actor = {
visibleUserIds?: string[] | null;
/** سطح دید تفکیکی هر بخش (از Membership.dataVisibilityScopes) */
scopes?: Partial<Record<DataScope, ScopeVisibility>>;
/** off = فیلتر خاموش؛ current = کار جاری؛ archive = بایگانی اطلاعات قبل */
priorLens?: 'off' | 'current' | 'archive';
};
export type ScopedActor = Pick<Actor, 'userId' | 'role' | 'dataVisibility' | 'visibleUserIds' | 'scopes'>;