mirror of
https://github.com/eliasstepanik/core.git
synced 2026-01-24 04:08:32 +00:00
Feat: added database
This commit is contained in:
parent
25ed9aa430
commit
ee3146e7ac
@ -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:
|
||||||
|
|||||||
@ -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";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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: {
|
||||||
|
|||||||
@ -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",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -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];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "echo",
|
"name": "recall",
|
||||||
"private": true,
|
"private": true,
|
||||||
"workspaces":
|
"workspaces":
|
||||||
[ "apps/*", "packages/*" ]
|
[ "apps/*", "packages/*" ]
|
||||||
|
|||||||
@ -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
6
pnpm-lock.yaml
generated
@ -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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user