mirror of
https://github.com/fergalmoran/kidarr-server.git
synced 2025-12-30 05:18:49 +00:00
Initial trpc calls done
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
61
.idea/codeStyles/Project.xml
generated
Normal file
61
.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<HTMLCodeStyleSettings>
|
||||||
|
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
||||||
|
<option name="HTML_KEEP_WHITESPACES_INSIDE" value="" />
|
||||||
|
</HTMLCodeStyleSettings>
|
||||||
|
<JSCodeStyleSettings version="0">
|
||||||
|
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||||
|
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||||
|
<option name="USE_DOUBLE_QUOTES" value="false" />
|
||||||
|
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||||
|
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
|
||||||
|
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||||
|
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||||
|
</JSCodeStyleSettings>
|
||||||
|
<TypeScriptCodeStyleSettings version="0">
|
||||||
|
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||||
|
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||||
|
<option name="USE_DOUBLE_QUOTES" value="false" />
|
||||||
|
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||||
|
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
|
||||||
|
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||||
|
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||||
|
</TypeScriptCodeStyleSettings>
|
||||||
|
<VueCodeStyleSettings>
|
||||||
|
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
|
||||||
|
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
|
||||||
|
</VueCodeStyleSettings>
|
||||||
|
<codeStyleSettings language="HTML">
|
||||||
|
<option name="SOFT_MARGINS" value="80" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||||
|
<option name="TAB_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="JavaScript">
|
||||||
|
<option name="SOFT_MARGINS" value="80" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||||
|
<option name="TAB_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="TypeScript">
|
||||||
|
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||||
|
<option name="SOFT_MARGINS" value="80" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||||
|
<option name="TAB_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="Vue">
|
||||||
|
<option name="SOFT_MARGINS" value="80" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
||||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
12
.idea/dataSources.xml
generated
Normal file
12
.idea/dataSources.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||||
|
<data-source source="LOCAL" name="parentgrine@localhost" uuid="da0ccf76-47f7-499f-8f35-82c39250995f">
|
||||||
|
<driver-ref>postgresql</driver-ref>
|
||||||
|
<synchronize>true</synchronize>
|
||||||
|
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||||
|
<jdbc-url>jdbc:postgresql://localhost:5432/parentgrine</jdbc-url>
|
||||||
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
|
</data-source>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/parentgrine-server.iml" filepath="$PROJECT_DIR$/.idea/parentgrine-server.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
12
.idea/parentgrine-server.iml
generated
Normal file
12
.idea/parentgrine-server.iml
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
"use client";
|
import React from 'react';
|
||||||
import React from "react";
|
import DashboardPage from '@/components/pages/dashboard-page';
|
||||||
import DashboardPage from "@/components/pages/dashboard-page";
|
import { api } from '@/trpc/server';
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = async () => {
|
||||||
return <DashboardPage />;
|
const kids = await api.child.mine.query();
|
||||||
|
return <DashboardPage kids={kids} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Dashboard;
|
export default Dashboard;
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
import { newChildSchema } from '@/lib/validations/child';
|
import { newChildSchema } from '@/lib/validations/child';
|
||||||
import { getServerAuthSession } from '@/lib/services/auth/config';
|
|
||||||
import { createApiKey } from '@/lib/services/auth/api';
|
import { createApiKey } from '@/lib/services/auth/api';
|
||||||
|
|
||||||
import { NextResponse } from 'next/server';
|
import { NextResponse } from 'next/server';
|
||||||
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
||||||
import {db} from '@/server/db';
|
import { db } from '@/server/db';
|
||||||
|
|
||||||
import { child } from '@/server/db/schema';
|
import { child } from '@/server/db/schema';
|
||||||
import { users } from '@/server/db/schema';
|
import { users } from '@/server/db/schema';
|
||||||
import { eq } from 'drizzle-orm';
|
import { eq } from 'drizzle-orm';
|
||||||
import { device } from '@/server/db/schema';
|
import { getServerAuthSession } from '@/server/auth';
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
const session = await getServerAuthSession();
|
const session = await getServerAuthSession();
|
||||||
if (!session || !session.user?.email)
|
if (!session?.user?.email)
|
||||||
return NextResponse.next({
|
return NextResponse.next({
|
||||||
statusText: getReasonPhrase(StatusCodes.UNAUTHORIZED),
|
statusText: getReasonPhrase(StatusCodes.UNAUTHORIZED),
|
||||||
status: StatusCodes.UNAUTHORIZED,
|
status: StatusCodes.UNAUTHORIZED,
|
||||||
@@ -36,7 +35,7 @@ export async function POST(req: Request) {
|
|||||||
const newChild = await db
|
const newChild = await db
|
||||||
.insert(child)
|
.insert(child)
|
||||||
.values({
|
.values({
|
||||||
parentId: user[0].id.toString(),
|
parentId: "asdkfjhsa",
|
||||||
name,
|
name,
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { db } from "@/server/db";
|
import { db } from '@/server/db';
|
||||||
import { child } from "@/server/db/schema";
|
import { child } from '@/server/db/schema';
|
||||||
import { StatusCodes, getReasonPhrase } from "http-status-codes";
|
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from 'next/server';
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from 'drizzle-orm';
|
||||||
import { getServerAuthSession } from "@/server/auth";
|
import { getServerAuthSession } from '@/server/auth';
|
||||||
|
|
||||||
export async function GET(request: Request) {
|
export async function GET(request: Request) {
|
||||||
const session = await getServerAuthSession();
|
const session = await getServerAuthSession();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
'use client'
|
'use client';
|
||||||
import React from 'react'
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
@@ -7,35 +7,25 @@ import {
|
|||||||
SelectItem,
|
SelectItem,
|
||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from '@/components/ui/select'
|
} from '@/components/ui/select';
|
||||||
import axios from 'axios'
|
import axios from 'axios';
|
||||||
import { useQuery } from '@tanstack/react-query'
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { env } from '@/env'
|
import { env } from '@/env';
|
||||||
|
import ChildModel from '@/lib/models/child';
|
||||||
|
|
||||||
const ChildSelectList = () => {
|
type ChildSelectListProps = {
|
||||||
const { data, isLoading, isError } = useQuery({
|
kids: ChildModel[];
|
||||||
queryKey: ['user-children'],
|
}
|
||||||
queryFn: async () => {
|
const ChildSelectList: React.FC<ChildSelectListProps> = ({ kids }) => {
|
||||||
const { data } = await axios.get(
|
|
||||||
`${env.NEXT_PUBLIC_BASE_URL}/child`,
|
|
||||||
{
|
|
||||||
withCredentials: true,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
return data as ChildModel[]
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if (isLoading) return <div>Loading....</div>
|
|
||||||
if (isError) return <div>Error loading</div>
|
|
||||||
return (
|
return (
|
||||||
<Select defaultValue={'____all____'}>
|
<Select defaultValue={'____all____'}>
|
||||||
<SelectTrigger className='w-[180px]'>
|
<SelectTrigger className="w-[180px]">
|
||||||
<SelectValue placeholder='Choose child' />
|
<SelectValue placeholder="Choose child" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectItem value='____all____'>(All Children)</SelectItem>
|
<SelectItem value="____all____">(All Children)</SelectItem>
|
||||||
{data?.map((r) => (
|
{kids?.map((r) => (
|
||||||
<SelectItem
|
<SelectItem
|
||||||
key={r.name}
|
key={r.name}
|
||||||
value={r.name.toLowerCase()}
|
value={r.name.toLowerCase()}
|
||||||
@@ -46,7 +36,7 @@ const ChildSelectList = () => {
|
|||||||
</SelectGroup>
|
</SelectGroup>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default ChildSelectList
|
export default ChildSelectList;
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
import React from 'react'
|
import React from 'react';
|
||||||
import ChildSelectList from './child-select-list'
|
import ChildSelectList from './child-select-list';
|
||||||
|
|
||||||
import AddChildComponent from './add-child-component'
|
import AddChildComponent from './add-child-component';
|
||||||
|
import ChildModel from '@/lib/models/child';
|
||||||
|
|
||||||
const ChildrenFilter = async () => {
|
type ChildrenFilterProps = {
|
||||||
|
kids: ChildModel[];
|
||||||
|
}
|
||||||
|
const ChildrenFilter: React.FC<ChildrenFilterProps> = async ({ kids }) => {
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-row space-x-2 justify-center items-center'>
|
<div className="flex flex-row space-x-2 justify-center items-center">
|
||||||
<ChildSelectList />
|
<ChildSelectList kids={kids} />
|
||||||
<AddChildComponent />
|
<AddChildComponent />
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default ChildrenFilter
|
export default ChildrenFilter;
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import ChildrenFilter from "@/components/children/children-filter";
|
import ChildrenFilter from '@/components/children/children-filter';
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from 'next/dynamic';
|
||||||
|
import ChildModel from '@/lib/models/child';
|
||||||
|
|
||||||
const DashboardPage: React.FC = () => {
|
type DashboardPageProps = {
|
||||||
|
kids: ChildModel[];
|
||||||
|
}
|
||||||
|
const DashboardPage: React.FC<DashboardPageProps> = ({ kids }) => {
|
||||||
//this needs to be a dynamic import
|
//this needs to be a dynamic import
|
||||||
//otherwise it causes window not found errors
|
//otherwise it causes window not found errors
|
||||||
const Map = dynamic(() => import("@/components/maps/main-map"), {
|
const Map = dynamic(() => import('@/components/maps/main-map'), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="z-10">
|
<div className="z-10">
|
||||||
<ChildrenFilter />
|
<ChildrenFilter kids={kids} />
|
||||||
</div>
|
</div>
|
||||||
<div className="z-0 mt-4">
|
<div className="z-0 mt-4">
|
||||||
<Map />
|
<Map />
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
interface ChildModel {
|
export default interface ChildModel {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
recentLocations: Location[];
|
// recentLocations: Location[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,33 @@
|
|||||||
import { z } from "zod";
|
import { z } from 'zod';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createTRPCRouter,
|
createTRPCRouter,
|
||||||
protectedProcedure,
|
protectedProcedure,
|
||||||
publicProcedure,
|
publicProcedure,
|
||||||
} from "@/server/api/trpc";
|
} from '@/server/api/trpc';
|
||||||
import { child } from "@/server/db/schema";
|
import { child } from '@/server/db/schema';
|
||||||
|
import { eq } from 'drizzle-orm';
|
||||||
|
|
||||||
export const childRouter = createTRPCRouter({
|
export const childRouter = createTRPCRouter({
|
||||||
hello: publicProcedure
|
|
||||||
.input(z.object({ text: z.string() }))
|
|
||||||
.query(({ input }) => {
|
|
||||||
return {
|
|
||||||
greeting: `Hello ${input.text}`,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
|
|
||||||
create: protectedProcedure
|
create: protectedProcedure
|
||||||
.input(z.object({ name: z.string().min(1) }))
|
.input(z.object({ name: z.string().min(1) }))
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
await ctx.db.insert(child).values({
|
const c = {
|
||||||
parentId: ctx.session.user.id,
|
parentId: ctx.session.user.id,
|
||||||
name,
|
name: input.name,
|
||||||
});
|
};
|
||||||
|
await ctx.db.insert(child).values(c);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getLatest: publicProcedure.query(({ ctx }) => {
|
mine: protectedProcedure.query(async ({ ctx }) => {
|
||||||
return ctx.db.query.child.findFirst({
|
return ctx.db.query.child.findMany({
|
||||||
orderBy: (posts, { asc }) => [asc(child.name)],
|
orderBy: (posts, { asc }) => [asc(child.name)],
|
||||||
|
where: eq(child.parentId, ctx.session.user.id),
|
||||||
|
with: {
|
||||||
|
devices: {
|
||||||
|
with: { pings: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSecretMessage: protectedProcedure.query(() => {
|
|
||||||
return "you can now see this secret message!";
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,60 +8,61 @@ import {
|
|||||||
varchar,
|
varchar,
|
||||||
pgSchema,
|
pgSchema,
|
||||||
doublePrecision,
|
doublePrecision,
|
||||||
} from "drizzle-orm/pg-core";
|
} from 'drizzle-orm/pg-core';
|
||||||
import type { AdapterAccount } from "@auth/core/adapters";
|
import type { AdapterAccount } from '@auth/core/adapters';
|
||||||
import { relations, sql } from "drizzle-orm";
|
import { relations, sql } from 'drizzle-orm';
|
||||||
|
|
||||||
//#region auth
|
//#region auth
|
||||||
//TODO: use this schema once https://github.com/drizzle-team/drizzle-orm/issues/636 is fixed
|
//TODO: use this schema once https://github.com/drizzle-team/drizzle-orm/issues/636 is fixed
|
||||||
const authSchema = pgSchema("auth");
|
const authSchema = pgSchema('auth');
|
||||||
export const users = pgTable("user", {
|
export const users = pgTable('user', {
|
||||||
id: uuid("id")
|
id: uuid('id')
|
||||||
.notNull()
|
.notNull()
|
||||||
.primaryKey()
|
.primaryKey()
|
||||||
.default(sql`gen_random_uuid()`),
|
.default(sql`gen_random_uuid
|
||||||
name: text("name"),
|
()`),
|
||||||
email: text("email").notNull(),
|
name: text('name'),
|
||||||
emailVerified: timestamp("emailVerified", { mode: "date" }),
|
email: text('email').notNull(),
|
||||||
image: text("image"),
|
emailVerified: timestamp('emailVerified', { mode: 'date' }),
|
||||||
|
image: text('image'),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const accounts = pgTable(
|
export const accounts = pgTable(
|
||||||
"account",
|
'account',
|
||||||
{
|
{
|
||||||
userId: uuid("userId")
|
userId: uuid('userId')
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => users.id, { onDelete: "cascade" }),
|
.references(() => users.id, { onDelete: 'cascade' }),
|
||||||
type: text("type").$type<AdapterAccount["type"]>().notNull(),
|
type: text('type').$type<AdapterAccount['type']>().notNull(),
|
||||||
provider: text("provider").notNull(),
|
provider: text('provider').notNull(),
|
||||||
providerAccountId: text("providerAccountId").notNull(),
|
providerAccountId: text('providerAccountId').notNull(),
|
||||||
refresh_token: text("refresh_token"),
|
refresh_token: text('refresh_token'),
|
||||||
access_token: text("access_token"),
|
access_token: text('access_token'),
|
||||||
expires_at: integer("expires_at"),
|
expires_at: integer('expires_at'),
|
||||||
token_type: text("token_type"),
|
token_type: text('token_type'),
|
||||||
scope: text("scope"),
|
scope: text('scope'),
|
||||||
id_token: text("id_token"),
|
id_token: text('id_token'),
|
||||||
session_state: text("session_state"),
|
session_state: text('session_state'),
|
||||||
},
|
},
|
||||||
(account) => ({
|
(account) => ({
|
||||||
compoundKey: primaryKey(account.provider, account.providerAccountId),
|
compoundKey: primaryKey(account.provider, account.providerAccountId),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const sessions = pgTable("session", {
|
export const sessions = pgTable('session', {
|
||||||
sessionToken: text("sessionToken").notNull().primaryKey(),
|
sessionToken: text('sessionToken').notNull().primaryKey(),
|
||||||
userId: uuid("userId")
|
userId: uuid('userId')
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => users.id, { onDelete: "cascade" }),
|
.references(() => users.id, { onDelete: 'cascade' }),
|
||||||
expires: timestamp("expires", { mode: "date" }).notNull(),
|
expires: timestamp('expires', { mode: 'date' }).notNull(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const verificationTokens = pgTable(
|
export const verificationTokens = pgTable(
|
||||||
"verification_token",
|
'verification_token',
|
||||||
{
|
{
|
||||||
identifier: varchar("identifier", { length: 255 }).notNull(),
|
identifier: varchar('identifier', { length: 255 }).notNull(),
|
||||||
token: varchar("token", { length: 255 }).notNull(),
|
token: varchar('token', { length: 255 }).notNull(),
|
||||||
expires: timestamp("expires", { mode: "date" }).notNull(),
|
expires: timestamp('expires', { mode: 'date' }).notNull(),
|
||||||
},
|
},
|
||||||
(vt) => ({
|
(vt) => ({
|
||||||
compoundKey: primaryKey(vt.identifier, vt.token),
|
compoundKey: primaryKey(vt.identifier, vt.token),
|
||||||
@@ -74,15 +75,16 @@ export const userRelations = relations(users, ({ many }) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
//#region child
|
//#region child
|
||||||
export const child = pgTable("child", {
|
export const child = pgTable('child', {
|
||||||
id: uuid("id")
|
id: uuid('id')
|
||||||
.primaryKey()
|
.primaryKey()
|
||||||
.default(sql`gen_random_uuid()`),
|
.default(sql`gen_random_uuid
|
||||||
name: varchar("name", { length: 256 }),
|
()`),
|
||||||
email: varchar("email", { length: 256 }),
|
name: varchar('name', { length: 256 }).notNull(),
|
||||||
phone: varchar("phone", { length: 256 }),
|
email: varchar('email', { length: 256 }),
|
||||||
apiKey: varchar("key", { length: 256 }),
|
phone: varchar('phone', { length: 256 }),
|
||||||
parentId: uuid("parent_id").notNull(),
|
apiKey: varchar('key', { length: 256 }),
|
||||||
|
parentId: uuid('parent_id').notNull(),
|
||||||
});
|
});
|
||||||
export const childRelations = relations(child, ({ one, many }) => ({
|
export const childRelations = relations(child, ({ one, many }) => ({
|
||||||
parent: one(users, {
|
parent: one(users, {
|
||||||
@@ -92,17 +94,18 @@ export const childRelations = relations(child, ({ one, many }) => ({
|
|||||||
devices: many(device),
|
devices: many(device),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const device = pgTable("device", {
|
export const device = pgTable('device', {
|
||||||
id: uuid("id")
|
id: uuid('id')
|
||||||
.primaryKey()
|
.primaryKey()
|
||||||
.default(sql`gen_random_uuid()`),
|
.default(sql`gen_random_uuid
|
||||||
deviceId: varchar("device_id").notNull().unique(),
|
()`),
|
||||||
childId: uuid("child_id").notNull(),
|
deviceId: varchar('device_id').notNull().unique(),
|
||||||
apiKey: varchar("api_key").notNull().unique(),
|
childId: uuid('child_id').notNull(),
|
||||||
|
apiKey: varchar('api_key').notNull().unique(),
|
||||||
//TODO: make the device request/pin a separate table and enforce the expiry
|
//TODO: make the device request/pin a separate table and enforce the expiry
|
||||||
pin: integer("pin").notNull(),
|
pin: integer('pin').notNull(),
|
||||||
expires: timestamp("expires").default(sql`now
|
expires: timestamp('expires').default(sql`now
|
||||||
()
|
()
|
||||||
+ interval '1 hour'`),
|
+ interval '1 hour'`),
|
||||||
});
|
});
|
||||||
export const deviceRelations = relations(device, ({ one, many }) => ({
|
export const deviceRelations = relations(device, ({ one, many }) => ({
|
||||||
@@ -113,14 +116,15 @@ export const deviceRelations = relations(device, ({ one, many }) => ({
|
|||||||
pings: many(ping),
|
pings: many(ping),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const ping = pgTable("ping", {
|
export const ping = pgTable('ping', {
|
||||||
id: uuid("id")
|
id: uuid('id')
|
||||||
.primaryKey()
|
.primaryKey()
|
||||||
.default(sql`gen_random_uuid()`),
|
.default(sql`gen_random_uuid
|
||||||
deviceId: uuid("device_id").notNull(),
|
()`),
|
||||||
latitude: doublePrecision("latitude").notNull(),
|
deviceId: uuid('device_id').notNull(),
|
||||||
longitude: doublePrecision("longitude").notNull(),
|
latitude: doublePrecision('latitude').notNull(),
|
||||||
timestamp: timestamp("timestamp").notNull(),
|
longitude: doublePrecision('longitude').notNull(),
|
||||||
|
timestamp: timestamp('timestamp').notNull(),
|
||||||
});
|
});
|
||||||
export const pingRelations = relations(ping, ({ one, many }) => ({
|
export const pingRelations = relations(ping, ({ one, many }) => ({
|
||||||
device: one(device, {
|
device: one(device, {
|
||||||
|
|||||||
Reference in New Issue
Block a user