Switch to Postgres
This commit is contained in:
parent
6e96eed3f1
commit
b7031bbd9d
19
.direnv/bin/nix-direnv-reload
Executable file
19
.direnv/bin/nix-direnv-reload
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
if [[ ! -d "/home/ryan/Documents/Code/lifetracker" ]]; then
|
||||||
|
echo "Cannot find source directory; Did you move it?"
|
||||||
|
echo "(Looking for "/home/ryan/Documents/Code/lifetracker")"
|
||||||
|
echo 'Cannot force reload with this script - use "direnv reload" manually and then try again'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# rebuild the cache forcefully
|
||||||
|
_nix_direnv_force_reload=1 direnv exec "/home/ryan/Documents/Code/lifetracker" true
|
||||||
|
|
||||||
|
# Update the mtime for .envrc.
|
||||||
|
# This will cause direnv to reload again - but without re-building.
|
||||||
|
touch "/home/ryan/Documents/Code/lifetracker/.envrc"
|
||||||
|
|
||||||
|
# Also update the timestamp of whatever profile_rc we have.
|
||||||
|
# This makes sure that we know we are up to date.
|
||||||
|
touch -r "/home/ryan/Documents/Code/lifetracker/.envrc" "/home/ryan/Documents/Code/lifetracker/.direnv"/*.rc
|
||||||
1
.direnv/flake-inputs/r3pr5wyvfdi4h1b3wja7jcdwqjrfk9px-source
Symbolic link
1
.direnv/flake-inputs/r3pr5wyvfdi4h1b3wja7jcdwqjrfk9px-source
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/nix/store/r3pr5wyvfdi4h1b3wja7jcdwqjrfk9px-source
|
||||||
1
.direnv/flake-inputs/xpkysrb9pn0yqrm1bkll4dr2gqahj43x-source
Symbolic link
1
.direnv/flake-inputs/xpkysrb9pn0yqrm1bkll4dr2gqahj43x-source
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/nix/store/xpkysrb9pn0yqrm1bkll4dr2gqahj43x-source
|
||||||
1
.direnv/flake-inputs/yj1wxm9hh8610iyzqnz75kvs6xl8j3my-source
Symbolic link
1
.direnv/flake-inputs/yj1wxm9hh8610iyzqnz75kvs6xl8j3my-source
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/nix/store/yj1wxm9hh8610iyzqnz75kvs6xl8j3my-source
|
||||||
1
.direnv/flake-inputs/yp0xr7fzkk7rjgp564pn28r7f2mpdcj1-source
Symbolic link
1
.direnv/flake-inputs/yp0xr7fzkk7rjgp564pn28r7f2mpdcj1-source
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/nix/store/yp0xr7fzkk7rjgp564pn28r7f2mpdcj1-source
|
||||||
@ -1 +0,0 @@
|
|||||||
flake-profile-2-link
|
|
||||||
@ -1 +0,0 @@
|
|||||||
/nix/store/w46qqqb484a76v5k0lzv524yp9s89vly-nix-shell-env
|
|
||||||
1
.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa
Symbolic link
1
.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/nix/store/11hqs52hdjhxhcb8idddn312grl1hr5i-nix-shell-env
|
||||||
2008
.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc
Normal file
2008
.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc
Normal file
File diff suppressed because it is too large
Load Diff
@ -35,6 +35,7 @@ RUN pnpm turbo run build
|
|||||||
|
|
||||||
FROM base AS runner
|
FROM base AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
# Don't run production as root
|
# Don't run production as root
|
||||||
RUN addgroup --system --gid 1001 nodejs
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
@ -47,5 +48,12 @@ COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
|
|||||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
|
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
|
||||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
|
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
|
||||||
|
|
||||||
|
# Handle db migrations
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/packages/db ./packages/db
|
||||||
|
|
||||||
|
RUN ["pnpm", "db:generate"]
|
||||||
|
RUN ["pnpm", "db:migrate"]
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
CMD node apps/web/server.js
|
CMD node apps/web/server.js
|
||||||
|
|||||||
@ -12188,7 +12188,7 @@ const timezones$1 = {
|
|||||||
"America/Los_Angeles": "Pacific Time",
|
"America/Los_Angeles": "Pacific Time",
|
||||||
// "Atlantic/Azores": "Azores",
|
// "Atlantic/Azores": "Azores",
|
||||||
// "Atlantic/Cape_Verde": "Cape Verde Islands",
|
// "Atlantic/Cape_Verde": "Cape Verde Islands",
|
||||||
// GMT: "UTC",
|
"Etc/UTC": "UTC",
|
||||||
"Europe/London": "The UK",
|
"Europe/London": "The UK",
|
||||||
"Europe/Dublin": "Ireland",
|
"Europe/Dublin": "Ireland",
|
||||||
// "Europe/Lisbon": "Lisbon",
|
// "Europe/Lisbon": "Lisbon",
|
||||||
|
|||||||
@ -2,17 +2,24 @@ import { NextRequest, NextResponse } from 'next/server';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import serverConfig from '@lifetracker/shared/config';
|
import serverConfig from '@lifetracker/shared/config';
|
||||||
|
import { getConnectionDetails } from '@lifetracker/db/drizzle';
|
||||||
|
import { pgDump } from 'pg-dump-restore';
|
||||||
|
|
||||||
const DB_PATH = path.join(serverConfig.dataDir, 'lifetracker.db');
|
|
||||||
|
const dbPath = path.join(serverConfig.dataDir, `lifetracker-${new Date().getTime()}.sql`);
|
||||||
|
|
||||||
|
const returnVal = (await pgDump(getConnectionDetails(), {
|
||||||
|
filePath: dbPath,
|
||||||
|
}));
|
||||||
|
|
||||||
export async function GET(req: NextRequest) {
|
export async function GET(req: NextRequest) {
|
||||||
try {
|
try {
|
||||||
// Read the production database file
|
// Read the production database file
|
||||||
const dbFile = fs.readFileSync(DB_PATH);
|
const dbFile = fs.readFileSync(dbPath);
|
||||||
return new NextResponse(dbFile, {
|
return new NextResponse(dbFile, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/octet-stream',
|
'Content-Type': 'application/octet-stream',
|
||||||
'Content-Disposition': 'attachment; filename="lifetracker.db"'
|
'Content-Disposition': `attachment; filename="lifetracker-${new Date().getTime()}.sql"`
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,10 +2,13 @@ import { NextRequest, NextResponse } from 'next/server';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import serverConfig from '@lifetracker/shared/config';
|
import serverConfig from '@lifetracker/shared/config';
|
||||||
|
import { pgDump, pgRestore } from 'pg-dump-restore';
|
||||||
|
import { db, getConnectionDetails } from '@lifetracker/db/drizzle';
|
||||||
|
import { sql } from 'drizzle-orm';
|
||||||
|
|
||||||
// Define paths for uploaded files and the production DB
|
// Define paths for uploaded files and the production DB
|
||||||
const UPLOAD_DIR = path.join(process.cwd(), 'uploads');
|
const UPLOAD_DIR = path.join(process.cwd(), 'uploads');
|
||||||
const DB_PATH = path.join(serverConfig.dataDir, 'lifetracker.db');
|
const DB_PATH = path.join(serverConfig.dataDir, `lifetracker-${new Date().getTime()}.sql`);
|
||||||
|
|
||||||
// Ensure upload directory exists
|
// Ensure upload directory exists
|
||||||
if (!fs.existsSync(UPLOAD_DIR)) {
|
if (!fs.existsSync(UPLOAD_DIR)) {
|
||||||
@ -35,25 +38,31 @@ export async function POST(req: NextRequest) {
|
|||||||
const fileContent = bodyBuffer.slice(start, end);
|
const fileContent = bodyBuffer.slice(start, end);
|
||||||
|
|
||||||
// Save the uploaded file to the upload directory
|
// Save the uploaded file to the upload directory
|
||||||
const uploadedFilePath = path.join(UPLOAD_DIR, 'uploaded.db');
|
const uploadedFilePath = path.join(UPLOAD_DIR, 'uploaded.sql');
|
||||||
fs.writeFileSync(uploadedFilePath, fileContent);
|
fs.writeFileSync(uploadedFilePath, fileContent);
|
||||||
|
|
||||||
// Validate the uploaded file extension
|
// Back up the existing production database
|
||||||
if (!uploadedFilePath.endsWith('.db')) {
|
const backupPath = `${serverConfig.dataDir}/pg-backup-${new Date().getTime()}.sql`;
|
||||||
return NextResponse.json({ message: 'Invalid file type. Please upload a .db file.' }, { status: 400 });
|
const { stdout, stderr } = await pgDump(getConnectionDetails(), {
|
||||||
}
|
filePath: `${backupPath}`,
|
||||||
|
});
|
||||||
|
|
||||||
// Backup the current production database
|
console.log("Backed up existing data to ", backupPath);
|
||||||
const backupPath = path.join(
|
console.log(stdout);
|
||||||
serverConfig.dataDir,
|
|
||||||
`backup_${Date.now()}.db`
|
|
||||||
);
|
|
||||||
if (fs.existsSync(DB_PATH)) {
|
|
||||||
fs.copyFileSync(DB_PATH, backupPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the production database with the uploaded file
|
// If it's a SQL file, restore the production database from the uploaded file
|
||||||
fs.renameSync(uploadedFilePath, DB_PATH);
|
if (uploadedFilePath.endsWith('.sql')) {
|
||||||
|
const { stdout: restoreStdout, stderr: restoreStderr } = await pgRestore(getConnectionDetails(), {
|
||||||
|
clean: true,
|
||||||
|
filePath: uploadedFilePath,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// If it ends in .db, assume it's a sqlite
|
||||||
|
else if (uploadedFilePath.endsWith('.db')) {
|
||||||
|
// TODO, if ever
|
||||||
|
return NextResponse.json({ message: 'Invalid file type. Please upload a .sql file.' }, { status: 400 });
|
||||||
|
}
|
||||||
|
else { return NextResponse.json({ message: 'Invalid file type. Please upload a .sql file.' }, { status: 400 }); }
|
||||||
|
|
||||||
return NextResponse.json({ message: 'Database uploaded and replaced successfully!' }, { status: 200 });
|
return NextResponse.json({ message: 'Database uploaded and replaced successfully!' }, { status: 200 });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export default async function AdminPage() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="rounded-md border bg-background p-4">
|
<div className="rounded-md border bg-background p-4">
|
||||||
<ServerStats />
|
{/* <ServerStats /> */}
|
||||||
{/* <AdminActions /> */}
|
{/* <AdminActions /> */}
|
||||||
<Separator />
|
<Separator />
|
||||||
<DatabaseSettings />
|
<DatabaseSettings />
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import {
|
|||||||
import { getServerAuthSession } from "@/server/auth";
|
import { getServerAuthSession } from "@/server/auth";
|
||||||
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
||||||
|
|
||||||
import { clientConfig } from "@lifetracker/shared/config";
|
import serverConfig, { clientConfig } from "@lifetracker/shared/config";
|
||||||
import { useTimezone } from "@lifetracker/shared-react/hooks/timezones";
|
import { useTimezone } from "@lifetracker/shared-react/hooks/timezones";
|
||||||
import { getUserLocalSettings } from "@/lib/userLocalSettings/userLocalSettings";
|
import { getUserLocalSettings } from "@/lib/userLocalSettings/userLocalSettings";
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ export default function DatabaseSettings() {
|
|||||||
const dbData = await download.blob();
|
const dbData = await download.blob();
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('sqliteFile', dbData, 'remoteDB-file.db');
|
formData.append('sqlFile', dbData, 'remoteDB-file.sql');
|
||||||
uploadDB(formData, setRemoteCopyStatus);
|
uploadDB(formData, setRemoteCopyStatus);
|
||||||
|
|
||||||
// try {
|
// try {
|
||||||
@ -71,12 +71,12 @@ export default function DatabaseSettings() {
|
|||||||
return (
|
return (
|
||||||
<><div className="mt-8 mb-2 flex w-full flex-col sm:flex-row">
|
<><div className="mt-8 mb-2 flex w-full flex-col sm:flex-row">
|
||||||
<div className="mb-4 w-full text-lg font-medium sm:w-1/3">
|
<div className="mb-4 w-full text-lg font-medium sm:w-1/3">
|
||||||
Upload SQLite Database
|
Upload Postgres SQL
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<form onSubmit={handleSubmit} encType="multipart/form-data">
|
<form onSubmit={handleSubmit} encType="multipart/form-data">
|
||||||
<input type="file" name="sqliteFile" accept=".db" required />
|
<input type="file" name="sqlFile" accept=".sql" required />
|
||||||
<button type="submit">Upload</button>
|
<button type="submit">Upload</button>
|
||||||
</form>
|
</form>
|
||||||
{uploadStatus && <p>{uploadStatus}</p>}
|
{uploadStatus && <p>{uploadStatus}</p>}
|
||||||
@ -85,7 +85,7 @@ export default function DatabaseSettings() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mb-2 flex w-full flex-col sm:flex-row">
|
<div className="mb-2 flex w-full flex-col sm:flex-row">
|
||||||
<div className="mb-4 w-full text-lg font-medium sm:w-1/3">
|
<div className="mb-4 w-full text-lg font-medium sm:w-1/3">
|
||||||
Download SQLite Database
|
Download Postgres SQL
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
|
|||||||
@ -48,8 +48,8 @@ export default function AnalyticsView() {
|
|||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
// spacetime.now().subtract(1, "week").toNativeDate(),
|
// spacetime.now().subtract(1, "week").toNativeDate(),
|
||||||
spacetime.now(useTimezone()).toNativeDate(),
|
parseISO(spacetime.now(useTimezone()).format("iso-short")),
|
||||||
spacetime.now(useTimezone()).toNativeDate()
|
parseISO(spacetime.now(useTimezone()).format("iso-short")),
|
||||||
];
|
];
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -75,6 +75,12 @@ export default function AnalyticsView() {
|
|||||||
timezone: useTimezone(),
|
timezone: useTimezone(),
|
||||||
}).data ?? [];
|
}).data ?? [];
|
||||||
|
|
||||||
|
const weightData = api.measurements.getTimeseries.useQuery({
|
||||||
|
dateRange,
|
||||||
|
timezone: useTimezone(),
|
||||||
|
metricName: "weight"
|
||||||
|
}).data ?? [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="px-4 flex flex-col gap-y-4">
|
<div className="px-4 flex flex-col gap-y-4">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
@ -176,7 +182,27 @@ export default function AnalyticsView() {
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex gap-4">
|
||||||
|
<h2>Weight</h2>
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
!weightData ? <LoadingSpinner /> :
|
||||||
|
<ul>
|
||||||
|
{weightData.map((measurement) => (
|
||||||
|
<li key={measurement.id}>
|
||||||
|
{measurement.value} {measurement.unit}
|
||||||
|
,
|
||||||
|
{
|
||||||
|
spacetime(measurement.datetime)
|
||||||
|
.goto(useTimezone())
|
||||||
|
.format("{iso-short} at {hour} {ampm}")
|
||||||
|
}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="flex gap-4">
|
<div className="flex gap-4">
|
||||||
<h2 className="">Drugs</h2>
|
<h2 className="">Drugs</h2>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import Link from "next/link";
|
|||||||
export default function CategoriesView() {
|
export default function CategoriesView() {
|
||||||
const { data: session } = useSession();
|
const { data: session } = useSession();
|
||||||
const { data: categories } = api.categories.list.useQuery();
|
const { data: categories } = api.categories.list.useQuery();
|
||||||
const { data: categoryStats } = api.categories.categoryStats.useQuery();
|
// const { data: categoryStats } = api.categories.categoryStats.useQuery();
|
||||||
|
|
||||||
const invalidateCategoryList = api.useUtils().categories.list.invalidate;
|
const invalidateCategoryList = api.useUtils().categories.list.invalidate;
|
||||||
const { mutate: deleteCategory, isPending: isDeletionPending } =
|
const { mutate: deleteCategory, isPending: isDeletionPending } =
|
||||||
@ -57,7 +57,7 @@ export default function CategoriesView() {
|
|||||||
<TableCell className="py-1">{c.name}</TableCell>
|
<TableCell className="py-1">{c.name}</TableCell>
|
||||||
<TableCell className="py-1">{c.description}</TableCell>
|
<TableCell className="py-1">{c.description}</TableCell>
|
||||||
<TableCell className="py-1">
|
<TableCell className="py-1">
|
||||||
{categoryStats[c.id].numEntries}
|
categoryStats[c.id].numEntries
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="flex gap-1 py-1">
|
<TableCell className="flex gap-1 py-1">
|
||||||
<ActionButtonWithTooltip
|
<ActionButtonWithTooltip
|
||||||
|
|||||||
@ -103,11 +103,8 @@ export default function EditableHour({
|
|||||||
|
|
||||||
|
|
||||||
const localDateTime = (h: ZHour): string => {
|
const localDateTime = (h: ZHour): string => {
|
||||||
return spacetime(h.date).add(h.time + tzOffset, "hour").format('{hour} {ampm}');
|
return spacetime(h.datetime).format('{hour} {ampm}');
|
||||||
}
|
}
|
||||||
hour.datetime = localDateTime(hour);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// console.log(hour.categoryDesc);
|
// console.log(hour.categoryDesc);
|
||||||
@ -133,12 +130,12 @@ export default function EditableHour({
|
|||||||
{hourGroup.length > 1
|
{hourGroup.length > 1
|
||||||
? (
|
? (
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<span>{hour.datetime}</span>
|
<span>{format(hour.datetime, "hh")}</span>
|
||||||
<span>|</span>
|
<span>|</span>
|
||||||
<span>{localDateTime(hourGroup[hourGroup.length - 1])}</span>
|
<span>{localDateTime(hourGroup[hourGroup.length - 1])}</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
: <div className="flex flex-col items-center">{hour.datetime}</div>
|
: <div className="flex flex-col items-center">{spacetime(hour.datetime).format('{hour} {ampm}')}</div>
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
|||||||
import { TRPCClientError } from "@trpc/client";
|
import { TRPCClientError } from "@trpc/client";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { zMeasurementSchema, ZMetric } from "@lifetracker/shared/types/metrics";
|
import { ZMeasurement, zMeasurementSchema, ZMetric } from "@lifetracker/shared/types/metrics";
|
||||||
import { ZHour } from "@lifetracker/shared/types/days";
|
import { ZHour } from "@lifetracker/shared/types/days";
|
||||||
|
|
||||||
import { Icon } from "@/components/ui/icon";
|
import { Icon } from "@/components/ui/icon";
|
||||||
@ -37,7 +37,7 @@ export default function HourMeasurementsDialog({
|
|||||||
}) {
|
}) {
|
||||||
const [hour, setHour] = useState(initialHour);
|
const [hour, setHour] = useState(initialHour);
|
||||||
const [isOpen, onOpenChange] = useState(false);
|
const [isOpen, onOpenChange] = useState(false);
|
||||||
const [pendingMeasurement, setPendingMeasurement] = useState(false);
|
const [pendingMeasurement, setPendingMeasurement] = useState<Boolean | ZMeasurement>(false);
|
||||||
const pendingRef = useRef<HTMLInputElement>(null);
|
const pendingRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -78,6 +78,7 @@
|
|||||||
"next-auth": "^4.24.5",
|
"next-auth": "^4.24.5",
|
||||||
"next-pwa": "^5.6.0",
|
"next-pwa": "^5.6.0",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
|
"pg-dump-restore": "^1.0.12",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-colorful": "^5.6.1",
|
"react-colorful": "^5.6.1",
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
BIN
apps/web/uploads/uploaded.sql
Normal file
BIN
apps/web/uploads/uploaded.sql
Normal file
Binary file not shown.
@ -22,8 +22,7 @@
|
|||||||
emacs-nox
|
emacs-nox
|
||||||
nodejs
|
nodejs
|
||||||
pnpm
|
pnpm
|
||||||
sqlite
|
postgresql
|
||||||
|
|
||||||
] ++ optional stdenv.isLinux inotify-tools
|
] ++ optional stdenv.isLinux inotify-tools
|
||||||
++ optional stdenv.isDarwin terminal-notifier
|
++ optional stdenv.isDarwin terminal-notifier
|
||||||
++ optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [
|
++ optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
|
"tsx": "^4.19.2",
|
||||||
"turbo": "^2.2.3",
|
"turbo": "^2.2.3",
|
||||||
"typescript": "^5.6.3"
|
"typescript": "^5.6.3"
|
||||||
},
|
},
|
||||||
|
|||||||
16
packages/db/drizzle-sqlite.ts
Normal file
16
packages/db/drizzle-sqlite.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import "dotenv/config";
|
||||||
|
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||||
|
import Database from "better-sqlite3";
|
||||||
|
import * as schema from "./schema";
|
||||||
|
import serverConfig from "@lifetracker/shared/config";
|
||||||
|
|
||||||
|
export const databaseUrl = serverConfig.dataDir
|
||||||
|
? `${serverConfig.dataDir}/lifetracker.db`
|
||||||
|
: "./lifetracker.db";
|
||||||
|
|
||||||
|
|
||||||
|
const sqlite = new Database(databaseUrl);
|
||||||
|
export const db = drizzle(sqlite, {
|
||||||
|
schema,
|
||||||
|
logger: false,
|
||||||
|
});
|
||||||
@ -1,17 +1,17 @@
|
|||||||
import dotenv from "dotenv";
|
|
||||||
import type { Config } from "drizzle-kit";
|
import type { Config } from "drizzle-kit";
|
||||||
import serverConfig from "@lifetracker/shared/config";
|
import serverConfig from "@lifetracker/shared/config";
|
||||||
|
|
||||||
const databaseURL = serverConfig.dataDir
|
const dbInfo = {
|
||||||
? `${serverConfig.dataDir}/lifetracker.db`
|
|
||||||
: "./lifetracker.db";
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
dialect: "sqlite",
|
|
||||||
schema: "./schema.ts",
|
schema: "./schema.ts",
|
||||||
out: "./migrations",
|
out: "./migrations",
|
||||||
|
dialect: "postgresql",
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
url: databaseURL,
|
url: process.env.NODE_ENV === "test"
|
||||||
},
|
? serverConfig.testDatabaseUrl
|
||||||
|
: serverConfig.databaseUrl,
|
||||||
|
|
||||||
|
}
|
||||||
} satisfies Config;
|
} satisfies Config;
|
||||||
|
|
||||||
|
export default dbInfo;
|
||||||
|
|
||||||
|
|||||||
@ -1,23 +1,34 @@
|
|||||||
import "dotenv/config";
|
import "dotenv/config";
|
||||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
import { drizzle } from "drizzle-orm/node-postgres";
|
||||||
import Database from "better-sqlite3";
|
import { Pool } from "pg";
|
||||||
import * as schema from "./schema";
|
import * as schema from "./schema";
|
||||||
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
import serverConfig from "@lifetracker/shared/config";
|
||||||
import path from "path";
|
|
||||||
|
|
||||||
import dbConfig from "./drizzle.config";
|
const pool = new Pool({
|
||||||
|
connectionString: serverConfig.databaseUrl,
|
||||||
|
});
|
||||||
|
|
||||||
const sqlite = new Database(dbConfig.dbCredentials.url);
|
export const db = drizzle(pool, {
|
||||||
export const db = drizzle(sqlite, {
|
|
||||||
schema,
|
schema,
|
||||||
logger: false,
|
logger: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
export function getInMemoryDB(runMigrations: boolean) {
|
|
||||||
const mem = new Database(":memory:");
|
export function getConnectionDetails() {
|
||||||
const db = drizzle(mem, { schema, logger: true });
|
const sourceDb = serverConfig.databaseUrl
|
||||||
if (runMigrations) {
|
const sourceDbUrl = new URL(sourceDb)
|
||||||
migrate(db, { migrationsFolder: path.resolve(__dirname, "./migrations") });
|
return {
|
||||||
|
port: parseInt(sourceDbUrl.port),
|
||||||
|
host: sourceDbUrl.hostname,
|
||||||
|
database: sourceDbUrl.pathname.slice(1),
|
||||||
|
username: sourceDbUrl.username,
|
||||||
|
password: sourceDbUrl.password
|
||||||
}
|
}
|
||||||
return db;
|
}
|
||||||
|
// Testing utility
|
||||||
|
export async function getTestDB() {
|
||||||
|
const testPool = new Pool({
|
||||||
|
connectionString: serverConfig.testDatabaseUrl,
|
||||||
|
});
|
||||||
|
return drizzle(testPool, { schema });
|
||||||
}
|
}
|
||||||
@ -1,17 +1,24 @@
|
|||||||
import Database from "better-sqlite3";
|
import { Pool, QueryResult } from "pg";
|
||||||
import { ExtractTablesWithRelations } from "drizzle-orm";
|
import { ExtractTablesWithRelations } from "drizzle-orm";
|
||||||
import { SQLiteTransaction } from "drizzle-orm/sqlite-core";
|
import { PgTransaction } from "drizzle-orm/pg-core";
|
||||||
|
|
||||||
import * as schema from "./schema";
|
import * as schema from "./schema";
|
||||||
|
|
||||||
|
// Export the db instance from your drizzle setup (make sure your drizzle file is updated for Postgres)
|
||||||
export { db } from "./drizzle";
|
export { db } from "./drizzle";
|
||||||
export * as schema from "./schema";
|
export * as schema from "./schema";
|
||||||
export { SqliteError } from "better-sqlite3";
|
|
||||||
|
|
||||||
// This is exported here to avoid leaking better-sqlite types outside of this package.
|
// If you need to export Postgres errors, you can export them from the pg package.
|
||||||
export type LifetrackerDBTransaction = SQLiteTransaction<
|
// (Optional – remove if not needed)
|
||||||
"sync",
|
export { DatabaseError } from "pg";
|
||||||
Database.RunResult,
|
export const ErrorCodes = {
|
||||||
typeof schema,
|
UNIQUE_VIOLATION: "23505",
|
||||||
ExtractTablesWithRelations<typeof schema>
|
};
|
||||||
>;
|
|
||||||
|
/**
|
||||||
|
* This type alias is provided to avoid leaking pg types outside of this package.
|
||||||
|
*
|
||||||
|
* Note:
|
||||||
|
* - The first generic parameter is set to "async" because most PostgreSQL drivers (like pg) are asynchronous.
|
||||||
|
* - The second generic parameter uses pg's QueryResult type.
|
||||||
|
*/
|
||||||
|
export type LifetrackerDBTransaction = PgTransaction<any, ExtractTablesWithRelations<typeof schema>>;
|
||||||
|
|||||||
Binary file not shown.
63
packages/db/migrate-to-postgres.ts
Normal file
63
packages/db/migrate-to-postgres.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// migrate-to-postgres.ts
|
||||||
|
import { sql } from "drizzle-orm";
|
||||||
|
import { db as pgDb, getConnectionDetails } from "./drizzle";
|
||||||
|
import { db as sqliteDb, databaseUrl } from "./drizzle-sqlite";
|
||||||
|
import * as schema from "./schema";
|
||||||
|
import { pgDump, pgRestore } from "pg-dump-restore";
|
||||||
|
import serverConfig from "@lifetracker/shared/config";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export async function migrateData() {
|
||||||
|
// First back up existing pg data
|
||||||
|
const filename = `${serverConfig.dataDir}/pg-backup-${new Date().getTime()}.sql`;
|
||||||
|
const { stdout, stderr } = await pgDump(getConnectionDetails(), {
|
||||||
|
filePath: `${filename}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Backed up existing data to ", filename);
|
||||||
|
console.log(stdout);
|
||||||
|
|
||||||
|
console.log(`Using sqlite db: ${databaseUrl}`);
|
||||||
|
|
||||||
|
const tables = {
|
||||||
|
"users": schema.users,
|
||||||
|
// "apiKeys": schema.apiKeys,
|
||||||
|
// "colors": schema.colors,
|
||||||
|
// "categories": schema.categories,
|
||||||
|
// "days": schema.days,
|
||||||
|
// "hours": schema.hours,
|
||||||
|
// "metrics": schema.metrics,
|
||||||
|
// "measurements": schema.measurements,
|
||||||
|
};
|
||||||
|
|
||||||
|
// console.log(await sqliteDb.select().from(schema.apiKeys));
|
||||||
|
|
||||||
|
// For each table in your schema, transfer the data
|
||||||
|
for (const tableName of Object.keys(tables)) {
|
||||||
|
const oldData = await sqliteDb.query[tableName].findMany();
|
||||||
|
console.log(`Table: ${tableName}`);
|
||||||
|
var skippedRecords = 0;
|
||||||
|
var migratedRecords = 0;
|
||||||
|
for (const record of oldData) {
|
||||||
|
if ((await pgDb.select().from(tables[tableName]).where(sql`${tables[tableName].id} = ${record.id}`)).length == 0) {
|
||||||
|
|
||||||
|
await pgDb.insert(tables[tableName]).values({
|
||||||
|
...record,
|
||||||
|
createdAt: new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
migratedRecords++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
skippedRecords++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Migrated ${migratedRecords} records (skipped ${skippedRecords}) from ${tableName}\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Migration complete!");
|
||||||
|
}
|
||||||
|
|
||||||
|
migrateData().catch(console.error);
|
||||||
@ -1,4 +1,17 @@
|
|||||||
import { db } from "./drizzle";
|
import { db } from "./drizzle";
|
||||||
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
import { migrate } from "drizzle-orm/node-postgres/migrator";
|
||||||
|
|
||||||
migrate(db, { migrationsFolder: "./migrations" });
|
async function runMigrations() {
|
||||||
|
try {
|
||||||
|
console.log('Starting database migrations...');
|
||||||
|
await migrate(db, { migrationsFolder: "./migrations" });
|
||||||
|
console.log('Migrations completed successfully');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error during migration:', error);
|
||||||
|
process.exit(1);
|
||||||
|
} finally {
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runMigrations();
|
||||||
|
|||||||
@ -1,137 +0,0 @@
|
|||||||
CREATE TABLE `account` (
|
|
||||||
`userId` text NOT NULL,
|
|
||||||
`type` text NOT NULL,
|
|
||||||
`provider` text NOT NULL,
|
|
||||||
`providerAccountId` text NOT NULL,
|
|
||||||
`refresh_token` text,
|
|
||||||
`access_token` text,
|
|
||||||
`expires_at` integer,
|
|
||||||
`token_type` text,
|
|
||||||
`scope` text,
|
|
||||||
`id_token` text,
|
|
||||||
`session_state` text,
|
|
||||||
PRIMARY KEY(`provider`, `providerAccountId`),
|
|
||||||
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `apiKey` (
|
|
||||||
`id` text PRIMARY KEY NOT NULL,
|
|
||||||
`name` text NOT NULL,
|
|
||||||
`createdAt` integer NOT NULL,
|
|
||||||
`keyId` text NOT NULL,
|
|
||||||
`keyHash` text NOT NULL,
|
|
||||||
`userId` text NOT NULL,
|
|
||||||
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `category` (
|
|
||||||
`id` text PRIMARY KEY NOT NULL,
|
|
||||||
`createdAt` integer NOT NULL,
|
|
||||||
`name` text NOT NULL,
|
|
||||||
`code` real NOT NULL,
|
|
||||||
`description` text,
|
|
||||||
`colorId` text NOT NULL,
|
|
||||||
`parentId` text,
|
|
||||||
`userId` text NOT NULL,
|
|
||||||
FOREIGN KEY (`colorId`) REFERENCES `color`(`id`) ON UPDATE no action ON DELETE no action,
|
|
||||||
FOREIGN KEY (`parentId`) REFERENCES `category`(`id`) ON UPDATE no action ON DELETE no action,
|
|
||||||
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `color` (
|
|
||||||
`id` text PRIMARY KEY NOT NULL,
|
|
||||||
`createdAt` integer NOT NULL,
|
|
||||||
`name` text NOT NULL,
|
|
||||||
`hexcode` text NOT NULL,
|
|
||||||
`inverse` text,
|
|
||||||
`userId` text NOT NULL,
|
|
||||||
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `config` (
|
|
||||||
`key` text PRIMARY KEY NOT NULL,
|
|
||||||
`value` text NOT NULL
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `day` (
|
|
||||||
`id` text PRIMARY KEY NOT NULL,
|
|
||||||
`date` text NOT NULL,
|
|
||||||
`mood` integer,
|
|
||||||
`comment` text,
|
|
||||||
`userId` text NOT NULL,
|
|
||||||
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `hour` (
|
|
||||||
`id` text PRIMARY KEY NOT NULL,
|
|
||||||
`createdAt` integer NOT NULL,
|
|
||||||
`userId` text NOT NULL,
|
|
||||||
`comment` text,
|
|
||||||
`time` integer NOT NULL,
|
|
||||||
`dayId` text NOT NULL,
|
|
||||||
`categoryId` text,
|
|
||||||
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
||||||
FOREIGN KEY (`dayId`) REFERENCES `day`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
||||||
FOREIGN KEY (`categoryId`) REFERENCES `category`(`id`) ON UPDATE no action ON DELETE no action
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `measurement` (
|
|
||||||
`id` text PRIMARY KEY NOT NULL,
|
|
||||||
`hourId` text,
|
|
||||||
`dayId` text NOT NULL,
|
|
||||||
`metricId` text NOT NULL,
|
|
||||||
`createdAt` integer NOT NULL,
|
|
||||||
`userId` text NOT NULL,
|
|
||||||
`value` text NOT NULL,
|
|
||||||
FOREIGN KEY (`hourId`) REFERENCES `hour`(`id`) ON UPDATE no action ON DELETE no action,
|
|
||||||
FOREIGN KEY (`dayId`) REFERENCES `day`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
||||||
FOREIGN KEY (`metricId`) REFERENCES `metric`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
||||||
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `metric` (
|
|
||||||
`id` text PRIMARY KEY NOT NULL,
|
|
||||||
`name` text NOT NULL,
|
|
||||||
`description` text,
|
|
||||||
`userId` text NOT NULL,
|
|
||||||
`type` text NOT NULL,
|
|
||||||
`unit` text,
|
|
||||||
`goal` real,
|
|
||||||
`icon` text NOT NULL,
|
|
||||||
`createdAt` integer NOT NULL,
|
|
||||||
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `session` (
|
|
||||||
`sessionToken` text PRIMARY KEY NOT NULL,
|
|
||||||
`userId` text NOT NULL,
|
|
||||||
`expires` integer NOT NULL,
|
|
||||||
FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `user` (
|
|
||||||
`id` text PRIMARY KEY NOT NULL,
|
|
||||||
`name` text NOT NULL,
|
|
||||||
`email` text NOT NULL,
|
|
||||||
`emailVerified` integer,
|
|
||||||
`image` text,
|
|
||||||
`password` text,
|
|
||||||
`role` text DEFAULT 'user',
|
|
||||||
`timezone` text DEFAULT 'America/Los_Angeles' NOT NULL
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `verificationToken` (
|
|
||||||
`identifier` text NOT NULL,
|
|
||||||
`token` text NOT NULL,
|
|
||||||
`expires` integer NOT NULL,
|
|
||||||
PRIMARY KEY(`identifier`, `token`)
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `apiKey_keyId_unique` ON `apiKey` (`keyId`);--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `apiKey_name_userId_unique` ON `apiKey` (`name`,`userId`);--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `category_userId_code_unique` ON `category` (`userId`,`code`);--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `color_userId_name_unique` ON `color` (`userId`,`name`);--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `day_date_unique` ON `day` (`date`);--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `hour_dayId_time_unique` ON `hour` (`dayId`,`time`);--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `metric_userId_name_unique` ON `metric` (`userId`,`name`);--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `user_email_unique` ON `user` (`email`);
|
|
||||||
215
packages/db/migrations/0000_redundant_glorian.sql
Normal file
215
packages/db/migrations/0000_redundant_glorian.sql
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS "account" (
|
||||||
|
"userId" text NOT NULL,
|
||||||
|
"type" text NOT NULL,
|
||||||
|
"provider" text NOT NULL,
|
||||||
|
"providerAccountId" text NOT NULL,
|
||||||
|
"refresh_token" text,
|
||||||
|
"access_token" text,
|
||||||
|
"expires_at" integer,
|
||||||
|
"token_type" text,
|
||||||
|
"scope" text,
|
||||||
|
"id_token" text,
|
||||||
|
"session_state" text,
|
||||||
|
CONSTRAINT "account_provider_providerAccountId_pk" PRIMARY KEY("provider","providerAccountId")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "apiKey" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"name" text NOT NULL,
|
||||||
|
"createdAt" timestamp DEFAULT now() NOT NULL,
|
||||||
|
"keyId" text NOT NULL,
|
||||||
|
"keyHash" text NOT NULL,
|
||||||
|
"userId" text NOT NULL,
|
||||||
|
CONSTRAINT "apiKey_keyId_unique" UNIQUE("keyId"),
|
||||||
|
CONSTRAINT "apiKey_name_userId_unique" UNIQUE("name","userId")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "category" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"createdAt" timestamp DEFAULT now() NOT NULL,
|
||||||
|
"name" text NOT NULL,
|
||||||
|
"code" real NOT NULL,
|
||||||
|
"description" text,
|
||||||
|
"colorId" text NOT NULL,
|
||||||
|
"parentId" text,
|
||||||
|
"userId" text NOT NULL,
|
||||||
|
CONSTRAINT "category_userId_code_unique" UNIQUE("userId","code")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "color" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"createdAt" timestamp DEFAULT now() NOT NULL,
|
||||||
|
"name" text NOT NULL,
|
||||||
|
"hexcode" text NOT NULL,
|
||||||
|
"inverse" text,
|
||||||
|
"userId" text NOT NULL,
|
||||||
|
CONSTRAINT "color_userId_name_unique" UNIQUE("userId","name")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "config" (
|
||||||
|
"key" text PRIMARY KEY NOT NULL,
|
||||||
|
"value" text NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "day" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"date" text NOT NULL,
|
||||||
|
"mood" integer,
|
||||||
|
"comment" text,
|
||||||
|
"userId" text NOT NULL,
|
||||||
|
CONSTRAINT "day_date_unique" UNIQUE("date")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "hour" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"createdAt" timestamp DEFAULT now() NOT NULL,
|
||||||
|
"userId" text NOT NULL,
|
||||||
|
"comment" text,
|
||||||
|
"time" integer NOT NULL,
|
||||||
|
"dayId" text NOT NULL,
|
||||||
|
"categoryId" text
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "measurement" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"hourId" text,
|
||||||
|
"dayId" text NOT NULL,
|
||||||
|
"metricId" text NOT NULL,
|
||||||
|
"createdAt" timestamp DEFAULT now() NOT NULL,
|
||||||
|
"userId" text NOT NULL,
|
||||||
|
"value" text NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "metric" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"name" text NOT NULL,
|
||||||
|
"description" text,
|
||||||
|
"userId" text NOT NULL,
|
||||||
|
"type" text NOT NULL,
|
||||||
|
"unit" text,
|
||||||
|
"goal" real,
|
||||||
|
"icon" text NOT NULL,
|
||||||
|
"createdAt" timestamp DEFAULT now() NOT NULL,
|
||||||
|
CONSTRAINT "metric_userId_name_unique" UNIQUE("userId","name")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "session" (
|
||||||
|
"sessionToken" text PRIMARY KEY NOT NULL,
|
||||||
|
"userId" text NOT NULL,
|
||||||
|
"expires" timestamp NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "user" (
|
||||||
|
"id" text PRIMARY KEY NOT NULL,
|
||||||
|
"name" text NOT NULL,
|
||||||
|
"email" text NOT NULL,
|
||||||
|
"emailVerified" integer,
|
||||||
|
"image" text,
|
||||||
|
"password" text,
|
||||||
|
"role" text DEFAULT 'user',
|
||||||
|
"timezone" text DEFAULT 'America/Los_Angeles' NOT NULL,
|
||||||
|
CONSTRAINT "user_email_unique" UNIQUE("email")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "verificationToken" (
|
||||||
|
"identifier" text NOT NULL,
|
||||||
|
"token" text NOT NULL,
|
||||||
|
"expires" timestamp NOT NULL,
|
||||||
|
CONSTRAINT "verificationToken_identifier_token_pk" PRIMARY KEY("identifier","token")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "account" ADD CONSTRAINT "account_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "apiKey" ADD CONSTRAINT "apiKey_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "category" ADD CONSTRAINT "category_colorId_color_id_fk" FOREIGN KEY ("colorId") REFERENCES "public"."color"("id") ON DELETE no action ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "category" ADD CONSTRAINT "category_parentId_category_id_fk" FOREIGN KEY ("parentId") REFERENCES "public"."category"("id") ON DELETE no action ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "category" ADD CONSTRAINT "category_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "color" ADD CONSTRAINT "color_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "day" ADD CONSTRAINT "day_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "hour" ADD CONSTRAINT "hour_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "hour" ADD CONSTRAINT "hour_dayId_day_id_fk" FOREIGN KEY ("dayId") REFERENCES "public"."day"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "hour" ADD CONSTRAINT "hour_categoryId_category_id_fk" FOREIGN KEY ("categoryId") REFERENCES "public"."category"("id") ON DELETE no action ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "measurement" ADD CONSTRAINT "measurement_hourId_hour_id_fk" FOREIGN KEY ("hourId") REFERENCES "public"."hour"("id") ON DELETE no action ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "measurement" ADD CONSTRAINT "measurement_dayId_day_id_fk" FOREIGN KEY ("dayId") REFERENCES "public"."day"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "measurement" ADD CONSTRAINT "measurement_metricId_metric_id_fk" FOREIGN KEY ("metricId") REFERENCES "public"."metric"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "measurement" ADD CONSTRAINT "measurement_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "metric" ADD CONSTRAINT "metric_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "session" ADD CONSTRAINT "session_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
18
packages/db/migrations/0001_modify_hour_datetime.sql
Normal file
18
packages/db/migrations/0001_modify_hour_datetime.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-- Custom SQL migration file, put you code below! --
|
||||||
|
-- Step 1: Add the new 'datetime' column
|
||||||
|
ALTER TABLE "hour"
|
||||||
|
ADD COLUMN "datetime" TIMESTAMPTZ;
|
||||||
|
|
||||||
|
-- Step 2: Update 'datetime' by combining 'Day.date' and 'Hour.time'
|
||||||
|
UPDATE "hour"
|
||||||
|
SET "datetime" = ("day"."date"::timestamp + ("hour"."time" * INTERVAL '1 hour')) AT TIME ZONE 'UTC'
|
||||||
|
FROM "day"
|
||||||
|
WHERE "hour"."dayId" = "day"."id";
|
||||||
|
|
||||||
|
-- Step 3: Add a unique constraint to 'datetime'
|
||||||
|
ALTER TABLE "hour"
|
||||||
|
ADD CONSTRAINT "hour_datetime_unique" UNIQUE("datetime");
|
||||||
|
|
||||||
|
-- Step 3: Drop the old 'time' column
|
||||||
|
ALTER TABLE "hour"
|
||||||
|
DROP COLUMN "time";
|
||||||
54
packages/db/migrations/0002_seed_ryan_user.sql
Normal file
54
packages/db/migrations/0002_seed_ryan_user.sql
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
INSERT INTO "user" (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"email",
|
||||||
|
"emailVerified",
|
||||||
|
"image",
|
||||||
|
"password",
|
||||||
|
"role",
|
||||||
|
"timezone"
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'n7yns1s5b122y5e8v0p6uyt8',
|
||||||
|
'Ryan Pandya',
|
||||||
|
'ryan@ryanpandya.com',
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
'$2a$10$ngv9752uxDT11hSPfdZmAe2D8VXLB9mcXkN7TRPI5GZQCuriIu1gC',
|
||||||
|
'admin',
|
||||||
|
'America/Los_Angeles'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO "apiKey" (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"keyId",
|
||||||
|
"keyHash",
|
||||||
|
"userId"
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'wxl62dg2n721tgzlz3spnjbu',
|
||||||
|
'CLI App',
|
||||||
|
to_timestamp('1731634820') AT TIME ZONE 'UTC',
|
||||||
|
'b9b17eb909ce0ecdbf33',
|
||||||
|
'$2a$10$NhOG42FjMbDycWHcJI4LH.Jp.aCV.op7llIP0zw/CBUmB3lO0HHQu',
|
||||||
|
'n7yns1s5b122y5e8v0p6uyt8'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO "apiKey" (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"keyId",
|
||||||
|
"keyHash",
|
||||||
|
"userId"
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'i703hxfm1xoov08jc214jnoz',
|
||||||
|
'Node-Red',
|
||||||
|
to_timestamp('1737068601') AT TIME ZONE 'UTC',
|
||||||
|
'820b8395dee76268b559',
|
||||||
|
'$2a$10$eUs4vYj2jr47LY6Rou4peudddpB/pyHRo2.cbomoUqNbAJf9RtZDS',
|
||||||
|
'n7yns1s5b122y5e8v0p6uyt8'
|
||||||
|
);
|
||||||
6
packages/db/migrations/0003_silky_mongu.sql
Normal file
6
packages/db/migrations/0003_silky_mongu.sql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
ALTER TABLE "apiKey" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;--> statement-breakpoint
|
||||||
|
ALTER TABLE "category" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;--> statement-breakpoint
|
||||||
|
ALTER TABLE "color" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;--> statement-breakpoint
|
||||||
|
ALTER TABLE "hour" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;--> statement-breakpoint
|
||||||
|
ALTER TABLE "measurement" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;--> statement-breakpoint
|
||||||
|
ALTER TABLE "metric" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;
|
||||||
1
packages/db/migrations/0004_tan_justin_hammer.sql
Normal file
1
packages/db/migrations/0004_tan_justin_hammer.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "hour" DROP COLUMN IF EXISTS "time";
|
||||||
@ -1,88 +1,78 @@
|
|||||||
{
|
{
|
||||||
"version": "6",
|
"id": "8809abd6-6301-4dba-9f67-13071abd3086",
|
||||||
"dialect": "sqlite",
|
|
||||||
"id": "9a832735-dcfa-42cc-ad15-6be5b898a160",
|
|
||||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
"tables": {
|
"tables": {
|
||||||
"account": {
|
"public.account": {
|
||||||
"name": "account",
|
"name": "account",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"userId": {
|
"userId": {
|
||||||
"name": "userId",
|
"name": "userId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"name": "type",
|
"name": "type",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
"name": "provider",
|
"name": "provider",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"providerAccountId": {
|
"providerAccountId": {
|
||||||
"name": "providerAccountId",
|
"name": "providerAccountId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"refresh_token": {
|
"refresh_token": {
|
||||||
"name": "refresh_token",
|
"name": "refresh_token",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"access_token": {
|
"access_token": {
|
||||||
"name": "access_token",
|
"name": "access_token",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"expires_at": {
|
"expires_at": {
|
||||||
"name": "expires_at",
|
"name": "expires_at",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"token_type": {
|
"token_type": {
|
||||||
"name": "token_type",
|
"name": "token_type",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"scope": {
|
"scope": {
|
||||||
"name": "scope",
|
"name": "scope",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"id_token": {
|
"id_token": {
|
||||||
"name": "id_token",
|
"name": "id_token",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"session_state": {
|
"session_state": {
|
||||||
"name": "session_state",
|
"name": "session_state",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -103,78 +93,58 @@
|
|||||||
},
|
},
|
||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"account_provider_providerAccountId_pk": {
|
"account_provider_providerAccountId_pk": {
|
||||||
|
"name": "account_provider_providerAccountId_pk",
|
||||||
"columns": [
|
"columns": [
|
||||||
"provider",
|
"provider",
|
||||||
"providerAccountId"
|
"providerAccountId"
|
||||||
],
|
]
|
||||||
"name": "account_provider_providerAccountId_pk"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {}
|
||||||
},
|
},
|
||||||
"apiKey": {
|
"public.apiKey": {
|
||||||
"name": "apiKey",
|
"name": "apiKey",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"name": "name",
|
"name": "name",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"name": "createdAt",
|
"name": "createdAt",
|
||||||
"type": "integer",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false
|
"default": "now()"
|
||||||
},
|
},
|
||||||
"keyId": {
|
"keyId": {
|
||||||
"name": "keyId",
|
"name": "keyId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"keyHash": {
|
"keyHash": {
|
||||||
"name": "keyHash",
|
"name": "keyHash",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"name": "userId",
|
"name": "userId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"apiKey_keyId_unique": {
|
|
||||||
"name": "apiKey_keyId_unique",
|
|
||||||
"columns": [
|
|
||||||
"keyId"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
},
|
|
||||||
"apiKey_name_userId_unique": {
|
|
||||||
"name": "apiKey_name_userId_unique",
|
|
||||||
"columns": [
|
|
||||||
"name",
|
|
||||||
"userId"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"indexes": {},
|
||||||
"foreignKeys": {
|
"foreignKeys": {
|
||||||
"apiKey_userId_user_id_fk": {
|
"apiKey_userId_user_id_fk": {
|
||||||
"name": "apiKey_userId_user_id_fk",
|
"name": "apiKey_userId_user_id_fk",
|
||||||
@ -191,78 +161,79 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {
|
||||||
|
"apiKey_keyId_unique": {
|
||||||
|
"name": "apiKey_keyId_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"keyId"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"category": {
|
"apiKey_name_userId_unique": {
|
||||||
|
"name": "apiKey_name_userId_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"name",
|
||||||
|
"userId"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.category": {
|
||||||
"name": "category",
|
"name": "category",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"name": "createdAt",
|
"name": "createdAt",
|
||||||
"type": "integer",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false
|
"default": "now()"
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"name": "name",
|
"name": "name",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"code": {
|
"code": {
|
||||||
"name": "code",
|
"name": "code",
|
||||||
"type": "real",
|
"type": "real",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"name": "description",
|
"name": "description",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"colorId": {
|
"colorId": {
|
||||||
"name": "colorId",
|
"name": "colorId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"parentId": {
|
"parentId": {
|
||||||
"name": "parentId",
|
"name": "parentId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"name": "userId",
|
"name": "userId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"category_userId_code_unique": {
|
|
||||||
"name": "category_userId_code_unique",
|
|
||||||
"columns": [
|
|
||||||
"userId",
|
|
||||||
"code"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"indexes": {},
|
||||||
"foreignKeys": {
|
"foreignKeys": {
|
||||||
"category_colorId_color_id_fk": {
|
"category_colorId_color_id_fk": {
|
||||||
"name": "category_colorId_color_id_fk",
|
"name": "category_colorId_color_id_fk",
|
||||||
@ -305,64 +276,60 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {
|
||||||
|
"category_userId_code_unique": {
|
||||||
|
"name": "category_userId_code_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"color": {
|
"public.color": {
|
||||||
"name": "color",
|
"name": "color",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"name": "createdAt",
|
"name": "createdAt",
|
||||||
"type": "integer",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false
|
"default": "now()"
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"name": "name",
|
"name": "name",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"hexcode": {
|
"hexcode": {
|
||||||
"name": "hexcode",
|
"name": "hexcode",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"inverse": {
|
"inverse": {
|
||||||
"name": "inverse",
|
"name": "inverse",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"name": "userId",
|
"name": "userId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"color_userId_name_unique": {
|
|
||||||
"name": "color_userId_name_unique",
|
|
||||||
"columns": [
|
|
||||||
"userId",
|
|
||||||
"name"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"indexes": {},
|
||||||
"foreignKeys": {
|
"foreignKeys": {
|
||||||
"color_userId_user_id_fk": {
|
"color_userId_user_id_fk": {
|
||||||
"name": "color_userId_user_id_fk",
|
"name": "color_userId_user_id_fk",
|
||||||
@ -379,24 +346,32 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {
|
||||||
|
"color_userId_name_unique": {
|
||||||
|
"name": "color_userId_name_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"config": {
|
"public.config": {
|
||||||
"name": "config",
|
"name": "config",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"key": {
|
"key": {
|
||||||
"name": "key",
|
"name": "key",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
"name": "value",
|
"name": "value",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -404,54 +379,42 @@
|
|||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {}
|
||||||
},
|
},
|
||||||
"day": {
|
"public.day": {
|
||||||
"name": "day",
|
"name": "day",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"date": {
|
"date": {
|
||||||
"name": "date",
|
"name": "date",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"mood": {
|
"mood": {
|
||||||
"name": "mood",
|
"name": "mood",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"comment": {
|
"comment": {
|
||||||
"name": "comment",
|
"name": "comment",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"name": "userId",
|
"name": "userId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"day_date_unique": {
|
|
||||||
"name": "day_date_unique",
|
|
||||||
"columns": [
|
|
||||||
"date"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"indexes": {},
|
||||||
"foreignKeys": {
|
"foreignKeys": {
|
||||||
"day_userId_user_id_fk": {
|
"day_userId_user_id_fk": {
|
||||||
"name": "day_userId_user_id_fk",
|
"name": "day_userId_user_id_fk",
|
||||||
@ -468,71 +431,71 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {
|
||||||
|
"day_date_unique": {
|
||||||
|
"name": "day_date_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"date"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"hour": {
|
"public.hour": {
|
||||||
"name": "hour",
|
"name": "hour",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"name": "createdAt",
|
"name": "createdAt",
|
||||||
"type": "integer",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false
|
"default": "now()"
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"name": "userId",
|
"name": "userId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"comment": {
|
"comment": {
|
||||||
"name": "comment",
|
"name": "comment",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"name": "time",
|
"name": "time",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
},
|
||||||
|
"datetime": {
|
||||||
|
"name": "datetime",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
},
|
},
|
||||||
"dayId": {
|
"dayId": {
|
||||||
"name": "dayId",
|
"name": "dayId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"categoryId": {
|
"categoryId": {
|
||||||
"name": "categoryId",
|
"name": "categoryId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"hour_dayId_time_unique": {
|
|
||||||
"name": "hour_dayId_time_unique",
|
|
||||||
"columns": [
|
|
||||||
"dayId",
|
|
||||||
"time"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"indexes": {},
|
||||||
"foreignKeys": {
|
"foreignKeys": {
|
||||||
"hour_userId_user_id_fk": {
|
"hour_userId_user_id_fk": {
|
||||||
"name": "hour_userId_user_id_fk",
|
"name": "hour_userId_user_id_fk",
|
||||||
@ -575,59 +538,63 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {
|
||||||
|
"hour_dayId_datetime_unique": {
|
||||||
|
"name": "hour_dayId_datetime_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"dayId",
|
||||||
|
"datetime"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"measurement": {
|
"public.measurement": {
|
||||||
"name": "measurement",
|
"name": "measurement",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"hourId": {
|
"hourId": {
|
||||||
"name": "hourId",
|
"name": "hourId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"dayId": {
|
"dayId": {
|
||||||
"name": "dayId",
|
"name": "dayId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"metricId": {
|
"metricId": {
|
||||||
"name": "metricId",
|
"name": "metricId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"name": "createdAt",
|
"name": "createdAt",
|
||||||
"type": "integer",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false
|
"default": "now()"
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"name": "userId",
|
"name": "userId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
"name": "value",
|
"name": "value",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -688,83 +655,67 @@
|
|||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {}
|
||||||
},
|
},
|
||||||
"metric": {
|
"public.metric": {
|
||||||
"name": "metric",
|
"name": "metric",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"name": "name",
|
"name": "name",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"name": "description",
|
"name": "description",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"name": "userId",
|
"name": "userId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"name": "type",
|
"name": "type",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"unit": {
|
"unit": {
|
||||||
"name": "unit",
|
"name": "unit",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"goal": {
|
"goal": {
|
||||||
"name": "goal",
|
"name": "goal",
|
||||||
"type": "real",
|
"type": "real",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"icon": {
|
"icon": {
|
||||||
"name": "icon",
|
"name": "icon",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"name": "createdAt",
|
"name": "createdAt",
|
||||||
"type": "integer",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false
|
"default": "now()"
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"metric_userId_name_unique": {
|
|
||||||
"name": "metric_userId_name_unique",
|
|
||||||
"columns": [
|
|
||||||
"userId",
|
|
||||||
"name"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"indexes": {},
|
||||||
"foreignKeys": {
|
"foreignKeys": {
|
||||||
"metric_userId_user_id_fk": {
|
"metric_userId_user_id_fk": {
|
||||||
"name": "metric_userId_user_id_fk",
|
"name": "metric_userId_user_id_fk",
|
||||||
@ -781,31 +732,38 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {
|
||||||
|
"metric_userId_name_unique": {
|
||||||
|
"name": "metric_userId_name_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"session": {
|
"public.session": {
|
||||||
"name": "session",
|
"name": "session",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"sessionToken": {
|
"sessionToken": {
|
||||||
"name": "sessionToken",
|
"name": "sessionToken",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"name": "userId",
|
"name": "userId",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"expires": {
|
"expires": {
|
||||||
"name": "expires",
|
"name": "expires",
|
||||||
"type": "integer",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
@ -827,57 +785,51 @@
|
|||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {}
|
||||||
},
|
},
|
||||||
"user": {
|
"public.user": {
|
||||||
"name": "user",
|
"name": "user",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"name": "name",
|
"name": "name",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"email": {
|
"email": {
|
||||||
"name": "email",
|
"name": "email",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"emailVerified": {
|
"emailVerified": {
|
||||||
"name": "emailVerified",
|
"name": "emailVerified",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"image": {
|
"image": {
|
||||||
"name": "image",
|
"name": "image",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"name": "password",
|
"name": "password",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"role": {
|
"role": {
|
||||||
"name": "role",
|
"name": "role",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false,
|
||||||
"autoincrement": false,
|
|
||||||
"default": "'user'"
|
"default": "'user'"
|
||||||
},
|
},
|
||||||
"timezone": {
|
"timezone": {
|
||||||
@ -885,69 +837,65 @@
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false,
|
|
||||||
"default": "'America/Los_Angeles'"
|
"default": "'America/Los_Angeles'"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {
|
"indexes": {},
|
||||||
"user_email_unique": {
|
|
||||||
"name": "user_email_unique",
|
|
||||||
"columns": [
|
|
||||||
"email"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"foreignKeys": {},
|
"foreignKeys": {},
|
||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {
|
||||||
|
"user_email_unique": {
|
||||||
|
"name": "user_email_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"email"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"verificationToken": {
|
"public.verificationToken": {
|
||||||
"name": "verificationToken",
|
"name": "verificationToken",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"name": "identifier",
|
"name": "identifier",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"token": {
|
"token": {
|
||||||
"name": "token",
|
"name": "token",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"expires": {
|
"expires": {
|
||||||
"name": "expires",
|
"name": "expires",
|
||||||
"type": "integer",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {},
|
"indexes": {},
|
||||||
"foreignKeys": {},
|
"foreignKeys": {},
|
||||||
"compositePrimaryKeys": {
|
"compositePrimaryKeys": {
|
||||||
"verificationToken_identifier_token_pk": {
|
"verificationToken_identifier_token_pk": {
|
||||||
|
"name": "verificationToken_identifier_token_pk",
|
||||||
"columns": [
|
"columns": [
|
||||||
"identifier",
|
"identifier",
|
||||||
"token"
|
"token"
|
||||||
],
|
]
|
||||||
"name": "verificationToken_identifier_token_pk"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"enums": {},
|
"enums": {},
|
||||||
"_meta": {
|
|
||||||
"schemas": {},
|
"schemas": {},
|
||||||
"tables": {},
|
"sequences": {},
|
||||||
"columns": {}
|
"_meta": {
|
||||||
},
|
"columns": {},
|
||||||
"internal": {
|
"schemas": {},
|
||||||
"indexes": {}
|
"tables": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
901
packages/db/migrations/meta/0001_snapshot.json
Normal file
901
packages/db/migrations/meta/0001_snapshot.json
Normal file
@ -0,0 +1,901 @@
|
|||||||
|
{
|
||||||
|
"id": "d1116059-9901-4852-9826-5a4458564eb5",
|
||||||
|
"prevId": "8809abd6-6301-4dba-9f67-13071abd3086",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"tables": {
|
||||||
|
"public.account": {
|
||||||
|
"name": "account",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"name": "provider",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"providerAccountId": {
|
||||||
|
"name": "providerAccountId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"refresh_token": {
|
||||||
|
"name": "refresh_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"access_token": {
|
||||||
|
"name": "access_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"expires_at": {
|
||||||
|
"name": "expires_at",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"token_type": {
|
||||||
|
"name": "token_type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"name": "scope",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"id_token": {
|
||||||
|
"name": "id_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"session_state": {
|
||||||
|
"name": "session_state",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"account_userId_user_id_fk": {
|
||||||
|
"name": "account_userId_user_id_fk",
|
||||||
|
"tableFrom": "account",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"account_provider_providerAccountId_pk": {
|
||||||
|
"name": "account_provider_providerAccountId_pk",
|
||||||
|
"columns": [
|
||||||
|
"provider",
|
||||||
|
"providerAccountId"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.apiKey": {
|
||||||
|
"name": "apiKey",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"keyId": {
|
||||||
|
"name": "keyId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"keyHash": {
|
||||||
|
"name": "keyHash",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"apiKey_userId_user_id_fk": {
|
||||||
|
"name": "apiKey_userId_user_id_fk",
|
||||||
|
"tableFrom": "apiKey",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"apiKey_keyId_unique": {
|
||||||
|
"name": "apiKey_keyId_unique",
|
||||||
|
"columns": [
|
||||||
|
"keyId"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
},
|
||||||
|
"apiKey_name_userId_unique": {
|
||||||
|
"name": "apiKey_name_userId_unique",
|
||||||
|
"columns": [
|
||||||
|
"name",
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.category": {
|
||||||
|
"name": "category",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"name": "code",
|
||||||
|
"type": "real",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"colorId": {
|
||||||
|
"name": "colorId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"parentId": {
|
||||||
|
"name": "parentId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"category_colorId_color_id_fk": {
|
||||||
|
"name": "category_colorId_color_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"columnsFrom": [
|
||||||
|
"colorId"
|
||||||
|
],
|
||||||
|
"tableTo": "color",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "no action"
|
||||||
|
},
|
||||||
|
"category_parentId_category_id_fk": {
|
||||||
|
"name": "category_parentId_category_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"columnsFrom": [
|
||||||
|
"parentId"
|
||||||
|
],
|
||||||
|
"tableTo": "category",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "no action"
|
||||||
|
},
|
||||||
|
"category_userId_user_id_fk": {
|
||||||
|
"name": "category_userId_user_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"category_userId_code_unique": {
|
||||||
|
"name": "category_userId_code_unique",
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"code"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.color": {
|
||||||
|
"name": "color",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"hexcode": {
|
||||||
|
"name": "hexcode",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"inverse": {
|
||||||
|
"name": "inverse",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"color_userId_user_id_fk": {
|
||||||
|
"name": "color_userId_user_id_fk",
|
||||||
|
"tableFrom": "color",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"color_userId_name_unique": {
|
||||||
|
"name": "color_userId_name_unique",
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.config": {
|
||||||
|
"name": "config",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"key": {
|
||||||
|
"name": "key",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.day": {
|
||||||
|
"name": "day",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"name": "date",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"mood": {
|
||||||
|
"name": "mood",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"name": "comment",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"day_userId_user_id_fk": {
|
||||||
|
"name": "day_userId_user_id_fk",
|
||||||
|
"tableFrom": "day",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"day_date_unique": {
|
||||||
|
"name": "day_date_unique",
|
||||||
|
"columns": [
|
||||||
|
"date"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.hour": {
|
||||||
|
"name": "hour",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"name": "comment",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"name": "time",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"datetime": {
|
||||||
|
"name": "datetime",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"dayId": {
|
||||||
|
"name": "dayId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"categoryId": {
|
||||||
|
"name": "categoryId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"hour_userId_user_id_fk": {
|
||||||
|
"name": "hour_userId_user_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
},
|
||||||
|
"hour_dayId_day_id_fk": {
|
||||||
|
"name": "hour_dayId_day_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"columnsFrom": [
|
||||||
|
"dayId"
|
||||||
|
],
|
||||||
|
"tableTo": "day",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
},
|
||||||
|
"hour_categoryId_category_id_fk": {
|
||||||
|
"name": "hour_categoryId_category_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"columnsFrom": [
|
||||||
|
"categoryId"
|
||||||
|
],
|
||||||
|
"tableTo": "category",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"hour_dayId_datetime_unique": {
|
||||||
|
"name": "hour_dayId_datetime_unique",
|
||||||
|
"columns": [
|
||||||
|
"dayId",
|
||||||
|
"datetime"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.measurement": {
|
||||||
|
"name": "measurement",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"hourId": {
|
||||||
|
"name": "hourId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"dayId": {
|
||||||
|
"name": "dayId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"metricId": {
|
||||||
|
"name": "metricId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"measurement_hourId_hour_id_fk": {
|
||||||
|
"name": "measurement_hourId_hour_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"columnsFrom": [
|
||||||
|
"hourId"
|
||||||
|
],
|
||||||
|
"tableTo": "hour",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "no action"
|
||||||
|
},
|
||||||
|
"measurement_dayId_day_id_fk": {
|
||||||
|
"name": "measurement_dayId_day_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"columnsFrom": [
|
||||||
|
"dayId"
|
||||||
|
],
|
||||||
|
"tableTo": "day",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
},
|
||||||
|
"measurement_metricId_metric_id_fk": {
|
||||||
|
"name": "measurement_metricId_metric_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"columnsFrom": [
|
||||||
|
"metricId"
|
||||||
|
],
|
||||||
|
"tableTo": "metric",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
},
|
||||||
|
"measurement_userId_user_id_fk": {
|
||||||
|
"name": "measurement_userId_user_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.metric": {
|
||||||
|
"name": "metric",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"unit": {
|
||||||
|
"name": "unit",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"goal": {
|
||||||
|
"name": "goal",
|
||||||
|
"type": "real",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"name": "icon",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"metric_userId_user_id_fk": {
|
||||||
|
"name": "metric_userId_user_id_fk",
|
||||||
|
"tableFrom": "metric",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"metric_userId_name_unique": {
|
||||||
|
"name": "metric_userId_name_unique",
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.session": {
|
||||||
|
"name": "session",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"sessionToken": {
|
||||||
|
"name": "sessionToken",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expires": {
|
||||||
|
"name": "expires",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"session_userId_user_id_fk": {
|
||||||
|
"name": "session_userId_user_id_fk",
|
||||||
|
"tableFrom": "session",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.user": {
|
||||||
|
"name": "user",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"emailVerified": {
|
||||||
|
"name": "emailVerified",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"name": "image",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"name": "password",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"name": "role",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "'user'"
|
||||||
|
},
|
||||||
|
"timezone": {
|
||||||
|
"name": "timezone",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'America/Los_Angeles'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"user_email_unique": {
|
||||||
|
"name": "user_email_unique",
|
||||||
|
"columns": [
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.verificationToken": {
|
||||||
|
"name": "verificationToken",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"identifier": {
|
||||||
|
"name": "identifier",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"name": "token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expires": {
|
||||||
|
"name": "expires",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"verificationToken_identifier_token_pk": {
|
||||||
|
"name": "verificationToken_identifier_token_pk",
|
||||||
|
"columns": [
|
||||||
|
"identifier",
|
||||||
|
"token"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
|
"_meta": {
|
||||||
|
"columns": {},
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
901
packages/db/migrations/meta/0002_snapshot.json
Normal file
901
packages/db/migrations/meta/0002_snapshot.json
Normal file
@ -0,0 +1,901 @@
|
|||||||
|
{
|
||||||
|
"id": "708d11dd-ccaa-48dd-b152-f012b2412704",
|
||||||
|
"prevId": "d1116059-9901-4852-9826-5a4458564eb5",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"tables": {
|
||||||
|
"public.account": {
|
||||||
|
"name": "account",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"name": "provider",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"providerAccountId": {
|
||||||
|
"name": "providerAccountId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"refresh_token": {
|
||||||
|
"name": "refresh_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"access_token": {
|
||||||
|
"name": "access_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"expires_at": {
|
||||||
|
"name": "expires_at",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"token_type": {
|
||||||
|
"name": "token_type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"name": "scope",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"id_token": {
|
||||||
|
"name": "id_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"session_state": {
|
||||||
|
"name": "session_state",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"account_userId_user_id_fk": {
|
||||||
|
"name": "account_userId_user_id_fk",
|
||||||
|
"tableFrom": "account",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"account_provider_providerAccountId_pk": {
|
||||||
|
"name": "account_provider_providerAccountId_pk",
|
||||||
|
"columns": [
|
||||||
|
"provider",
|
||||||
|
"providerAccountId"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.apiKey": {
|
||||||
|
"name": "apiKey",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"keyId": {
|
||||||
|
"name": "keyId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"keyHash": {
|
||||||
|
"name": "keyHash",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"apiKey_userId_user_id_fk": {
|
||||||
|
"name": "apiKey_userId_user_id_fk",
|
||||||
|
"tableFrom": "apiKey",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"apiKey_keyId_unique": {
|
||||||
|
"name": "apiKey_keyId_unique",
|
||||||
|
"columns": [
|
||||||
|
"keyId"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
},
|
||||||
|
"apiKey_name_userId_unique": {
|
||||||
|
"name": "apiKey_name_userId_unique",
|
||||||
|
"columns": [
|
||||||
|
"name",
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.category": {
|
||||||
|
"name": "category",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"name": "code",
|
||||||
|
"type": "real",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"colorId": {
|
||||||
|
"name": "colorId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"parentId": {
|
||||||
|
"name": "parentId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"category_colorId_color_id_fk": {
|
||||||
|
"name": "category_colorId_color_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"columnsFrom": [
|
||||||
|
"colorId"
|
||||||
|
],
|
||||||
|
"tableTo": "color",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "no action"
|
||||||
|
},
|
||||||
|
"category_parentId_category_id_fk": {
|
||||||
|
"name": "category_parentId_category_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"columnsFrom": [
|
||||||
|
"parentId"
|
||||||
|
],
|
||||||
|
"tableTo": "category",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "no action"
|
||||||
|
},
|
||||||
|
"category_userId_user_id_fk": {
|
||||||
|
"name": "category_userId_user_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"category_userId_code_unique": {
|
||||||
|
"name": "category_userId_code_unique",
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"code"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.color": {
|
||||||
|
"name": "color",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"hexcode": {
|
||||||
|
"name": "hexcode",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"inverse": {
|
||||||
|
"name": "inverse",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"color_userId_user_id_fk": {
|
||||||
|
"name": "color_userId_user_id_fk",
|
||||||
|
"tableFrom": "color",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"color_userId_name_unique": {
|
||||||
|
"name": "color_userId_name_unique",
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.config": {
|
||||||
|
"name": "config",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"key": {
|
||||||
|
"name": "key",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.day": {
|
||||||
|
"name": "day",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"name": "date",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"mood": {
|
||||||
|
"name": "mood",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"name": "comment",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"day_userId_user_id_fk": {
|
||||||
|
"name": "day_userId_user_id_fk",
|
||||||
|
"tableFrom": "day",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"day_date_unique": {
|
||||||
|
"name": "day_date_unique",
|
||||||
|
"columns": [
|
||||||
|
"date"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.hour": {
|
||||||
|
"name": "hour",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"name": "comment",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"name": "time",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"datetime": {
|
||||||
|
"name": "datetime",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"dayId": {
|
||||||
|
"name": "dayId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"categoryId": {
|
||||||
|
"name": "categoryId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"hour_userId_user_id_fk": {
|
||||||
|
"name": "hour_userId_user_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
},
|
||||||
|
"hour_dayId_day_id_fk": {
|
||||||
|
"name": "hour_dayId_day_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"columnsFrom": [
|
||||||
|
"dayId"
|
||||||
|
],
|
||||||
|
"tableTo": "day",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
},
|
||||||
|
"hour_categoryId_category_id_fk": {
|
||||||
|
"name": "hour_categoryId_category_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"columnsFrom": [
|
||||||
|
"categoryId"
|
||||||
|
],
|
||||||
|
"tableTo": "category",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"hour_dayId_datetime_unique": {
|
||||||
|
"name": "hour_dayId_datetime_unique",
|
||||||
|
"columns": [
|
||||||
|
"dayId",
|
||||||
|
"datetime"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.measurement": {
|
||||||
|
"name": "measurement",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"hourId": {
|
||||||
|
"name": "hourId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"dayId": {
|
||||||
|
"name": "dayId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"metricId": {
|
||||||
|
"name": "metricId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"measurement_hourId_hour_id_fk": {
|
||||||
|
"name": "measurement_hourId_hour_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"columnsFrom": [
|
||||||
|
"hourId"
|
||||||
|
],
|
||||||
|
"tableTo": "hour",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "no action"
|
||||||
|
},
|
||||||
|
"measurement_dayId_day_id_fk": {
|
||||||
|
"name": "measurement_dayId_day_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"columnsFrom": [
|
||||||
|
"dayId"
|
||||||
|
],
|
||||||
|
"tableTo": "day",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
},
|
||||||
|
"measurement_metricId_metric_id_fk": {
|
||||||
|
"name": "measurement_metricId_metric_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"columnsFrom": [
|
||||||
|
"metricId"
|
||||||
|
],
|
||||||
|
"tableTo": "metric",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
},
|
||||||
|
"measurement_userId_user_id_fk": {
|
||||||
|
"name": "measurement_userId_user_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.metric": {
|
||||||
|
"name": "metric",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"unit": {
|
||||||
|
"name": "unit",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"goal": {
|
||||||
|
"name": "goal",
|
||||||
|
"type": "real",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"name": "icon",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"metric_userId_user_id_fk": {
|
||||||
|
"name": "metric_userId_user_id_fk",
|
||||||
|
"tableFrom": "metric",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"metric_userId_name_unique": {
|
||||||
|
"name": "metric_userId_name_unique",
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.session": {
|
||||||
|
"name": "session",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"sessionToken": {
|
||||||
|
"name": "sessionToken",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expires": {
|
||||||
|
"name": "expires",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"session_userId_user_id_fk": {
|
||||||
|
"name": "session_userId_user_id_fk",
|
||||||
|
"tableFrom": "session",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onUpdate": "no action",
|
||||||
|
"onDelete": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.user": {
|
||||||
|
"name": "user",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"emailVerified": {
|
||||||
|
"name": "emailVerified",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"name": "image",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"name": "password",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"name": "role",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "'user'"
|
||||||
|
},
|
||||||
|
"timezone": {
|
||||||
|
"name": "timezone",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'America/Los_Angeles'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"user_email_unique": {
|
||||||
|
"name": "user_email_unique",
|
||||||
|
"columns": [
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"nullsNotDistinct": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.verificationToken": {
|
||||||
|
"name": "verificationToken",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"identifier": {
|
||||||
|
"name": "identifier",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"name": "token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expires": {
|
||||||
|
"name": "expires",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"verificationToken_identifier_token_pk": {
|
||||||
|
"name": "verificationToken_identifier_token_pk",
|
||||||
|
"columns": [
|
||||||
|
"identifier",
|
||||||
|
"token"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
|
"_meta": {
|
||||||
|
"columns": {},
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
901
packages/db/migrations/meta/0003_snapshot.json
Normal file
901
packages/db/migrations/meta/0003_snapshot.json
Normal file
@ -0,0 +1,901 @@
|
|||||||
|
{
|
||||||
|
"id": "2e969918-73b6-4418-bb7b-76acda909a8a",
|
||||||
|
"prevId": "708d11dd-ccaa-48dd-b152-f012b2412704",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"tables": {
|
||||||
|
"public.account": {
|
||||||
|
"name": "account",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"name": "provider",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"providerAccountId": {
|
||||||
|
"name": "providerAccountId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"refresh_token": {
|
||||||
|
"name": "refresh_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"access_token": {
|
||||||
|
"name": "access_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"expires_at": {
|
||||||
|
"name": "expires_at",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"token_type": {
|
||||||
|
"name": "token_type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"name": "scope",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"id_token": {
|
||||||
|
"name": "id_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"session_state": {
|
||||||
|
"name": "session_state",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"account_userId_user_id_fk": {
|
||||||
|
"name": "account_userId_user_id_fk",
|
||||||
|
"tableFrom": "account",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"account_provider_providerAccountId_pk": {
|
||||||
|
"name": "account_provider_providerAccountId_pk",
|
||||||
|
"columns": [
|
||||||
|
"provider",
|
||||||
|
"providerAccountId"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.apiKey": {
|
||||||
|
"name": "apiKey",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"keyId": {
|
||||||
|
"name": "keyId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"keyHash": {
|
||||||
|
"name": "keyHash",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"apiKey_userId_user_id_fk": {
|
||||||
|
"name": "apiKey_userId_user_id_fk",
|
||||||
|
"tableFrom": "apiKey",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"apiKey_keyId_unique": {
|
||||||
|
"name": "apiKey_keyId_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"keyId"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"apiKey_name_userId_unique": {
|
||||||
|
"name": "apiKey_name_userId_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"name",
|
||||||
|
"userId"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.category": {
|
||||||
|
"name": "category",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"name": "code",
|
||||||
|
"type": "real",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"colorId": {
|
||||||
|
"name": "colorId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"parentId": {
|
||||||
|
"name": "parentId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"category_colorId_color_id_fk": {
|
||||||
|
"name": "category_colorId_color_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"tableTo": "color",
|
||||||
|
"columnsFrom": [
|
||||||
|
"colorId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"category_parentId_category_id_fk": {
|
||||||
|
"name": "category_parentId_category_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"tableTo": "category",
|
||||||
|
"columnsFrom": [
|
||||||
|
"parentId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"category_userId_user_id_fk": {
|
||||||
|
"name": "category_userId_user_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"category_userId_code_unique": {
|
||||||
|
"name": "category_userId_code_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.color": {
|
||||||
|
"name": "color",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"hexcode": {
|
||||||
|
"name": "hexcode",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"inverse": {
|
||||||
|
"name": "inverse",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"color_userId_user_id_fk": {
|
||||||
|
"name": "color_userId_user_id_fk",
|
||||||
|
"tableFrom": "color",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"color_userId_name_unique": {
|
||||||
|
"name": "color_userId_name_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.config": {
|
||||||
|
"name": "config",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"key": {
|
||||||
|
"name": "key",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.day": {
|
||||||
|
"name": "day",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"name": "date",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"mood": {
|
||||||
|
"name": "mood",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"name": "comment",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"day_userId_user_id_fk": {
|
||||||
|
"name": "day_userId_user_id_fk",
|
||||||
|
"tableFrom": "day",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"day_date_unique": {
|
||||||
|
"name": "day_date_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"date"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.hour": {
|
||||||
|
"name": "hour",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"name": "comment",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"name": "time",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"datetime": {
|
||||||
|
"name": "datetime",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"dayId": {
|
||||||
|
"name": "dayId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"categoryId": {
|
||||||
|
"name": "categoryId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"hour_userId_user_id_fk": {
|
||||||
|
"name": "hour_userId_user_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"hour_dayId_day_id_fk": {
|
||||||
|
"name": "hour_dayId_day_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"tableTo": "day",
|
||||||
|
"columnsFrom": [
|
||||||
|
"dayId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"hour_categoryId_category_id_fk": {
|
||||||
|
"name": "hour_categoryId_category_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"tableTo": "category",
|
||||||
|
"columnsFrom": [
|
||||||
|
"categoryId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"hour_dayId_datetime_unique": {
|
||||||
|
"name": "hour_dayId_datetime_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"dayId",
|
||||||
|
"datetime"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.measurement": {
|
||||||
|
"name": "measurement",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"hourId": {
|
||||||
|
"name": "hourId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"dayId": {
|
||||||
|
"name": "dayId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"metricId": {
|
||||||
|
"name": "metricId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"measurement_hourId_hour_id_fk": {
|
||||||
|
"name": "measurement_hourId_hour_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"tableTo": "hour",
|
||||||
|
"columnsFrom": [
|
||||||
|
"hourId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"measurement_dayId_day_id_fk": {
|
||||||
|
"name": "measurement_dayId_day_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"tableTo": "day",
|
||||||
|
"columnsFrom": [
|
||||||
|
"dayId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"measurement_metricId_metric_id_fk": {
|
||||||
|
"name": "measurement_metricId_metric_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"tableTo": "metric",
|
||||||
|
"columnsFrom": [
|
||||||
|
"metricId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"measurement_userId_user_id_fk": {
|
||||||
|
"name": "measurement_userId_user_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.metric": {
|
||||||
|
"name": "metric",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"unit": {
|
||||||
|
"name": "unit",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"goal": {
|
||||||
|
"name": "goal",
|
||||||
|
"type": "real",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"name": "icon",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"metric_userId_user_id_fk": {
|
||||||
|
"name": "metric_userId_user_id_fk",
|
||||||
|
"tableFrom": "metric",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"metric_userId_name_unique": {
|
||||||
|
"name": "metric_userId_name_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.session": {
|
||||||
|
"name": "session",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"sessionToken": {
|
||||||
|
"name": "sessionToken",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expires": {
|
||||||
|
"name": "expires",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"session_userId_user_id_fk": {
|
||||||
|
"name": "session_userId_user_id_fk",
|
||||||
|
"tableFrom": "session",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.user": {
|
||||||
|
"name": "user",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"emailVerified": {
|
||||||
|
"name": "emailVerified",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"name": "image",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"name": "password",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"name": "role",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "'user'"
|
||||||
|
},
|
||||||
|
"timezone": {
|
||||||
|
"name": "timezone",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'America/Los_Angeles'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"user_email_unique": {
|
||||||
|
"name": "user_email_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"email"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.verificationToken": {
|
||||||
|
"name": "verificationToken",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"identifier": {
|
||||||
|
"name": "identifier",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"name": "token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expires": {
|
||||||
|
"name": "expires",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"verificationToken_identifier_token_pk": {
|
||||||
|
"name": "verificationToken_identifier_token_pk",
|
||||||
|
"columns": [
|
||||||
|
"identifier",
|
||||||
|
"token"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
|
"_meta": {
|
||||||
|
"columns": {},
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
895
packages/db/migrations/meta/0004_snapshot.json
Normal file
895
packages/db/migrations/meta/0004_snapshot.json
Normal file
@ -0,0 +1,895 @@
|
|||||||
|
{
|
||||||
|
"id": "37a5291a-eed6-4576-a240-2825abdff575",
|
||||||
|
"prevId": "2e969918-73b6-4418-bb7b-76acda909a8a",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"tables": {
|
||||||
|
"public.account": {
|
||||||
|
"name": "account",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"name": "provider",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"providerAccountId": {
|
||||||
|
"name": "providerAccountId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"refresh_token": {
|
||||||
|
"name": "refresh_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"access_token": {
|
||||||
|
"name": "access_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"expires_at": {
|
||||||
|
"name": "expires_at",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"token_type": {
|
||||||
|
"name": "token_type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"name": "scope",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"id_token": {
|
||||||
|
"name": "id_token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"session_state": {
|
||||||
|
"name": "session_state",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"account_userId_user_id_fk": {
|
||||||
|
"name": "account_userId_user_id_fk",
|
||||||
|
"tableFrom": "account",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"account_provider_providerAccountId_pk": {
|
||||||
|
"name": "account_provider_providerAccountId_pk",
|
||||||
|
"columns": [
|
||||||
|
"provider",
|
||||||
|
"providerAccountId"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.apiKey": {
|
||||||
|
"name": "apiKey",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"keyId": {
|
||||||
|
"name": "keyId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"keyHash": {
|
||||||
|
"name": "keyHash",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"apiKey_userId_user_id_fk": {
|
||||||
|
"name": "apiKey_userId_user_id_fk",
|
||||||
|
"tableFrom": "apiKey",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"apiKey_keyId_unique": {
|
||||||
|
"name": "apiKey_keyId_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"keyId"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"apiKey_name_userId_unique": {
|
||||||
|
"name": "apiKey_name_userId_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"name",
|
||||||
|
"userId"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.category": {
|
||||||
|
"name": "category",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"name": "code",
|
||||||
|
"type": "real",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"colorId": {
|
||||||
|
"name": "colorId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"parentId": {
|
||||||
|
"name": "parentId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"category_colorId_color_id_fk": {
|
||||||
|
"name": "category_colorId_color_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"tableTo": "color",
|
||||||
|
"columnsFrom": [
|
||||||
|
"colorId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"category_parentId_category_id_fk": {
|
||||||
|
"name": "category_parentId_category_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"tableTo": "category",
|
||||||
|
"columnsFrom": [
|
||||||
|
"parentId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"category_userId_user_id_fk": {
|
||||||
|
"name": "category_userId_user_id_fk",
|
||||||
|
"tableFrom": "category",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"category_userId_code_unique": {
|
||||||
|
"name": "category_userId_code_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.color": {
|
||||||
|
"name": "color",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"hexcode": {
|
||||||
|
"name": "hexcode",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"inverse": {
|
||||||
|
"name": "inverse",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"color_userId_user_id_fk": {
|
||||||
|
"name": "color_userId_user_id_fk",
|
||||||
|
"tableFrom": "color",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"color_userId_name_unique": {
|
||||||
|
"name": "color_userId_name_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.config": {
|
||||||
|
"name": "config",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"key": {
|
||||||
|
"name": "key",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.day": {
|
||||||
|
"name": "day",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"name": "date",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"mood": {
|
||||||
|
"name": "mood",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"name": "comment",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"day_userId_user_id_fk": {
|
||||||
|
"name": "day_userId_user_id_fk",
|
||||||
|
"tableFrom": "day",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"day_date_unique": {
|
||||||
|
"name": "day_date_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"date"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.hour": {
|
||||||
|
"name": "hour",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"name": "comment",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"datetime": {
|
||||||
|
"name": "datetime",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"dayId": {
|
||||||
|
"name": "dayId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"categoryId": {
|
||||||
|
"name": "categoryId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"hour_userId_user_id_fk": {
|
||||||
|
"name": "hour_userId_user_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"hour_dayId_day_id_fk": {
|
||||||
|
"name": "hour_dayId_day_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"tableTo": "day",
|
||||||
|
"columnsFrom": [
|
||||||
|
"dayId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"hour_categoryId_category_id_fk": {
|
||||||
|
"name": "hour_categoryId_category_id_fk",
|
||||||
|
"tableFrom": "hour",
|
||||||
|
"tableTo": "category",
|
||||||
|
"columnsFrom": [
|
||||||
|
"categoryId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"hour_dayId_datetime_unique": {
|
||||||
|
"name": "hour_dayId_datetime_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"dayId",
|
||||||
|
"datetime"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.measurement": {
|
||||||
|
"name": "measurement",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"hourId": {
|
||||||
|
"name": "hourId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"dayId": {
|
||||||
|
"name": "dayId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"metricId": {
|
||||||
|
"name": "metricId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"measurement_hourId_hour_id_fk": {
|
||||||
|
"name": "measurement_hourId_hour_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"tableTo": "hour",
|
||||||
|
"columnsFrom": [
|
||||||
|
"hourId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"measurement_dayId_day_id_fk": {
|
||||||
|
"name": "measurement_dayId_day_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"tableTo": "day",
|
||||||
|
"columnsFrom": [
|
||||||
|
"dayId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"measurement_metricId_metric_id_fk": {
|
||||||
|
"name": "measurement_metricId_metric_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"tableTo": "metric",
|
||||||
|
"columnsFrom": [
|
||||||
|
"metricId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"measurement_userId_user_id_fk": {
|
||||||
|
"name": "measurement_userId_user_id_fk",
|
||||||
|
"tableFrom": "measurement",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.metric": {
|
||||||
|
"name": "metric",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"unit": {
|
||||||
|
"name": "unit",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"goal": {
|
||||||
|
"name": "goal",
|
||||||
|
"type": "real",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"name": "icon",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "timestamp with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"metric_userId_user_id_fk": {
|
||||||
|
"name": "metric_userId_user_id_fk",
|
||||||
|
"tableFrom": "metric",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"metric_userId_name_unique": {
|
||||||
|
"name": "metric_userId_name_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"userId",
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.session": {
|
||||||
|
"name": "session",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"sessionToken": {
|
||||||
|
"name": "sessionToken",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"name": "userId",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expires": {
|
||||||
|
"name": "expires",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"session_userId_user_id_fk": {
|
||||||
|
"name": "session_userId_user_id_fk",
|
||||||
|
"tableFrom": "session",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"public.user": {
|
||||||
|
"name": "user",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"emailVerified": {
|
||||||
|
"name": "emailVerified",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"name": "image",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"name": "password",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"name": "role",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"default": "'user'"
|
||||||
|
},
|
||||||
|
"timezone": {
|
||||||
|
"name": "timezone",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'America/Los_Angeles'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"user_email_unique": {
|
||||||
|
"name": "user_email_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
|
"columns": [
|
||||||
|
"email"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public.verificationToken": {
|
||||||
|
"name": "verificationToken",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"identifier": {
|
||||||
|
"name": "identifier",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"name": "token",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"expires": {
|
||||||
|
"name": "expires",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"verificationToken_identifier_token_pk": {
|
||||||
|
"name": "verificationToken_identifier_token_pk",
|
||||||
|
"columns": [
|
||||||
|
"identifier",
|
||||||
|
"token"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
|
"_meta": {
|
||||||
|
"columns": {},
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,12 +1,40 @@
|
|||||||
{
|
{
|
||||||
"version": "7",
|
"version": "7",
|
||||||
"dialect": "sqlite",
|
"dialect": "postgresql",
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"version": "6",
|
"version": "7",
|
||||||
"when": 1733614471710,
|
"when": 1738348952600,
|
||||||
"tag": "0000_moaning_thor",
|
"tag": "0000_redundant_glorian",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 1,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1738348955500,
|
||||||
|
"tag": "0001_modify_hour_datetime",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 2,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1738368573808,
|
||||||
|
"tag": "0002_seed_ryan_user",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 3,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1738369747329,
|
||||||
|
"tag": "0003_silky_mongu",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 4,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1738371187519,
|
||||||
|
"tag": "0004_tan_justin_hammer",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -9,24 +9,26 @@
|
|||||||
"generate": "drizzle-kit generate",
|
"generate": "drizzle-kit generate",
|
||||||
"reset": "tsx reset.ts",
|
"reset": "tsx reset.ts",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"migrate": "tsx migrate.ts",
|
"migrate": "drizzle-kit migrate",
|
||||||
"studio": "drizzle-kit studio"
|
"studio": "drizzle-kit studio",
|
||||||
|
"drizzle-kit": "drizzle-kit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@auth/core": "^0.37.3",
|
"@auth/core": "^0.37.3",
|
||||||
"@paralleldrive/cuid2": "^2.2.2",
|
"@paralleldrive/cuid2": "^2.2.2",
|
||||||
"better-sqlite3": "^11.3.0",
|
|
||||||
"dotenv": "^16.4.1",
|
"dotenv": "^16.4.1",
|
||||||
"drizzle-orm": "^0.33.0",
|
"drizzle-orm": "^0.33.0",
|
||||||
"expo-sqlite": "^14.0.6",
|
"pg": "^8.11.3",
|
||||||
"tsx": "^4.7.1"
|
"tsx": "^4.7.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"better-sqlite3": "^11.3.0",
|
||||||
"@lifetracker/eslint-config": "workspace:*",
|
"@lifetracker/eslint-config": "workspace:*",
|
||||||
"@lifetracker/typescript-config": "workspace:*",
|
"@lifetracker/typescript-config": "workspace:*",
|
||||||
"@tsconfig/node21": "^21.0.1",
|
"@tsconfig/node21": "^21.0.1",
|
||||||
"@types/better-sqlite3": "^7.6.9",
|
"@types/pg": "^8.11.0",
|
||||||
"drizzle-kit": "^0.24.2",
|
"drizzle-kit": "^0.24.2",
|
||||||
|
"pg-dump-restore": "^1.0.12",
|
||||||
"sqlite3": "^5.1.7"
|
"sqlite3": "^5.1.7"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
|
|||||||
@ -1,23 +1,19 @@
|
|||||||
import type { AdapterAccount } from "@auth/core/adapters";
|
import type { AdapterAccount } from "@auth/core/adapters";
|
||||||
import { createId } from "@paralleldrive/cuid2";
|
import { createId } from "@paralleldrive/cuid2";
|
||||||
import { relations, SQL, sql } from "drizzle-orm";
|
import { relations, SQL, sql } from "drizzle-orm";
|
||||||
import { date } from "drizzle-orm/mysql-core";
|
import { time, timestamp } from "drizzle-orm/pg-core";
|
||||||
import {
|
import {
|
||||||
AnySQLiteColumn,
|
pgTable,
|
||||||
index,
|
|
||||||
integer,
|
integer,
|
||||||
real,
|
real,
|
||||||
primaryKey,
|
primaryKey,
|
||||||
sqliteTable,
|
|
||||||
text,
|
text,
|
||||||
unique,
|
unique,
|
||||||
|
|
||||||
} from "drizzle-orm/sqlite-core";
|
} from "drizzle-orm/pg-core";
|
||||||
|
|
||||||
function createdAtField() {
|
function createdAtField() {
|
||||||
return integer("createdAt", { mode: "timestamp" })
|
return timestamp("createdAt", { withTimezone: true }).notNull().defaultNow();
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => new Date());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calcInverseColor(hexcode: string): string {
|
export function calcInverseColor(hexcode: string): string {
|
||||||
@ -35,12 +31,12 @@ export function calcInverseColor(hexcode: string): string {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const config = sqliteTable("config", {
|
export const config = pgTable("config", {
|
||||||
key: text("key").notNull().primaryKey(),
|
key: text("key").notNull().primaryKey(),
|
||||||
value: text("value").notNull(),
|
value: text("value").notNull(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const apiKeys = sqliteTable(
|
export const apiKeys = pgTable(
|
||||||
"apiKey",
|
"apiKey",
|
||||||
{
|
{
|
||||||
id: text("id")
|
id: text("id")
|
||||||
@ -61,21 +57,21 @@ export const apiKeys = sqliteTable(
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
export const users = sqliteTable("user", {
|
export const users = pgTable("user", {
|
||||||
id: text("id")
|
id: text("id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.primaryKey()
|
.primaryKey()
|
||||||
.$defaultFn(() => createId()),
|
.$defaultFn(() => createId()),
|
||||||
name: text("name").notNull(),
|
name: text("name").notNull(),
|
||||||
email: text("email").notNull().unique(),
|
email: text("email").notNull().unique(),
|
||||||
emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
|
emailVerified: integer("emailVerified"),
|
||||||
image: text("image"),
|
image: text("image"),
|
||||||
password: text("password"),
|
password: text("password"),
|
||||||
role: text("role", { enum: ["admin", "user"] }).default("user"),
|
role: text("role", { enum: ["admin", "user"] }).default("user"),
|
||||||
timezone: text("timezone").notNull().default("America/Los_Angeles"),
|
timezone: text("timezone").notNull().default("America/Los_Angeles"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const accounts = sqliteTable(
|
export const accounts = pgTable(
|
||||||
"account",
|
"account",
|
||||||
{
|
{
|
||||||
userId: text("userId")
|
userId: text("userId")
|
||||||
@ -99,7 +95,7 @@ export const accounts = sqliteTable(
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const sessions = sqliteTable("session", {
|
export const sessions = pgTable("session", {
|
||||||
sessionToken: text("sessionToken")
|
sessionToken: text("sessionToken")
|
||||||
.notNull()
|
.notNull()
|
||||||
.primaryKey()
|
.primaryKey()
|
||||||
@ -107,22 +103,22 @@ export const sessions = sqliteTable("session", {
|
|||||||
userId: text("userId")
|
userId: text("userId")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => users.id, { onDelete: "cascade" }),
|
.references(() => users.id, { onDelete: "cascade" }),
|
||||||
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
|
expires: timestamp("expires").notNull(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const verificationTokens = sqliteTable(
|
export const verificationTokens = pgTable(
|
||||||
"verificationToken",
|
"verificationToken",
|
||||||
{
|
{
|
||||||
identifier: text("identifier").notNull(),
|
identifier: text("identifier").notNull(),
|
||||||
token: text("token").notNull(),
|
token: text("token").notNull(),
|
||||||
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
|
expires: timestamp("expires").notNull(),
|
||||||
},
|
},
|
||||||
(vt) => ({
|
(vt) => ({
|
||||||
compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
|
compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const metrics = sqliteTable("metric", {
|
export const metrics = pgTable("metric", {
|
||||||
id: text("id")
|
id: text("id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.primaryKey()
|
.primaryKey()
|
||||||
@ -143,7 +139,7 @@ export const metrics = sqliteTable("metric", {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const measurements = sqliteTable("measurement", {
|
export const measurements = pgTable("measurement", {
|
||||||
id: text("id")
|
id: text("id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.primaryKey()
|
.primaryKey()
|
||||||
@ -162,7 +158,7 @@ export const measurements = sqliteTable("measurement", {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const days = sqliteTable("day", {
|
export const days = pgTable("day", {
|
||||||
id: text("id")
|
id: text("id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.primaryKey()
|
.primaryKey()
|
||||||
@ -175,7 +171,7 @@ export const days = sqliteTable("day", {
|
|||||||
.references(() => users.id, { onDelete: "cascade" }),
|
.references(() => users.id, { onDelete: "cascade" }),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const hours = sqliteTable(
|
export const hours = pgTable(
|
||||||
"hour",
|
"hour",
|
||||||
{
|
{
|
||||||
id: text("id")
|
id: text("id")
|
||||||
@ -187,17 +183,17 @@ export const hours = sqliteTable(
|
|||||||
.notNull()
|
.notNull()
|
||||||
.references(() => users.id, { onDelete: "cascade" }),
|
.references(() => users.id, { onDelete: "cascade" }),
|
||||||
comment: text("comment"),
|
comment: text("comment"),
|
||||||
time: integer("time").notNull(),
|
datetime: timestamp("datetime").notNull(),
|
||||||
dayId: text("dayId").notNull().references(() => days.id, { onDelete: "cascade" }),
|
dayId: text("dayId").notNull().references(() => days.id, { onDelete: "cascade" }),
|
||||||
categoryId: text("categoryId").references(() => categories.id),
|
categoryId: text("categoryId").references(() => categories.id),
|
||||||
},
|
},
|
||||||
(e) => ({
|
(e) => ({
|
||||||
uniq: unique().on(e.dayId, e.time)
|
uniq: unique().on(e.dayId, e.datetime)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
export const colors = sqliteTable(
|
export const colors = pgTable(
|
||||||
"color",
|
"color",
|
||||||
{
|
{
|
||||||
id: text("id")
|
id: text("id")
|
||||||
@ -220,7 +216,7 @@ export const colors = sqliteTable(
|
|||||||
// and fuck if the in built documentation makes any sense
|
// and fuck if the in built documentation makes any sense
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
export const categories = sqliteTable(
|
export const categories = pgTable(
|
||||||
"category",
|
"category",
|
||||||
{
|
{
|
||||||
id: text("id")
|
id: text("id")
|
||||||
@ -254,7 +250,11 @@ export const apiKeyRelations = relations(apiKeys, ({ one }) => ({
|
|||||||
references: [users.id],
|
references: [users.id],
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
export const userRelations = relations(users, ({ many }) => ({
|
export const userRelations = relations(users, ({ many, one }) => ({
|
||||||
|
apiKeys: one(apiKeys, {
|
||||||
|
fields: [users.id],
|
||||||
|
references: [apiKeys.userId],
|
||||||
|
}),
|
||||||
categories: many(categories),
|
categories: many(categories),
|
||||||
colors: many(colors),
|
colors: many(colors),
|
||||||
days: many(days),
|
days: many(days),
|
||||||
@ -348,9 +348,9 @@ export const measurementsRelations = relations(
|
|||||||
fields: [measurements.dayId],
|
fields: [measurements.dayId],
|
||||||
references: [days.id],
|
references: [days.id],
|
||||||
}),
|
}),
|
||||||
hour: measurements.hourId ? one(hours, {
|
hour: one(hours, {
|
||||||
fields: [measurements.hourId],
|
fields: [measurements.hourId],
|
||||||
references: [hours.id],
|
references: [hours.id],
|
||||||
}) : undefined,
|
}),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
dotenv.config({
|
dotenv.config({
|
||||||
path: ".env.local",
|
path: "../../.env.local",
|
||||||
});
|
});
|
||||||
const stringBool = (defaultValue: string) =>
|
const stringBool = (defaultValue: string) =>
|
||||||
z
|
z
|
||||||
@ -55,6 +55,8 @@ const allEnv = z.object({
|
|||||||
DEMO_MODE_EMAIL: z.string().optional(),
|
DEMO_MODE_EMAIL: z.string().optional(),
|
||||||
DEMO_MODE_PASSWORD: z.string().optional(),
|
DEMO_MODE_PASSWORD: z.string().optional(),
|
||||||
DATA_DIR: z.string().default(""),
|
DATA_DIR: z.string().default(""),
|
||||||
|
DATABASE_URL: z.string().default("postgres://lifetracker:pleasework@postgresql.home:5432/lifetracker"),
|
||||||
|
TEST_DATABASE_URL: z.string().default("postgres://lifetracker:pleasework@postgresql.home:5432/lifetracker_test"),
|
||||||
MAX_ASSET_SIZE_MB: z.coerce.number().default(4),
|
MAX_ASSET_SIZE_MB: z.coerce.number().default(4),
|
||||||
INFERENCE_LANG: z.string().default("english"),
|
INFERENCE_LANG: z.string().default("english"),
|
||||||
// Build only flag
|
// Build only flag
|
||||||
@ -127,6 +129,8 @@ const serverConfigSchema = allEnv.transform((val) => {
|
|||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
dataDir: val.DATA_DIR,
|
dataDir: val.DATA_DIR,
|
||||||
|
databaseUrl: val.DATABASE_URL,
|
||||||
|
testDatabaseUrl: val.TEST_DATABASE_URL,
|
||||||
maxAssetSizeMb: val.MAX_ASSET_SIZE_MB,
|
maxAssetSizeMb: val.MAX_ASSET_SIZE_MB,
|
||||||
serverVersion: val.SERVER_VERSION,
|
serverVersion: val.SERVER_VERSION,
|
||||||
disableNewReleaseCheck: val.DISABLE_NEW_RELEASE_CHECK,
|
disableNewReleaseCheck: val.DISABLE_NEW_RELEASE_CHECK,
|
||||||
|
|||||||
@ -6,8 +6,7 @@ export const zHourSchema = z.object({
|
|||||||
id: z.string().optional(),
|
id: z.string().optional(),
|
||||||
dayId: z.string(),
|
dayId: z.string(),
|
||||||
date: z.string().optional(),
|
date: z.string().optional(),
|
||||||
time: z.number(),
|
datetime: z.date(),
|
||||||
datetime: z.string().optional(),
|
|
||||||
categoryCode: z.coerce.number().nullish(),
|
categoryCode: z.coerce.number().nullish(),
|
||||||
categoryId: z.string().nullish(),
|
categoryId: z.string().nullish(),
|
||||||
categoryName: z.string().nullish(),
|
categoryName: z.string().nullish(),
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { apiKeys } from "@lifetracker/db/schema";
|
|
||||||
import { router } from "../index";
|
import { router } from "../index";
|
||||||
import { usersAppRouter } from "./users";
|
import { usersAppRouter } from "./users";
|
||||||
import { apiKeysAppRouter } from "./apiKeys";
|
import { apiKeysAppRouter } from "./apiKeys";
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { experimental_trpcMiddleware, TRPCError } from "@trpc/server";
|
|||||||
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SqliteError } from "@lifetracker/db";
|
import { DatabaseError } from "@lifetracker/db";
|
||||||
import { categories, colors } from "@lifetracker/db/schema";
|
import { categories, colors } from "@lifetracker/db/schema";
|
||||||
import {
|
import {
|
||||||
ZCategories,
|
ZCategories,
|
||||||
@ -54,8 +54,8 @@ async function createCategory(
|
|||||||
};
|
};
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof SqliteError) {
|
if (e instanceof DatabaseError) {
|
||||||
if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
|
if (e.code == "23505") {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "There's already a category with this code",
|
message: "There's already a category with this code",
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { experimental_trpcMiddleware, TRPCError } from "@trpc/server";
|
|||||||
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SqliteError } from "@lifetracker/db";
|
import { DatabaseError, ErrorCodes } from "@lifetracker/db";
|
||||||
import { colors, calcInverseColor } from "@lifetracker/db/schema";
|
import { colors, calcInverseColor } from "@lifetracker/db/schema";
|
||||||
import {
|
import {
|
||||||
zColorSchema, ZColor
|
zColorSchema, ZColor
|
||||||
@ -37,8 +37,8 @@ async function createColor(
|
|||||||
});
|
});
|
||||||
return result[0];
|
return result[0];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof SqliteError) {
|
if (e instanceof DatabaseError) {
|
||||||
if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
|
if (e.code == ErrorCodes.UNIQUE_VIOLATION) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "This color already exists",
|
message: "This color already exists",
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { experimental_trpcMiddleware, TRPCError } from "@trpc/server";
|
|||||||
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { db, SqliteError } from "@lifetracker/db";
|
import { db, DatabaseError, ErrorCodes } from "@lifetracker/db";
|
||||||
import { categories, days, hours, users } from "@lifetracker/db/schema";
|
import { categories, days, hours, users } from "@lifetracker/db/schema";
|
||||||
import {
|
import {
|
||||||
zDaySchema, ZDay,
|
zDaySchema, ZDay,
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
import type { Context } from "../index";
|
import type { Context } from "../index";
|
||||||
import { authedProcedure, router } from "../index";
|
import { authedProcedure, router } from "../index";
|
||||||
import { dateFromInput, hoursListInUTC } from "@lifetracker/shared/utils/days";
|
import { dateFromInput, hoursListInUTC } from "@lifetracker/shared/utils/days";
|
||||||
import { closestIndexTo, format } from "date-fns";
|
import { addDays, closestIndexTo, format, parseISO } from "date-fns";
|
||||||
import { TZDate } from "@date-fns/tz";
|
import { TZDate } from "@date-fns/tz";
|
||||||
import { hoursAppRouter, hourColors, hourJoinsQuery, getHours, createHour } from "./hours";
|
import { hoursAppRouter, hourColors, hourJoinsQuery, getHours, createHour } from "./hours";
|
||||||
import spacetime from "spacetime";
|
import spacetime from "spacetime";
|
||||||
@ -36,8 +36,8 @@ export async function createDay(date: string, ctx: Context) {
|
|||||||
|
|
||||||
return dayRes[0];
|
return dayRes[0];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof SqliteError) {
|
if (e instanceof DatabaseError) {
|
||||||
if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
|
if (e.code == ErrorCodes.UNIQUE_VIOLATION) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "This day already exists",
|
message: "This day already exists",
|
||||||
@ -75,6 +75,27 @@ export async function getDay(ctx: Context, input: { dateQuery: string, timezone:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function listOfDates(dateRange: [Date, Date]) {
|
||||||
|
const [start, end] = dateRange.map((date) => dateFromInput({
|
||||||
|
dateQuery: spacetime(date, "UTC").goto("UTC").format("iso-short"),
|
||||||
|
timezone: "Etc/UTC"
|
||||||
|
}));
|
||||||
|
const dates = [];
|
||||||
|
let currentDate = parseISO(start);
|
||||||
|
while (currentDate <= parseISO(end)) {
|
||||||
|
dates.push(format(currentDate, "yyyy-MM-dd"));
|
||||||
|
currentDate = addDays(currentDate, 1);
|
||||||
|
}
|
||||||
|
return dates.length === 0 ? [format(parseISO(start), "yyyy-MM-dd")] : dates;
|
||||||
|
}
|
||||||
|
export function listOfDayIds(dateRange: [Date, Date]) {
|
||||||
|
return listOfDates(dateRange).map((date) =>
|
||||||
|
db.select({ id: days.id })
|
||||||
|
.from(days)
|
||||||
|
.where(eq(days.date, date))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export const daysAppRouter = router({
|
export const daysAppRouter = router({
|
||||||
get: authedProcedure
|
get: authedProcedure
|
||||||
.input(z.object({
|
.input(z.object({
|
||||||
|
|||||||
@ -1,27 +1,23 @@
|
|||||||
import { experimental_trpcMiddleware, TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
||||||
import { date, z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SqliteError } from "@lifetracker/db";
|
import { DatabaseError } from "@lifetracker/db";
|
||||||
import { categories, days, hours, colors, measurements, metrics } from "@lifetracker/db/schema";
|
import { categories, days, hours, colors, measurements, metrics } from "@lifetracker/db/schema";
|
||||||
import {
|
import {
|
||||||
zDaySchema, ZDay, ZHour, zHourSchema
|
ZDay, ZHour, zHourSchema
|
||||||
} from "@lifetracker/shared/types/days";
|
} from "@lifetracker/shared/types/days";
|
||||||
import type { Context } from "../index";
|
import type { Context } from "../index";
|
||||||
import { authedProcedure, router } from "../index";
|
import { authedProcedure, router } from "../index";
|
||||||
import { addDays, format, parseISO } from "date-fns";
|
|
||||||
import { TZDate } from "@date-fns/tz";
|
|
||||||
import { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
|
|
||||||
import { zCategorySchema } from "@lifetracker/shared/types/categories";
|
|
||||||
import spacetime from "spacetime";
|
import spacetime from "spacetime";
|
||||||
import { dateFromInput, hoursListInUTC } from "@lifetracker/shared/utils/days";
|
import { hoursListInUTC } from "@lifetracker/shared/utils/days";
|
||||||
import { createDay, getDay } from "./days";
|
import { createDay, listOfDates } from "./days";
|
||||||
|
|
||||||
|
|
||||||
export async function createHour(day: ZDay | { id: string }, time: number, ctx: Context,) {
|
export async function createHour(day: { id: string }, datetime: Date, ctx: Context,) {
|
||||||
const newHour = (await ctx.db.insert(hours).values({
|
const newHour = (await ctx.db.insert(hours).values({
|
||||||
dayId: day.id!,
|
dayId: day.id,
|
||||||
time: time,
|
datetime: datetime,
|
||||||
userId: ctx.user!.id,
|
userId: ctx.user!.id,
|
||||||
}).returning());
|
}).returning());
|
||||||
return newHour[0];
|
return newHour[0];
|
||||||
@ -52,7 +48,7 @@ export async function hourColors(hour: ZHour, ctx: Context) {
|
|||||||
|
|
||||||
export async function hourJoinsQuery(
|
export async function hourJoinsQuery(
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
time: number,
|
datetime: Date,
|
||||||
dayId?: string,
|
dayId?: string,
|
||||||
day?: ZDay,
|
day?: ZDay,
|
||||||
) {
|
) {
|
||||||
@ -67,7 +63,7 @@ export async function hourJoinsQuery(
|
|||||||
const res = await ctx.db.select({
|
const res = await ctx.db.select({
|
||||||
id: hours.id,
|
id: hours.id,
|
||||||
dayId: hours.dayId,
|
dayId: hours.dayId,
|
||||||
time: hours.time,
|
datetime: hours.datetime,
|
||||||
categoryId: hours.categoryId,
|
categoryId: hours.categoryId,
|
||||||
categoryCode: categories.code,
|
categoryCode: categories.code,
|
||||||
categoryName: categories.name,
|
categoryName: categories.name,
|
||||||
@ -78,11 +74,11 @@ export async function hourJoinsQuery(
|
|||||||
.leftJoin(categories, eq(categories.id, hours.categoryId))
|
.leftJoin(categories, eq(categories.id, hours.categoryId))
|
||||||
.leftJoin(days, eq(days.id, hours.dayId))
|
.leftJoin(days, eq(days.id, hours.dayId))
|
||||||
.where(and(
|
.where(and(
|
||||||
eq(hours.time, time),
|
eq(hours.datetime, datetime),
|
||||||
eq(hours.dayId, id)
|
eq(hours.dayId, id)
|
||||||
));
|
));
|
||||||
|
|
||||||
const hourMatch = res[0] ?? createHour({ id: id }, time, ctx);
|
const hourMatch = res[0] ?? createHour({ id }, datetime, ctx);
|
||||||
|
|
||||||
|
|
||||||
const hourMeasurements = await ctx.db.select({
|
const hourMeasurements = await ctx.db.select({
|
||||||
@ -131,33 +127,16 @@ export async function getHours(ctx: Context, input: { dateQuery: string | [Date,
|
|||||||
// Finally, use the two unique day IDs and the 24 hours to get the actual Hour objects for each day
|
// Finally, use the two unique day IDs and the 24 hours to get the actual Hour objects for each day
|
||||||
const dayHours = await Promise.all(uniqueHours.map(async function (map: { date: string, time: number }, i) {
|
const dayHours = await Promise.all(uniqueHours.map(async function (map: { date: string, time: number }, i) {
|
||||||
const dayId = uniqueDayIds.find((dayIds: { id: string, date: string }) => map.date == dayIds.date)!.id;
|
const dayId = uniqueDayIds.find((dayIds: { id: string, date: string }) => map.date == dayIds.date)!.id;
|
||||||
|
const datetime = spacetime(map.date, "Etc/UTC").hour(map.time).toNativeDate();
|
||||||
return hourJoinsQuery(ctx, map.time, dayId);
|
return hourJoinsQuery(ctx, datetime, dayId);
|
||||||
}));
|
}));
|
||||||
return dayHours;
|
return dayHours;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function listOfDates(dateRange: [Date, Date]) {
|
|
||||||
const [start, end] = dateRange.map((date) => dateFromInput({
|
|
||||||
dateQuery: spacetime(date, "UTC").goto("UTC").format("iso-short"),
|
|
||||||
timezone: "Etc/UTC"
|
|
||||||
}));
|
|
||||||
const dates = [];
|
|
||||||
let currentDate = parseISO(start);
|
|
||||||
while (currentDate <= parseISO(end)) {
|
|
||||||
dates.push(format(currentDate, "yyyy-MM-dd"));
|
|
||||||
currentDate = addDays(currentDate, 1);
|
|
||||||
}
|
|
||||||
return dates.length === 0 ? [format(parseISO(start), "yyyy-MM-dd")] : dates;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export const hoursAppRouter = router({
|
export const hoursAppRouter = router({
|
||||||
get: authedProcedure
|
get: authedProcedure
|
||||||
.input(z.object({
|
.input(z.object({
|
||||||
dateQuery: z.string(),
|
dateQuery: z.string(),
|
||||||
time: z.number()
|
|
||||||
}))
|
}))
|
||||||
.output(zHourSchema)
|
.output(zHourSchema)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
@ -165,8 +144,7 @@ export const hoursAppRouter = router({
|
|||||||
.leftJoin(days, eq(days.id, hours.dayId))
|
.leftJoin(days, eq(days.id, hours.dayId))
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
eq(hours.time, input.time),
|
eq(hours.datetime, spacetime(input.dateQuery, "Etc/UTC").toNativeDate()),
|
||||||
eq(days.date, input.dateQuery),
|
|
||||||
eq(hours.userId, ctx.user!.id)
|
eq(hours.userId, ctx.user!.id)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -255,10 +233,20 @@ export const hoursAppRouter = router({
|
|||||||
}
|
}
|
||||||
)))
|
)))
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
|
|
||||||
|
// console.log(input.dateRange, input.timezone);
|
||||||
const hoursList = await getHours(ctx, {
|
const hoursList = await getHours(ctx, {
|
||||||
dateQuery: input.dateRange,
|
dateQuery: input.dateRange,
|
||||||
timezone: input.timezone
|
timezone: input.timezone
|
||||||
});
|
});
|
||||||
|
// console.log(hoursList.map(h => {
|
||||||
|
// return {
|
||||||
|
// datetime: spacetime(h.datetime).goto("America/Los_Angeles").format("{iso-short} {hour-24}:{minute}"),
|
||||||
|
// id: h.id,
|
||||||
|
// date: h.date,
|
||||||
|
// };
|
||||||
|
// }));
|
||||||
|
|
||||||
|
|
||||||
// Count total hours in the filtered range
|
// Count total hours in the filtered range
|
||||||
const totalHours = hoursList.length;
|
const totalHours = hoursList.length;
|
||||||
|
|||||||
@ -1,14 +1,17 @@
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
import { and, desc, eq, inArray, notExists, sql } from "drizzle-orm";
|
||||||
import { z, ZodNull } from "zod";
|
import { z, ZodNull } from "zod";
|
||||||
|
|
||||||
import { SqliteError } from "@lifetracker/db";
|
import { DatabaseError } from "@lifetracker/db";
|
||||||
import { colors, metrics, measurements, hours } from "@lifetracker/db/schema";
|
import { colors, metrics, measurements, hours, days } from "@lifetracker/db/schema";
|
||||||
import { zMetricSchema, zMeasurementSchema } from "@lifetracker/shared/types/metrics";
|
import { zMetricSchema, zMeasurementSchema } from "@lifetracker/shared/types/metrics";
|
||||||
import type { Context } from "../index";
|
import type { Context } from "../index";
|
||||||
import { authedProcedure, router } from "../index";
|
import { authedProcedure, router } from "../index";
|
||||||
import { zColorSchema } from "@lifetracker/shared/types/colors";
|
import { zColorSchema } from "@lifetracker/shared/types/colors";
|
||||||
import { titleCase } from "title-case";
|
import { titleCase } from "title-case";
|
||||||
|
import { listOfDates, listOfDayIds } from "./days";
|
||||||
|
import { getHours } from "./hours";
|
||||||
|
import { datetime } from "drizzle-orm/mysql-core";
|
||||||
|
|
||||||
const getMetricFromInput = async (ctx: Context, input:
|
const getMetricFromInput = async (ctx: Context, input:
|
||||||
{ metricId?: string | null | undefined; metricName?: string | null | undefined; }) => {
|
{ metricId?: string | null | undefined; metricName?: string | null | undefined; }) => {
|
||||||
@ -181,4 +184,44 @@ export const measurementsAppRouter = router({
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
getTimeseries: authedProcedure
|
||||||
|
.input(z.object({
|
||||||
|
dateRange: z.tuple([z.date(), z.date()]),
|
||||||
|
timezone: z.string(),
|
||||||
|
metricName: z.string()
|
||||||
|
}))
|
||||||
|
.output(z.array(z.object({
|
||||||
|
id: z.string(),
|
||||||
|
value: z.string(),
|
||||||
|
unit: z.string(),
|
||||||
|
datetime: z.date(),
|
||||||
|
})
|
||||||
|
))
|
||||||
|
.query(async ({ input, ctx }) => {
|
||||||
|
const hoursList = await getHours(ctx, {
|
||||||
|
dateQuery: input.dateRange,
|
||||||
|
timezone: input.timezone,
|
||||||
|
});
|
||||||
|
const hourIds = hoursList.map((hour) => hour.id);
|
||||||
|
const metric = await ctx.db.select().from(metrics).where(eq(metrics.name, titleCase(input.metricName)));
|
||||||
|
if (!metric[0]) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Metric not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const measurementsList = await ctx.db.select({
|
||||||
|
id: measurements.id,
|
||||||
|
value: measurements.value,
|
||||||
|
unit: metrics.unit,
|
||||||
|
datetime: hours.datetime,
|
||||||
|
}).from(measurements)
|
||||||
|
.leftJoin(metrics, eq(measurements.metricId, metrics.id))
|
||||||
|
.leftJoin(hours, eq(measurements.hourId, hours.id))
|
||||||
|
.where(and(
|
||||||
|
eq(measurements.metricId, metric[0].id),
|
||||||
|
inArray(measurements.hourId, hourIds),
|
||||||
|
));
|
||||||
|
return measurementsList;
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
@ -2,7 +2,7 @@ import { TRPCError } from "@trpc/server";
|
|||||||
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SqliteError } from "@lifetracker/db";
|
import { DatabaseError, ErrorCodes } from "@lifetracker/db";
|
||||||
import { colors, metrics } from "@lifetracker/db/schema";
|
import { colors, metrics } from "@lifetracker/db/schema";
|
||||||
import { zMetricSchema, zMeasurementSchema } from "@lifetracker/shared/types/metrics";
|
import { zMetricSchema, zMeasurementSchema } from "@lifetracker/shared/types/metrics";
|
||||||
import type { Context } from "../index";
|
import type { Context } from "../index";
|
||||||
@ -40,8 +40,8 @@ export const metricsAppRouter = router({
|
|||||||
.returning();
|
.returning();
|
||||||
return result[0];
|
return result[0];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof SqliteError) {
|
if (e instanceof DatabaseError) {
|
||||||
if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
|
if (e.code == ErrorCodes.UNIQUE_VIOLATION) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "This metric already exists",
|
message: "This metric already exists",
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { and, count, eq } from "drizzle-orm";
|
|||||||
import invariant from "tiny-invariant";
|
import invariant from "tiny-invariant";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SqliteError } from "@lifetracker/db";
|
import { DatabaseError, ErrorCodes } from "@lifetracker/db";
|
||||||
import { users } from "@lifetracker/db/schema";
|
import { users } from "@lifetracker/db/schema";
|
||||||
import serverConfig from "@lifetracker/shared/config";
|
import serverConfig from "@lifetracker/shared/config";
|
||||||
import { zSignUpSchema } from "@lifetracker/shared/types/users";
|
import { zSignUpSchema } from "@lifetracker/shared/types/users";
|
||||||
@ -49,8 +49,8 @@ export async function createUser(
|
|||||||
});
|
});
|
||||||
return result[0];
|
return result[0];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof SqliteError) {
|
if (e instanceof DatabaseError) {
|
||||||
if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
|
if (e.code == ErrorCodes.UNIQUE_VIOLATION) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "Email is already taken",
|
message: "Email is already taken",
|
||||||
|
|||||||
742
pnpm-lock.yaml
generated
742
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user