make app usable without account, remove extra stuff

This commit is contained in:
m5r
2023-04-29 18:30:07 +02:00
parent cb35455722
commit 03ae466c66
128 changed files with 617 additions and 14061 deletions

View File

@ -1,234 +0,0 @@
-- CreateEnum
CREATE TYPE "SubscriptionStatus" AS ENUM ('active', 'trialing', 'past_due', 'paused', 'deleted');
-- CreateEnum
CREATE TYPE "MembershipRole" AS ENUM ('OWNER', 'USER');
-- CreateEnum
CREATE TYPE "GlobalRole" AS ENUM ('SUPERADMIN', 'CUSTOMER');
-- CreateEnum
CREATE TYPE "TokenType" AS ENUM ('RESET_PASSWORD', 'INVITE_MEMBER');
-- CreateEnum
CREATE TYPE "Direction" AS ENUM ('Inbound', 'Outbound');
-- CreateEnum
CREATE TYPE "MessageStatus" AS ENUM ('Queued', 'Sending', 'Sent', 'Failed', 'Delivered', 'Undelivered', 'Receiving', 'Received', 'Accepted', 'Scheduled', 'Read', 'PartiallyDelivered', 'Canceled', 'Error');
-- CreateEnum
CREATE TYPE "CallStatus" AS ENUM ('Queued', 'Ringing', 'InProgress', 'Completed', 'Busy', 'Failed', 'NoAnswer', 'Canceled');
-- CreateTable
CREATE TABLE "TwilioAccount" (
"accountSid" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(6) NOT NULL,
"authToken" TEXT NOT NULL,
"twimlAppSid" TEXT,
"apiKeySid" TEXT,
"apiKeySecret" TEXT,
"organizationId" TEXT NOT NULL,
CONSTRAINT "TwilioAccount_pkey" PRIMARY KEY ("accountSid")
);
-- CreateTable
CREATE TABLE "Organization" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ NOT NULL,
CONSTRAINT "Organization_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Subscription" (
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ NOT NULL,
"paddleSubscriptionId" INTEGER NOT NULL,
"paddlePlanId" INTEGER NOT NULL,
"paddleCheckoutId" TEXT NOT NULL,
"status" "SubscriptionStatus" NOT NULL,
"updateUrl" TEXT NOT NULL,
"cancelUrl" TEXT NOT NULL,
"currency" TEXT NOT NULL,
"unitPrice" DOUBLE PRECISION NOT NULL,
"nextBillDate" DATE NOT NULL,
"lastEventTime" TIMESTAMP NOT NULL,
"cancellationEffectiveDate" DATE,
"organizationId" TEXT NOT NULL,
CONSTRAINT "Subscription_pkey" PRIMARY KEY ("paddleSubscriptionId")
);
-- CreateTable
CREATE TABLE "Membership" (
"id" TEXT NOT NULL,
"role" "MembershipRole" NOT NULL,
"organizationId" TEXT NOT NULL,
"userId" TEXT,
"invitedEmail" TEXT,
CONSTRAINT "Membership_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ NOT NULL,
"fullName" TEXT NOT NULL,
"email" TEXT NOT NULL,
"hashedPassword" TEXT,
"role" "GlobalRole" NOT NULL DEFAULT E'CUSTOMER',
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Session" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ NOT NULL,
"expiresAt" TIMESTAMPTZ,
"data" TEXT NOT NULL,
"userId" TEXT,
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Token" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ NOT NULL,
"hashedToken" TEXT NOT NULL,
"type" "TokenType" NOT NULL,
"expiresAt" TIMESTAMPTZ NOT NULL,
"sentTo" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"membershipId" TEXT NOT NULL,
CONSTRAINT "Token_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Message" (
"id" TEXT NOT NULL,
"sentAt" TIMESTAMPTZ NOT NULL,
"content" TEXT NOT NULL,
"recipient" TEXT NOT NULL,
"from" TEXT NOT NULL,
"to" TEXT NOT NULL,
"direction" "Direction" NOT NULL,
"status" "MessageStatus" NOT NULL,
"phoneNumberId" TEXT NOT NULL,
CONSTRAINT "Message_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PhoneCall" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"recipient" TEXT NOT NULL,
"from" TEXT NOT NULL,
"to" TEXT NOT NULL,
"status" "CallStatus" NOT NULL,
"direction" "Direction" NOT NULL,
"duration" TEXT NOT NULL,
"phoneNumberId" TEXT NOT NULL,
CONSTRAINT "PhoneCall_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PhoneNumber" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"number" TEXT NOT NULL,
"isCurrent" BOOLEAN NOT NULL,
"isFetchingMessages" BOOLEAN,
"isFetchingCalls" BOOLEAN,
"twilioAccountSid" TEXT NOT NULL,
CONSTRAINT "PhoneNumber_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "NotificationSubscription" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ NOT NULL,
"endpoint" TEXT NOT NULL,
"expirationTime" INTEGER,
"keys_p256dh" TEXT NOT NULL,
"keys_auth" TEXT NOT NULL,
"membershipId" TEXT NOT NULL,
CONSTRAINT "NotificationSubscription_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "TwilioAccount_organizationId_key" ON "TwilioAccount"("organizationId");
-- CreateIndex
CREATE UNIQUE INDEX "Subscription_paddleSubscriptionId_key" ON "Subscription"("paddleSubscriptionId");
-- CreateIndex
CREATE UNIQUE INDEX "Membership_organizationId_invitedEmail_key" ON "Membership"("organizationId", "invitedEmail");
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE UNIQUE INDEX "Token_membershipId_key" ON "Token"("membershipId");
-- CreateIndex
CREATE UNIQUE INDEX "Token_hashedToken_type_key" ON "Token"("hashedToken", "type");
-- CreateIndex
CREATE INDEX "Message_phoneNumberId_recipient_idx" ON "Message"("phoneNumberId", "recipient");
-- CreateIndex
CREATE INDEX "PhoneCall_phoneNumberId_recipient_idx" ON "PhoneCall"("phoneNumberId", "recipient");
-- CreateIndex
CREATE UNIQUE INDEX "PhoneNumber_twilioAccountSid_isCurrent_key" ON "PhoneNumber"("twilioAccountSid", "isCurrent") WHERE ("isCurrent" = true);
-- CreateIndex
CREATE UNIQUE INDEX "NotificationSubscription_endpoint_key" ON "NotificationSubscription"("endpoint");
-- AddForeignKey
ALTER TABLE "TwilioAccount" ADD CONSTRAINT "TwilioAccount_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Subscription" ADD CONSTRAINT "Subscription_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Membership" ADD CONSTRAINT "Membership_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Membership" ADD CONSTRAINT "Membership_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Token" ADD CONSTRAINT "Token_membershipId_fkey" FOREIGN KEY ("membershipId") REFERENCES "Membership"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Token" ADD CONSTRAINT "Token_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Message" ADD CONSTRAINT "Message_phoneNumberId_fkey" FOREIGN KEY ("phoneNumberId") REFERENCES "PhoneNumber"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PhoneCall" ADD CONSTRAINT "PhoneCall_phoneNumberId_fkey" FOREIGN KEY ("phoneNumberId") REFERENCES "PhoneNumber"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PhoneNumber" ADD CONSTRAINT "PhoneNumber_twilioAccountSid_fkey" FOREIGN KEY ("twilioAccountSid") REFERENCES "TwilioAccount"("accountSid") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "NotificationSubscription" ADD CONSTRAINT "NotificationSubscription_membershipId_fkey" FOREIGN KEY ("membershipId") REFERENCES "Membership"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,117 @@
-- CreateEnum
CREATE TYPE "Direction" AS ENUM ('Inbound', 'Outbound');
-- CreateEnum
CREATE TYPE "MessageStatus" AS ENUM ('Queued', 'Sending', 'Sent', 'Failed', 'Delivered', 'Undelivered', 'Receiving', 'Received', 'Accepted', 'Scheduled', 'Read', 'PartiallyDelivered', 'Canceled', 'Error');
-- CreateEnum
CREATE TYPE "CallStatus" AS ENUM ('Queued', 'Ringing', 'InProgress', 'Completed', 'Busy', 'Failed', 'NoAnswer', 'Canceled');
-- CreateTable
CREATE TABLE "TwilioAccount" (
"accountSid" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(6) NOT NULL,
"authToken" TEXT NOT NULL,
"twimlAppSid" TEXT,
"apiKeySid" TEXT,
"apiKeySecret" TEXT,
CONSTRAINT "TwilioAccount_pkey" PRIMARY KEY ("accountSid")
);
-- CreateTable
CREATE TABLE "Session" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(6) NOT NULL,
"expiresAt" TIMESTAMPTZ(6),
"data" TEXT NOT NULL,
"twilioAccountSid" TEXT,
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Message" (
"id" TEXT NOT NULL,
"sentAt" TIMESTAMPTZ(6) NOT NULL,
"content" TEXT NOT NULL,
"recipient" TEXT NOT NULL,
"from" TEXT NOT NULL,
"to" TEXT NOT NULL,
"direction" "Direction" NOT NULL,
"status" "MessageStatus" NOT NULL,
"phoneNumberId" TEXT NOT NULL,
CONSTRAINT "Message_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PhoneCall" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"recipient" TEXT NOT NULL,
"from" TEXT NOT NULL,
"to" TEXT NOT NULL,
"status" "CallStatus" NOT NULL,
"direction" "Direction" NOT NULL,
"duration" TEXT NOT NULL,
"phoneNumberId" TEXT NOT NULL,
CONSTRAINT "PhoneCall_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PhoneNumber" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"number" TEXT NOT NULL,
"isCurrent" BOOLEAN NOT NULL,
"isFetchingMessages" BOOLEAN,
"isFetchingCalls" BOOLEAN,
"twilioAccountSid" TEXT NOT NULL,
CONSTRAINT "PhoneNumber_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "NotificationSubscription" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ NOT NULL,
"endpoint" TEXT NOT NULL,
"expirationTime" INTEGER,
"keys_p256dh" TEXT NOT NULL,
"keys_auth" TEXT NOT NULL,
"twilioAccountSid" TEXT NOT NULL,
CONSTRAINT "NotificationSubscription_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "Message_phoneNumberId_recipient_idx" ON "Message"("phoneNumberId", "recipient");
-- CreateIndex
CREATE INDEX "PhoneCall_phoneNumberId_recipient_idx" ON "PhoneCall"("phoneNumberId", "recipient");
-- CreateIndex
CREATE UNIQUE INDEX "PhoneNumber_twilioAccountSid_isCurrent_key" ON "PhoneNumber"("twilioAccountSid", "isCurrent") WHERE ("isCurrent" = true);
-- CreateIndex
CREATE UNIQUE INDEX "NotificationSubscription_endpoint_key" ON "NotificationSubscription"("endpoint");
-- AddForeignKey
ALTER TABLE "Session" ADD CONSTRAINT "Session_twilioAccountSid_fkey" FOREIGN KEY ("twilioAccountSid") REFERENCES "TwilioAccount"("accountSid") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Message" ADD CONSTRAINT "Message_phoneNumberId_fkey" FOREIGN KEY ("phoneNumberId") REFERENCES "PhoneNumber"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PhoneCall" ADD CONSTRAINT "PhoneCall_phoneNumberId_fkey" FOREIGN KEY ("phoneNumberId") REFERENCES "PhoneNumber"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PhoneNumber" ADD CONSTRAINT "PhoneNumber_twilioAccountSid_fkey" FOREIGN KEY ("twilioAccountSid") REFERENCES "TwilioAccount"("accountSid") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "NotificationSubscription" ADD CONSTRAINT "NotificationSubscription_twilioAccountSid_fkey" FOREIGN KEY ("twilioAccountSid") REFERENCES "TwilioAccount"("accountSid") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -8,97 +8,26 @@ datasource db {
}
model TwilioAccount {
accountSid String @id
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
authToken String
twimlAppSid String?
apiKeySid String?
apiKeySecret String?
organizationId String @unique
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
phoneNumbers PhoneNumber[]
}
model Organization {
id String @id @default(cuid())
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
twilioAccount TwilioAccount?
memberships Membership[]
subscriptions Subscription[] // many subscriptions to keep a history
}
model Subscription {
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
paddleSubscriptionId Int @id @unique
paddlePlanId Int
paddleCheckoutId String
status SubscriptionStatus
updateUrl String
cancelUrl String
currency String
unitPrice Float
nextBillDate DateTime @db.Date
lastEventTime DateTime @db.Timestamp(6)
cancellationEffectiveDate DateTime? @db.Date
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
}
model Membership {
id String @id @default(cuid())
role MembershipRole
organizationId String
userId String?
invitedEmail String?
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
invitationToken Token?
notificationSubscription NotificationSubscription[]
@@unique([organizationId, invitedEmail])
}
model User {
id String @id @default(cuid())
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
fullName String
email String @unique
hashedPassword String?
role GlobalRole @default(CUSTOMER)
memberships Membership[]
sessions Session[]
tokens Token[]
accountSid String @id
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
authToken String
twimlAppSid String?
apiKeySid String?
apiKeySecret String?
phoneNumbers PhoneNumber[]
notificationSubscriptions NotificationSubscription[]
sessions Session[]
}
model Session {
id String @id @default(cuid())
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
expiresAt DateTime? @db.Timestamptz(6)
data String
userId String?
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model Token {
id String @id @default(cuid())
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
hashedToken String
type TokenType
expiresAt DateTime @db.Timestamptz(6)
sentTo String
userId String
membershipId String @unique
membership Membership @relation(fields: [membershipId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([hashedToken, type])
id String @id @default(cuid())
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
expiresAt DateTime? @db.Timestamptz(6)
data String
twilioAccountSid String?
twilioAccount TwilioAccount? @relation(fields: [twilioAccountSid], references: [accountSid], onDelete: Cascade)
}
model Message {
@ -155,31 +84,8 @@ model NotificationSubscription {
keys_p256dh String
keys_auth String
membership Membership @relation(fields: [membershipId], references: [id], onDelete: Cascade)
membershipId String
}
enum SubscriptionStatus {
active
trialing
past_due
paused
deleted
}
enum MembershipRole {
OWNER
USER
}
enum GlobalRole {
SUPERADMIN
CUSTOMER
}
enum TokenType {
RESET_PASSWORD
INVITE_MEMBER
twilioAccount TwilioAccount @relation(fields: [twilioAccountSid], references: [accountSid], onDelete: Cascade)
twilioAccountSid String
}
enum Direction {

View File

@ -1,52 +0,0 @@
import crypto from "crypto";
import { GlobalRole, MembershipRole } from "@prisma/client";
import db from "~/utils/db.server";
import { hashPassword } from "~/utils/auth.server";
async function seed() {
const email = "remixtape@admin.local";
const password = crypto.randomBytes(8).toString("hex");
// cleanup the existing database
await db.user.delete({ where: { email } }).catch(() => {});
await db.organization.deleteMany({
where: {
memberships: {
some: { user: { email } },
},
},
}).catch(() => {});
await db.user.create({
data: {
email,
fullName: "Admin",
hashedPassword: await hashPassword(password),
role: GlobalRole.SUPERADMIN,
memberships: {
create: {
role: MembershipRole.OWNER,
organization: {
create: {},
},
},
},
},
});
console.log("\nDatabase has been seeded. 🌱");
console.log("You can log into the newly-seeded admin account with the following credentials:");
console.log(`\x1B[1m\x1B[4memail\x1B[0m: ${email}`);
console.log(`\x1B[1m\x1B[4mpassword:\x1B[0m ${password}`);
}
seed()
.catch((error) => {
console.error(error);
process.exit(1);
})
.finally(async () => {
await db.$disconnect();
});