From 78c7ddcebfe3fa8d980ef9999bf24493fb02bd03 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Thu, 22 Aug 2024 00:54:06 +0100 Subject: [PATCH 01/18] ar(feat) [DPCP-40]: Parse Services. --- prisma/mock/services.mts | 7 +++---- prisma/schema-private.prisma | 3 +++ prisma/seed.mts | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/prisma/mock/services.mts b/prisma/mock/services.mts index af3098af..afae92a5 100644 --- a/prisma/mock/services.mts +++ b/prisma/mock/services.mts @@ -10,11 +10,10 @@ import { mockTerm, mockTerm2 } from './taxonomies.mts'; import { HOMock } from './helpers.mts'; -export const createMockService = ({ community, user, features, refUsers, refCommunities }: any): any => { +export const createMockService = ({ name, slug, community, user, features, refUsers, refCommunities }: any): any => { const data = { - name: { - es: 'Service 1', - }, + name, + slug, status: 'ACTIVE', type: 'CONSUMER', nature: 'COMMON', diff --git a/prisma/schema-private.prisma b/prisma/schema-private.prisma index 5a34c5b2..671ebf3e 100644 --- a/prisma/schema-private.prisma +++ b/prisma/schema-private.prisma @@ -370,6 +370,7 @@ model Roles { model Services { id String @id @default(auto()) @map("_id") @db.ObjectId name ILocaleString + slug String status EServiceStatus type EServiceType nature EServiceNature @@ -639,6 +640,8 @@ type ILocaleString { bg String? bs String? sq String? + ja String? + ru String? } diff --git a/prisma/seed.mts b/prisma/seed.mts index 958c1b19..b5741283 100644 --- a/prisma/seed.mts +++ b/prisma/seed.mts @@ -124,8 +124,42 @@ if (seedType === 'private') { }); // // services + const service1name = { + en: 'The Rick Morty Experience', + it: "L'esperienza di Rick Morty", + pt: 'A Experiência Rick Morty', + es: 'La Experiencia Rick Morty', + de: 'Das Rick Morty Erlebnis', + fr: "L'expérience Rick Morty", + ro: 'Experiența Rick Morty', + cz: 'Rick Morty Zážitek', + pl: 'Doświadczenie Rick Morty', + et: 'Rick Morty Kogemus', + sv: 'Rick Morty-upplevelsen', + ja: 'リック・モーティ体験', + ru: 'Опыт Рика и Морти', + }; + + const service2name = { + en: 'The Vibe Modulator', + it: 'Il Modulatore di Vibrazioni', + pt: 'O Modulador de Vibração', + es: 'El Modulador de Ambiente', + de: 'Der Vibe-Modulator', + fr: 'Le Modulateur de Vibration', + ro: 'Modulatorul de Vibrații', + cz: 'Vibrační Modulátor', + pl: 'Modulator Nastroju', + et: 'Vibe Modulaator', + sv: 'Vibe-modulatorn', + ja: 'バイブモジュレーター', + ru: 'Вибромодулятор', + }; + const service1 = await pvtPrisma.services.create({ data: createMockService({ + name: service1name, + slug: 'rickmorty', user: user1.id, community: community1.id, features: [{ id: feature1.id }, { id: feature2.id }], @@ -135,6 +169,8 @@ if (seedType === 'private') { }); const service2 = await pvtPrisma.services.create({ data: createMockService({ + name: service2name, + slug: 'dpcp-vibemodulator', user: user1.id, community: community1.id, refUsers: [{ id: user2.id }, { id: user3.id }], From 0e3918a1c0a13976a9f2044e53c9b5f98a671555 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Thu, 22 Aug 2024 01:27:51 +0100 Subject: [PATCH 02/18] ar(feat) [DPCP-40]: Parse Services. --- lib/model/interfaces/get-private-services.ts | 75 ++++++++++++------- .../interfaces/middleware/authorization.ts | 4 +- .../update-private-user-favorite-listings.ts | 6 +- prisma/mock/abilities.mts | 23 ++++-- prisma/schema-private.prisma | 10 ++- prisma/seed.mts | 61 ++++++++++++++- .../v1/services/dpcp-vibemodulator/route.ts | 60 +++++++++++++++ src/app/api/v1/services/rickmorty/route.ts | 60 +++++++++++++++ 8 files changed, 259 insertions(+), 40 deletions(-) create mode 100644 src/app/api/v1/services/dpcp-vibemodulator/route.ts create mode 100644 src/app/api/v1/services/rickmorty/route.ts diff --git a/lib/model/interfaces/get-private-services.ts b/lib/model/interfaces/get-private-services.ts index a8020ec8..f6d75990 100644 --- a/lib/model/interfaces/get-private-services.ts +++ b/lib/model/interfaces/get-private-services.ts @@ -9,6 +9,7 @@ const getPrivateServices = async ({ name, locale = 'es', user, + target, page = 0, offset = 0, limit = PAGE_SIZE, @@ -19,43 +20,63 @@ const getPrivateServices = async ({ const adaptQuery: any = { where: { id, - name: { [locale]: name }, + slug: name, }, skip: page * (limit + offset), take: limit, cacheStrategy: { ttl: 90 }, }; - if (filters?.length) { - try { - const supportedQueries: Record = { - user: { - query: { - OR: [{ id: { in: loggedUser?.servicesIds }, name: { [locale]: name } }, { userOwner: loggedUser?.id }], + if ((await canI({ type: 'R', action: 'view-listings', target, user: loggedUser })) && type === 'id') { + if (filters?.length) { + try { + const supportedQueries: Record = { + user: { + query: { + OR: [{ id: { in: loggedUser?.servicesIds }, name: { [locale]: name } }, { userOwner: loggedUser?.id }], + }, }, - }, - // group: { - // query: { - // OR: [ - // { id, name, groupOwner: session?.user?.id }, - // ], - // }, - // }, - }; + // group: { + // query: { + // OR: [ + // { id, name, groupOwner: session?.user?.id }, + // ], + // }, + // }, + }; - const query: any = filters?.reduce((acc: any, filter: string) => { - if (!acc.OR) acc.OR = []; - acc.OR.push(supportedQueries[filter].query); - return acc; - }, {}); + const query: any = filters?.reduce((acc: any, filter: string) => { + if (!acc.OR) acc.OR = []; + acc.OR.push(supportedQueries[filter].query); + return acc; + }, {}); - adaptQuery.where = { - ...adaptQuery.where, - ...query, - }; - } catch (e) { - throw new Error('Code 001: Wrong filter'); + adaptQuery.where = { + ...adaptQuery.where, + ...query, + }; + } catch (e) { + throw new Error('Code 001: Wrong filter'); + } } + + const swapUserData = loggedUser.favorites.filter((listing: string) => !listings.includes(listing)); + const payload = upsert + ? { + favoritesIds: [...swapUserData, ...delta], + } + : { + favoritesIds: listings, + }; + const adaptQuery: any = { + where: { + email: loggedUser.email, + }, + data: payload, + }; + + const response = await PrivatePrisma.user.update(adaptQuery); + return response; } const response = await PrivatePrisma.services.findMany(adaptQuery); diff --git a/lib/model/interfaces/middleware/authorization.ts b/lib/model/interfaces/middleware/authorization.ts index 658c4155..c177a31b 100644 --- a/lib/model/interfaces/middleware/authorization.ts +++ b/lib/model/interfaces/middleware/authorization.ts @@ -2,9 +2,9 @@ import { getSession, GetSession } from '@auth'; import { GetPrivateAbilities } from '@controller'; import { cookies as nextCookies } from 'next/headers'; -export const canI = async ({ name, user }: any) => { +export const canI = async ({ type, target, action, user }: any) => { try { - const ability = await GetPrivateAbilities({ name }); + const ability = await GetPrivateAbilities({ type, target, action }); // to-do add authorization/validation checks const yes = user?.abilities?.includes(ability[0]?.id); // return the capacity diff --git a/lib/model/interfaces/update-private-user-favorite-listings.ts b/lib/model/interfaces/update-private-user-favorite-listings.ts index 640481c6..e360d878 100644 --- a/lib/model/interfaces/update-private-user-favorite-listings.ts +++ b/lib/model/interfaces/update-private-user-favorite-listings.ts @@ -3,7 +3,7 @@ import { whoAmI, canI } from '@controller'; import { PrivatePrisma } from '@model'; -const updatePrivateUserFavoriteListings = async ({ upsert = true, user, listings = [], type = 'id' }: any) => { +const updatePrivateUserFavoriteListings = async ({ upsert = true, user, target, listings = [], type = 'id' }: any) => { try { if (listings?.length === 0) return new Error('Code 002: Missing data (listings)'); @@ -13,7 +13,7 @@ const updatePrivateUserFavoriteListings = async ({ upsert = true, user, listings const delta = upsert ? listings.filter((listing: any) => !loggedUser?.favorites?.includes(listing)) : []; - if ((await canI({ name: 'Ability 1', user: loggedUser })) && type === 'id') { + if ((await canI({ type: 'U', action: 'favorite', target, user: loggedUser })) && type === 'id') { const swapUserData = loggedUser.favorites.filter((listing: string) => !listings.includes(listing)); const payload = upsert ? { @@ -31,7 +31,7 @@ const updatePrivateUserFavoriteListings = async ({ upsert = true, user, listings const response = await PrivatePrisma.user.update(adaptQuery); return response; - } else if ((await canI({ name: 'Ability 1', user: loggedUser })) && type === 'string') { + } else if ((await canI({ type: 'U', action: 'favorite', target, user: loggedUser })) && type === 'string') { const userData = loggedUser?.favoritesStrings; const swapData = userData.filter((listing: string) => listings.includes(listing)); const transaction = userData diff --git a/prisma/mock/abilities.mts b/prisma/mock/abilities.mts index 00c7c6bc..bbe62ba0 100644 --- a/prisma/mock/abilities.mts +++ b/prisma/mock/abilities.mts @@ -10,14 +10,25 @@ import { mockTerm, mockTerm2 } from './taxonomies.mts'; import { HOMock } from './helpers.mts'; -export const createMockAbility = ({ community, user, roles, refUsers, refCommunities }: any): any => { +export const createMockAbility = ({ + name, + action, + type, + nature, + target, + community, + user, + roles, + refUsers, + refCommunities, +}: any): any => { const data = { - name: { - es: 'Ability 1', - }, + name, + target, + action, status: 'ACTIVE', - type: 'R', - nature: 'COMMON', + type, + nature, roles: { connect: roles, }, diff --git a/prisma/schema-private.prisma b/prisma/schema-private.prisma index 671ebf3e..0d86c905 100644 --- a/prisma/schema-private.prisma +++ b/prisma/schema-private.prisma @@ -432,6 +432,8 @@ model Abilities { status EAbilityStatus type EAbilityType nature EAbilityNature + target String + action String features Features[] @relation("featureAbilities", fields: [featuresIds], references: [id]) featuresIds String[] @db.ObjectId @@ -462,6 +464,7 @@ model Abilities { model Moods { id String @id @default(auto()) @map("_id") @db.ObjectId name ILocaleString + slug String description ILocaleString title ILocaleString @@ -489,6 +492,7 @@ model Moods { model Actions { id String @id @default(auto()) @map("_id") @db.ObjectId name ILocaleString + slug String description ILocaleString title ILocaleString @@ -516,6 +520,7 @@ model Actions { model Thoughts { id String @id @default(auto()) @map("_id") @db.ObjectId name ILocaleString + slug String description ILocaleString title ILocaleString @@ -543,6 +548,7 @@ model Thoughts { model Projects { id String @id @default(auto()) @map("_id") @db.ObjectId name ILocaleString + slug String description ILocaleString title ILocaleString @@ -575,6 +581,7 @@ model Projects { model Investments { id String @id @default(auto()) @map("_id") @db.ObjectId name ILocaleString + slug String description ILocaleString title ILocaleString @@ -887,8 +894,9 @@ enum EAbilityNature { } enum EAbilityType { + C R - W + U D } diff --git a/prisma/seed.mts b/prisma/seed.mts index b5741283..2890fa67 100644 --- a/prisma/seed.mts +++ b/prisma/seed.mts @@ -84,18 +84,77 @@ if (seedType === 'private') { }); // // abilities + + const ability1name = { + en: 'Favorite Listings', + it: 'Aggiungi ai Preferiti', + pt: 'Favoritar Listagens', + es: 'Marcar como Favorito', + de: 'Anzeigen favorisieren', + fr: 'Mettre en Favori', + ro: 'Favoritează liste', + cz: 'Oblíbené inzeráty', + pl: 'Dodaj do Ulubionych', + et: 'Lisa lemmikutesse', + sv: 'Gör till Favoriter', + ja: 'お気に入りにする', + ru: 'Добавить в Избранное', + }; + + const ability2name = { + en: 'View Listings', + it: 'Visualizza inserzioni', + pt: 'Ver listagens', + es: 'Ver listados', + de: 'Anzeigen anzeigen', + fr: 'Voir les annonces', + ro: 'Vizualizare liste', + cz: 'Zobrazit inzeráty', + pl: 'Wyświetl oferty', + et: 'Vaata kuulutusi', + sv: 'Visa listor', + ja: 'リストを表示する', + ru: 'Просмотр объявлений', + }; + const ability1 = await pvtPrisma.abilities.create({ data: createMockAbility({ + name: ability2name, user: user1.id, community: community1.id, + type: 'R', + action: 'view-listings', + nature: 'COMMON', + target: 'rickmorty', roles: [{ id: role1.id }, { id: role2.id }], refUsers: [{ id: user1.id }], refCommunities: [{ id: community1.id }], }), }); + const ability2 = await pvtPrisma.abilities.create({ data: createMockAbility({ + name: ability2name, + user: user1.id, + type: 'R', + action: 'view-listings', + nature: 'PRIVILEGE', + target: 'dpcp-vibemodulator', + community: community1.id, + roles: [{ id: role1.id }, { id: role2.id }], + refUsers: [{ id: user1.id }, { id: user2.id }, { id: user3.id }], + refCommunities: [{ id: community2.id }, { id: community3.id }], + }), + }); + + const ability3 = await pvtPrisma.abilities.create({ + data: createMockAbility({ + name: ability1name, user: user1.id, + type: 'U', + action: 'favorite', + nature: 'COMMON', + target: 'rickmorty', community: community1.id, roles: [{ id: role1.id }, { id: role2.id }], refUsers: [{ id: user1.id }, { id: user2.id }, { id: user3.id }], @@ -144,7 +203,7 @@ if (seedType === 'private') { en: 'The Vibe Modulator', it: 'Il Modulatore di Vibrazioni', pt: 'O Modulador de Vibração', - es: 'El Modulador de Ambiente', + es: 'El Modulador de Vibra', de: 'Der Vibe-Modulator', fr: 'Le Modulateur de Vibration', ro: 'Modulatorul de Vibrații', diff --git a/src/app/api/v1/services/dpcp-vibemodulator/route.ts b/src/app/api/v1/services/dpcp-vibemodulator/route.ts new file mode 100644 index 00000000..f0010c30 --- /dev/null +++ b/src/app/api/v1/services/dpcp-vibemodulator/route.ts @@ -0,0 +1,60 @@ +// @api/v1/services/dpcp-vibemodulator/index.ts +import type { NextApiRequest } from 'next'; +import type { NextRequest } from 'next/server'; +import { NextResponse } from 'next/server'; +import { GetPublicListings } from '@controller'; +type CombineRequest = NextRequest & NextApiRequest; + +const generateErrorResponse = (e: any, status: number) => { + return { + ok: false, + status, + message: e.message, + }; +}; + +// export const dynamic = 'force-static'; +export async function GET(request: CombineRequest) { + console.log({ + request: request.cookies, + requestOrigin: request.headers.get('x-forwarded-host'), + cache: request.headers.get('cache-control'), + }); + try { + const url = new URL(request.url); + const query = url.searchParams; + + const page = query.get('page'); + const limit = query.get('limit'); + const offset = query.get('offset'); + const filters = query.get('filters'); + + const filterArray = filters ? (Array.isArray(filters) ? filters : [filters]) : []; + + const coercedPage = Number(page ? (Array.isArray(page) ? page[0] : page) : 0); + const coercedLimit = Number(limit ? (Array.isArray(limit) ? limit[0] : limit) : 100); + const coercedOffset = Number(offset ? (Array.isArray(offset) ? offset[0] : offset) : 0); + + const data = await GetPublicListings({ + page: coercedPage, + limit: coercedLimit, + offset: coercedOffset, + filters: filterArray, + }); + + console.log({ headers: request.headers }); + + return NextResponse.json( + { + ok: true, + status: 200, + data, + }, + { + status: 200, + }, + ); + } catch (e) { + return NextResponse.json(generateErrorResponse(e, 403), { status: 403 }); + } +} diff --git a/src/app/api/v1/services/rickmorty/route.ts b/src/app/api/v1/services/rickmorty/route.ts new file mode 100644 index 00000000..a5bcbecc --- /dev/null +++ b/src/app/api/v1/services/rickmorty/route.ts @@ -0,0 +1,60 @@ +// @api/v1/services/rickmorty/index.ts +import type { NextApiRequest } from 'next'; +import type { NextRequest } from 'next/server'; +import { NextResponse } from 'next/server'; +import { GetPublicListings } from '@controller'; +type CombineRequest = NextRequest & NextApiRequest; + +const generateErrorResponse = (e: any, status: number) => { + return { + ok: false, + status, + message: e.message, + }; +}; + +// export const dynamic = 'force-static'; +export async function GET(request: CombineRequest) { + console.log({ + request: request.cookies, + requestOrigin: request.headers.get('x-forwarded-host'), + cache: request.headers.get('cache-control'), + }); + try { + const url = new URL(request.url); + const query = url.searchParams; + + const page = query.get('page'); + const limit = query.get('limit'); + const offset = query.get('offset'); + const filters = query.get('filters'); + + const filterArray = filters ? (Array.isArray(filters) ? filters : [filters]) : []; + + const coercedPage = Number(page ? (Array.isArray(page) ? page[0] : page) : 0); + const coercedLimit = Number(limit ? (Array.isArray(limit) ? limit[0] : limit) : 100); + const coercedOffset = Number(offset ? (Array.isArray(offset) ? offset[0] : offset) : 0); + + const data = await GetPublicListings({ + page: coercedPage, + limit: coercedLimit, + offset: coercedOffset, + filters: filterArray, + }); + + console.log({ headers: request.headers }); + + return NextResponse.json( + { + ok: true, + status: 200, + data, + }, + { + status: 200, + }, + ); + } catch (e) { + return NextResponse.json(generateErrorResponse(e, 403), { status: 403 }); + } +} From 86d2901269fcf85a94d9bf2c41c7bab803fe116a Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Thu, 22 Aug 2024 02:20:50 +0100 Subject: [PATCH 03/18] ar(feat) [DPCP-40]: Parse Services. --- lib/auth/constants.ts | 12 ++++- lib/model/interfaces/get-private-abilities.ts | 16 ++++++- lib/model/interfaces/get-private-services.ts | 44 ++++--------------- .../interfaces/middleware/authorization.ts | 6 ++- prisma/schema-private.prisma | 6 +-- .../v1/services/dpcp-vibemodulator/route.ts | 13 ++++-- 6 files changed, 51 insertions(+), 46 deletions(-) diff --git a/lib/auth/constants.ts b/lib/auth/constants.ts index 00c17f20..86aea4f2 100644 --- a/lib/auth/constants.ts +++ b/lib/auth/constants.ts @@ -16,6 +16,7 @@ import { GetPrivateCommonServices, UpdatePrivateUserAbilities, GetPrivateCommonAbilities, + GetPrivateAbilities, } from '@controller'; export const GetSession = async ({ cookies = '' }) => { @@ -36,6 +37,8 @@ export const GetSession = async ({ cookies = '' }) => { } }; +// to-do: admin sanitizer + // schema sanitizer const allUsersSideEffects = async ({ user }: any) => { const services = await GetPrivateCommonServices({}); @@ -43,8 +46,15 @@ const allUsersSideEffects = async ({ user }: any) => { const commonServices = services.map((service) => service?.id).map((el) => el); const commonAbilities = abilities.map((ability) => ability?.id).map((el) => el); + const [dpcpAbility] = await GetPrivateAbilities({ id: '66c6859aa06abeda1c830c56' }); + console.log({ dpcpAbility }); + await UpdatePrivateUserServices({ user, services: [...commonServices, ...user.servicesIds], upsert: false }); - await UpdatePrivateUserAbilities({ user, abilities: [...commonAbilities, ...user.abilitiesIds], upsert: false }); + await UpdatePrivateUserAbilities({ + user, + abilities: [...commonAbilities, ...user.abilitiesIds, dpcpAbility.id], + upsert: false, + }); }; export const providers: any[] = [ diff --git a/lib/model/interfaces/get-private-abilities.ts b/lib/model/interfaces/get-private-abilities.ts index 08bc2029..5be76461 100644 --- a/lib/model/interfaces/get-private-abilities.ts +++ b/lib/model/interfaces/get-private-abilities.ts @@ -9,6 +9,9 @@ const getPrivateAbilities = async ({ name, locale = 'es', user, + type, + target, + action, page = 0, offset = 0, limit = PAGE_SIZE, @@ -18,8 +21,16 @@ const getPrivateAbilities = async ({ const adaptQuery: any = { where: { - id, - name: { [locale]: name }, + OR: [ + { + id, + }, + { + type, + target, + action, + }, + ], }, skip: page * (limit + offset), take: limit, @@ -59,6 +70,7 @@ const getPrivateAbilities = async ({ } const response = await PrivatePrisma.abilities.findMany(adaptQuery); + console.log({ abilitiesMatched: response }); return response; }; diff --git a/lib/model/interfaces/get-private-services.ts b/lib/model/interfaces/get-private-services.ts index f6d75990..8544a808 100644 --- a/lib/model/interfaces/get-private-services.ts +++ b/lib/model/interfaces/get-private-services.ts @@ -1,39 +1,30 @@ // @controller/get-private-services.ts import { PrivatePrisma } from '@model'; -import { whoAmI } from '@controller'; +import { whoAmI, canI } from '@controller'; const PAGE_SIZE = 100; -const getPrivateServices = async ({ - id, - name, - locale = 'es', - user, - target, - page = 0, - offset = 0, - limit = PAGE_SIZE, - filters = [], -}: any) => { +const getPrivateServices = async ({ id, user, target, page = 0, offset = 0, limit = PAGE_SIZE, filters = [] }: any) => { const loggedUser = user || (await whoAmI({})); const adaptQuery: any = { where: { id, - slug: name, + slug: target, }, skip: page * (limit + offset), take: limit, cacheStrategy: { ttl: 90 }, }; - if ((await canI({ type: 'R', action: 'view-listings', target, user: loggedUser })) && type === 'id') { + if (await canI({ type: 'R', action: 'view-listings', target, user: loggedUser })) { if (filters?.length) { + // to-do: add common services filter queries later, e.g. ACTIVE services, Updatable Services, etc. try { const supportedQueries: Record = { user: { query: { - OR: [{ id: { in: loggedUser?.servicesIds }, name: { [locale]: name } }, { userOwner: loggedUser?.id }], + OR: [{ id: { in: loggedUser?.servicesIds } }, { slug: name }, { userOwner: loggedUser?.id }], }, }, // group: { @@ -60,28 +51,11 @@ const getPrivateServices = async ({ } } - const swapUserData = loggedUser.favorites.filter((listing: string) => !listings.includes(listing)); - const payload = upsert - ? { - favoritesIds: [...swapUserData, ...delta], - } - : { - favoritesIds: listings, - }; - const adaptQuery: any = { - where: { - email: loggedUser.email, - }, - data: payload, - }; - - const response = await PrivatePrisma.user.update(adaptQuery); + const response = await PrivatePrisma.services.findMany(adaptQuery); return response; + } else { + throw new Error(`403: Not authorized.`); } - - const response = await PrivatePrisma.services.findMany(adaptQuery); - - return response; }; export default getPrivateServices; diff --git a/lib/model/interfaces/middleware/authorization.ts b/lib/model/interfaces/middleware/authorization.ts index c177a31b..8132ea70 100644 --- a/lib/model/interfaces/middleware/authorization.ts +++ b/lib/model/interfaces/middleware/authorization.ts @@ -4,9 +4,11 @@ import { GetPrivateAbilities } from '@controller'; import { cookies as nextCookies } from 'next/headers'; export const canI = async ({ type, target, action, user }: any) => { try { - const ability = await GetPrivateAbilities({ type, target, action }); + console.log({ type, target, action, user }); + const abilities = await GetPrivateAbilities({ type, target, action }); // to-do add authorization/validation checks - const yes = user?.abilities?.includes(ability[0]?.id); + const yes = abilities?.some((ability) => user?.abilities.includes(ability.id)); + console.log({ abilities, userAbilities: user.abilities, yes }); // return the capacity return yes; } catch (e) { diff --git a/prisma/schema-private.prisma b/prisma/schema-private.prisma index 0d86c905..6f78f123 100644 --- a/prisma/schema-private.prisma +++ b/prisma/schema-private.prisma @@ -370,7 +370,7 @@ model Roles { model Services { id String @id @default(auto()) @map("_id") @db.ObjectId name ILocaleString - slug String + slug String? status EServiceStatus type EServiceType nature EServiceNature @@ -432,8 +432,8 @@ model Abilities { status EAbilityStatus type EAbilityType nature EAbilityNature - target String - action String + target String? + action String? features Features[] @relation("featureAbilities", fields: [featuresIds], references: [id]) featuresIds String[] @db.ObjectId diff --git a/src/app/api/v1/services/dpcp-vibemodulator/route.ts b/src/app/api/v1/services/dpcp-vibemodulator/route.ts index f0010c30..e4e80518 100644 --- a/src/app/api/v1/services/dpcp-vibemodulator/route.ts +++ b/src/app/api/v1/services/dpcp-vibemodulator/route.ts @@ -2,7 +2,8 @@ import type { NextApiRequest } from 'next'; import type { NextRequest } from 'next/server'; import { NextResponse } from 'next/server'; -import { GetPublicListings } from '@controller'; +import { GetPrivateServices } from '@controller'; +import { GetSession } from '@auth'; type CombineRequest = NextRequest & NextApiRequest; const generateErrorResponse = (e: any, status: number) => { @@ -21,6 +22,10 @@ export async function GET(request: CombineRequest) { cache: request.headers.get('cache-control'), }); try { + const cookies = request?.cookies || request?.headers.get('cookies'); + const session = await GetSession({ cookies: cookies || '' }); + const user = session?.user; + console.log('handler', { session, user }); const url = new URL(request.url); const query = url.searchParams; @@ -35,14 +40,16 @@ export async function GET(request: CombineRequest) { const coercedLimit = Number(limit ? (Array.isArray(limit) ? limit[0] : limit) : 100); const coercedOffset = Number(offset ? (Array.isArray(offset) ? offset[0] : offset) : 0); - const data = await GetPublicListings({ + const data = await GetPrivateServices({ + user, + target: 'dpcp-vibemodulator', page: coercedPage, limit: coercedLimit, offset: coercedOffset, filters: filterArray, }); - console.log({ headers: request.headers }); + console.log({ data, headers: request.headers }); return NextResponse.json( { From 44e934de3dce96259340f3a547535841afe94de0 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Thu, 22 Aug 2024 02:27:09 +0100 Subject: [PATCH 04/18] ar(feat) [DPCP-40]: Parse Services. --- lib/auth/constants.ts | 8 +++----- lib/model/interfaces/get-private-abilities.ts | 1 - lib/model/interfaces/middleware/authorization.ts | 3 --- .../interfaces/update-private-user-favorite-listings.ts | 2 -- src/app/api/v1/auth/callback/apple/route.ts | 1 - 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/lib/auth/constants.ts b/lib/auth/constants.ts index 86aea4f2..c9808c47 100644 --- a/lib/auth/constants.ts +++ b/lib/auth/constants.ts @@ -30,7 +30,6 @@ export const GetSession = async ({ cookies = '' }) => { }, }); const session = await response.json(); - console.log({ cookies, session }); return session; } catch (e) { console.error(e); @@ -46,8 +45,7 @@ const allUsersSideEffects = async ({ user }: any) => { const commonServices = services.map((service) => service?.id).map((el) => el); const commonAbilities = abilities.map((ability) => ability?.id).map((el) => el); - const [dpcpAbility] = await GetPrivateAbilities({ id: '66c6859aa06abeda1c830c56' }); - console.log({ dpcpAbility }); + const [dpcpAbility] = await GetPrivateAbilities({ type: 'R', target: 'dpcp-vibemodulator', action: 'view-listings' }); await UpdatePrivateUserServices({ user, services: [...commonServices, ...user.servicesIds], upsert: false }); await UpdatePrivateUserAbilities({ @@ -148,7 +146,7 @@ export const authConfig = { return true; }, async redirect() { - return `${process.env.MAIN_URL}/dash`; + return `${process.env.MAIN_URL}/dash/signin`; }, // async jwt({ user, token }) { // if (user) { @@ -204,7 +202,7 @@ export const authConfig = { trustHost: true, pages: { signIn: '/dash/signin', - signOut: '/', + signOut: '/dash/signin', error: '/dash/error', // Error code passed in query string as ?error= verifyRequest: '/dash/verify', // (used for check email message) // newUser: '/' // New users will be directed here on first sign in (leave the property out if not of interest) diff --git a/lib/model/interfaces/get-private-abilities.ts b/lib/model/interfaces/get-private-abilities.ts index 5be76461..4fd47d25 100644 --- a/lib/model/interfaces/get-private-abilities.ts +++ b/lib/model/interfaces/get-private-abilities.ts @@ -70,7 +70,6 @@ const getPrivateAbilities = async ({ } const response = await PrivatePrisma.abilities.findMany(adaptQuery); - console.log({ abilitiesMatched: response }); return response; }; diff --git a/lib/model/interfaces/middleware/authorization.ts b/lib/model/interfaces/middleware/authorization.ts index 8132ea70..6fe9083b 100644 --- a/lib/model/interfaces/middleware/authorization.ts +++ b/lib/model/interfaces/middleware/authorization.ts @@ -4,11 +4,9 @@ import { GetPrivateAbilities } from '@controller'; import { cookies as nextCookies } from 'next/headers'; export const canI = async ({ type, target, action, user }: any) => { try { - console.log({ type, target, action, user }); const abilities = await GetPrivateAbilities({ type, target, action }); // to-do add authorization/validation checks const yes = abilities?.some((ability) => user?.abilities.includes(ability.id)); - console.log({ abilities, userAbilities: user.abilities, yes }); // return the capacity return yes; } catch (e) { @@ -20,7 +18,6 @@ export const whoAmI = async ({ cookies }: any) => { const cookieString = nextCookies().getAll().toString(); const session = (await getSession()) || (await GetSession({ cookies: cookieString || cookies })); // to-do add authorization/validation checks - console.log({ cookieString, session }); return session?.user; } catch (e) { throw new Error(`Code 007: Can't identify user ${e}`); diff --git a/lib/model/interfaces/update-private-user-favorite-listings.ts b/lib/model/interfaces/update-private-user-favorite-listings.ts index e360d878..239c07ad 100644 --- a/lib/model/interfaces/update-private-user-favorite-listings.ts +++ b/lib/model/interfaces/update-private-user-favorite-listings.ts @@ -9,8 +9,6 @@ const updatePrivateUserFavoriteListings = async ({ upsert = true, user, target, const loggedUser = user || (await whoAmI({})); - console.log({ user, loggedUser }); - const delta = upsert ? listings.filter((listing: any) => !loggedUser?.favorites?.includes(listing)) : []; if ((await canI({ type: 'U', action: 'favorite', target, user: loggedUser })) && type === 'id') { diff --git a/src/app/api/v1/auth/callback/apple/route.ts b/src/app/api/v1/auth/callback/apple/route.ts index d66820ae..1b9e973f 100644 --- a/src/app/api/v1/auth/callback/apple/route.ts +++ b/src/app/api/v1/auth/callback/apple/route.ts @@ -30,7 +30,6 @@ export async function POST(req: NextRequest) { secure: true, }); response.headers.set('Cookie', response.cookies.toString()); - console.log({ pkce, response, to: req.nextUrl.pathname }); } // const cookies = req.headers.get('Cookie') || req.cookies.toString() || ''; From ac0a26a0fbfc93bbad6dbef9d8422ba026f90631 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Thu, 22 Aug 2024 02:32:50 +0100 Subject: [PATCH 05/18] ar(feat) [DPCP-40]: Parse Services. --- src/app/api/v1/services/dpcp-vibemodulator/route.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/app/api/v1/services/dpcp-vibemodulator/route.ts b/src/app/api/v1/services/dpcp-vibemodulator/route.ts index e4e80518..1c7e670b 100644 --- a/src/app/api/v1/services/dpcp-vibemodulator/route.ts +++ b/src/app/api/v1/services/dpcp-vibemodulator/route.ts @@ -25,7 +25,7 @@ export async function GET(request: CombineRequest) { const cookies = request?.cookies || request?.headers.get('cookies'); const session = await GetSession({ cookies: cookies || '' }); const user = session?.user; - console.log('handler', { session, user }); + const url = new URL(request.url); const query = url.searchParams; @@ -49,8 +49,6 @@ export async function GET(request: CombineRequest) { filters: filterArray, }); - console.log({ data, headers: request.headers }); - return NextResponse.json( { ok: true, From 897a9c6985aa517ac2feade110f7237174bddec3 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Thu, 22 Aug 2024 02:33:34 +0100 Subject: [PATCH 06/18] ar(feat) [DPCP-40]: Parse Services. --- src/app/api/v1/services/dpcp-vibemodulator/route.ts | 5 ----- src/app/api/v1/services/rickmorty/route.ts | 7 ------- 2 files changed, 12 deletions(-) diff --git a/src/app/api/v1/services/dpcp-vibemodulator/route.ts b/src/app/api/v1/services/dpcp-vibemodulator/route.ts index 1c7e670b..151a2617 100644 --- a/src/app/api/v1/services/dpcp-vibemodulator/route.ts +++ b/src/app/api/v1/services/dpcp-vibemodulator/route.ts @@ -16,11 +16,6 @@ const generateErrorResponse = (e: any, status: number) => { // export const dynamic = 'force-static'; export async function GET(request: CombineRequest) { - console.log({ - request: request.cookies, - requestOrigin: request.headers.get('x-forwarded-host'), - cache: request.headers.get('cache-control'), - }); try { const cookies = request?.cookies || request?.headers.get('cookies'); const session = await GetSession({ cookies: cookies || '' }); diff --git a/src/app/api/v1/services/rickmorty/route.ts b/src/app/api/v1/services/rickmorty/route.ts index a5bcbecc..30bccadc 100644 --- a/src/app/api/v1/services/rickmorty/route.ts +++ b/src/app/api/v1/services/rickmorty/route.ts @@ -15,11 +15,6 @@ const generateErrorResponse = (e: any, status: number) => { // export const dynamic = 'force-static'; export async function GET(request: CombineRequest) { - console.log({ - request: request.cookies, - requestOrigin: request.headers.get('x-forwarded-host'), - cache: request.headers.get('cache-control'), - }); try { const url = new URL(request.url); const query = url.searchParams; @@ -42,8 +37,6 @@ export async function GET(request: CombineRequest) { filters: filterArray, }); - console.log({ headers: request.headers }); - return NextResponse.json( { ok: true, From db7ee218b02a4d95ad897edd3774d0b05cdd3cc1 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sat, 24 Aug 2024 02:33:56 +0100 Subject: [PATCH 07/18] ar(feat) [DPCP-40]: Parse Services. --- prisma/schema-private.prisma | 4 + prisma/seed.mts | 612 ++++++++++++++++++++++++++++++++++- 2 files changed, 601 insertions(+), 15 deletions(-) diff --git a/prisma/schema-private.prisma b/prisma/schema-private.prisma index 6f78f123..46fd02e3 100644 --- a/prisma/schema-private.prisma +++ b/prisma/schema-private.prisma @@ -352,6 +352,7 @@ model Messages { model Roles { id String @id @default(auto()) @map("_id") @db.ObjectId name ILocaleString + slug String? status ERoleStatus type ERoleType nature ERoleNature @@ -401,6 +402,7 @@ model Services { model Features { id String @id @default(auto()) @map("_id") @db.ObjectId name ILocaleString + slug String? status EFeatureStatus type EFeatureType nature EFeatureNature @@ -429,6 +431,7 @@ model Features { model Abilities { id String @id @default(auto()) @map("_id") @db.ObjectId name ILocaleString + slug String? status EAbilityStatus type EAbilityType nature EAbilityNature @@ -888,6 +891,7 @@ enum EAbilityStatus { enum EAbilityNature { ROLE_BASED + BILLING_BASED PRIVILEGE COMMON TEMPORARY diff --git a/prisma/seed.mts b/prisma/seed.mts index 2890fa67..2787fcac 100644 --- a/prisma/seed.mts +++ b/prisma/seed.mts @@ -36,6 +36,596 @@ if (seedType === 'private') { datasourceUrl: process.env.PRISMA_PRIVATE_URI, }); + const main = async () => { + try { + // await pvtPrisma.products.deleteMany(); + + // // cleanup the existing database + const allProperties = Reflect.ownKeys(Object.getPrototypeOf(pvtPrisma)); + const modelNames = allProperties.filter( + (x) => x != 'constructor' && x != 'on' && x != 'connect' && x != 'runDisconnect' && x != 'disconnect', + ); + + // if (modelNames.length > 0) { + // console.log("WARNING! ERASING DB.") + // cleanupDatabase() + // console.log("~ ERASED ~") + // } + + /* + ~~~~ PRIVATE ~~~~ + */ + + // user0 + const user0 = await pvtPrisma.user.create({ data: mockUser }); + + // community0 + const community0 = await pvtPrisma.communities.create({ data: mockCommunity }); + + // roles + const role1name = { + en: 'Superuser', + it: 'Superutente', + pt: 'Superusuário', + es: 'Superusuario', + de: 'Superbenutzer', + fr: 'Superutilisateur', + ro: 'Superutilizator', + cz: 'Superuživatel', + pl: 'Superużytkownik', + et: 'Superkasutaja', + sv: 'Superanvändare', + ja: 'スーパーユーザー', + ru: 'Суперпользователь', + ar: 'المستخدم الخارق', + he: 'משתמש מרשים', + zh: '超级用户', + nl: 'Supergebruiker', + da: 'Superbruger', + hu: 'Szuperfelhasználó', + ca: 'Superusuari', + eu: 'Supererabiltzaile', + gl: 'Superusuario', + sw: 'Mtumiaji Mkuu', + hi: 'सुपरउपयोगकर्ता', + ms: 'Superpengguna', + bn: 'সুপার ব্যবহারকারী', + pa: 'ਸੁਪਰਯੂਜ਼ਰ', + tr: 'Süper Kullanıcı', + fi: 'Superkäyttäjä', + el: 'Σούπερχρήστης', + uk: 'Суперкористувач', + }; + + const role2name = { + en: 'Admin', + it: 'Amministratore', + pt: 'Admin', + es: 'Administrador', + de: 'Administrator', + fr: 'Administrateur', + ro: 'Administrator', + cz: 'Správce', + pl: 'Administrator', + et: 'Administraator', + sv: 'Administratör', + ja: '管理者', + ru: 'Администратор', + ar: 'مدير', + he: 'מנהל', + zh: '管理员', + nl: 'Beheerder', + da: 'Administrator', + hu: 'Adminisztrátor', + ca: 'Administrador', + eu: 'Administratzaile', + gl: 'Administrador', + sw: 'Msimamizi', + hi: 'प्रशासक', + ms: 'Pentadbir', + bn: 'প্রশাসক', + pa: 'ਐਡਮਿਨ', + tr: 'Yönetici', + fi: 'Ylläpitäjä', + el: 'Διαχειριστής', + uk: 'Адміністратор', + }; + + const role3name = { + en: 'Manager', + it: 'Manager', + pt: 'Gerente', + es: 'Gerente', + de: 'Manager', + fr: 'Manager', + ro: 'Manager', + cz: 'Manažer', + pl: 'Menedżer', + et: 'Juht', + sv: 'Chef', + ja: 'マネージャー', + ru: 'Менеджер', + ar: 'مدير', + he: 'מנהל', + zh: '经理', + nl: 'Manager', + da: 'Manager', + hu: 'Menedzser', + ca: 'Gerent', + eu: 'Kudeatzaile', + gl: 'Xestor', + sw: 'Meneja', + hi: 'प्रबंधक', + ms: 'Pengurus', + bn: 'ম্যানেজার', + pa: 'ਮੈਨੇਜਰ', + tr: 'Yönetici', + fi: 'Johtaja', + el: 'Διευθυντής', + uk: 'Менеджер', + }; + + const role4name = { + en: 'User', + it: 'Utente', + pt: 'Usuário', + es: 'Usuario', + de: 'Benutzer', + fr: 'Utilisateur', + ro: 'Utilizator', + cz: 'Uživatel', + pl: 'Użytkownik', + et: 'Kasutaja', + sv: 'Användare', + ja: 'ユーザー', + ru: 'Пользователь', + ar: 'مستخدم', + he: 'משתמש', + zh: '用户', + nl: 'Gebruiker', + da: 'Bruger', + hu: 'Felhasználó', + ca: 'Usuari', + eu: 'Erabiltzaile', + gl: 'Usuario', + sw: 'Mtumiaji', + hi: 'उपयोगकर्ता', + ms: 'Pengguna', + bn: 'ব্যবহারকারী', + pa: 'ਵਰਤੋਂਕਾਰ', + tr: 'Kullanıcı', + fi: 'Käyttäjä', + el: 'Χρήστης', + uk: 'Користувач', + }; + + const role1 = await pvtPrisma.roles.create({ + data: createMockRole({ + name: role1name, + slug: 'role-su', + user: user0.id, + community: community0.id, + refUsers: [], + refCommunities: [], + }), + }); + const role2 = await pvtPrisma.roles.create({ + data: createMockRole({ + name: role2name, + slug: 'role-admin', + user: user0.id, + community: community0.id, + refUsers: [], + refCommunities: [], + }), + }); + const role3 = await pvtPrisma.roles.create({ + data: createMockRole({ + name: role3name, + slug: 'role-manager', + user: user0.id, + community: community0.id, + refUsers: [], + refCommunities: [], + }), + }); + const role4 = await pvtPrisma.roles.create({ + data: createMockRole({ + name: role4name, + slug: 'role-user', + user: user0.id, + community: community0.id, + refUsers: [], + refCommunities: [], + }), + }); + + // abilities + const favoriteListings = { + en: 'Favorite Listings', + it: 'Aggiungi ai Preferiti', + pt: 'Favoritar Listagens', + es: 'Marcar como Favorito', + de: 'Anzeigen favorisieren', + fr: 'Mettre en Favori', + ro: 'Favoritează liste', + cz: 'Oblíbené inzeráty', + pl: 'Dodaj do Ulubionych', + et: 'Lisa lemmikutesse', + sv: 'Gör till Favoriter', + ja: 'お気に入りにする', + ru: 'Добавить в Избранное', + ar: 'القوائم المفضلة', + he: 'הוסף למועדפים', + zh: '收藏清单', + nl: 'Favoriete vermeldingen', + da: 'Favoritlister', + hu: 'Kedvenc hirdetések', + ca: 'Afegir a Preferits', + eu: 'Gehitu Gogokoenetara', + gl: 'Engadir a Favoritos', + sw: 'Orodhesha Pendwa', + hi: 'पसंदीदा सूची', + ms: 'Senarai Kegemaran', + bn: 'পছন্দের তালিকা', + pa: 'ਪਸੰਦੀਦਾ ਸੂਚੀਆਂ', + tr: 'Favori İlanlar', + fi: 'Suosikkiluettelot', + el: 'Αγαπημένες καταχωρήσεις', + uk: 'Обрані оголошення', + }; + + const ability2name = { + en: 'View Listings', + it: 'Visualizza inserzioni', + pt: 'Ver listagens', + es: 'Ver listados', + de: 'Anzeigen anzeigen', + fr: 'Voir les annonces', + ro: 'Vizualizare liste', + cz: 'Zobrazit inzeráty', + pl: 'Wyświetl oferty', + et: 'Vaata kuulutusi', + sv: 'Visa listor', + ja: 'リストを表示する', + ru: 'Просмотр объявлений', + ar: 'عرض القوائم', + he: 'הצג רשימות', + zh: '查看列表', + nl: 'Bekijk aanbiedingen', + da: 'Se lister', + hu: 'Listázások megtekintése', + ca: 'Veure llistats', + eu: 'Eman ikuspegiak', + gl: 'Ver listados', + sw: 'Tazama Orodha', + hi: 'लिस्टिंग देखें', + ms: 'Lihat Senarai', + bn: 'লিস্টিং দেখুন', + pa: 'ਲਿਸਟਿੰਗ ਵੇਖੋ', + tr: 'İlanları Görüntüle', + fi: 'Näytä ilmoitukset', + el: 'Προβολή καταχωρήσεων', + uk: 'Переглянути оголошення', + }; + + const ability1 = await pvtPrisma.abilities.create({ + data: createMockAbility({ + name: ability2name, + user: user0.id, + slug: 'abil-view-rm', + community: community0.id, + type: 'R', + action: 'view-listings', + nature: 'COMMON', + target: 'rickmorty', + roles: [{ id: role1.id }, { id: role2.id }], + refUsers: [{ id: user0.id }], + refCommunities: [{ id: community0.id }], + }), + }); + + const ability2 = await pvtPrisma.abilities.create({ + data: createMockAbility({ + name: ability2name, + user: user0.id, + slug: 'abil-view-vm', + type: 'R', + action: 'view-listings', + nature: 'PRIVILEGE', + target: 'dpcp-vibemodulator', + community: community0.id, + roles: [{ id: role1.id }], + refUsers: [{ id: user0.id }], + refCommunities: [{ id: community0.id }], + }), + }); + + const ability3 = await pvtPrisma.abilities.create({ + data: createMockAbility({ + name: ability1name, + user: user0.id, + slug: 'abil-favorite-rm', + type: 'U', + action: 'favorite', + nature: 'COMMON', + target: 'rickmorty', + community: community0.id, + roles: [{ id: role1.id }], + refUsers: [{ id: user0.id }], + refCommunities: [{ id: community0.id }], + }), + }); + + // // features + const feature1name = { + en: 'Favoriting of entries', + it: 'Aggiunta ai preferiti delle voci', + pt: 'Favoritar entradas', + es: 'Marcar entradas como favoritas', + de: 'Einträge favorisieren', + fr: 'Mise en favori des entrées', + ro: 'Adăugarea la favorite a intrărilor', + cz: 'Přidání záznamů do oblíbených', + pl: 'Dodawanie wpisów do ulubionych', + et: 'Kirjete lemmikuks märkimine', + sv: 'Favoritmarkera poster', + ja: 'エントリーのお気に入り登録', + ru: 'Добавление в избранное записей', + ar: 'تحديد الإدخالات كمفضلة', + he: 'הוספת כתבות למועדפים', + zh: '添加收藏条目', + nl: 'Toevoegen van items aan favorieten', + da: 'Tilføjelse af emner til favoritter', + hu: 'Bejegyzések kedvencekké nyilvánítása', + ca: 'Afavorir entrades', + eu: 'Sarrera gehitzea gogokoak direla', + gl: 'Engadido de entradas a favoritos', + sw: 'Kupendezesha vya kuingia', + hi: 'प्रविष्टियों को पसंदीदा बनाना', + ms: 'Menanda buku entri', + bn: 'এন্ট্রিগুলিকে পছন্দমূলক করা', + pa: 'ਇੰਟਰੀਆਂ ਨੂੰ ਪਸੰਦੀਦਾ ਬਣਾਉਣਾ', + tr: 'Girişleri favorilere ekleme', + fi: 'Merkintöjen suosiminen', + el: 'Προτίμηση καταχωρήσεων', + uk: 'Додавання записів до обраного', + }; + + const feature1 = await pvtPrisma.features.create({ + data: createMockFeature({ + name: feature1name, + slug: 'feat-favorite-entries', + user: user0.id, + community: community0.id, + abilities: [{ id: ability1.id }], + refUsers: [{ id: user0.id }], + refCommunities: [{ id: community0.id }], + }), + }); + + // // services + const service1name = { + en: 'The Rick Morty Experience', + it: "L'esperienza di Rick Morty", + pt: 'A Experiência Rick Morty', + es: 'La Experiencia Rick Morty', + de: 'Das Rick Morty Erlebnis', + fr: "L'expérience Rick Morty", + ro: 'Experiența Rick Morty', + cz: 'Rick Morty Zážitek', + pl: 'Doświadczenie Rick Morty', + et: 'Rick Morty Kogemus', + sv: 'Rick Morty-upplevelsen', + ja: 'リック・モーティ体験', + ru: 'Опыт Рика и Морти', + ar: 'تجربة ريك مورتي', + he: 'חוויית ריק מורטי', + zh: '瑞克莫蒂体验', + nl: 'De Rick Morty-ervaring', + da: 'Rick Morty Oplevelsen', + hu: 'A Rick és Morty Élménye', + ca: "L'experiència Rick Morty", + eu: 'The Rick Morty Esperientzia', + gl: 'A Experiencia Rick Morty', + sw: 'Uzoefu wa Rick Morty', + hi: 'रिक मोर्टी अनुभव', + ms: 'Pengalaman Rick Morty', + bn: 'রিক এবং মর্টি অভিজ্ঞতা', + pa: 'ਰਿਕ ਮੋਰਟੀ ਦਾ ਅਨੁਭਵ', + tr: 'Rick Morty Deneyimi', + fi: 'Rick Morty Kokemus', + el: 'Η Εμπειρία Rick Morty', + uk: 'Досвід Ріка і Морті', + }; + + const service2name = { + en: 'The Vibe Modulator', + it: 'Il Modulatore di Vibrazioni', + pt: 'O Modulador de Vibração', + es: 'El Modulador de Vibra', + de: 'Der Vibe-Modulator', + fr: 'Le Modulateur de Vibration', + ro: 'Modulatorul de Vibrații', + cz: 'Vibrační Modulátor', + pl: 'Modulator Nastroju', + et: 'Vibe Modulaator', + sv: 'Vibe-modulatorn', + ja: 'バイブモジュレーター', + ru: 'Вибромодулятор', + ar: 'معدل الجو', + he: 'מייסד הוייב', + zh: '振动调制器', + nl: 'De Vibe Modulator', + da: 'Vibe-modulatoren', + hu: 'Vibe modulátor', + ca: 'El Modulador de Vibra', + eu: 'The Vibe Modulator', + gl: 'O Modulador de Vibration', + sw: 'Mbadala wa Vibe', + hi: 'द वाइब मॉड्यूलेटर', + ms: 'Modulator Getaran', + bn: 'দ্য ভাইব মড্যুলেটর', + pa: 'ਵਾਇਬ ਮੋਡੂਲੇਟਰ', + tr: 'Vibe Modülatör', + fi: 'Vibe-modulaattori', + el: 'Ο Μετατροπέας Δόνησης', + uk: 'Вібромодулятор', + }; + + const service1 = await pvtPrisma.services.create({ + data: createMockService({ + name: service1name, + slug: 'rickmorty', + user: user0.id, + community: community0.id, + features: [{ id: feature1.id }], + refUsers: [{ id: user0.id }], + refCommunities: [{ id: community0.id }], + }), + }); + const service2 = await pvtPrisma.services.create({ + data: createMockService({ + name: service2name, + slug: 'dpcp-vibemodulator', + user: user0.id, + community: community0.id, + refUsers: [{ id: user0.id }], + refCommunities: [{ id: community0.id }], + }), + }); + + console.log(`Private Database has been seeded. 🌱`); + } catch (error) { + throw error; + } + }; + func = main; +} else if (seedType === 'public') { + console.log('~ SEEDING PUBLIC DB ~'); + + const pvtPrisma = new PrivatePrisma({ + datasourceUrl: process.env.PRISMA_PRIVATE_URI, + }); + + const pubPrisma = new PublicPrisma({ + datasourceUrl: process.env.PRISMA_PUBLIC_URI, + }); + + const main = async () => { + try { + // await pvtPrisma.products.deleteMany(); + + // // cleanup the existing database + const allProperties = Reflect.ownKeys(Object.getPrototypeOf(pubPrisma)); + const modelNames = allProperties.filter( + (x) => x != 'constructor' && x != 'on' && x != 'connect' && x != 'runDisconnect' && x != 'disconnect', + ); + + // if (modelNames.length > 0) { + // console.log("WARNING! ERASING DB.") + // cleanupDatabase() + // console.log("~ ERASED ~") + // } + + /* + ~~~~ PUBLIC ~~~~ + */ + + const facadeEntry = (fields: string[], facades: Record) => (entry: any) => { + const facader = fields.reduce((fac, field, index) => { + let content = entry[field]; + if (facades && facades[field]) { + content = facades[field](content); + } + fac[field] = content; + return fac; + }, {}); + + return facader; + }; + + const facadeTaxonomy = facadeEntry(['id', 'name', 'description', 'status', 'type', 'nature', 'audiencesIds']); + + // const decorateAd = facadeEntry([ + // 'userFits', + // 'communityFits', + // ]); + + const facadeMessage = facadeEntry([ + 'id', + 'name', + 'description', + 'status', + 'type', + 'nature', + 'title', + 'body', + 'queuedOn', + 'scheduledOn', + 'sentOn', + ]); + + const facadeUser = facadeEntry(['id', 'image', 'firstName']); + + const facadeCommunity = facadeEntry(['id', 'image', 'name', 'urls', 'status']); + + const getSeedData = () => { + try { + const data = JSON.parse(fs.readFileSync('stub.json')); + return data; + } catch (e) { + execSync('npm run schema:seed:getseeds'); + return { retry: true }; + } + }; + + let data = getSeedData(); + + if (data?.retry) { + data = getSeedData(); + } + + const { community, user, model, term } = data; + + const pubListing1 = await pubPrisma.publicListings.create({ + data: createMockPubListing({ + community: facadeCommunity(community), + user: facadeUser(user), + taxonomies: [facadeTaxonomy(term)], + }), + }); + + const pubListing2 = await pubPrisma.publicListings.create({ + data: createMockPubListing({ + community: facadeCommunity(community), + user: facadeUser(user), + taxonomies: [facadeTaxonomy(term)], + }), + }); + + const pubListing3 = await pubPrisma.publicListings.create({ + data: createMockPubListing({ + community: facadeCommunity(community), + user: facadeUser(user), + taxonomies: [facadeTaxonomy(term)], + }), + }); + + console.log(`Public Database has been seeded. 🌱`); + } catch (error) { + throw error; + } + }; + func = main; +} else if (seedType === 'mock') { + console.log('~ SEEDIND DBS WITH MOCK DATA ~'); + console.log('~ SEEDING PRIVATE DB WITH MOCK DATA ~'); + + const pvtPrisma = new PrivatePrisma({ + datasourceUrl: process.env.PRISMA_PRIVATE_URI, + }); + const main = async () => { try { // await pvtPrisma.products.deleteMany(); @@ -307,25 +897,16 @@ if (seedType === 'private') { }), }); - console.log(`Private Database has been seeded. 🌱`); + console.log(`Private Database has been seeded with mock data. 🌱`); } catch (error) { throw error; } - }; - func = main; -} else { - console.log('~ SEEDING PUBLIC DB ~'); - - const pvtPrisma = new PrivatePrisma({ - datasourceUrl: process.env.PRISMA_PRIVATE_URI, - }); - - const pubPrisma = new PublicPrisma({ - datasourceUrl: process.env.PRISMA_PUBLIC_URI, - }); - - const main = async () => { try { + console.log('~ SEEDING PUBLIC DB WITH MOCK DATA ~'); + + const pubPrisma = new PublicPrisma({ + datasourceUrl: process.env.PRISMA_PUBLIC_URI, + }); // await pvtPrisma.products.deleteMany(); // // cleanup the existing database @@ -429,6 +1010,7 @@ if (seedType === 'private') { throw error; } }; + func = main; } From 65d715adb2aa91406881798da74f2fd3d7cf20e7 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 02:24:33 +0100 Subject: [PATCH 08/18] ar(feat) [DPCP-40]: Parse Services. --- package.json | 9 +- prisma/mock/communities.mts | 30 ++-- prisma/mock/listings.mts | 6 +- prisma/mock/public.mts | 72 ++++++++- prisma/mock/user.mts | 35 ++-- prisma/schema-private.prisma | 14 ++ prisma/schema-public.prisma | 16 ++ prisma/seed.mts | 302 +++++++++++------------------------ 8 files changed, 236 insertions(+), 248 deletions(-) diff --git a/package.json b/package.json index 5df9de62..c4d42a43 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,11 @@ "schema:pull:public": "npx prisma db pull --schema prisma/schema-public.prisma", "schema:push:all": "npm run schema:push:private && npm run schema:push:public", "schema:pull:all": "npm run schema:pull:private && npm run schema:pull:public", - "schema:seed:private": "npm run schema:generate:private && prisma db seed --schema=./prisma/schema-private.prisma -- private", - "schema:seed:getseeds": "npm run schema:generate:private && node --loader ts-node/esm prisma/getSeeds.mts --schema=./prisma/schema-private.prisma -- private", - "schema:seed:public": "npm run schema:generate:public && prisma db seed --schema=./prisma/schema-public.prisma -- public", - "schema:seed:all": "npm run schema:seed:private && npm run schema:seed:public", + "schema:seed:private": "NEXUS_STANDALONE=true npm run schema:generate:private:standalone && prisma db seed --schema=./prisma/schema-private.prisma -- private", + "schema:seed:getseeds": "NEXUS_STANDALONE=true npm run schema:generate:private:standalone && node --loader ts-node/esm prisma/getSeeds.mts --schema=./prisma/schema-private.prisma -- private", + "schema:seed:public": "NEXUS_STANDALONE=true npm run schema:generate:private:standalone && npm run schema:generate:public:standalone && prisma db seed --schema=./prisma/schema-public.prisma -- public", + "schema:seed:mock": "NEXUS_STANDALONE=true npm run schema:generate:private:standalone && npm run schema:generate:public:standalone && prisma db seed --schema=./prisma/schema-public.prisma -- mock", + "schema:seed:all": "NEXUS_STANDALONE=true npm run schema:seed:private:standalone && npm run schema:seed:public:standalone", "schema:generate:private": "npx prisma generate --no-engine --schema=./prisma/schema-private.prisma", "schema:generate:public": "npx prisma generate --no-engine --schema=./prisma/schema-public.prisma", "schema:generate:all": "npm run schema:generate:private && npm run schema:generate:public", diff --git a/prisma/mock/communities.mts b/prisma/mock/communities.mts index 94b302a8..555e287d 100644 --- a/prisma/mock/communities.mts +++ b/prisma/mock/communities.mts @@ -5,18 +5,20 @@ import { createMockListing } from './listings.mts'; import { createMockMessage } from './messages.mts'; import { createMockTerm } from './taxonomies.mts'; import { createMockRole } from './roles.mts'; +import { HOMock } from './helpers.mts'; -export const createMockCommunity = (): any => { +export const createMockCommunity = ({ name, description, urls, image, user, refUsers }): any => { const id = faker.database.mongodbObjectId(); - return { + const data = { id, - name: 'My Community 1', - description: 'My community 1 description', - urls: ['https://mycommunity.com'], - image: faker.image.avatar(), + name: name || 'My Community 1', + description: description || 'My community 1 description', + urls: urls || ['https://mycommunity.com'], + image: image || faker.image.avatar(), users: { - create: [createMockUser(), createMockUser()], + create: !refUsers ? [createMockUser({}), createMockUser({})] : undefined, + connect: refUsers ? refUsers : undefined, }, status: 'ACTIVE', favorites: { @@ -52,15 +54,11 @@ export const createMockCommunity = (): any => { messagesReceived: { create: [], }, - userOwner: { - create: createMockUser(), - }, - userCreator: { - create: createMockUser(), - }, }; + + return HOMock(data, { user }); }; -export const mockCommunity = createMockCommunity(); -export const mockCommunity2 = createMockCommunity(); -export const mockCommunity3 = createMockCommunity(); +export const mockCommunity = createMockCommunity({}); +export const mockCommunity2 = createMockCommunity({}); +export const mockCommunity3 = createMockCommunity({}); diff --git a/prisma/mock/listings.mts b/prisma/mock/listings.mts index 35dee539..e8a0260f 100644 --- a/prisma/mock/listings.mts +++ b/prisma/mock/listings.mts @@ -9,10 +9,10 @@ import { createMockTerm, mockTerm } from './taxonomies.mts'; import { HOMock } from './helpers.mts'; const mockLocation = { - name: 'Home', + name: faker.company.name(), geo: { - lat: 0.75, - lng: 1.02, + lat: faker.location.latitude(), + lng: faker.location.longitude(), radius: 0.98, }, address: { diff --git a/prisma/mock/public.mts b/prisma/mock/public.mts index f235f499..f4540c9a 100644 --- a/prisma/mock/public.mts +++ b/prisma/mock/public.mts @@ -5,10 +5,10 @@ import { faker } from '@faker-js/faker'; import { HOMock } from './helpers.mts'; const mockLocation = { - name: 'Home', + name: faker.company.name(), geo: { - lat: 0.75, - lng: 1.02, + lat: faker.location.latitude(), + lng: faker.location.longitude(), radius: 0.98, }, address: { @@ -36,11 +36,73 @@ export const createMockPubListing = ({ communityCreator: community, communityOwner: community, title: { - es: 'Lorem ipsum title', + en: faker.airline.airplane().name, + it: faker.airline.airplane().name, + pt: faker.airline.airplane().name, + es: faker.airline.airplane().name, + de: faker.airline.airplane().name, + fr: faker.airline.airplane().name, + ro: faker.airline.airplane().name, + cz: faker.airline.airplane().name, + pl: faker.airline.airplane().name, + et: faker.airline.airplane().name, + sv: faker.airline.airplane().name, + ja: faker.airline.airplane().name, + ru: faker.airline.airplane().name, + ar: faker.airline.airplane().name, + he: faker.airline.airplane().name, + zh: faker.airline.airplane().name, + nl: faker.airline.airplane().name, + da: faker.airline.airplane().name, + hu: faker.airline.airplane().name, + ca: faker.airline.airplane().name, + eu: faker.airline.airplane().name, + gl: faker.airline.airplane().name, + sw: faker.airline.airplane().name, + hi: faker.airline.airplane().name, + ms: faker.airline.airplane().name, + bn: faker.airline.airplane().name, + pa: faker.airline.airplane().name, + tr: faker.airline.airplane().name, + fi: faker.airline.airplane().name, + el: faker.airline.airplane().name, + uk: faker.airline.airplane().name, }, description: { - es: 'Lorem ipsum description', + en: faker.finance.transactionDescription(), + it: faker.finance.transactionDescription(), + pt: faker.finance.transactionDescription(), + es: faker.finance.transactionDescription(), + de: faker.finance.transactionDescription(), + fr: faker.finance.transactionDescription(), + ro: faker.finance.transactionDescription(), + cz: faker.finance.transactionDescription(), + pl: faker.finance.transactionDescription(), + et: faker.finance.transactionDescription(), + sv: faker.finance.transactionDescription(), + ja: faker.finance.transactionDescription(), + ru: faker.finance.transactionDescription(), + ar: faker.finance.transactionDescription(), + he: faker.finance.transactionDescription(), + zh: faker.finance.transactionDescription(), + nl: faker.finance.transactionDescription(), + da: faker.finance.transactionDescription(), + hu: faker.finance.transactionDescription(), + ca: faker.finance.transactionDescription(), + eu: faker.finance.transactionDescription(), + gl: faker.finance.transactionDescription(), + sw: faker.finance.transactionDescription(), + hi: faker.finance.transactionDescription(), + ms: faker.finance.transactionDescription(), + bn: faker.finance.transactionDescription(), + pa: faker.finance.transactionDescription(), + tr: faker.finance.transactionDescription(), + fi: faker.finance.transactionDescription(), + el: faker.finance.transactionDescription(), + uk: faker.finance.transactionDescription(), }, + scheduledFor: faker.date.future(), + value: faker.number.float(3500), status: 'ACTIVE', location: mockLocation, taxonomies, diff --git a/prisma/mock/user.mts b/prisma/mock/user.mts index 1f80feda..ded25222 100644 --- a/prisma/mock/user.mts +++ b/prisma/mock/user.mts @@ -1,5 +1,6 @@ // user.ts import { faker } from '@faker-js/faker'; +import { HOMock } from './helpers.mts'; interface UserModel { id: string; @@ -19,19 +20,23 @@ export const _mockUser = { userId: '66315b93521b49388fe71aa8', }; -export const createMockUser = () => ({ - id: faker.database.mongodbObjectId(), - name: faker.person.fullName(), - email: faker.internet.email(), - image: faker.image.avatar(), - firstName: 'Vars', - lastName: 'Nothing', - birthday: new Date(), - location: { - name: 'Nowhere', - }, -}); +export const createMockUser = ({ name, firstName, lastName, location, email, avatar }: any) => { + const data = { + id: faker.database.mongodbObjectId(), + name: name || faker.person.fullName(), + email: email || faker.internet.email(), + image: avatar || faker.image.avatar(), + firstName: firstName || 'DreamPip', + lastName: lastName || 'Superuser', + birthday: new Date(), + location: location || { + name: 'Nowhere', + }, + }; + + return data; +}; -export const mockUser = createMockUser(); -export const mockUser2 = createMockUser(); -export const mockUser3 = createMockUser(); +export const mockUser = createMockUser({}); +export const mockUser2 = createMockUser({}); +export const mockUser3 = createMockUser({}); diff --git a/prisma/schema-private.prisma b/prisma/schema-private.prisma index 46fd02e3..b2e4bb11 100644 --- a/prisma/schema-private.prisma +++ b/prisma/schema-private.prisma @@ -239,6 +239,8 @@ model Listings { description ILocaleString //model description status EListingStatus location ILocation + scheduledFor DateTime? @db.Date + value Float? taxonomies Taxonomies[] @relation("listingTaxonomies", fields: [taxonomiesIds], references: [id]) taxonomiesIds String[] @db.ObjectId @@ -652,6 +654,18 @@ type ILocaleString { sq String? ja String? ru String? + ar String? + he String? + zh String? + gl String? + sw String? + hi String? + ms String? + bn String? + pa String? + tr String? + fi String? + uk String? } diff --git a/prisma/schema-public.prisma b/prisma/schema-public.prisma index 64c25227..451d1ab9 100644 --- a/prisma/schema-public.prisma +++ b/prisma/schema-public.prisma @@ -19,6 +19,8 @@ model PublicListings { description ILocaleString status EListingStatus location ILocation + scheduledFor DateTime? @db.Date + value Float? taxonomies ITaxonomiesFacade[] reviews IReviewFacade[] @@ -86,6 +88,20 @@ type ILocaleString { bg String? bs String? sq String? + ja String? + ru String? + ar String? + he String? + zh String? + gl String? + sw String? + hi String? + ms String? + bn String? + pa String? + tr String? + fi String? + uk String? } enum ECurrency { diff --git a/prisma/seed.mts b/prisma/seed.mts index 2787fcac..9e1931ba 100644 --- a/prisma/seed.mts +++ b/prisma/seed.mts @@ -6,8 +6,8 @@ import { faker } from '@faker-js/faker'; import { PrismaClient as PrivatePrisma } from '@dreampipcom/db-private/prisma-client'; import { PrismaClient as PublicPrisma } from '@dreampipcom/db-public/prisma-client'; -import { mockUser, mockUser2, mockUser3 } from './mock/user.mts'; -import { mockCommunity, mockCommunity2, mockCommunity3 } from './mock/communities.mts'; +import { createMockUser, mockUser, mockUser2, mockUser3 } from './mock/user.mts'; +import { createMockCommunity, mockCommunity, mockCommunity2, mockCommunity3 } from './mock/communities.mts'; import { createMockListing } from './mock/listings.mts'; import { createMockAudience } from './mock/audiences.mts'; import { createMockTerm } from './mock/taxonomies.mts'; @@ -17,6 +17,7 @@ import { createMockPubListing } from './mock/public.mts'; import { createMockAbility } from './mock/abilities.mts'; import { createMockFeature } from './mock/features.mts'; import { createMockService } from './mock/services.mts'; +import _ from 'lodash'; export const cleanupDatabase = () => { const propertyNames = Object.getOwnPropertyNames(pvtPrisma); @@ -38,29 +39,26 @@ if (seedType === 'private') { const main = async () => { try { - // await pvtPrisma.products.deleteMany(); - - // // cleanup the existing database - const allProperties = Reflect.ownKeys(Object.getPrototypeOf(pvtPrisma)); - const modelNames = allProperties.filter( - (x) => x != 'constructor' && x != 'on' && x != 'connect' && x != 'runDisconnect' && x != 'disconnect', - ); - - // if (modelNames.length > 0) { - // console.log("WARNING! ERASING DB.") - // cleanupDatabase() - // console.log("~ ERASED ~") - // } - - /* - ~~~~ PRIVATE ~~~~ - */ - // user0 - const user0 = await pvtPrisma.user.create({ data: mockUser }); + const user0 = await pvtPrisma.user.create({ + data: createMockUser({ + name: 'DreamPip', + firstName: 'DreamPip', + lastName: 'Superuser', + email: process.env.NEXUS_EMAIL, + }), + }); // community0 - const community0 = await pvtPrisma.communities.create({ data: mockCommunity }); + const community0 = await pvtPrisma.communities.create({ + data: createMockCommunity({ + name: 'DreamPip', + description: 'Fintech for compassion.', + urls: ['https://www.dreampip.com'], + user: user0.id, + refUsers: [{ id: user0.id }], + }), + }); // roles const role1name = { @@ -205,10 +203,11 @@ if (seedType === 'private') { slug: 'role-su', user: user0.id, community: community0.id, - refUsers: [], + refUsers: [{ id: user0.id }], refCommunities: [], }), }); + const role2 = await pvtPrisma.roles.create({ data: createMockRole({ name: role2name, @@ -219,6 +218,7 @@ if (seedType === 'private') { refCommunities: [], }), }); + const role3 = await pvtPrisma.roles.create({ data: createMockRole({ name: role3name, @@ -229,6 +229,7 @@ if (seedType === 'private') { refCommunities: [], }), }); + const role4 = await pvtPrisma.roles.create({ data: createMockRole({ name: role4name, @@ -241,7 +242,7 @@ if (seedType === 'private') { }); // abilities - const favoriteListings = { + const ability1name = { en: 'Favorite Listings', it: 'Aggiungi ai Preferiti', pt: 'Favoritar Listagens', @@ -484,6 +485,7 @@ if (seedType === 'private') { refCommunities: [{ id: community0.id }], }), }); + const service2 = await pvtPrisma.services.create({ data: createMockService({ name: service2name, @@ -514,24 +516,6 @@ if (seedType === 'private') { const main = async () => { try { - // await pvtPrisma.products.deleteMany(); - - // // cleanup the existing database - const allProperties = Reflect.ownKeys(Object.getPrototypeOf(pubPrisma)); - const modelNames = allProperties.filter( - (x) => x != 'constructor' && x != 'on' && x != 'connect' && x != 'runDisconnect' && x != 'disconnect', - ); - - // if (modelNames.length > 0) { - // console.log("WARNING! ERASING DB.") - // cleanupDatabase() - // console.log("~ ERASED ~") - // } - - /* - ~~~~ PUBLIC ~~~~ - */ - const facadeEntry = (fields: string[], facades: Record) => (entry: any) => { const facader = fields.reduce((fac, field, index) => { let content = entry[field]; @@ -545,73 +529,6 @@ if (seedType === 'private') { return facader; }; - const facadeTaxonomy = facadeEntry(['id', 'name', 'description', 'status', 'type', 'nature', 'audiencesIds']); - - // const decorateAd = facadeEntry([ - // 'userFits', - // 'communityFits', - // ]); - - const facadeMessage = facadeEntry([ - 'id', - 'name', - 'description', - 'status', - 'type', - 'nature', - 'title', - 'body', - 'queuedOn', - 'scheduledOn', - 'sentOn', - ]); - - const facadeUser = facadeEntry(['id', 'image', 'firstName']); - - const facadeCommunity = facadeEntry(['id', 'image', 'name', 'urls', 'status']); - - const getSeedData = () => { - try { - const data = JSON.parse(fs.readFileSync('stub.json')); - return data; - } catch (e) { - execSync('npm run schema:seed:getseeds'); - return { retry: true }; - } - }; - - let data = getSeedData(); - - if (data?.retry) { - data = getSeedData(); - } - - const { community, user, model, term } = data; - - const pubListing1 = await pubPrisma.publicListings.create({ - data: createMockPubListing({ - community: facadeCommunity(community), - user: facadeUser(user), - taxonomies: [facadeTaxonomy(term)], - }), - }); - - const pubListing2 = await pubPrisma.publicListings.create({ - data: createMockPubListing({ - community: facadeCommunity(community), - user: facadeUser(user), - taxonomies: [facadeTaxonomy(term)], - }), - }); - - const pubListing3 = await pubPrisma.publicListings.create({ - data: createMockPubListing({ - community: facadeCommunity(community), - user: facadeUser(user), - taxonomies: [facadeTaxonomy(term)], - }), - }); - console.log(`Public Database has been seeded. 🌱`); } catch (error) { throw error; @@ -628,24 +545,6 @@ if (seedType === 'private') { const main = async () => { try { - // await pvtPrisma.products.deleteMany(); - - // // cleanup the existing database - const allProperties = Reflect.ownKeys(Object.getPrototypeOf(pvtPrisma)); - const modelNames = allProperties.filter( - (x) => x != 'constructor' && x != 'on' && x != 'connect' && x != 'runDisconnect' && x != 'disconnect', - ); - - // if (modelNames.length > 0) { - // console.log("WARNING! ERASING DB.") - // cleanupDatabase() - // console.log("~ ERASED ~") - // } - - /* - ~~~~ PRIVATE ~~~~ - */ - const user1 = await pvtPrisma.user.create({ data: mockUser }); const user2 = await pvtPrisma.user.create({ data: mockUser2 }); const user3 = await pvtPrisma.user.create({ data: mockUser3 }); @@ -676,35 +575,35 @@ if (seedType === 'private') { // // abilities const ability1name = { - en: 'Favorite Listings', - it: 'Aggiungi ai Preferiti', - pt: 'Favoritar Listagens', - es: 'Marcar como Favorito', - de: 'Anzeigen favorisieren', - fr: 'Mettre en Favori', - ro: 'Favoritează liste', - cz: 'Oblíbené inzeráty', - pl: 'Dodaj do Ulubionych', - et: 'Lisa lemmikutesse', - sv: 'Gör till Favoriter', - ja: 'お気に入りにする', - ru: 'Добавить в Избранное', + en: 'Favorite Listings (mock)', + it: 'Aggiungi ai Preferiti (mock)', + pt: 'Favoritar Listagens (mock)', + es: 'Marcar como Favorito (mock)', + de: 'Anzeigen favorisieren (mock)', + fr: 'Mettre en Favori (mock)', + ro: 'Favoritează liste (mock)', + cz: 'Oblíbené inzeráty (mock)', + pl: 'Dodaj do Ulubionych (mock)', + et: 'Lisa lemmikutesse (mock)', + sv: 'Gör till Favoriter (mock)', + ja: 'お気に入りにする (mock)', + ru: 'Добавить в Избранное (mock)', }; const ability2name = { - en: 'View Listings', - it: 'Visualizza inserzioni', - pt: 'Ver listagens', - es: 'Ver listados', - de: 'Anzeigen anzeigen', - fr: 'Voir les annonces', - ro: 'Vizualizare liste', - cz: 'Zobrazit inzeráty', - pl: 'Wyświetl oferty', - et: 'Vaata kuulutusi', - sv: 'Visa listor', - ja: 'リストを表示する', - ru: 'Просмотр объявлений', + en: 'View Listings (mock)', + it: 'Visualizza inserzioni (mock)', + pt: 'Ver listagens (mock)', + es: 'Ver listados (mock)', + de: 'Anzeigen anzeigen (mock)', + fr: 'Voir les annonces (mock)', + ro: 'Vizualizare liste (mock)', + cz: 'Zobrazit inzeráty (mock)', + pl: 'Wyświetl oferty (mock)', + et: 'Vaata kuulutusi (mock)', + sv: 'Visa listor (mock)', + ja: 'リストを表示する (mock)', + ru: 'Просмотр объявлений (mock)', }; const ability1 = await pvtPrisma.abilities.create({ @@ -713,7 +612,7 @@ if (seedType === 'private') { user: user1.id, community: community1.id, type: 'R', - action: 'view-listings', + action: 'view-listings-mock', nature: 'COMMON', target: 'rickmorty', roles: [{ id: role1.id }, { id: role2.id }], @@ -727,7 +626,7 @@ if (seedType === 'private') { name: ability2name, user: user1.id, type: 'R', - action: 'view-listings', + action: 'view-listings-mock', nature: 'PRIVILEGE', target: 'dpcp-vibemodulator', community: community1.id, @@ -742,7 +641,7 @@ if (seedType === 'private') { name: ability1name, user: user1.id, type: 'U', - action: 'favorite', + action: 'favorite-mock', nature: 'COMMON', target: 'rickmorty', community: community1.id, @@ -774,41 +673,41 @@ if (seedType === 'private') { // // services const service1name = { - en: 'The Rick Morty Experience', + en: 'The Rick Morty Experience (mock)', it: "L'esperienza di Rick Morty", - pt: 'A Experiência Rick Morty', - es: 'La Experiencia Rick Morty', - de: 'Das Rick Morty Erlebnis', + pt: 'A Experiência Rick Morty (mock)', + es: 'La Experiencia Rick Morty (mock)', + de: 'Das Rick Morty Erlebnis (mock)', fr: "L'expérience Rick Morty", - ro: 'Experiența Rick Morty', - cz: 'Rick Morty Zážitek', - pl: 'Doświadczenie Rick Morty', - et: 'Rick Morty Kogemus', - sv: 'Rick Morty-upplevelsen', - ja: 'リック・モーティ体験', - ru: 'Опыт Рика и Морти', + ro: 'Experiența Rick Morty (mock)', + cz: 'Rick Morty Zážitek (mock)', + pl: 'Doświadczenie Rick Morty (mock)', + et: 'Rick Morty Kogemus (mock)', + sv: 'Rick Morty-upplevelsen (mock)', + ja: 'リック・モーティ体験 (mock)', + ru: 'Опыт Рика и Морти (mock)', }; const service2name = { - en: 'The Vibe Modulator', - it: 'Il Modulatore di Vibrazioni', - pt: 'O Modulador de Vibração', - es: 'El Modulador de Vibra', - de: 'Der Vibe-Modulator', - fr: 'Le Modulateur de Vibration', - ro: 'Modulatorul de Vibrații', - cz: 'Vibrační Modulátor', - pl: 'Modulator Nastroju', - et: 'Vibe Modulaator', - sv: 'Vibe-modulatorn', - ja: 'バイブモジュレーター', - ru: 'Вибромодулятор', + en: 'The Vibe Modulator (mock)', + it: 'Il Modulatore di Vibrazioni (mock)', + pt: 'O Modulador de Vibração (mock)', + es: 'El Modulador de Vibra (mock)', + de: 'Der Vibe-Modulator (mock)', + fr: 'Le Modulateur de Vibration (mock)', + ro: 'Modulatorul de Vibrații (mock)', + cz: 'Vibrační Modulátor (mock)', + pl: 'Modulator Nastroju (mock)', + et: 'Vibe Modulaator (mock)', + sv: 'Vibe-modulatorn (mock)', + ja: 'バイブモジュレーター (mock)', + ru: 'Вибромодулятор (mock)', }; const service1 = await pvtPrisma.services.create({ data: createMockService({ name: service1name, - slug: 'rickmorty', + slug: 'rickmorty-mock', user: user1.id, community: community1.id, features: [{ id: feature1.id }, { id: feature2.id }], @@ -816,10 +715,11 @@ if (seedType === 'private') { refCommunities: [{ id: community1.id }], }), }); + const service2 = await pvtPrisma.services.create({ data: createMockService({ name: service2name, - slug: 'dpcp-vibemodulator', + slug: 'dpcp-vibemodulator-mock', user: user1.id, community: community1.id, refUsers: [{ id: user2.id }, { id: user3.id }], @@ -836,6 +736,7 @@ if (seedType === 'private') { communityFavorited: [{ id: community2.id }, { id: community3.id }], }), }); + const listing2 = await pvtPrisma.listings.create({ data: createMockListing({ favorited: [{ id: user2.id }, { id: user3.id }], @@ -855,6 +756,7 @@ if (seedType === 'private') { targetUser: [{ id: user2.id }], }), }); + const term2 = await pvtPrisma.taxonomies.create({ data: createMockTerm({ community: community3.id, @@ -876,6 +778,7 @@ if (seedType === 'private') { toListings: [], }), }); + const message2 = await pvtPrisma.messages.create({ data: createMockMessage({ community: community3.id, @@ -886,6 +789,7 @@ if (seedType === 'private') { toListings: [{ id: listing1.id }, { id: listing2.id }], }), }); + const message3 = await pvtPrisma.messages.create({ data: createMockMessage({ community: community3.id, @@ -907,23 +811,6 @@ if (seedType === 'private') { const pubPrisma = new PublicPrisma({ datasourceUrl: process.env.PRISMA_PUBLIC_URI, }); - // await pvtPrisma.products.deleteMany(); - - // // cleanup the existing database - const allProperties = Reflect.ownKeys(Object.getPrototypeOf(pubPrisma)); - const modelNames = allProperties.filter( - (x) => x != 'constructor' && x != 'on' && x != 'connect' && x != 'runDisconnect' && x != 'disconnect', - ); - - // if (modelNames.length > 0) { - // console.log("WARNING! ERASING DB.") - // cleanupDatabase() - // console.log("~ ERASED ~") - // } - - /* - ~~~~ PUBLIC ~~~~ - */ const facadeEntry = (fields: string[], facades: Record) => (entry: any) => { const facader = fields.reduce((fac, field, index) => { @@ -940,11 +827,6 @@ if (seedType === 'private') { const facadeTaxonomy = facadeEntry(['id', 'name', 'description', 'status', 'type', 'nature', 'audiencesIds']); - // const decorateAd = facadeEntry([ - // 'userFits', - // 'communityFits', - // ]); - const facadeMessage = facadeEntry([ 'id', 'name', @@ -1005,7 +887,17 @@ if (seedType === 'private') { }), }); - console.log(`Public Database has been seeded. 🌱`); + _.times(100, async () => { + await pubPrisma.publicListings.create({ + data: createMockPubListing({ + community: facadeCommunity(community), + user: facadeUser(user), + taxonomies: [facadeTaxonomy(term)], + }), + }); + }); + + console.log(`Public Database has been seeded with mock data. 🌱`); } catch (error) { throw error; } From 86dda3a19a382f8dd9d846d856ccfa42cc6ce479 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 02:42:57 +0100 Subject: [PATCH 09/18] ar(feat) [DPCP-40]: Parse Services. --- next.config.mjs | 5 ++++- package.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index dcb829d2..dfeb2039 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -19,7 +19,10 @@ const nextConfig = { return config; }, - output: process.env.NEXUS_STANDALONE === 'true' ? 'standalone' : undefined, + output: + process.env.NEXUS_STANDALONE === 'true' && process.env.NEXUS_STANDALONE_PRISMA_ONLY !== 'true' + ? 'standalone' + : undefined, basePath: process.env.NEXUS_BASE_PATH, transpilePackages: ['next-auth'], images: { diff --git a/package.json b/package.json index c4d42a43..9d360314 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "schema:seed:getseeds": "NEXUS_STANDALONE=true npm run schema:generate:private:standalone && node --loader ts-node/esm prisma/getSeeds.mts --schema=./prisma/schema-private.prisma -- private", "schema:seed:public": "NEXUS_STANDALONE=true npm run schema:generate:private:standalone && npm run schema:generate:public:standalone && prisma db seed --schema=./prisma/schema-public.prisma -- public", "schema:seed:mock": "NEXUS_STANDALONE=true npm run schema:generate:private:standalone && npm run schema:generate:public:standalone && prisma db seed --schema=./prisma/schema-public.prisma -- mock", - "schema:seed:all": "NEXUS_STANDALONE=true npm run schema:seed:private:standalone && npm run schema:seed:public:standalone", + "schema:seed:all": "NEXUS_STANDALONE=true npm run schema:seed:private && npm run schema:seed:public", "schema:generate:private": "npx prisma generate --no-engine --schema=./prisma/schema-private.prisma", "schema:generate:public": "npx prisma generate --no-engine --schema=./prisma/schema-public.prisma", "schema:generate:all": "npm run schema:generate:private && npm run schema:generate:public", From 8e189ff325c289f391720debd7d8ff0386f49539 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 03:41:52 +0100 Subject: [PATCH 10/18] ar(feat) [DPCP-40]: Parse Services. --- prisma/mock/listings.mts | 4 ++-- prisma/mock/public.mts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/prisma/mock/listings.mts b/prisma/mock/listings.mts index e8a0260f..3db96bdc 100644 --- a/prisma/mock/listings.mts +++ b/prisma/mock/listings.mts @@ -8,7 +8,7 @@ import { createMockTerm, mockTerm } from './taxonomies.mts'; import { HOMock } from './helpers.mts'; -const mockLocation = { +const mockLocation = () => ({ name: faker.company.name(), geo: { lat: faker.location.latitude(), @@ -25,7 +25,7 @@ const mockLocation = { zipCode: '000000', phone: '01010101010', }, -}; +}); export const createMockListing = ({ community, user, communityFavorited, favorited, audiences, model }: any) => { const data = { diff --git a/prisma/mock/public.mts b/prisma/mock/public.mts index f4540c9a..fda07e7b 100644 --- a/prisma/mock/public.mts +++ b/prisma/mock/public.mts @@ -4,7 +4,7 @@ import { faker } from '@faker-js/faker'; import { HOMock } from './helpers.mts'; -const mockLocation = { +const mockLocation = () => ({ name: faker.company.name(), geo: { lat: faker.location.latitude(), @@ -17,7 +17,7 @@ const mockLocation = { country: 'Sit', zipCode: '000000', }, -}; +}); export const createMockPubListing = ({ user, @@ -104,7 +104,7 @@ export const createMockPubListing = ({ scheduledFor: faker.date.future(), value: faker.number.float(3500), status: 'ACTIVE', - location: mockLocation, + location: mockLocation(), taxonomies, }; From 73780e0e8a559d66495fec5adc166eeecab93892 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 03:52:17 +0100 Subject: [PATCH 11/18] ar(feat) [DPCP-40]: Parse Services. --- prisma/mock/listings.mts | 7 ++++++- prisma/mock/public.mts | 5 +++++ prisma/schema-private.prisma | 1 + prisma/schema-public.prisma | 1 + 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/prisma/mock/listings.mts b/prisma/mock/listings.mts index 3db96bdc..df2f5231 100644 --- a/prisma/mock/listings.mts +++ b/prisma/mock/listings.mts @@ -32,11 +32,16 @@ export const createMockListing = ({ community, user, communityFavorited, favorit title: { es: 'INTERNAL aud', }, + images: [ + faker.image.urlLoremFlickr({ category: 'crypto' }), + faker.image.urlLoremFlickr({ category: 'crypto' }), + faker.image.urlLoremFlickr({ category: 'crypto' }), + ], description: { es: 'Lorem ipsum dolor sit amet consectetur', }, status: 'ACTIVE', - location: mockLocation, + location: mockLocation(), favorited: { connect: favorited, }, diff --git a/prisma/mock/public.mts b/prisma/mock/public.mts index fda07e7b..bfe567d3 100644 --- a/prisma/mock/public.mts +++ b/prisma/mock/public.mts @@ -35,6 +35,11 @@ export const createMockPubListing = ({ userCreator: user, communityCreator: community, communityOwner: community, + images: [ + faker.image.urlLoremFlickr({ category: 'crypto' }), + faker.image.urlLoremFlickr({ category: 'crypto' }), + faker.image.urlLoremFlickr({ category: 'crypto' }), + ], title: { en: faker.airline.airplane().name, it: faker.airline.airplane().name, diff --git a/prisma/schema-private.prisma b/prisma/schema-private.prisma index b2e4bb11..2f57c959 100644 --- a/prisma/schema-private.prisma +++ b/prisma/schema-private.prisma @@ -241,6 +241,7 @@ model Listings { location ILocation scheduledFor DateTime? @db.Date value Float? + images String[] taxonomies Taxonomies[] @relation("listingTaxonomies", fields: [taxonomiesIds], references: [id]) taxonomiesIds String[] @db.ObjectId diff --git a/prisma/schema-public.prisma b/prisma/schema-public.prisma index 451d1ab9..bb49eadd 100644 --- a/prisma/schema-public.prisma +++ b/prisma/schema-public.prisma @@ -21,6 +21,7 @@ model PublicListings { location ILocation scheduledFor DateTime? @db.Date value Float? + images String[] taxonomies ITaxonomiesFacade[] reviews IReviewFacade[] From 8a197dd0143959cb7724e50abcd3f737e47b6cd2 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 04:22:43 +0100 Subject: [PATCH 12/18] ar(feat) [DPCP-40]: Parse Services. --- src/app/api/v1/services/dpcp-vibemodulator/route.ts | 2 +- src/app/api/v1/user/route.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/api/v1/services/dpcp-vibemodulator/route.ts b/src/app/api/v1/services/dpcp-vibemodulator/route.ts index 151a2617..583eab7a 100644 --- a/src/app/api/v1/services/dpcp-vibemodulator/route.ts +++ b/src/app/api/v1/services/dpcp-vibemodulator/route.ts @@ -17,7 +17,7 @@ const generateErrorResponse = (e: any, status: number) => { // export const dynamic = 'force-static'; export async function GET(request: CombineRequest) { try { - const cookies = request?.cookies || request?.headers.get('cookies'); + const cookies = request?.cookies || request?.headers.get('cookies').toString(); const session = await GetSession({ cookies: cookies || '' }); const user = session?.user; diff --git a/src/app/api/v1/user/route.ts b/src/app/api/v1/user/route.ts index 54a3e284..3e6b6457 100644 --- a/src/app/api/v1/user/route.ts +++ b/src/app/api/v1/user/route.ts @@ -40,7 +40,7 @@ export async function POST(request: CombineRequest) { export async function PATCH(request: CombineRequest) { try { - const cookies = request?.headers.get('cookies'); + const cookies = request?.headers.get('cookies').toString(); const session = await GetSession({ cookies: cookies || '' }); const url = new URL(request.url); const query = url.searchParams; From d213a5c455b171fe3e6d599fc7e687b2f47b9beb Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 04:24:47 +0100 Subject: [PATCH 13/18] ar(feat) [DPCP-40]: Parse Services. --- src/app/api/v1/services/dpcp-vibemodulator/route.ts | 2 +- src/app/api/v1/user/route.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/api/v1/services/dpcp-vibemodulator/route.ts b/src/app/api/v1/services/dpcp-vibemodulator/route.ts index 583eab7a..76dcd6df 100644 --- a/src/app/api/v1/services/dpcp-vibemodulator/route.ts +++ b/src/app/api/v1/services/dpcp-vibemodulator/route.ts @@ -17,7 +17,7 @@ const generateErrorResponse = (e: any, status: number) => { // export const dynamic = 'force-static'; export async function GET(request: CombineRequest) { try { - const cookies = request?.cookies || request?.headers.get('cookies').toString(); + const cookies = request?.cookies || request?.headers?.get('cookies')?.toString(); const session = await GetSession({ cookies: cookies || '' }); const user = session?.user; diff --git a/src/app/api/v1/user/route.ts b/src/app/api/v1/user/route.ts index 3e6b6457..bd8bfb75 100644 --- a/src/app/api/v1/user/route.ts +++ b/src/app/api/v1/user/route.ts @@ -40,7 +40,7 @@ export async function POST(request: CombineRequest) { export async function PATCH(request: CombineRequest) { try { - const cookies = request?.headers.get('cookies').toString(); + const cookies = request?.headers?.get('cookies')?.toString(); const session = await GetSession({ cookies: cookies || '' }); const url = new URL(request.url); const query = url.searchParams; From ea813cce253dc1d6a23844d7b514d0fb3a077089 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 11:56:03 +0100 Subject: [PATCH 14/18] ar(feat) [DPCP-40]: Parse Services. --- src/app/api/v1/services/dpcp-vibemodulator/route.ts | 2 +- src/app/api/v1/user/route.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/api/v1/services/dpcp-vibemodulator/route.ts b/src/app/api/v1/services/dpcp-vibemodulator/route.ts index 76dcd6df..008b791f 100644 --- a/src/app/api/v1/services/dpcp-vibemodulator/route.ts +++ b/src/app/api/v1/services/dpcp-vibemodulator/route.ts @@ -17,7 +17,7 @@ const generateErrorResponse = (e: any, status: number) => { // export const dynamic = 'force-static'; export async function GET(request: CombineRequest) { try { - const cookies = request?.cookies || request?.headers?.get('cookies')?.toString(); + const cookies = request?.cookies?.toString() || request?.headers?.get('cookies'); const session = await GetSession({ cookies: cookies || '' }); const user = session?.user; diff --git a/src/app/api/v1/user/route.ts b/src/app/api/v1/user/route.ts index bd8bfb75..3f24afcf 100644 --- a/src/app/api/v1/user/route.ts +++ b/src/app/api/v1/user/route.ts @@ -40,7 +40,7 @@ export async function POST(request: CombineRequest) { export async function PATCH(request: CombineRequest) { try { - const cookies = request?.headers?.get('cookies')?.toString(); + const cookies = request?.cookies?.toString() || request?.headers?.get('cookies'); const session = await GetSession({ cookies: cookies || '' }); const url = new URL(request.url); const query = url.searchParams; From 3aa0aa890104e7805a9ac49359c794495fcebd1d Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 11:57:02 +0100 Subject: [PATCH 15/18] ar(feat) [DPCP-40]: Parse Services. --- src/app/api/v1/user/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/v1/user/route.ts b/src/app/api/v1/user/route.ts index 3f24afcf..e4c9adb2 100644 --- a/src/app/api/v1/user/route.ts +++ b/src/app/api/v1/user/route.ts @@ -58,7 +58,7 @@ export async function PATCH(request: CombineRequest) { // [DPCP-116]: https://www.notion.so/angeloreale/Hypnos-Add-transactional-websockets-de3667b32a4c4cd4ade76080203e68fd?pvs=4 // might have idempotency issues. - // need ui to signal request was received, + // need optimistic ui to signal request was sent + received, // but subsequent webhook to confirm it was processed correctly // const headers = { // 'content-type': 'application/json', From e18b0550ad67f075c98dbea6b0d6924f9d27aafc Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 12:29:12 +0100 Subject: [PATCH 16/18] ar(feat) [DPCP-40]: Parse Services. --- lib/model/interfaces/get-private-abilities.ts | 13 ++-- .../get-private-common-abilities.ts | 17 ++-- .../interfaces/get-private-common-services.ts | 17 ++-- lib/model/interfaces/get-private-services.ts | 77 +++++++++++-------- .../interfaces/get-public-listings-iface.ts | 10 ++- .../update-private-user-abilities.ts | 4 +- .../update-private-user-favorite-listings.ts | 4 +- .../update-private-user-services.ts | 4 +- src/app/api/v1/user/route.ts | 43 ++++++++++- 9 files changed, 125 insertions(+), 64 deletions(-) diff --git a/lib/model/interfaces/get-private-abilities.ts b/lib/model/interfaces/get-private-abilities.ts index a9ce9dbd..89c56bc3 100644 --- a/lib/model/interfaces/get-private-abilities.ts +++ b/lib/model/interfaces/get-private-abilities.ts @@ -42,7 +42,7 @@ const getPrivateAbilities = async ({ const supportedQueries: Record = { user: { query: { - OR: [{ id: { in: loggedUser?.servicesIds }, name: { [locale]: name } }, { userOwner: loggedUser?.id }], + OR: [{ id: { in: loggedUser?.abilitiesIds }, name: { [locale]: name } }, { userOwner: loggedUser?.id }], }, }, // group: { @@ -60,15 +60,16 @@ const getPrivateAbilities = async ({ return acc; }, {}); - adaptQuery.where = { - ...adaptQuery.where, - ...query, - }; + adaptQuery.where?.OR = query?.OR; } catch (e) { - throw new Error('Code 001: Wrong filter'); + throw new Error('Code 000/2: Wrong filter'); } } + if (!adaptQuery?.where?.OR?.length > 0) { + throw new Error('Code 000/1: Malformed request'); + } + const response = await PrivatePrisma.abilities.findMany(adaptQuery); return response; diff --git a/lib/model/interfaces/get-private-common-abilities.ts b/lib/model/interfaces/get-private-common-abilities.ts index 3c4b47e2..8e23bc38 100644 --- a/lib/model/interfaces/get-private-common-abilities.ts +++ b/lib/model/interfaces/get-private-common-abilities.ts @@ -7,7 +7,11 @@ const getPrivateCommonAbilities = async ({ page = 0, offset = 0, limit = PAGE_SI // to-do: move, this will be a middleware const adaptQuery: any = { where: { - nature: 'COMMON', + OR: [ + { + nature: 'COMMON', + }, + ], }, skip: page * (limit + offset), take: limit, @@ -37,15 +41,16 @@ const getPrivateCommonAbilities = async ({ page = 0, offset = 0, limit = PAGE_SI return acc; }, {}); - adaptQuery.where = { - ...adaptQuery.where, - ...query, - }; + adaptQuery.where?.OR = query?.OR; } catch (e) { - throw new Error('Code 001: Wrong filter'); + throw new Error('Code 000/2: Wrong filter'); } } + if (!adaptQuery?.where?.OR?.length > 0) { + throw new Error('Code 000/1: Malformed request'); + } + const response = await PrivatePrisma.abilities.findMany(adaptQuery); return response; diff --git a/lib/model/interfaces/get-private-common-services.ts b/lib/model/interfaces/get-private-common-services.ts index bc60d1be..338489cd 100644 --- a/lib/model/interfaces/get-private-common-services.ts +++ b/lib/model/interfaces/get-private-common-services.ts @@ -7,7 +7,11 @@ const getPrivateCommonServices = async ({ page = 0, offset = 0, limit = PAGE_SIZ // to-do: move, this will be a middleware const adaptQuery: any = { where: { - nature: 'COMMON', + OR: [ + { + nature: 'COMMON', + }, + ], }, skip: page * (limit + offset), take: limit, @@ -37,15 +41,16 @@ const getPrivateCommonServices = async ({ page = 0, offset = 0, limit = PAGE_SIZ return acc; }, {}); - adaptQuery.where = { - ...adaptQuery.where, - ...query, - }; + adaptQuery.where?.OR = query?.OR; } catch (e) { - throw new Error('Code 001: Wrong filter'); + throw new Error('Code 000/2: Wrong filter'); } } + if (!adaptQuery?.where?.OR?.length > 0) { + throw new Error('Code 000/1: Malformed request'); + } + const response = await PrivatePrisma.services.findMany(adaptQuery); return response; diff --git a/lib/model/interfaces/get-private-services.ts b/lib/model/interfaces/get-private-services.ts index 867a43ca..d42b05d1 100644 --- a/lib/model/interfaces/get-private-services.ts +++ b/lib/model/interfaces/get-private-services.ts @@ -9,52 +9,61 @@ const getPrivateServices = async ({ id, user, target, page = 0, offset = 0, limi const adaptQuery: any = { where: { - id, - slug: target, + OR: [ + { + id, + }, + { + slug: target, + }, + ], }, skip: page * (limit + offset), take: limit, cacheStrategy: process.env.NEXUS_STANDALONE !== 'true' ? { ttl: 90, swr: 60 * 60 * 24 * 1 } : undefined, }; - if (await canI({ type: 'R', action: 'view-listings', target, user: loggedUser })) { - if (filters?.length) { - // to-do: add common services filter queries later, e.g. ACTIVE services, Updatable Services, etc. - try { - const supportedQueries: Record = { - user: { - query: { - OR: [{ id: { in: loggedUser?.servicesIds } }, { slug: name }, { userOwner: loggedUser?.id }], - }, + if (filters?.length) { + try { + const supportedQueries: Record = { + user: { + query: { + OR: [{ id: { in: loggedUser?.servicesIds }, name: { [locale]: name } }, { userOwner: loggedUser?.id }], }, - // group: { - // query: { - // OR: [ - // { id, name, groupOwner: session?.user?.id }, - // ], - // }, - // }, - }; - - const query: any = filters?.reduce((acc: any, filter: string) => { - if (!acc.OR) acc.OR = []; - acc.OR.push(supportedQueries[filter].query); - return acc; - }, {}); - - adaptQuery.where = { - ...adaptQuery.where, - ...query, - }; - } catch (e) { - throw new Error('Code 001: Wrong filter'); - } + }, + // group: { + // query: { + // OR: [ + // { id, name, groupOwner: session?.user?.id }, + // ], + // }, + // }, + }; + + const query: any = filters?.reduce((acc: any, filter: string) => { + if (!acc.OR) acc.OR = []; + acc.OR.push(supportedQueries[filter].query); + return acc; + }, {}); + + adaptQuery.where?.OR = query?.OR; + + const response = await PrivatePrisma.services.findMany(adaptQuery); + return response; + } catch (e) { + throw new Error('Code 000/2: Wrong filter'); } + } + + if (!adaptQuery?.where?.OR?.length > 0) { + throw new Error('Code 000/1: Malformed request'); + } + if (await canI({ type: 'R', action: 'view-listings', target, user: loggedUser })) { const response = await PrivatePrisma.services.findMany(adaptQuery); return response; } else { - throw new Error(`403: Not authorized.`); + throw new Error(`Code 001/0: Not authorized.`); } }; diff --git a/lib/model/interfaces/get-public-listings-iface.ts b/lib/model/interfaces/get-public-listings-iface.ts index c5fed8ab..85bcb480 100644 --- a/lib/model/interfaces/get-public-listings-iface.ts +++ b/lib/model/interfaces/get-public-listings-iface.ts @@ -45,14 +45,16 @@ const getPublicListings = async ({ page = 0, offset = 0, limit = PAGE_SIZE, filt return acc; }, {}); - adaptQuery.where = { - ...query, - }; + adaptQuery.where?.OR = query?.OR; } catch (e) { - throw new Error('Code 001: Wrong filter'); + throw new Error('Code 000/2: Wrong filter'); } } + if (!adaptQuery?.where?.OR?.length > 0) { + throw new Error('Code 000/1: Malformed request'); + } + const response = await PublicPrisma.publicListings.findMany(adaptQuery); return response; diff --git a/lib/model/interfaces/update-private-user-abilities.ts b/lib/model/interfaces/update-private-user-abilities.ts index ef1f72e0..1778a71f 100644 --- a/lib/model/interfaces/update-private-user-abilities.ts +++ b/lib/model/interfaces/update-private-user-abilities.ts @@ -6,7 +6,7 @@ import { PrivatePrisma } from '@model'; const updatePrivateUserAbilities = async ({ upsert = false, user, abilities }: any) => { try { // to-do: move this will be a middleware - if (abilities?.length === 0) return new Error('Code 002: Missing data (abilities)'); + if (abilities?.length === 0) return new Error('Code 002/1: Missing data (abilities)'); const loggedUser = user || (await whoAmI({})); @@ -29,7 +29,7 @@ const updatePrivateUserAbilities = async ({ upsert = false, user, abilities }: a return response; } catch (e) { - throw new Error(`Code 003: Missing results: ${e}`); + throw new Error(`Code 002/0: Missing results: ${e}`); } }; diff --git a/lib/model/interfaces/update-private-user-favorite-listings.ts b/lib/model/interfaces/update-private-user-favorite-listings.ts index 239c07ad..4ab59e90 100644 --- a/lib/model/interfaces/update-private-user-favorite-listings.ts +++ b/lib/model/interfaces/update-private-user-favorite-listings.ts @@ -52,10 +52,10 @@ const updatePrivateUserFavoriteListings = async ({ upsert = true, user, target, const response = await PrivatePrisma.user.update(adaptQuery); return response; } else { - throw new Error(`403: Not authorized.`); + throw new Error(`Code 001/0: Not authorized.`); } } catch (e) { - throw new Error(`Code 003: Missing results: ${e}`); + throw new Error(`Code 002/0: Missing results: ${e}`); } }; diff --git a/lib/model/interfaces/update-private-user-services.ts b/lib/model/interfaces/update-private-user-services.ts index 094ff9a5..d8a6d7ec 100644 --- a/lib/model/interfaces/update-private-user-services.ts +++ b/lib/model/interfaces/update-private-user-services.ts @@ -6,7 +6,7 @@ import { PrivatePrisma } from '@model'; const updatePrivateUserServices = async ({ upsert = false, user, services }: any) => { try { // to-do: move this will be a middleware - if (services?.length === 0) return new Error('Code 002: Missing data (services)'); + if (services?.length === 0) return new Error('Code 002/0: Missing data (services)'); const loggedUser = user || (await whoAmI({})); @@ -29,7 +29,7 @@ const updatePrivateUserServices = async ({ upsert = false, user, services }: any return response; } catch (e) { - throw new Error(`Code 003: Missing results: ${e}`); + throw new Error(`Code 002/0: Missing results: ${e}`); } }; diff --git a/src/app/api/v1/user/route.ts b/src/app/api/v1/user/route.ts index e4c9adb2..0a66a34d 100644 --- a/src/app/api/v1/user/route.ts +++ b/src/app/api/v1/user/route.ts @@ -3,7 +3,12 @@ import type { NextApiRequest } from 'next'; import type { NextRequest } from 'next/server'; import { NextResponse } from 'next/server'; import { GetSession } from '@auth'; -import { UpdatePrivateUserFavoriteListings, GetPrivateCommonAbilities } from '@controller'; +import { + GetPrivateAbilities, + GetPrivateServices, + UpdatePrivateUserFavoriteListings, + GetPrivateCommonAbilities, +} from '@controller'; type CombineRequest = NextRequest & NextApiRequest; const generateErrorResponse = (e: any, status: number) => { @@ -35,7 +40,41 @@ export async function POST(request: CombineRequest) { } } - return NextResponse.json(generateErrorResponse('Not authorized', 403), { status: 403 }); + const cookies = request?.cookies?.toString() || request?.headers?.get('cookies'); + const session = await GetSession({ cookies: cookies || '' }); + const user = session?.user; + + const body = await request?.json(); + const action = body?.action; + // const listings = body?.action; + + if (!!user && !!action) { + const payload = {}; + try { + if (action === 'get-own-abilities') { + payload.data = await GetPrivateAbilities({ filters: ['user'] }); + } else if (action === 'get-own-services') { + payload.data = await GetPrivateServices({ filters: ['user'] }); + } else { + throw new Error('Code 000/1: No specified action'); + } + } catch (e) { + return NextResponse.json(generateErrorResponse(e, 400), { status: 400 }); + } + + return NextResponse.json( + { + ok: true, + status: 200, + data: payload.data, + }, + { + status: 200, + }, + ); + } + + return NextResponse.json(generateErrorResponse('Code 000: Malformed request', 400), { status: 400 }); } export async function PATCH(request: CombineRequest) { From d5470a760c3608e507df6dfa9a5dba9e89781448 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 13:14:23 +0100 Subject: [PATCH 17/18] ar(feat) [DPCP-40]: Parse Services. --- .env.local.public | 1 + lib/model/interfaces/get-private-abilities.ts | 6 +++--- .../interfaces/get-private-common-abilities.ts | 4 ++-- .../interfaces/get-private-common-services.ts | 4 ++-- lib/model/interfaces/get-private-services.ts | 15 ++++++++++++--- lib/model/interfaces/get-public-listings-iface.ts | 11 +++++++++-- lib/model/prisma-private-connector.ts | 8 +++++++- lib/model/prisma-public-connector.ts | 8 +++++++- package.json | 1 + src/app/api/v1/user/route.ts | 2 +- 10 files changed, 45 insertions(+), 15 deletions(-) diff --git a/.env.local.public b/.env.local.public index 207055d5..ef950f43 100644 --- a/.env.local.public +++ b/.env.local.public @@ -34,6 +34,7 @@ NEXUS_BASE_PATH= # for docker images only NEXUS_STANDALONE= +NEXUS_STANDALONE_PRISMA_ONLY= # keep alive secret for private endpoints healthcheck NEXUS_KEEPALIVE= diff --git a/lib/model/interfaces/get-private-abilities.ts b/lib/model/interfaces/get-private-abilities.ts index 89c56bc3..27197080 100644 --- a/lib/model/interfaces/get-private-abilities.ts +++ b/lib/model/interfaces/get-private-abilities.ts @@ -7,7 +7,7 @@ const PAGE_SIZE = 100; const getPrivateAbilities = async ({ id, name, - locale = 'es', + locale = 'en', user, type, target, @@ -60,13 +60,13 @@ const getPrivateAbilities = async ({ return acc; }, {}); - adaptQuery.where?.OR = query?.OR; + adaptQuery.where.OR = query?.OR; } catch (e) { throw new Error('Code 000/2: Wrong filter'); } } - if (!adaptQuery?.where?.OR?.length > 0) { + if (!(adaptQuery?.where?.OR?.length > 0)) { throw new Error('Code 000/1: Malformed request'); } diff --git a/lib/model/interfaces/get-private-common-abilities.ts b/lib/model/interfaces/get-private-common-abilities.ts index 8e23bc38..931051c8 100644 --- a/lib/model/interfaces/get-private-common-abilities.ts +++ b/lib/model/interfaces/get-private-common-abilities.ts @@ -41,13 +41,13 @@ const getPrivateCommonAbilities = async ({ page = 0, offset = 0, limit = PAGE_SI return acc; }, {}); - adaptQuery.where?.OR = query?.OR; + adaptQuery.where.OR = query?.OR; } catch (e) { throw new Error('Code 000/2: Wrong filter'); } } - if (!adaptQuery?.where?.OR?.length > 0) { + if (!(adaptQuery?.where?.OR?.length > 0)) { throw new Error('Code 000/1: Malformed request'); } diff --git a/lib/model/interfaces/get-private-common-services.ts b/lib/model/interfaces/get-private-common-services.ts index 338489cd..8177a7ab 100644 --- a/lib/model/interfaces/get-private-common-services.ts +++ b/lib/model/interfaces/get-private-common-services.ts @@ -41,13 +41,13 @@ const getPrivateCommonServices = async ({ page = 0, offset = 0, limit = PAGE_SIZ return acc; }, {}); - adaptQuery.where?.OR = query?.OR; + adaptQuery.where.OR = query?.OR; } catch (e) { throw new Error('Code 000/2: Wrong filter'); } } - if (!adaptQuery?.where?.OR?.length > 0) { + if (!(adaptQuery?.where?.OR?.length > 0)) { throw new Error('Code 000/1: Malformed request'); } diff --git a/lib/model/interfaces/get-private-services.ts b/lib/model/interfaces/get-private-services.ts index d42b05d1..bdcf7e1a 100644 --- a/lib/model/interfaces/get-private-services.ts +++ b/lib/model/interfaces/get-private-services.ts @@ -4,7 +4,16 @@ import { whoAmI, canI } from '@controller'; const PAGE_SIZE = 100; -const getPrivateServices = async ({ id, user, target, page = 0, offset = 0, limit = PAGE_SIZE, filters = [] }: any) => { +const getPrivateServices = async ({ + id, + user, + locale = 'en', + target, + page = 0, + offset = 0, + limit = PAGE_SIZE, + filters = [], +}: any) => { const loggedUser = user || (await whoAmI({})); const adaptQuery: any = { @@ -46,7 +55,7 @@ const getPrivateServices = async ({ id, user, target, page = 0, offset = 0, limi return acc; }, {}); - adaptQuery.where?.OR = query?.OR; + adaptQuery.where.OR = query?.OR; const response = await PrivatePrisma.services.findMany(adaptQuery); return response; @@ -55,7 +64,7 @@ const getPrivateServices = async ({ id, user, target, page = 0, offset = 0, limi } } - if (!adaptQuery?.where?.OR?.length > 0) { + if (!(adaptQuery?.where?.OR?.length > 0)) { throw new Error('Code 000/1: Malformed request'); } diff --git a/lib/model/interfaces/get-public-listings-iface.ts b/lib/model/interfaces/get-public-listings-iface.ts index 85bcb480..054e2b46 100644 --- a/lib/model/interfaces/get-public-listings-iface.ts +++ b/lib/model/interfaces/get-public-listings-iface.ts @@ -5,6 +5,13 @@ const PAGE_SIZE = 100; const getPublicListings = async ({ page = 0, offset = 0, limit = PAGE_SIZE, filters = [] }: any) => { const adaptQuery: any = { + where: { + OR: [ + { + status: 'ACTIVE', + }, + ], + }, skip: page * (limit + offset), take: limit, cacheStrategy: process.env.NEXUS_STANDALONE !== 'true' ? { ttl: 90, swr: 60 * 60 * 24 * 7 } : undefined, @@ -45,13 +52,13 @@ const getPublicListings = async ({ page = 0, offset = 0, limit = PAGE_SIZE, filt return acc; }, {}); - adaptQuery.where?.OR = query?.OR; + adaptQuery.where.OR = query?.OR; } catch (e) { throw new Error('Code 000/2: Wrong filter'); } } - if (!adaptQuery?.where?.OR?.length > 0) { + if (!(adaptQuery?.where?.OR?.length > 0)) { throw new Error('Code 000/1: Malformed request'); } diff --git a/lib/model/prisma-private-connector.ts b/lib/model/prisma-private-connector.ts index 5c40a157..3bef84ec 100644 --- a/lib/model/prisma-private-connector.ts +++ b/lib/model/prisma-private-connector.ts @@ -5,14 +5,20 @@ import { withAccelerate } from '@prisma/extension-accelerate'; const prismaClientSingleton = () => { if (process.env.NEXUS_STANDALONE_PRISMA_ONLY === 'true') { + console.log('--- USING EDGE, BUT NOT USING PRISMA ACCELERATE'); return new PrivatePrisma(); } else { + console.log('--- USING EDGE AND USING PRISMA ACCELERATE'); return new PrivatePrisma().$extends(withAccelerate()); } }; const prismaClientSingletonStandalone = () => { - return new PrivatePrismaStandalone(); + if (process.env.NEXUS_STANDALONE === 'true') { + console.log('--- NOT USING EDGE AND NOT USING PRISMA ACCELERATE'); + return new PrivatePrismaStandalone(); + } + return; }; declare const globalThis: { diff --git a/lib/model/prisma-public-connector.ts b/lib/model/prisma-public-connector.ts index 0e3e31cb..f4c6f5bf 100644 --- a/lib/model/prisma-public-connector.ts +++ b/lib/model/prisma-public-connector.ts @@ -5,13 +5,19 @@ import { withAccelerate } from '@prisma/extension-accelerate'; const prismaClientSingleton = () => { if (process.env.NEXUS_STANDALONE_PRISMA_ONLY === 'true') { + console.log('--- USING EDGE, BUT NOT USING PRISMA ACCELERATE'); return new PublicPrisma(); } else { + console.log('--- USING EDGE AND USING PRISMA ACCELERATE'); return new PublicPrisma().$extends(withAccelerate()); } }; const prismaClientSingletonStandalone = () => { - return new PublicPrismaStandalone(); + if (process.env.NEXUS_STANDALONE === 'true') { + console.log('--- NOT USING EDGE AND NOT USING PRISMA ACCELERATE'); + return new PublicPrismaStandalone(); + } + return; }; declare const globalThis: { diff --git a/package.json b/package.json index 3868a9be..dce64054 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "schema:generate:public:standalone": "npx prisma generate --schema=./prisma/schema-public.prisma", "schema:generate:all:standalone": "npm run schema:generate:private:standalone && npm run schema:generate:public:standalone", "dev": "npm run schema:generate:all && next dev -p 3001", + "dev:vm": "npm run schema:generate:all:standalone && next dev -p 3001", "build": "npm run schema:generate:all && next build", "build:vm": "npm run schema:generate:all:standalone && next build", "start": "next start", diff --git a/src/app/api/v1/user/route.ts b/src/app/api/v1/user/route.ts index 0a66a34d..a0f73ea6 100644 --- a/src/app/api/v1/user/route.ts +++ b/src/app/api/v1/user/route.ts @@ -49,7 +49,7 @@ export async function POST(request: CombineRequest) { // const listings = body?.action; if (!!user && !!action) { - const payload = {}; + const payload = { data: {} }; try { if (action === 'get-own-abilities') { payload.data = await GetPrivateAbilities({ filters: ['user'] }); From 17fb0247dd6e3b92ddc803fc00055ef416c086b2 Mon Sep 17 00:00:00 2001 From: Angelo Reale <12191809+angeloreale@users.noreply.github.com> Date: Sun, 25 Aug 2024 13:32:27 +0100 Subject: [PATCH 18/18] ar(feat) [DPCP-40]: Parse Services. --- lib/model/interfaces/get-private-abilities.ts | 3 ++- lib/model/interfaces/get-private-services.ts | 5 +++-- src/app/api/v1/user/route.ts | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/model/interfaces/get-private-abilities.ts b/lib/model/interfaces/get-private-abilities.ts index 27197080..130e5a84 100644 --- a/lib/model/interfaces/get-private-abilities.ts +++ b/lib/model/interfaces/get-private-abilities.ts @@ -1,3 +1,4 @@ +/* eslint @typescript-eslint/no-unused-vars:0 */ // @controller/get-private-services.ts import { whoAmI } from '@controller'; import { PrivatePrisma } from '@model'; @@ -42,7 +43,7 @@ const getPrivateAbilities = async ({ const supportedQueries: Record = { user: { query: { - OR: [{ id: { in: loggedUser?.abilitiesIds }, name: { [locale]: name } }, { userOwner: loggedUser?.id }], + OR: [{ id: { in: loggedUser?.abilities } }, { userOwnerId: loggedUser.id }], }, }, // group: { diff --git a/lib/model/interfaces/get-private-services.ts b/lib/model/interfaces/get-private-services.ts index bdcf7e1a..a00c3cb0 100644 --- a/lib/model/interfaces/get-private-services.ts +++ b/lib/model/interfaces/get-private-services.ts @@ -1,3 +1,4 @@ +/* eslint @typescript-eslint/no-unused-vars:0 */ // @controller/get-private-services.ts import { PrivatePrisma } from '@model'; import { whoAmI, canI } from '@controller'; @@ -37,7 +38,7 @@ const getPrivateServices = async ({ const supportedQueries: Record = { user: { query: { - OR: [{ id: { in: loggedUser?.servicesIds }, name: { [locale]: name } }, { userOwner: loggedUser?.id }], + OR: [{ id: { in: loggedUser?.services } }, { userOwnerId: loggedUser.id }], }, }, // group: { @@ -60,7 +61,7 @@ const getPrivateServices = async ({ const response = await PrivatePrisma.services.findMany(adaptQuery); return response; } catch (e) { - throw new Error('Code 000/2: Wrong filter'); + throw new Error(`Code 000/2: Wrong filter: ${e}`); } } diff --git a/src/app/api/v1/user/route.ts b/src/app/api/v1/user/route.ts index a0f73ea6..74c9e870 100644 --- a/src/app/api/v1/user/route.ts +++ b/src/app/api/v1/user/route.ts @@ -52,9 +52,9 @@ export async function POST(request: CombineRequest) { const payload = { data: {} }; try { if (action === 'get-own-abilities') { - payload.data = await GetPrivateAbilities({ filters: ['user'] }); + payload.data = await GetPrivateAbilities({ filters: ['user'], user }); } else if (action === 'get-own-services') { - payload.data = await GetPrivateServices({ filters: ['user'] }); + payload.data = await GetPrivateServices({ filters: ['user'], user }); } else { throw new Error('Code 000/1: No specified action'); }