Feat: added database

This commit is contained in:
Harshith Mullapudi 2025-05-27 23:24:50 +05:30
parent 25ed9aa430
commit ee3146e7ac
9 changed files with 58 additions and 33 deletions

View File

@ -12,11 +12,11 @@ interface QuoteType {
const quotes: QuoteType[] = [ const quotes: QuoteType[] = [
{ {
quote: quote:
"Echo remembers that I prefer emails in dark mode and hate promotional content. It automatically filters and formats my communications just the way I like.", "Recall remembers that I prefer emails in dark mode and hate promotional content. It automatically filters and formats my communications just the way I like.",
}, },
{ {
quote: quote:
"When I mention liking Nike's latest running shoes, Echo remembers this preference and helps surface relevant product launches and deals across my browsing.", "When I mention liking Nike's latest running shoes, Recall remembers this preference and helps surface relevant product launches and deals across my browsing.",
}, },
{ {
quote: quote:

View File

@ -6,7 +6,7 @@ import {
type PrismaTransactionClient, type PrismaTransactionClient,
type PrismaTransactionOptions, type PrismaTransactionOptions,
$transaction as transac, $transaction as transac,
} from "@echo/database"; } from "@recall/database";
import invariant from "tiny-invariant"; import invariant from "tiny-invariant";
import { z } from "zod"; import { z } from "zod";
import { env } from "./env.server"; import { env } from "./env.server";
@ -27,18 +27,20 @@ export async function $transaction<R>(
prisma: PrismaClientOrTransaction, prisma: PrismaClientOrTransaction,
name: string, name: string,
fn: (prisma: PrismaTransactionClient, span?: Span) => Promise<R>, fn: (prisma: PrismaTransactionClient, span?: Span) => Promise<R>,
options?: PrismaTransactionOptions options?: PrismaTransactionOptions,
): Promise<R | undefined>; ): Promise<R | undefined>;
export async function $transaction<R>( export async function $transaction<R>(
prisma: PrismaClientOrTransaction, prisma: PrismaClientOrTransaction,
fn: (prisma: PrismaTransactionClient) => Promise<R>, fn: (prisma: PrismaTransactionClient) => Promise<R>,
options?: PrismaTransactionOptions options?: PrismaTransactionOptions,
): Promise<R | undefined>; ): Promise<R | undefined>;
export async function $transaction<R>( export async function $transaction<R>(
prisma: PrismaClientOrTransaction, prisma: PrismaClientOrTransaction,
fnOrName: ((prisma: PrismaTransactionClient) => Promise<R>) | string, fnOrName: ((prisma: PrismaTransactionClient) => Promise<R>) | string,
fnOrOptions?: ((prisma: PrismaTransactionClient) => Promise<R>) | PrismaTransactionOptions, fnOrOptions?:
options?: PrismaTransactionOptions | ((prisma: PrismaTransactionClient) => Promise<R>)
| PrismaTransactionOptions,
options?: PrismaTransactionOptions,
): Promise<R | undefined> { ): Promise<R | undefined> {
if (typeof fnOrName === "string") { if (typeof fnOrName === "string") {
const fn = fnOrOptions as (prisma: PrismaTransactionClient) => Promise<R>; const fn = fnOrOptions as (prisma: PrismaTransactionClient) => Promise<R>;
@ -55,7 +57,7 @@ export async function $transaction<R>(
name: error.name, name: error.name,
}); });
}, },
options options,
); );
} else { } else {
return transac( return transac(
@ -70,7 +72,7 @@ export async function $transaction<R>(
name: error.name, name: error.name,
}); });
}, },
typeof fnOrOptions === "function" ? undefined : fnOrOptions typeof fnOrOptions === "function" ? undefined : fnOrOptions,
); );
} }
} }
@ -81,7 +83,7 @@ export const prisma = singleton("prisma", getClient);
export const $replica: PrismaReplicaClient = singleton( export const $replica: PrismaReplicaClient = singleton(
"replica", "replica",
() => getReplicaClient() ?? prisma () => getReplicaClient() ?? prisma,
); );
function getClient() { function getClient() {
@ -94,7 +96,9 @@ function getClient() {
connection_timeout: env.DATABASE_CONNECTION_TIMEOUT.toString(), connection_timeout: env.DATABASE_CONNECTION_TIMEOUT.toString(),
}); });
console.log(`🔌 setting up prisma client to ${redactUrlSecrets(databaseUrl)}`); console.log(
`🔌 setting up prisma client to ${redactUrlSecrets(databaseUrl)}`,
);
const client = new PrismaClient({ const client = new PrismaClient({
datasources: { datasources: {
@ -122,7 +126,7 @@ function getClient() {
{ emit: "event", level: "query" }, { emit: "event", level: "query" },
{ emit: "stdout", level: "query" }, { emit: "stdout", level: "query" },
] ]
: [] : [],
), ),
}); });
@ -146,7 +150,9 @@ function getReplicaClient() {
connection_timeout: env.DATABASE_CONNECTION_TIMEOUT.toString(), connection_timeout: env.DATABASE_CONNECTION_TIMEOUT.toString(),
}); });
console.log(`🔌 setting up read replica connection to ${redactUrlSecrets(replicaUrl)}`); console.log(
`🔌 setting up read replica connection to ${redactUrlSecrets(replicaUrl)}`,
);
const replicaClient = new PrismaClient({ const replicaClient = new PrismaClient({
datasources: { datasources: {
@ -174,7 +180,7 @@ function getReplicaClient() {
{ emit: "event", level: "query" }, { emit: "event", level: "query" },
{ emit: "stdout", level: "query" }, { emit: "stdout", level: "query" },
] ]
: [] : [],
), ),
}); });
@ -186,7 +192,10 @@ function getReplicaClient() {
return replicaClient; return replicaClient;
} }
function extendQueryParams(hrefOrUrl: string | URL, queryParams: Record<string, string>) { function extendQueryParams(
hrefOrUrl: string | URL,
queryParams: Record<string, string>,
) {
const url = new URL(hrefOrUrl); const url = new URL(hrefOrUrl);
const query = url.searchParams; const query = url.searchParams;
@ -205,7 +214,7 @@ function redactUrlSecrets(hrefOrUrl: string | URL) {
return url.href; return url.href;
} }
export type { PrismaClient } from "@echo/database"; export type { PrismaClient } from "@recall/database";
export const PrismaErrorSchema = z.object({ export const PrismaErrorSchema = z.object({
code: z.string(), code: z.string(),
@ -220,7 +229,9 @@ function getDatabaseSchema() {
const schemaFromSearchParam = databaseUrl.searchParams.get("schema"); const schemaFromSearchParam = databaseUrl.searchParams.get("schema");
if (!schemaFromSearchParam) { if (!schemaFromSearchParam) {
console.debug("❗ database schema unspecified, will default to `public` schema"); console.debug(
"❗ database schema unspecified, will default to `public` schema",
);
return "public"; return "public";
} }

View File

@ -1,7 +1,7 @@
import type { Prisma, User } from "@echo/database"; import type { Prisma, User } from "@recall/database";
import type { GoogleProfile } from "remix-auth-google"; import type { GoogleProfile } from "remix-auth-google";
import { prisma } from "~/db.server"; import { prisma } from "~/db.server";
export type { User } from "@echo/database"; export type { User } from "@recall/database";
type FindOrCreateGoogle = { type FindOrCreateGoogle = {
authenticationMethod: "GOOGLE"; authenticationMethod: "GOOGLE";
@ -17,7 +17,9 @@ type LoggedInUser = {
isNewUser: boolean; isNewUser: boolean;
}; };
export async function findOrCreateUser(input: FindOrCreateUser): Promise<LoggedInUser> { export async function findOrCreateUser(
input: FindOrCreateUser,
): Promise<LoggedInUser> {
return findOrCreateGoogleUser(input); return findOrCreateGoogleUser(input);
} }
@ -137,11 +139,23 @@ export function updateUser({
}) { }) {
return prisma.user.update({ return prisma.user.update({
where: { id }, where: { id },
data: { name, email, marketingEmails, referralSource, confirmedBasicDetails: true }, data: {
name,
email,
marketingEmails,
referralSource,
confirmedBasicDetails: true,
},
}); });
} }
export async function grantUserCloudAccess({ id, inviteCode }: { id: string; inviteCode: string }) { export async function grantUserCloudAccess({
id,
inviteCode,
}: {
id: string;
inviteCode: string;
}) {
return prisma.user.update({ return prisma.user.update({
where: { id }, where: { id },
data: { data: {

View File

@ -67,7 +67,7 @@ export const meta: MetaFunction = ({ data }) => {
const typedData = data as UseDataFunctionReturn<typeof loader>; const typedData = data as UseDataFunctionReturn<typeof loader>;
return [ return [
{ title: `Echo${typedData && appEnvTitleTag(typedData.appEnv)}` }, { title: `Recall${typedData && appEnvTitleTag(typedData.appEnv)}` },
{ {
name: "viewport", name: "viewport",
content: "width=1024, initial-scale=1", content: "width=1024, initial-scale=1",
@ -76,7 +76,7 @@ export const meta: MetaFunction = ({ data }) => {
name: "robots", name: "robots",
content: content:
typeof window === "undefined" || typeof window === "undefined" ||
window.location.hostname !== "echo.mysigma.ai" window.location.hostname !== "recall.mysigma.ai"
? "noindex, nofollow" ? "noindex, nofollow"
: "index, follow", : "index, follow",
}, },

View File

@ -1,6 +1,6 @@
export function singleton<T>(name: string, getValue: () => T): T { export function singleton<T>(name: string, getValue: () => T): T {
const thusly = globalThis as any; const thusly = globalThis as any;
thusly.__echo_singletons ??= {}; thusly.__recall_singletons ??= {};
thusly.__echo_singletons[name] ??= getValue(); thusly.__recall_singletons[name] ??= getValue();
return thusly.__echo_singletons[name]; return thusly.__recall_singletons[name];
} }

View File

@ -11,7 +11,7 @@
"typecheck": "tsc" "typecheck": "tsc"
}, },
"dependencies": { "dependencies": {
"@echo/database": "workspace:*", "@recall/database": "workspace:*",
"@opentelemetry/api": "1.9.0", "@opentelemetry/api": "1.9.0",
"@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-slot": "^1.2.3",
"@remix-run/express": "2.16.7", "@remix-run/express": "2.16.7",

View File

@ -1,5 +1,5 @@
{ {
"name": "echo", "name": "recall",
"private": true, "private": true,
"workspaces": "workspaces":
[ "apps/*", "packages/*" ] [ "apps/*", "packages/*" ]

View File

@ -1,5 +1,5 @@
{ {
"name": "@echo/database", "name": "@recall/database",
"private": true, "private": true,
"version": "0.0.1", "version": "0.0.1",
"main": "./dist/index.js", "main": "./dist/index.js",

6
pnpm-lock.yaml generated
View File

@ -30,15 +30,15 @@ importers:
apps/webapp: apps/webapp:
dependencies: dependencies:
'@echo/database':
specifier: workspace:*
version: link:../../packages/database
'@opentelemetry/api': '@opentelemetry/api':
specifier: 1.9.0 specifier: 1.9.0
version: 1.9.0 version: 1.9.0
'@radix-ui/react-slot': '@radix-ui/react-slot':
specifier: ^1.2.3 specifier: ^1.2.3
version: 1.2.3(@types/react@18.3.23)(react@18.3.1) version: 1.2.3(@types/react@18.3.23)(react@18.3.1)
'@recall/database':
specifier: workspace:*
version: link:../../packages/database
'@remix-run/express': '@remix-run/express':
specifier: 2.16.7 specifier: 2.16.7
version: 2.16.7(express@4.21.2)(typescript@5.8.3) version: 2.16.7(express@4.21.2)(typescript@5.8.3)