Skip to content

Commit

Permalink
refractor Planetscale to Neon
Browse files Browse the repository at this point in the history
  • Loading branch information
Codehagen committed Apr 17, 2024
1 parent 83521a4 commit 3002dd2
Show file tree
Hide file tree
Showing 17 changed files with 302 additions and 349 deletions.
29 changes: 0 additions & 29 deletions .github/workflows/vercel-preview.yaml

This file was deleted.

28 changes: 0 additions & 28 deletions .github/workflows/vercel-production.yaml

This file was deleted.

6 changes: 3 additions & 3 deletions apps/www/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ export const env = createEnv({
* This way you can ensure the app isn't built with invalid env vars.
*/
server: {
DATABASE_HOST: z.string().min(1),
DATABASE_USERNAME: z.string().min(1),
DATABASE_PASSWORD: z.string().min(1),
// DATABASE_HOST: z.string().min(1),
// DATABASE_USERNAME: z.string().min(1),
// DATABASE_PASSWORD: z.string().min(1),
STRIPE_API_KEY: z.string().min(1).optional(),
STRIPE_WEBHOOK_SECRET: z.string().min(1).optional(),
},
Expand Down
22 changes: 9 additions & 13 deletions packages/db/drizzle.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@ import type { Config } from "drizzle-kit";

dotenv.config({ path: "../../.env.local" });

const uri = [
"mysql://",
process.env.DATABASE_USERNAME,
":",
process.env.DATABASE_PASSWORD,
"@",
process.env.DATABASE_HOST,
":3306/",
process.env.DATABASE_NAME,
'?ssl={"rejectUnauthorized":true}',
].join("");
const uri = process.env.DATABASE_URL || "";

if (!uri) {
throw new Error("DATABASE_URL is not set in the environment variables.");
}

export default {
schema: "./src/schema",
driver: "mysql2",
dbCredentials: { uri },
driver: "pg",
dbCredentials: {
connectionString: uri,
},
tablesFilter: ["projectx_*"],
} satisfies Config;
3 changes: 2 additions & 1 deletion packages/db/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@
"clean": "git clean -xdf .turbo node_modules",
"format": "prettier --check . --ignore-path ../../.gitignore",
"lint": "eslint . --no-error-on-unmatched-pattern",
"push": "drizzle-kit push:mysql",
"push": "drizzle-kit push:pg",
"studio": "drizzle-kit studio",
"seed": "tsx ./src/seed.ts",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@neondatabase/serverless": "^0.9.1",
"@planetscale/database": "^1.16.0",
"drizzle-orm": "^0.29.3",
"iso-country-currency": "^0.7.2"
Expand Down
23 changes: 13 additions & 10 deletions packages/db/src/data/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,25 @@ const connectorsData: CanonicalConnector[] = [];
const integrationsData: CanonicalIntegration[] = [];
const resourcesData: CanonicalResource[] = [];

// Helper function to convert numeric IDs to string format for varchar fields
const formatId = (id: number) => id.toString();

// seed connectors
connectorsConfigData.push({
id: BigInt(1),
id: formatId(1),
env: "SANDBOX",
secret: {
clientId: process.env.PLAID_CLIENT_ID,
clientSecret: process.env.PLAID_CLIENT_SECRET,
},
orgId: "org_",
connectorId: BigInt(1),
connectorId: formatId(1),
createdAt: new Date(),
updatedAt: new Date(),
});

connectorsData.push({
id: BigInt(1),
id: formatId(1),
name: "plaid",
logoUrl:
"https://pbs.twimg.com/profile_images/1415067514460000256/1iPIdd20_400x400.png",
Expand All @@ -41,20 +44,20 @@ connectorsData.push({
});

connectorsConfigData.push({
id: BigInt(2),
id: formatId(2),
env: "SANDBOX",
secret: {
secretId: process.env.GOCARDLESS_SECRET_ID,
secretKey: process.env.GOCARDLESS_SECRET_KEY,
},
orgId: "org_",
connectorId: BigInt(2),
connectorId: formatId(2),
createdAt: new Date(),
updatedAt: new Date(),
});

connectorsData.push({
id: BigInt(2),
id: formatId(2),
name: "gocardless",
logoUrl: "https://asset.brandfetch.io/idNfPDHpG3/idamTYtkQh.png",
status: ConnectorStatus.ACTIVE,
Expand All @@ -64,15 +67,15 @@ connectorsData.push({
});

integrationsData.push({
id: BigInt(1),
id: formatId(1),
name: "Sandbox",
connectorId: BigInt(2),
connectorId: formatId(2),
});

resourcesData.push({
id: BigInt(1),
id: formatId(1),
originalId: "28ce28fb-877b-4e5c-882a-6066f3f5f728",
integrationId: BigInt(1),
integrationId: formatId(1),
userId: "user_",
createdAt: new Date(),
updatedAt: new Date(),
Expand Down
54 changes: 0 additions & 54 deletions packages/db/src/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,60 +19,6 @@ export const ResourceStatus = {
export type ResourceStatus =
(typeof ResourceStatus)[keyof typeof ResourceStatus];

// Plaid Enums

export const Products = {
Assets: "assets",
Auth: "auth",
Balance: "balance",
// Products.Identity, "identity",
// Products.Investments, "investments",
// Products.InvestmentsAuth, "investments_auth",
// Products.Liabilities, "liabilities",
// Products.PaymentInitiation, "payment_initiation",
// Products.IdentityVerification,
Transactions: "transactions",
// Products.CreditDetails,
// Products.Income,
// Products.IncomeVerification,
// Products.DepositSwitch,
// Products.StandingOrders,
// Products.Transfer,
// Products.Employment,
RecurringTransactions: "recurring_transactions",
// Products.Signal,
// Products.Statements,
} as const;
export type Products = (typeof Products)[keyof typeof Products];

export const TransactionCode = {
Adjustment: "adjustment",
Atm: "atm",
BankCharge: "bank charge",
BillPayment: "bill payment",
Cash: "cash",
Cashback: "cashback",
Cheque: "cheque",
DirectDebit: "direct debit",
Interest: "interest",
Null: "null",
Purchase: "purchase",
StandingOrder: "standing order",
Transfer: "transfer",
} as const;
export type TransactionCode =
(typeof TransactionCode)[keyof typeof TransactionCode];

export const MerchantConfidenceLevel = {
VeryHigh: "VERY_HIGH",
High: "HIGH",
Medium: "MEDIUM",
Low: "LOW",
Unknown: "UNKNOWN",
} as const;
export type MerchantConfidenceLevel =
(typeof MerchantConfidenceLevel)[keyof typeof MerchantConfidenceLevel];

export const PrimaryCategory = {
INCOME: "INCOME",
TRANSFER_IN: "TRANSFER_IN",
Expand Down
16 changes: 4 additions & 12 deletions packages/db/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Client } from "@planetscale/database";
import { drizzle } from "drizzle-orm/planetscale-serverless";
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";
import { customAlphabet } from "nanoid";

import * as asset from "./schema/asset";
Expand Down Expand Up @@ -30,20 +30,12 @@ export type CanonicalAccount = typeof schema.account.$inferInsert;
export type CanonicalBalance = typeof schema.balance.$inferInsert;
export type CanonicalTransaction = typeof schema.transaction.$inferInsert;

export { mySqlTable as tableCreator } from "./schema/_table";
export { pgTable as tableCreator } from "./schema/_table";
export * from "./enum";

export * from "drizzle-orm";

export const db = drizzle(
new Client({
host: process.env.DATABASE_HOST,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
}).connection(),
{ schema },
);
export const db = drizzle(neon(process.env.DATABASE_URL || ""));

// Use custom alphabet without special chars for less chaotic, copy-able URLs
// Will not collide for a long long time: https://zelark.github.io/nano-id-cc/
export const genId = customAlphabet("0123456789abcdefghijklmnopqrstuvwxyz", 16);
4 changes: 2 additions & 2 deletions packages/db/src/schema/_table.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { mysqlTableCreator } from "drizzle-orm/mysql-core";
import { pgTableCreator } from "drizzle-orm/pg-core";

/**
* This is an example of how to use the multi-project schema feature of Drizzle ORM.
* Use the same database instance for multiple projects.
*
* @see https://orm.drizzle.team/docs/goodies#multi-project-schema
*/
export const mySqlTable = mysqlTableCreator((name) => `projectx_${name}`);
export const pgTable = pgTableCreator((name) => `badget_${name}`);
60 changes: 33 additions & 27 deletions packages/db/src/schema/asset.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,66 @@
import { relations, sql } from "drizzle-orm";
import {
bigint,
index,
json,
mysqlEnum,
timestamp,
varchar,
} from "drizzle-orm/mysql-core";
import { index, json, pgEnum, timestamp, varchar } from "drizzle-orm/pg-core";

import { AssetType } from "../enum";
import { mySqlTable } from "./_table";
import { pgTable } from "./_table";

export const asset = mySqlTable(
export const assetTypeEnum = pgEnum("account_type", [
AssetType.STOCKS,
AssetType.CRYPTO,
AssetType.BONDS,
AssetType.ETF,
AssetType.OPTIONS,
AssetType.FUTURES,
AssetType.REAL_ESTATE,
AssetType.COMMODITIES,
]);

export const asset = pgTable(
"asset",
{
id: bigint("id", { mode: "bigint" }).primaryKey().autoincrement(),
id: varchar("id", { length: 30 }).primaryKey(), // prefix_ + nanoid (16)
createdAt: timestamp("created_at")
.default(sql`CURRENT_TIMESTAMP`)
.notNull(),
updatedAt: timestamp("updated_at").onUpdateNow(),
updatedAt: timestamp("updated_at")
.default(sql`CURRENT_TIMESTAMP`)
.notNull(),

userId: varchar("user_id", { length: 36 }),

name: varchar("name", { length: 255 }).notNull(),
assetType: mysqlEnum("asset_type", [
AssetType.STOCKS,
AssetType.CRYPTO,
AssetType.BONDS,
AssetType.ETF,
AssetType.OPTIONS,
AssetType.FUTURES,
AssetType.REAL_ESTATE,
AssetType.COMMODITIES,
]).notNull(),
assetType: assetTypeEnum("type").notNull(),
originalPayload: json("original_payload"),
},
(table) => {
return {
userIdIdx: index("user_id_idx").on(table.userId),
userIdIdx: index().on(table.userId),
};
},
);

export const assetRealEstate = mySqlTable("asset_real_estate", {
id: bigint("id", { mode: "bigint" }).primaryKey().autoincrement(),
assetId: bigint("asset_id", { mode: "bigint" }).notNull(),
export const assetRealEstate = pgTable("asset_real_estate", {
id: varchar("id", { length: 30 }).primaryKey(), // prefix_ + nanoid (16)
createdAt: timestamp("created_at")
.default(sql`CURRENT_TIMESTAMP`)
.notNull(),
updatedAt: timestamp("updated_at").onUpdateNow(),
updatedAt: timestamp("updated_at")
.default(sql`CURRENT_TIMESTAMP`)
.notNull(),

assetId: varchar("asset_id", { length: 30 }).notNull(),

address: varchar("address", { length: 255 }).notNull(),
city: varchar("city", { length: 255 }).notNull(),
state: varchar("state", { length: 255 }).notNull(),
postalCode: varchar("postal_code", { length: 10 }).notNull(),
purchaseDate: timestamp("purchase_date").notNull(),
});

/**
* 👇 This code block will tell Drizzle that asset is related to:
* - asset <-> real_estate -> 1-to-1
*/
export const assetRealEstateRelation = relations(
assetRealEstate,
({ one }) => ({
Expand Down
Loading

0 comments on commit 3002dd2

Please sign in to comment.