diff options
Diffstat (limited to 'src/queries/prisma')
| -rw-r--r-- | src/queries/prisma/index.ts | 8 | ||||
| -rw-r--r-- | src/queries/prisma/link.ts | 66 | ||||
| -rw-r--r-- | src/queries/prisma/pixel.ts | 60 | ||||
| -rw-r--r-- | src/queries/prisma/report.ts | 89 | ||||
| -rw-r--r-- | src/queries/prisma/segment.ts | 61 | ||||
| -rw-r--r-- | src/queries/prisma/team.ts | 165 | ||||
| -rw-r--r-- | src/queries/prisma/teamUser.ts | 66 | ||||
| -rw-r--r-- | src/queries/prisma/user.ts | 206 | ||||
| -rw-r--r-- | src/queries/prisma/website.ts | 234 |
9 files changed, 955 insertions, 0 deletions
diff --git a/src/queries/prisma/index.ts b/src/queries/prisma/index.ts new file mode 100644 index 0000000..b9730f5 --- /dev/null +++ b/src/queries/prisma/index.ts @@ -0,0 +1,8 @@ +export * from './link'; +export * from './pixel'; +export * from './report'; +export * from './segment'; +export * from './team'; +export * from './teamUser'; +export * from './user'; +export * from './website'; diff --git a/src/queries/prisma/link.ts b/src/queries/prisma/link.ts new file mode 100644 index 0000000..9b971de --- /dev/null +++ b/src/queries/prisma/link.ts @@ -0,0 +1,66 @@ +import type { Prisma } from '@/generated/prisma/client'; +import prisma from '@/lib/prisma'; +import type { QueryFilters } from '@/lib/types'; + +export async function findLink(criteria: Prisma.LinkFindUniqueArgs) { + return prisma.client.link.findUnique(criteria); +} + +export async function getLink(linkId: string) { + return findLink({ + where: { + id: linkId, + }, + }); +} + +export async function getLinks(criteria: Prisma.LinkFindManyArgs, filters: QueryFilters = {}) { + const { search } = filters; + const { getSearchParameters, pagedQuery } = prisma; + + const where: Prisma.LinkWhereInput = { + ...criteria.where, + ...getSearchParameters(search, [ + { name: 'contains' }, + { url: 'contains' }, + { slug: 'contains' }, + ]), + }; + + return pagedQuery('link', { ...criteria, where }, filters); +} + +export async function getUserLinks(userId: string, filters?: QueryFilters) { + return getLinks( + { + where: { + userId, + deletedAt: null, + }, + }, + filters, + ); +} + +export async function getTeamLinks(teamId: string, filters?: QueryFilters) { + return getLinks( + { + where: { + teamId, + }, + }, + filters, + ); +} + +export async function createLink(data: Prisma.LinkUncheckedCreateInput) { + return prisma.client.link.create({ data }); +} + +export async function updateLink(linkId: string, data: any) { + return prisma.client.link.update({ where: { id: linkId }, data }); +} + +export async function deleteLink(linkId: string) { + return prisma.client.link.delete({ where: { id: linkId } }); +} diff --git a/src/queries/prisma/pixel.ts b/src/queries/prisma/pixel.ts new file mode 100644 index 0000000..4c9e132 --- /dev/null +++ b/src/queries/prisma/pixel.ts @@ -0,0 +1,60 @@ +import type { Prisma } from '@/generated/prisma/client'; +import prisma from '@/lib/prisma'; +import type { QueryFilters } from '@/lib/types'; + +export async function findPixel(criteria: Prisma.PixelFindUniqueArgs) { + return prisma.client.pixel.findUnique(criteria); +} + +export async function getPixel(pixelId: string) { + return findPixel({ + where: { + id: pixelId, + }, + }); +} + +export async function getPixels(criteria: Prisma.PixelFindManyArgs, filters: QueryFilters = {}) { + const { search } = filters; + + const where: Prisma.PixelWhereInput = { + ...criteria.where, + ...prisma.getSearchParameters(search, [{ name: 'contains' }, { slug: 'contains' }]), + }; + + return prisma.pagedQuery('pixel', { ...criteria, where }, filters); +} + +export async function getUserPixels(userId: string, filters?: QueryFilters) { + return getPixels( + { + where: { + userId, + }, + }, + filters, + ); +} + +export async function getTeamPixels(teamId: string, filters?: QueryFilters) { + return getPixels( + { + where: { + teamId, + }, + }, + filters, + ); +} + +export async function createPixel(data: Prisma.PixelUncheckedCreateInput) { + return prisma.client.pixel.create({ data }); +} + +export async function updatePixel(pixelId: string, data: any) { + return prisma.client.pixel.update({ where: { id: pixelId }, data }); +} + +export async function deletePixel(pixelId: string) { + return prisma.client.pixel.delete({ where: { id: pixelId } }); +} diff --git a/src/queries/prisma/report.ts b/src/queries/prisma/report.ts new file mode 100644 index 0000000..4a5b755 --- /dev/null +++ b/src/queries/prisma/report.ts @@ -0,0 +1,89 @@ +import { Prisma } from '@/generated/prisma/client'; +import prisma from '@/lib/prisma'; +import type { QueryFilters } from '@/lib/types'; + +import ReportFindManyArgs = Prisma.ReportFindManyArgs; + +async function findReport(criteria: Prisma.ReportFindUniqueArgs) { + return prisma.client.report.findUnique(criteria); +} + +export async function getReport(reportId: string) { + return findReport({ + where: { + id: reportId, + }, + }); +} + +export async function getReports(criteria: ReportFindManyArgs, filters: QueryFilters = {}) { + const { search } = filters; + + const where: Prisma.ReportWhereInput = { + ...criteria.where, + ...prisma.getSearchParameters(search, [ + { name: 'contains' }, + { description: 'contains' }, + { type: 'contains' }, + { + user: { + username: 'contains', + }, + }, + { + website: { + name: 'contains', + }, + }, + { + website: { + domain: 'contains', + }, + }, + ]), + }; + + return prisma.pagedQuery('report', { ...criteria, where }, filters); +} + +export async function getUserReports(userId: string, filters?: QueryFilters) { + return getReports( + { + where: { + userId, + }, + include: { + website: { + select: { + domain: true, + userId: true, + }, + }, + }, + }, + filters, + ); +} + +export async function getWebsiteReports(websiteId: string, filters: QueryFilters = {}) { + return getReports( + { + where: { + websiteId, + }, + }, + filters, + ); +} + +export async function createReport(data: Prisma.ReportUncheckedCreateInput) { + return prisma.client.report.create({ data }); +} + +export async function updateReport(reportId: string, data: any) { + return prisma.client.report.update({ where: { id: reportId }, data }); +} + +export async function deleteReport(reportId: string) { + return prisma.client.report.delete({ where: { id: reportId } }); +} diff --git a/src/queries/prisma/segment.ts b/src/queries/prisma/segment.ts new file mode 100644 index 0000000..3a17d27 --- /dev/null +++ b/src/queries/prisma/segment.ts @@ -0,0 +1,61 @@ +import type { Prisma } from '@/generated/prisma/client'; +import prisma from '@/lib/prisma'; +import type { QueryFilters } from '@/lib/types'; + +async function findSegment(criteria: Prisma.SegmentFindUniqueArgs) { + return prisma.client.segment.findUnique(criteria); +} + +export async function getSegment(segmentId: string) { + return findSegment({ + where: { + id: segmentId, + }, + }); +} + +export async function getSegments(criteria: Prisma.SegmentFindManyArgs, filters: QueryFilters) { + const { search } = filters; + const { getSearchParameters, pagedQuery } = prisma; + + const where: Prisma.SegmentWhereInput = { + ...criteria.where, + ...getSearchParameters(search, [ + { + name: 'contains', + }, + ]), + }; + + return pagedQuery('segment', { ...criteria, where }, filters); +} + +export async function getWebsiteSegment(websiteId: string, segmentId: string) { + return prisma.client.segment.findFirst({ + where: { id: segmentId, websiteId }, + }); +} + +export async function getWebsiteSegments(websiteId: string, type: string, filters?: QueryFilters) { + return getSegments( + { + where: { + websiteId, + type, + }, + }, + filters, + ); +} + +export async function createSegment(data: Prisma.SegmentUncheckedCreateInput) { + return prisma.client.segment.create({ data }); +} + +export async function updateSegment(SegmentId: string, data: Prisma.SegmentUpdateInput) { + return prisma.client.segment.update({ where: { id: SegmentId }, data }); +} + +export async function deleteSegment(SegmentId: string) { + return prisma.client.segment.delete({ where: { id: SegmentId } }); +} diff --git a/src/queries/prisma/team.ts b/src/queries/prisma/team.ts new file mode 100644 index 0000000..5987c1d --- /dev/null +++ b/src/queries/prisma/team.ts @@ -0,0 +1,165 @@ +import { Prisma, type Team } from '@/generated/prisma/client'; +import { ROLES } from '@/lib/constants'; +import { uuid } from '@/lib/crypto'; +import prisma from '@/lib/prisma'; +import type { PageResult, QueryFilters } from '@/lib/types'; + +import TeamFindManyArgs = Prisma.TeamFindManyArgs; + +export async function findTeam(criteria: Prisma.TeamFindUniqueArgs): Promise<Team> { + return prisma.client.team.findUnique(criteria); +} + +export async function getTeam( + teamId: string, + options: { includeMembers?: boolean } = {}, +): Promise<Team> { + const { includeMembers } = options; + + return findTeam({ + where: { + id: teamId, + }, + ...(includeMembers && { include: { members: true } }), + }); +} + +export async function getTeams( + criteria: TeamFindManyArgs, + filters: QueryFilters, +): Promise<PageResult<Team[]>> { + const { getSearchParameters } = prisma; + const { search } = filters; + + const where: Prisma.TeamWhereInput = { + ...criteria.where, + ...getSearchParameters(search, [{ name: 'contains' }]), + }; + + return prisma.pagedQuery<TeamFindManyArgs>( + 'team', + { + ...criteria, + where, + }, + filters, + ); +} + +export async function getUserTeams(userId: string, filters: QueryFilters = {}) { + return getTeams( + { + where: { + deletedAt: null, + members: { + some: { userId }, + }, + }, + include: { + members: { + include: { + user: { + select: { + id: true, + username: true, + }, + }, + }, + }, + _count: { + select: { + websites: { + where: { deletedAt: null }, + }, + members: { + where: { + user: { deletedAt: null }, + }, + }, + }, + }, + }, + }, + filters, + ); +} + +export async function getAllUserTeams(userId: string) { + return prisma.client.team.findMany({ + where: { + deletedAt: null, + members: { + some: { userId }, + }, + }, + select: { + id: true, + name: true, + logoUrl: true, + }, + }); +} + +export async function createTeam(data: Prisma.TeamCreateInput, userId: string): Promise<any> { + const { id } = data; + const { client, transaction } = prisma; + + return transaction([ + client.team.create({ + data, + }), + client.teamUser.create({ + data: { + id: uuid(), + teamId: id, + userId, + role: ROLES.teamOwner, + }, + }), + ]); +} + +export async function updateTeam(teamId: string, data: Prisma.TeamUpdateInput): Promise<Team> { + const { client } = prisma; + + return client.team.update({ + where: { + id: teamId, + }, + data: { + ...data, + updatedAt: new Date(), + }, + }); +} + +export async function deleteTeam(teamId: string) { + const { client, transaction } = prisma; + const cloudMode = !!process.env.CLOUD_MODE; + + if (cloudMode) { + return transaction([ + client.team.update({ + data: { + deletedAt: new Date(), + }, + where: { + id: teamId, + }, + }), + ]); + } + + return transaction([ + client.teamUser.deleteMany({ + where: { + teamId, + }, + }), + client.team.delete({ + where: { + id: teamId, + }, + }), + ]); +} diff --git a/src/queries/prisma/teamUser.ts b/src/queries/prisma/teamUser.ts new file mode 100644 index 0000000..2210dee --- /dev/null +++ b/src/queries/prisma/teamUser.ts @@ -0,0 +1,66 @@ +import { Prisma } from '@/generated/prisma/client'; +import { uuid } from '@/lib/crypto'; +import prisma from '@/lib/prisma'; +import type { QueryFilters } from '@/lib/types'; + +import TeamUserFindManyArgs = Prisma.TeamUserFindManyArgs; + +export async function findTeamUser(criteria: Prisma.TeamUserFindUniqueArgs) { + return prisma.client.teamUser.findUnique(criteria); +} + +export async function getTeamUser(teamId: string, userId: string) { + return prisma.client.teamUser.findFirst({ + where: { + teamId, + userId, + }, + }); +} + +export async function getTeamUsers(criteria: TeamUserFindManyArgs, filters?: QueryFilters) { + const { search } = filters; + + const where: Prisma.TeamUserWhereInput = { + ...criteria.where, + ...prisma.getSearchParameters(search, [{ user: { username: 'contains' } }]), + }; + + return prisma.pagedQuery( + 'teamUser', + { + ...criteria, + where, + }, + filters, + ); +} + +export async function createTeamUser(userId: string, teamId: string, role: string) { + return prisma.client.teamUser.create({ + data: { + id: uuid(), + userId, + teamId, + role, + }, + }); +} + +export async function updateTeamUser(teamUserId: string, data: Prisma.TeamUserUpdateInput) { + return prisma.client.teamUser.update({ + where: { + id: teamUserId, + }, + data, + }); +} + +export async function deleteTeamUser(teamId: string, userId: string) { + return prisma.client.teamUser.deleteMany({ + where: { + teamId, + userId, + }, + }); +} diff --git a/src/queries/prisma/user.ts b/src/queries/prisma/user.ts new file mode 100644 index 0000000..14376fc --- /dev/null +++ b/src/queries/prisma/user.ts @@ -0,0 +1,206 @@ +import { Prisma } from '@/generated/prisma/client'; +import { ROLES } from '@/lib/constants'; +import { getRandomChars } from '@/lib/generate'; +import prisma from '@/lib/prisma'; +import type { QueryFilters, Role } from '@/lib/types'; + +import UserFindManyArgs = Prisma.UserFindManyArgs; + +export interface GetUserOptions { + includePassword?: boolean; + showDeleted?: boolean; +} + +async function findUser(criteria: Prisma.UserFindUniqueArgs, options: GetUserOptions = {}) { + const { includePassword = false, showDeleted = false } = options; + + return prisma.client.user.findUnique({ + ...criteria, + where: { + ...criteria.where, + ...(showDeleted && { deletedAt: null }), + }, + select: { + id: true, + username: true, + password: includePassword, + role: true, + createdAt: true, + }, + }); +} + +export async function getUser(userId: string, options: GetUserOptions = {}) { + return findUser( + { + where: { + id: userId, + }, + }, + options, + ); +} + +export async function getUserByUsername(username: string, options: GetUserOptions = {}) { + return findUser({ where: { username } }, options); +} + +export async function getUsers(criteria: UserFindManyArgs, filters: QueryFilters = {}) { + const { search } = filters; + + const where: Prisma.UserWhereInput = { + ...criteria.where, + ...prisma.getSearchParameters(search, [{ username: 'contains' }]), + deletedAt: null, + }; + + return prisma.pagedQuery( + 'user', + { + ...criteria, + where, + }, + { + orderBy: 'createdAt', + sortDescending: true, + ...filters, + }, + ); +} + +export async function createUser(data: { + id: string; + username: string; + password: string; + role: Role; +}) { + return prisma.client.user.create({ + data, + select: { + id: true, + username: true, + role: true, + }, + }); +} + +export async function updateUser(userId: string, data: Prisma.UserUpdateInput) { + return prisma.client.user.update({ + where: { + id: userId, + }, + data, + select: { + id: true, + username: true, + role: true, + createdAt: true, + }, + }); +} + +export async function deleteUser(userId: string) { + const { client, transaction } = prisma; + const cloudMode = !!process.env.CLOUD_MODE; + + const websites = await client.website.findMany({ + where: { userId }, + }); + + let websiteIds = []; + + if (websites.length > 0) { + websiteIds = websites.map(a => a.id); + } + + const teams = await client.team.findMany({ + where: { + members: { + some: { + userId, + role: ROLES.teamOwner, + }, + }, + }, + }); + + const teamIds = teams.map(a => a.id); + + if (cloudMode) { + return transaction([ + client.website.updateMany({ + data: { + deletedAt: new Date(), + }, + where: { id: { in: websiteIds } }, + }), + client.user.update({ + data: { + username: getRandomChars(32), + deletedAt: new Date(), + }, + where: { + id: userId, + }, + }), + ]); + } + + return transaction([ + client.eventData.deleteMany({ + where: { websiteId: { in: websiteIds } }, + }), + client.sessionData.deleteMany({ + where: { websiteId: { in: websiteIds } }, + }), + client.websiteEvent.deleteMany({ + where: { websiteId: { in: websiteIds } }, + }), + client.session.deleteMany({ + where: { websiteId: { in: websiteIds } }, + }), + client.teamUser.deleteMany({ + where: { + OR: [ + { + teamId: { + in: teamIds, + }, + }, + { + userId, + }, + ], + }, + }), + client.team.deleteMany({ + where: { + id: { + in: teamIds, + }, + }, + }), + client.report.deleteMany({ + where: { + OR: [ + { + websiteId: { + in: websiteIds, + }, + }, + { + userId, + }, + ], + }, + }), + client.website.deleteMany({ + where: { id: { in: websiteIds } }, + }), + client.user.delete({ + where: { + id: userId, + }, + }), + ]); +} diff --git a/src/queries/prisma/website.ts b/src/queries/prisma/website.ts new file mode 100644 index 0000000..79cb724 --- /dev/null +++ b/src/queries/prisma/website.ts @@ -0,0 +1,234 @@ +import type { Prisma } from '@/generated/prisma/client'; +import { ROLES } from '@/lib/constants'; +import prisma from '@/lib/prisma'; +import redis from '@/lib/redis'; +import type { QueryFilters } from '@/lib/types'; + +export async function findWebsite(criteria: Prisma.WebsiteFindUniqueArgs) { + return prisma.client.website.findUnique(criteria); +} + +export async function getWebsite(websiteId: string) { + return findWebsite({ + where: { + id: websiteId, + }, + }); +} + +export async function getSharedWebsite(shareId: string) { + return findWebsite({ + where: { + shareId, + deletedAt: null, + }, + }); +} + +export async function getWebsites(criteria: Prisma.WebsiteFindManyArgs, filters: QueryFilters) { + const { search } = filters; + const { getSearchParameters, pagedQuery } = prisma; + + const where: Prisma.WebsiteWhereInput = { + ...criteria.where, + ...getSearchParameters(search, [ + { + name: 'contains', + }, + { domain: 'contains' }, + ]), + deletedAt: null, + }; + + return pagedQuery('website', { ...criteria, where }, filters); +} + +export async function getAllUserWebsitesIncludingTeamOwner(userId: string, filters?: QueryFilters) { + return getWebsites( + { + where: { + OR: [ + { userId }, + { + team: { + deletedAt: null, + members: { + some: { + role: ROLES.teamOwner, + userId, + }, + }, + }, + }, + ], + }, + }, + { + orderBy: 'name', + ...filters, + }, + ); +} + +export async function getUserWebsites(userId: string, filters?: QueryFilters) { + return getWebsites( + { + where: { + userId, + }, + include: { + user: { + select: { + username: true, + id: true, + }, + }, + }, + }, + { + orderBy: 'name', + ...filters, + }, + ); +} + +export async function getTeamWebsites(teamId: string, filters?: QueryFilters) { + return getWebsites( + { + where: { + teamId, + }, + include: { + createUser: { + select: { + id: true, + username: true, + }, + }, + }, + }, + filters, + ); +} + +export async function createWebsite( + data: Prisma.WebsiteCreateInput | Prisma.WebsiteUncheckedCreateInput, +) { + return prisma.client.website.create({ + data, + }); +} + +export async function updateWebsite( + websiteId: string, + data: Prisma.WebsiteUpdateInput | Prisma.WebsiteUncheckedUpdateInput, +) { + return prisma.client.website.update({ + where: { + id: websiteId, + }, + data, + }); +} + +export async function resetWebsite(websiteId: string) { + const { client, transaction } = prisma; + const cloudMode = !!process.env.CLOUD_MODE; + + return transaction( + [ + client.revenue.deleteMany({ + where: { websiteId }, + }), + client.eventData.deleteMany({ + where: { websiteId }, + }), + client.sessionData.deleteMany({ + where: { websiteId }, + }), + client.websiteEvent.deleteMany({ + where: { websiteId }, + }), + client.session.deleteMany({ + where: { websiteId }, + }), + client.website.update({ + where: { id: websiteId }, + data: { + resetAt: new Date(), + }, + }), + ], + { + timeout: 30000, + }, + ).then(async data => { + if (cloudMode) { + await redis.client.set( + `website:${websiteId}`, + data.find(website => website.id), + ); + } + + return data; + }); +} + +export async function deleteWebsite(websiteId: string) { + const { client, transaction } = prisma; + const cloudMode = !!process.env.CLOUD_MODE; + + return transaction( + [ + client.revenue.deleteMany({ + where: { websiteId }, + }), + client.eventData.deleteMany({ + where: { websiteId }, + }), + client.sessionData.deleteMany({ + where: { websiteId }, + }), + client.websiteEvent.deleteMany({ + where: { websiteId }, + }), + client.session.deleteMany({ + where: { websiteId }, + }), + client.report.deleteMany({ + where: { websiteId }, + }), + client.segment.deleteMany({ + where: { websiteId }, + }), + cloudMode + ? client.website.update({ + data: { + deletedAt: new Date(), + }, + where: { id: websiteId }, + }) + : client.website.delete({ + where: { id: websiteId }, + }), + ], + { + timeout: 30000, + }, + ).then(async data => { + if (cloudMode) { + await redis.client.del(`website:${websiteId}`); + } + + return data; + }); +} + +export async function getWebsiteCount(userId: string) { + return prisma.client.website.count({ + where: { + userId, + deletedAt: null, + }, + }); +} |