Unified search algorithm across all lists; per-section record visibility (contacts, deals, activities, leads, finance, tickets, notes, projects)

This commit is contained in:
2026-10-06 15:04:46 +03:30
parent 43717392b2
commit e08f1452ef
38 changed files with 699 additions and 420 deletions
+9 -6
View File
@@ -16,9 +16,11 @@ import type {
} from '@mento/shared';
import { Prisma } from '@prisma/client';
import { PrismaService } from '../prisma/prisma.service';
import { buildSearchWhere, ci } from '../common/search';
import {
type Actor,
elevated,
forScope,
ownerWhere,
} from '../common/record-scope';
import {
@@ -69,10 +71,10 @@ export class SalesService {
if (opts.type && isGoalType(opts.type)) {
where.type = opts.type;
}
const q = opts.q?.trim();
if (q) {
where.title = { contains: q, mode: 'insensitive' };
}
const search = buildSearchWhere<Prisma.SalesGoalWhereInput>(opts.q, (t) => [
{ title: ci(t) },
]);
if (search) where.AND = [search];
const rows = await this.prisma.salesGoal.findMany({
where,
@@ -237,7 +239,7 @@ export class SalesService {
const dealOwner =
elevated(actor.role) && opts.userId
? { ownerId: opts.userId }
: ownerWhere(actor);
: ownerWhere(actor, 'deals');
const goalsWhere: Prisma.SalesGoalWhereInput = {
organizationId: actor.organizationId,
@@ -400,9 +402,10 @@ export class SalesService {
}
private goalVisibility(
actor: Actor,
baseActor: Actor,
filterUserId?: string,
): Prisma.SalesGoalWhereInput {
const actor = forScope(baseActor, 'deals');
if (elevated(actor.role) || actor.dataVisibility === 'org' || actor.visibleUserIds === null) {
if (filterUserId === 'org') return { userId: null };
if (filterUserId) return { userId: filterUserId };