From 30a0f0922817d009726d229404afce8aae5e52ba Mon Sep 17 00:00:00 2001 From: tazo90 Date: Fri, 6 May 2022 20:28:45 +0200 Subject: [PATCH 01/10] Add pick and omit utility functions --- src/lib/lodash.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/lib/lodash.ts diff --git a/src/lib/lodash.ts b/src/lib/lodash.ts new file mode 100644 index 0000000..2838b63 --- /dev/null +++ b/src/lib/lodash.ts @@ -0,0 +1,16 @@ +// TODO: get rid of any types + +export function pick(obj: any, ...props: any) { + return props.reduce((result: any, prop: string) => { + result[prop] = obj[prop]; + return result; + }, {}); +} + +export function omit(obj: any, ...props: any) { + const result = { ...obj }; + props.forEach((prop: string) => { + delete result[prop]; + }); + return result; +} From 574d6268e084e730badb5e212dcedfca0b532023 Mon Sep 17 00:00:00 2001 From: tazo90 Date: Fri, 6 May 2022 20:29:07 +0200 Subject: [PATCH 02/10] Rewrite db schema --- src/lib/prisma/schema.prisma | 114 ++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 48 deletions(-) diff --git a/src/lib/prisma/schema.prisma b/src/lib/prisma/schema.prisma index ae52dc9..99702ea 100644 --- a/src/lib/prisma/schema.prisma +++ b/src/lib/prisma/schema.prisma @@ -33,21 +33,22 @@ model Credential { } model User { - id Int @id @default(autoincrement()) - username String? @unique + id Int @id @default(autoincrement()) + username String? @unique name String? - email String @unique + email String @unique emailVerified DateTime? password String? avatar String? - createdDate DateTime @default(now()) @map(name: "created") + createdDate DateTime @default(now()) @map(name: "created") credentials Credential[] teams Membership[] // organizations applications Application[] - identityProvider IdentityProvider @default(STORE_EYE) + consumers ApplicationConsumer[] + identityProvider IdentityProvider @default(STORE_EYE) identityProviderId String? - plan UserPlan @default(TRIAL) - verified Boolean? @default(false) + plan UserPlan @default(TRIAL) + verified Boolean? @default(false) projects Project[] @@map(name: "users") @@ -78,9 +79,9 @@ model Country { organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) organizationId Int - applications Application[] - job Job[] - store Store[] + consumers ApplicationConsumer[] + job Job[] + store Store[] @@unique([name, code]) @@map(name: "country") @@ -93,9 +94,9 @@ model Brand { organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) organizationId Int - applications Application[] - job Job[] - store Store[] + consumers ApplicationConsumer[] + job Job[] + store Store[] @@unique([name, organizationId]) @@map(name: "brand") @@ -164,16 +165,16 @@ model Payment { } model Project { - id Int @id @default(autoincrement()) - name String @unique - slug String? @unique - organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) + id Int @id @default(autoincrement()) + name String @unique + slug String? @unique + organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) organizationId Int - owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) + owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) ownerId Int - createdAt DateTime @default(now()) + createdAt DateTime @default(now()) updatedAt DateTime? - applications Application[] + consumers ApplicationConsumer[] @@map(name: "project") } @@ -185,49 +186,66 @@ enum ApplicationType { TRAININGS @map("trainings") } -enum ApplicationStatus { +model Application { + id Int @id @default(autoincrement()) + name String + owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) + ownerId Int + createdAt DateTime @default(now()) + consumers ApplicationConsumer[] + paid Boolean + payment Payment[] + type ApplicationType + + @@map(name: "application") +} + +enum ApplicationConsumerStatus { ACTIVE @map("active") DRAFT @map("draft") CLOSED @map("closed") } -model Application { - id Int @id @default(autoincrement()) - uid String @unique - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - userId Int - project Project @relation(fields: [projectId], references: [id], onDelete: Cascade) - projectId Int +model ApplicationConsumer { + id Int @id @default(autoincrement()) + uid String @unique + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + userId Int + + application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade) + applicationId Int + + project Project @relation(fields: [projectId], references: [id], onDelete: Cascade) + projectId Int + title String description String? brands Brand[] countries Country[] - createdAt DateTime @default(now()) + createdAt DateTime @default(now()) updatedAt DateTime? - status ApplicationStatus @default(DRAFT) - type ApplicationType - paid Boolean - payment Payment[] - token String @unique - expires DateTime - domain String - components Component[] + status ApplicationConsumerStatus @default(DRAFT) + + token String @unique + expires DateTime + domain String + components Component[] // TODO: Allow to define colors per application - @@map(name: "application") + @@map(name: "application_consumer") } model Component { - id Int @id @default(autoincrement()) - name String - slug String - description String? - application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade) - applicationId Int - clientId String? - secretId String? - tokenUrl String? - dataUrl String? + id Int @id @default(autoincrement()) + name String + slug String + description String? + consumer ApplicationConsumer @relation(fields: [consumerId], references: [id], onDelete: Cascade) + consumerId Int + clientId String? + secretId String? + tokenUrl String? + dataUrl String? @@map(name: "component") } From 573225c60b35bc2b63fb474cd8c3f414c7d085eb Mon Sep 17 00:00:00 2001 From: tazo90 Date: Fri, 6 May 2022 20:29:17 +0200 Subject: [PATCH 03/10] Add migration --- .../migration.sql | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/lib/prisma/migrations/20220506180039_consumers_table/migration.sql diff --git a/src/lib/prisma/migrations/20220506180039_consumers_table/migration.sql b/src/lib/prisma/migrations/20220506180039_consumers_table/migration.sql new file mode 100644 index 0000000..426b14a --- /dev/null +++ b/src/lib/prisma/migrations/20220506180039_consumers_table/migration.sql @@ -0,0 +1,153 @@ +/* + Warnings: + + - You are about to drop the column `description` on the `application` table. All the data in the column will be lost. + - You are about to drop the column `domain` on the `application` table. All the data in the column will be lost. + - You are about to drop the column `expires` on the `application` table. All the data in the column will be lost. + - You are about to drop the column `projectId` on the `application` table. All the data in the column will be lost. + - You are about to drop the column `status` on the `application` table. All the data in the column will be lost. + - You are about to drop the column `title` on the `application` table. All the data in the column will be lost. + - You are about to drop the column `token` on the `application` table. All the data in the column will be lost. + - You are about to drop the column `uid` on the `application` table. All the data in the column will be lost. + - You are about to drop the column `updatedAt` on the `application` table. All the data in the column will be lost. + - You are about to drop the column `userId` on the `application` table. All the data in the column will be lost. + - You are about to drop the column `applicationId` on the `component` table. All the data in the column will be lost. + - You are about to drop the `_ApplicationToBrand` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `_ApplicationToCountry` table. If the table is not empty, all the data it contains will be lost. + - Added the required column `name` to the `application` table without a default value. This is not possible if the table is not empty. + - Added the required column `ownerId` to the `application` table without a default value. This is not possible if the table is not empty. + - Added the required column `consumerId` to the `component` table without a default value. This is not possible if the table is not empty. + +*/ +-- CreateEnum +CREATE TYPE "ApplicationConsumerStatus" AS ENUM ('active', 'draft', 'closed'); + +-- DropForeignKey +ALTER TABLE "_ApplicationToBrand" DROP CONSTRAINT "_ApplicationToBrand_A_fkey"; + +-- DropForeignKey +ALTER TABLE "_ApplicationToBrand" DROP CONSTRAINT "_ApplicationToBrand_B_fkey"; + +-- DropForeignKey +ALTER TABLE "_ApplicationToCountry" DROP CONSTRAINT "_ApplicationToCountry_A_fkey"; + +-- DropForeignKey +ALTER TABLE "_ApplicationToCountry" DROP CONSTRAINT "_ApplicationToCountry_B_fkey"; + +-- DropForeignKey +ALTER TABLE "application" DROP CONSTRAINT "application_projectId_fkey"; + +-- DropForeignKey +ALTER TABLE "application" DROP CONSTRAINT "application_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "component" DROP CONSTRAINT "component_applicationId_fkey"; + +-- DropIndex +DROP INDEX "application_token_key"; + +-- DropIndex +DROP INDEX "application_uid_key"; + +-- AlterTable +ALTER TABLE "application" DROP COLUMN "description", +DROP COLUMN "domain", +DROP COLUMN "expires", +DROP COLUMN "projectId", +DROP COLUMN "status", +DROP COLUMN "title", +DROP COLUMN "token", +DROP COLUMN "uid", +DROP COLUMN "updatedAt", +DROP COLUMN "userId", +ADD COLUMN "name" TEXT NOT NULL, +ADD COLUMN "ownerId" INTEGER NOT NULL; + +-- AlterTable +ALTER TABLE "component" DROP COLUMN "applicationId", +ADD COLUMN "consumerId" INTEGER NOT NULL; + +-- DropTable +DROP TABLE "_ApplicationToBrand"; + +-- DropTable +DROP TABLE "_ApplicationToCountry"; + +-- DropEnum +DROP TYPE "ApplicationStatus"; + +-- CreateTable +CREATE TABLE "application_consumer" ( + "id" SERIAL NOT NULL, + "uid" TEXT NOT NULL, + "userId" INTEGER NOT NULL, + "applicationId" INTEGER NOT NULL, + "projectId" INTEGER NOT NULL, + "title" TEXT NOT NULL, + "description" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3), + "status" "ApplicationConsumerStatus" NOT NULL DEFAULT E'draft', + "token" TEXT NOT NULL, + "expires" TIMESTAMP(3) NOT NULL, + "domain" TEXT NOT NULL, + + CONSTRAINT "application_consumer_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "_ApplicationConsumerToBrand" ( + "A" INTEGER NOT NULL, + "B" INTEGER NOT NULL +); + +-- CreateTable +CREATE TABLE "_ApplicationConsumerToCountry" ( + "A" INTEGER NOT NULL, + "B" INTEGER NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "application_consumer_uid_key" ON "application_consumer"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "application_consumer_token_key" ON "application_consumer"("token"); + +-- CreateIndex +CREATE UNIQUE INDEX "_ApplicationConsumerToBrand_AB_unique" ON "_ApplicationConsumerToBrand"("A", "B"); + +-- CreateIndex +CREATE INDEX "_ApplicationConsumerToBrand_B_index" ON "_ApplicationConsumerToBrand"("B"); + +-- CreateIndex +CREATE UNIQUE INDEX "_ApplicationConsumerToCountry_AB_unique" ON "_ApplicationConsumerToCountry"("A", "B"); + +-- CreateIndex +CREATE INDEX "_ApplicationConsumerToCountry_B_index" ON "_ApplicationConsumerToCountry"("B"); + +-- AddForeignKey +ALTER TABLE "application" ADD CONSTRAINT "application_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "application_consumer" ADD CONSTRAINT "application_consumer_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "application_consumer" ADD CONSTRAINT "application_consumer_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "project"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "application_consumer" ADD CONSTRAINT "application_consumer_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "application"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "component" ADD CONSTRAINT "component_consumerId_fkey" FOREIGN KEY ("consumerId") REFERENCES "application_consumer"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_ApplicationConsumerToBrand" ADD FOREIGN KEY ("A") REFERENCES "application_consumer"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_ApplicationConsumerToBrand" ADD FOREIGN KEY ("B") REFERENCES "brand"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_ApplicationConsumerToCountry" ADD FOREIGN KEY ("A") REFERENCES "application_consumer"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_ApplicationConsumerToCountry" ADD FOREIGN KEY ("B") REFERENCES "country"("id") ON DELETE CASCADE ON UPDATE CASCADE; From 14cde644ee039e2ce9a1c598cfc1a1bd9bd595dc Mon Sep 17 00:00:00 2001 From: tazo90 Date: Fri, 6 May 2022 20:29:31 +0200 Subject: [PATCH 04/10] Update amrest seed scripts --- src/lib/prisma/fixtures/amrest.ts | 94 +++++++++++++++++++------------ src/lib/prisma/seed.ts | 81 ++++++++++++++------------ 2 files changed, 103 insertions(+), 72 deletions(-) diff --git a/src/lib/prisma/fixtures/amrest.ts b/src/lib/prisma/fixtures/amrest.ts index b8d5384..821c475 100644 --- a/src/lib/prisma/fixtures/amrest.ts +++ b/src/lib/prisma/fixtures/amrest.ts @@ -1,4 +1,4 @@ -import { ApplicationStatus, ApplicationType, UserPlan } from "@prisma/client"; +import { ApplicationConsumerStatus, ApplicationType, UserPlan } from "@prisma/client"; const organization = { name: "AmRest", @@ -145,46 +145,68 @@ const projects = [ const apps = [ { - uid: "1", - title: "KFC PL", - token: "ctskfcpl", - status: ApplicationStatus.DRAFT, - type: ApplicationType.JOBS, - paid: false, - domain: "https://cts.pl", - project: "cts", - }, - { - uid: "2", - title: "KFC PL", - token: "ecommercekfcpl", - status: ApplicationStatus.DRAFT, - type: ApplicationType.ECOMMERCE, + name: "Stores", paid: false, - domain: "https://kfc.pl", - project: "ecommerce", - }, - { - uid: "3", - title: "PH PL", - token: "ecommercephpl", - status: ApplicationStatus.DRAFT, - type: ApplicationType.ECOMMERCE, + type: ApplicationType.STORES, + consumers: [ + { + uid: "1", + title: "AmRest Stores", + token: "amspacestores", + status: ApplicationConsumerStatus.DRAFT, + domain: "https://amspace.amrest.eu", + project: "amspace", + brands: ["kfc", "ph", "bk", "sbx"], + countries: ["pl", "cz", "hu"] + }, + ] + }, + { + name: "Jobs", paid: false, - domain: "http://pizzahut.pl", - project: "ecommerce", + type: ApplicationType.JOBS, + consumers: [ + { + uid: "2", + title: "KFC PL", + token: "ctskfcpl", + status: ApplicationConsumerStatus.DRAFT, + domain: "https://cts.pl", + project: "cts", + brands: ["kfc"], + countries: ["pl"], + }, + + ] }, { - uid: "4", - title: "AmRest Stores", - token: "amspacestores", - status: ApplicationStatus.DRAFT, - type: ApplicationType.STORES, + name: "ECommerce", paid: false, - domain: "https://amspace.amrest.eu", - project: "amspace", - }, -]; + type: ApplicationType.ECOMMERCE, + consumers: [ + { + uid: "3", + title: "KFC PL", + token: "ecommercekfcpl", + status: ApplicationConsumerStatus.DRAFT, + domain: "https://kfc.pl", + project: "ecommerce", + brands: ["kfc"], + countries: ["pl"] + }, + { + uid: "4", + title: "PH PL", + token: "ecommercephpl", + status: ApplicationConsumerStatus.DRAFT, + domain: "http://pizzahut.pl", + project: "ecommerce", + brands: ["ph"], + countries: ["pl"] + }, + ] + }, +] export default { organization, diff --git a/src/lib/prisma/seed.ts b/src/lib/prisma/seed.ts index 0416d34..c7473ed 100644 --- a/src/lib/prisma/seed.ts +++ b/src/lib/prisma/seed.ts @@ -1,8 +1,10 @@ +//@ts-nocheck import { PrismaClient, Prisma, MembershipRole, UserPlan } from "@prisma/client"; import { hashPassword } from "../auth"; import data from "./fixtures/amrest"; import { generateUniqueAPIKey } from "../api-keys"; +import { omit } from "../lodash"; require("dotenv"); @@ -123,46 +125,49 @@ async function createCountries( }); } -async function createProjectsAndApps( +async function createProjects( organization: any, projectOwner: any, - appOwner: any, - projects: any, - apps: any + projects: any ) { projects.map(async (project: any) => { - const projectApps = apps.filter((app: any) => app.project === project.slug); - - const proj = await prisma.project.create({ + await prisma.project.create({ data: { ...project, organization: { connect: { id: organization.id } }, owner: { connect: { id: projectOwner.id } }, + } + }) + }); +} + +async function createAppsAndConsumers( + appOwner: any, + apps: any +) { + apps.map(async (app: any) => { + // const projectApps = projects.filter((project: any) => app.project === project.slug); + + const appObj = await prisma.application.create({ + data: { + ...omit(app, 'consumers'), + owner: { connect: { id: appOwner.id } }, }, }); - console.log(`\t👤 Created project '${proj.name}'`); - - // Create apps - projectApps?.map(async (app: any) => { - const { project, ...appData } = app; + console.log(`\t👤 Created app '${app.name}'`); - await createApp(organization, appOwner, proj, appData); - }); + // Create consumers + app?.consumers.map(async (consumer: any) => await createConsumer(appObj, consumer)); }); } -async function createApp( - organization: any, - owner: any, - project: any, - app: any -) { +async function createConsumer(app: any, consumer: any) { const [hashedApiKey, apiKey] = generateUniqueAPIKey(); const brands = await prisma.brand.findMany({ where: { - organizationId: organization.id, + name: { in: consumer.brands } }, select: { id: true, @@ -170,33 +175,34 @@ async function createApp( }); const countries = await prisma.country.findMany({ where: { - organizationId: organization.id, + code: { in: consumer.countries } }, select: { id: true, }, }); - const application = await prisma.application.create({ + const consumerObj = await prisma.applicationConsumer.create({ data: { - ...app, - project: { connect: { id: project.id } }, - user: { connect: { id: owner.id } }, + ...consumer, + application: { connect: { id: app.id }}, + project: { connect: { slug: consumer.project } }, + user: { connect: { id: app.ownerId } }, expires: new Date( "Tue Sep 21 2022 16:16:50 GMT-0400 (Eastern Daylight Time)" ), token: hashedApiKey, brands: { - connect: [{ id: brands[0].id }, { id: brands[1].id }], // KFC & PH + connect: brands.map((brand) => ({id: brand.id})) }, countries: { - connect: [{ id: countries[0].id }, { id: countries[1].id }], // PL & CZ + connect: countries.map((country) => ({id: country.id})) }, }, }); console.log( - `\t👤 Created app '${application.title}' in project '${project.slug}` + `\t👤 Created consumer '${consumerObj.title}' in app ${app.name}` ); } @@ -230,13 +236,16 @@ async function main() { // Create countries await createCountries(org, data.countries); // Create projects - await createProjectsAndApps( - org, - proUser, - freeUser, - data.projects, - data.apps - ); + await createProjects(org, proUser, data.projects); + // Create apps and consumers + await createAppsAndConsumers(proUser, data.apps) + // await createProjectsAndApps( + // org, + // proUser, + // freeUser, + // data.projects, + // data.apps + // ); } } From 7b27b42595c521e8d684c4873e825a6f7e0bedf7 Mon Sep 17 00:00:00 2001 From: tazo90 Date: Fri, 6 May 2022 21:58:56 +0200 Subject: [PATCH 05/10] Remove name column from application entity --- src/lib/prisma/fixtures/amrest.ts | 21 ++++++++----------- .../migration.sql | 8 +++++++ src/lib/prisma/schema.prisma | 1 - src/lib/prisma/seed.ts | 21 ++++++------------- 4 files changed, 23 insertions(+), 28 deletions(-) create mode 100644 src/lib/prisma/migrations/20220506195808_remove_name_from_application/migration.sql diff --git a/src/lib/prisma/fixtures/amrest.ts b/src/lib/prisma/fixtures/amrest.ts index 821c475..28f9c00 100644 --- a/src/lib/prisma/fixtures/amrest.ts +++ b/src/lib/prisma/fixtures/amrest.ts @@ -113,18 +113,18 @@ const countries = [ const users = [ { - email: "tazo90@gmail.com", + email: "tazo@gmail.com", password: "pass", username: "tazo90", name: "ala", - plan: UserPlan.FREE, + plan: UserPlan.PRO, }, { - email: "dieselo@o2.pl", - password: "diesel", - username: "teampro", + email: "dieselo@gmail.pl", + password: "pass", + username: "dieselo", name: "Team Pro Example", - plan: UserPlan.PRO, + plan: UserPlan.FREE, }, ]; @@ -145,9 +145,8 @@ const projects = [ const apps = [ { - name: "Stores", - paid: false, type: ApplicationType.STORES, + paid: false, consumers: [ { uid: "1", @@ -162,9 +161,8 @@ const apps = [ ] }, { - name: "Jobs", - paid: false, type: ApplicationType.JOBS, + paid: false, consumers: [ { uid: "2", @@ -180,9 +178,8 @@ const apps = [ ] }, { - name: "ECommerce", - paid: false, type: ApplicationType.ECOMMERCE, + paid: false, consumers: [ { uid: "3", diff --git a/src/lib/prisma/migrations/20220506195808_remove_name_from_application/migration.sql b/src/lib/prisma/migrations/20220506195808_remove_name_from_application/migration.sql new file mode 100644 index 0000000..c9797a7 --- /dev/null +++ b/src/lib/prisma/migrations/20220506195808_remove_name_from_application/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - You are about to drop the column `name` on the `application` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "application" DROP COLUMN "name"; diff --git a/src/lib/prisma/schema.prisma b/src/lib/prisma/schema.prisma index 99702ea..1abc530 100644 --- a/src/lib/prisma/schema.prisma +++ b/src/lib/prisma/schema.prisma @@ -188,7 +188,6 @@ enum ApplicationType { model Application { id Int @id @default(autoincrement()) - name String owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) ownerId Int createdAt DateTime @default(now()) diff --git a/src/lib/prisma/seed.ts b/src/lib/prisma/seed.ts index c7473ed..8239a18 100644 --- a/src/lib/prisma/seed.ts +++ b/src/lib/prisma/seed.ts @@ -146,8 +146,6 @@ async function createAppsAndConsumers( apps: any ) { apps.map(async (app: any) => { - // const projectApps = projects.filter((project: any) => app.project === project.slug); - const appObj = await prisma.application.create({ data: { ...omit(app, 'consumers'), @@ -210,24 +208,24 @@ async function main() { await dropTables(); // Create users - const freeUser = await createUser({ + const proUser = await createUser({ user: data.users[0], }); - const proUser = await createUser({ + const freeUser = await createUser({ user: data.users[1], }); // Create organization and members const org = await createOrganizationAndUsers(data.organization, [ - { - id: freeUser.id, - username: freeUser.name || "Unknown", - }, { id: proUser.id, username: proUser.name || "Unknown", }, + { + id: freeUser.id, + username: freeUser.name || "Unknown", + }, ]); if (org) { @@ -239,13 +237,6 @@ async function main() { await createProjects(org, proUser, data.projects); // Create apps and consumers await createAppsAndConsumers(proUser, data.apps) - // await createProjectsAndApps( - // org, - // proUser, - // freeUser, - // data.projects, - // data.apps - // ); } } From 7811d46de074b85e4f75a3b2f50cb216899816d8 Mon Sep 17 00:00:00 2001 From: tazo90 Date: Fri, 6 May 2022 22:00:03 +0200 Subject: [PATCH 06/10] Rebuild application and project api --- src/components/apps/index.ts | 18 +++- src/pages/apps/[name]/overview.tsx | 19 +++- src/pages/apps/index.tsx | 58 +++++------ src/server/routers/api/application.ts | 133 +++++--------------------- src/server/routers/api/project.ts | 23 +---- 5 files changed, 87 insertions(+), 164 deletions(-) diff --git a/src/components/apps/index.ts b/src/components/apps/index.ts index b109d68..1ca9e2f 100644 --- a/src/components/apps/index.ts +++ b/src/components/apps/index.ts @@ -1,7 +1,21 @@ import StoresApp from "./stores"; import JobsApp from "./jobs"; +import { ApplicationType } from "@prisma/client"; export default { - stores: StoresApp, - jobs: JobsApp, + stores: { + app: StoresApp, + type: ApplicationType.STORES, + description: 'Stores locator' + }, + jobs: { + app: JobsApp, + type: ApplicationType.JOBS, + description: 'Jobs locator' + }, + ecommerce: { + app: null, + type: ApplicationType.ECOMMERCE, + description: 'Ecommerce locator' + } }; diff --git a/src/pages/apps/[name]/overview.tsx b/src/pages/apps/[name]/overview.tsx index b393abb..f6f8ae4 100644 --- a/src/pages/apps/[name]/overview.tsx +++ b/src/pages/apps/[name]/overview.tsx @@ -9,6 +9,8 @@ import { LocationMarkerIcon, TerminalIcon, } from "@heroicons/react/solid"; +import { capitalize } from "@lib/strings"; +import { useRouter } from "next/router"; export const appMenu = [ { @@ -46,13 +48,17 @@ export const appMenu = [ }, ]; -const MenuHeader = () => ( +type MenuHeaderProps = { + appName?: string; +} + +const MenuHeader = (props: MenuHeaderProps) => (

- Stores + {props.appName && capitalize(props.appName)}

); @@ -145,8 +151,15 @@ function Consumers() { } export default function AppPage() { + const { query } = useRouter(); + return ( - }> + + } + > ); diff --git a/src/pages/apps/index.tsx b/src/pages/apps/index.tsx index 2113197..cacbef4 100644 --- a/src/pages/apps/index.tsx +++ b/src/pages/apps/index.tsx @@ -1,29 +1,32 @@ -import DashboardLayout from "@components/layouts/dashboard"; +import { Fragment } from "react"; import Link from "next/link"; - -import { DotsHorizontalIcon, LocationMarkerIcon } from "@heroicons/react/solid"; import { Menu, Transition } from "@headlessui/react"; -import { classNames } from "@lib/classnames"; -import { Fragment } from "react"; +import { DotsHorizontalIcon, LocationMarkerIcon } from "@heroicons/react/solid"; -const apps = [ - { - id: "stores", - title: "Stores", - description: - "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.", - integrations: 10, - img: '"https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80";', - }, -]; +import DashboardLayout from "@components/layouts/dashboard"; +import apps from "@components/apps"; +import { classNames } from "@lib/classnames"; +import { trpc } from "@lib/trpc"; +import { capitalize } from "@lib/strings"; +import showToast from "@lib/notification"; export default function AppsPage() { + const { data } = trpc.useQuery(['api.application.all', {}]); + const utils = trpc.useContext(); + + const deleteApp = trpc.useMutation("api.application.delete", { + async onSuccess() { + showToast("Uninstalled app", "success"); + await utils.invalidateQueries(["api.application.all"]); + }, + }); + const projectActions = [ { - name: "Delete", + name: "Uninstall", href: "#", - // onClick: (slug: string) => deleteProject.mutate({ slug }), + onClick: (id: number) => deleteApp.mutate({ id }), }, ]; @@ -40,13 +43,13 @@ export default function AppsPage() { role="list" className="mt-4 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3" > - {apps?.map((app) => ( + {data?.map((app) => (
  • -

    Integrations:

    - {app.integrations} +

    Consumers:

    + {app._count.consumers}
    @@ -119,15 +122,6 @@ export default function AppsPage() {
  • ))} - - {/* Add project dialog */} - {/* setAddProjectModal(false)} - > - setAddProjectModal(false)} /> - */} ); } diff --git a/src/server/routers/api/application.ts b/src/server/routers/api/application.ts index 2cbfe2e..236503b 100644 --- a/src/server/routers/api/application.ts +++ b/src/server/routers/api/application.ts @@ -1,140 +1,55 @@ import { z } from "zod"; -import short from "short-uuid"; import { createProtectedRouter } from "@server/create-router"; -import { TRPCError } from "@trpc/server"; -import { generateUniqueAPIKey } from "@lib/api-keys"; export const applicationRouter = createProtectedRouter() // .query("all", { input: z.object({ - projectSlug: z.string().optional(), organizationSlug: z.string().optional(), }), - async resolve({ ctx, input }) { + async resolve({ ctx }) { let query: any = {}; - if (input.projectSlug) { - query.where = { - project: { - is: { - slug: input.projectSlug, - }, - }, - }; - } - - if (input.organizationSlug) { - query.where = { - project: { - is: { - organization: { - is: { - slug: input.organizationSlug, - }, - }, - }, - }, - }; - } + // if (input.organizationSlug) { + // query.where = { + // project: { + // is: { + // organization: { + // is: { + // slug: input.organizationSlug, + // }, + // }, + // }, + // }, + // }; + // } return await ctx.prisma.application.findMany({ ...query, select: { id: true, - uid: true, - title: true, - description: true, + name: true, + ownerId: true, type: true, - project: { - select: { - name: true, - }, - }, - brands: { - select: { - id: true, - name: true, - }, - }, - countries: { + paid: true, + _count: { select: { - id: true, - code: true, + consumers: true, }, }, - status: true, - paid: true, - token: true, - domain: true, - }, - }); - }, - }) - .query("get", { - input: z.object({ - uid: z.string(), - }), - async resolve({ ctx, input }) { - return await ctx.prisma.application.findUnique({ - where: { - uid: input.uid, - }, - select: { - uid: true, - title: true, - description: true, - status: true, - paid: true, - token: true, - domain: true, - brands: true, - countries: true, - type: true, - expires: true, }, }); }, }) - .mutation("add", { + .mutation("delete", { input: z.object({ - projectSlug: z.string(), - title: z.string(), - description: z.string().nullable(), - domain: z.string(), - brands: z.array(z.object({ id: z.number() })), - countries: z.array(z.object({ id: z.number() })), + id: z.number(), }), async resolve({ ctx, input }) { - const [hashedApiKey, apiKey] = generateUniqueAPIKey(); - - return await ctx.prisma.application.create({ - data: { - uid: short.uuid(), - user: { - connect: { id: ctx.user.id }, - }, - project: { - connect: { - slug: input.projectSlug, - }, - }, - title: input.title, - description: input.description, - brands: { - connect: input.brands, - }, - countries: { - connect: input.countries, - }, - domain: input.domain, - paid: false, - expires: new Date( - "Tue Sep 21 2022 16:16:50 GMT-0400 (Eastern Daylight Time)" - ), - token: hashedApiKey, - }, + await ctx.prisma.application.delete({ + where: { id: input.id }, }); }, }); + \ No newline at end of file diff --git a/src/server/routers/api/project.ts b/src/server/routers/api/project.ts index df9eea0..9185cde 100644 --- a/src/server/routers/api/project.ts +++ b/src/server/routers/api/project.ts @@ -20,11 +20,11 @@ export const projectRouter = createProtectedRouter() username: true, }, }, - _count: { - select: { - applications: true, - }, - }, + // _count: { + // select: { + // consumers: true, + // }, + // }, }, }); }, @@ -43,19 +43,6 @@ export const projectRouter = createProtectedRouter() slug: true, name: true, owner: true, - applications: { - select: { - id: true, - title: true, - description: true, - status: true, - paid: true, - token: true, - domain: true, - brands: true, - countries: true, - }, - }, }, }); }, From 2bdbbe7b53b55dfa6e547bccf0f10633cc0ae5fa Mon Sep 17 00:00:00 2001 From: tazo90 Date: Fri, 6 May 2022 22:03:38 +0200 Subject: [PATCH 07/10] Small changes in application api --- src/pages/apps/[name]/app.tsx | 2 +- src/pages/apps/[name]/consumers/[id]/app.tsx | 2 +- src/pages/projects/index.tsx | 2 +- src/server/routers/api/application.ts | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pages/apps/[name]/app.tsx b/src/pages/apps/[name]/app.tsx index be61831..77b0950 100644 --- a/src/pages/apps/[name]/app.tsx +++ b/src/pages/apps/[name]/app.tsx @@ -19,7 +19,7 @@ const MenuHeader = () => ( export default function AppPage() { const { query } = useRouter(); - const AppViewer = apps[query.name]; + const AppViewer = apps[query.name].app; return ( - {project._count.applications} + {/* {project._count.consumers} */} Apps diff --git a/src/server/routers/api/application.ts b/src/server/routers/api/application.ts index 236503b..edc558a 100644 --- a/src/server/routers/api/application.ts +++ b/src/server/routers/api/application.ts @@ -29,7 +29,6 @@ export const applicationRouter = createProtectedRouter() ...query, select: { id: true, - name: true, ownerId: true, type: true, paid: true, From 4d5a6540e8d2f1d7427a7eb1a31f9c2f4ff6a0e1 Mon Sep 17 00:00:00 2001 From: tazo90 Date: Sat, 7 May 2022 20:30:16 +0200 Subject: [PATCH 08/10] Use enable in useQuery to avoid undefined query params from useRouter --- src/components/common/page-menu.tsx | 1 - src/pages/apps/[name]/consumers/index.tsx | 10 ++++++---- src/server/routers/api.ts | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/common/page-menu.tsx b/src/components/common/page-menu.tsx index 8bf75d1..5879153 100644 --- a/src/components/common/page-menu.tsx +++ b/src/components/common/page-menu.tsx @@ -38,7 +38,6 @@ export default function PageMenu(props: PageMenuProps) { )}