From 14efa47b95ec769658e07fd1b97067356d55d86d Mon Sep 17 00:00:00 2001 From: Shivam Vijaywargi Date: Tue, 31 Dec 2024 18:42:43 +0530 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20add=20update=20settlement=20by=20id?= =?UTF-8?q?=20route=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.ts | 10 ++- src/db/schemas/settlement.model.ts | 5 +- .../settlements/settlements.handler.ts | 48 ++++++++++++ src/modules/settlements/settlements.index.ts | 9 +++ .../settlements/settlements.repository.ts | 30 +++++++ src/modules/settlements/settlements.route.ts | 78 +++++++++++++++++++ 6 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 src/modules/settlements/settlements.handler.ts create mode 100644 src/modules/settlements/settlements.index.ts create mode 100644 src/modules/settlements/settlements.repository.ts create mode 100644 src/modules/settlements/settlements.route.ts diff --git a/src/app.ts b/src/app.ts index 9034d38..aa44d4c 100644 --- a/src/app.ts +++ b/src/app.ts @@ -6,10 +6,18 @@ import { categoryRouter } from "./modules/categories/category.index"; import { expenseRouter } from "./modules/expenses/expense.index"; import { groupRouters } from "./modules/group/group.index"; import { healthCheckRouter } from "./modules/health-check/health-check.index"; +import { settlementsRouter } from "./modules/settlements/settlements.index"; export const app = createApp(); -const routesV1 = [authRouter, categoryRouter, groupRouters, activityRouter, expenseRouter]; +const routesV1 = [ + authRouter, + categoryRouter, + groupRouters, + activityRouter, + expenseRouter, + settlementsRouter, +]; configureOpenAPI(app); diff --git a/src/db/schemas/settlement.model.ts b/src/db/schemas/settlement.model.ts index d4660f7..16de5fb 100644 --- a/src/db/schemas/settlement.model.ts +++ b/src/db/schemas/settlement.model.ts @@ -15,7 +15,10 @@ const settlementModel = pgTable("settlement", { groupId: varchar({ length: 60 }), amount: real().notNull(), createdAt: timestamp().notNull().defaultNow(), - updatedAt: timestamp().notNull().defaultNow(), + updatedAt: timestamp() + .defaultNow() + .$onUpdate(() => new Date()) + .notNull(), }); // Schema for selecting/inserting a settlement diff --git a/src/modules/settlements/settlements.handler.ts b/src/modules/settlements/settlements.handler.ts new file mode 100644 index 0000000..61bb5d4 --- /dev/null +++ b/src/modules/settlements/settlements.handler.ts @@ -0,0 +1,48 @@ +import type { AppRouteHandler } from "@/common/lib/types"; +import { AUTHORIZATION_ERROR_MESSAGE } from "@/common/utils/constants"; +import * as HTTPStatusCodes from "@/common/utils/http-status-codes.util"; + +import { updateSettlementRepository } from "./settlements.repository"; +import type { IUpdateSettlementsRoute } from "./settlements.route"; + +export const updateSettlement: AppRouteHandler< + IUpdateSettlementsRoute +> = async (c) => { + const user = c.get("user"); + const { settlementId } = c.req.valid("param"); + const payload = c.req.valid("json"); + const logger = c.get("logger"); + + if (!user) { + logger.error("User is not logged in"); + return c.json( + { + success: false, + message: AUTHORIZATION_ERROR_MESSAGE, + }, + HTTPStatusCodes.UNAUTHORIZED, + ); + } + + const settlement = await updateSettlementRepository(payload, settlementId); + + if (!settlement) { + logger.error("Settlement not found"); + return c.json( + { + success: false, + message: "Settlement not found", + }, + HTTPStatusCodes.NOT_FOUND, + ); + } + + logger.info(`Settlement with id: ${settlementId} updated successfully`); + return c.json( + { + success: true, + message: "Settlement updated successfully", + }, + HTTPStatusCodes.OK, + ); +}; diff --git a/src/modules/settlements/settlements.index.ts b/src/modules/settlements/settlements.index.ts new file mode 100644 index 0000000..a4a2231 --- /dev/null +++ b/src/modules/settlements/settlements.index.ts @@ -0,0 +1,9 @@ +import { createRouter } from "@/common/lib/create-app.lib"; + +import * as handlers from "./settlements.handler"; +import * as routes from "./settlements.route"; + +export const settlementsRouter = createRouter().openapi( + routes.updateSettlementRoute, + handlers.updateSettlement, +); diff --git a/src/modules/settlements/settlements.repository.ts b/src/modules/settlements/settlements.repository.ts new file mode 100644 index 0000000..21a9683 --- /dev/null +++ b/src/modules/settlements/settlements.repository.ts @@ -0,0 +1,30 @@ +import type { SQL } from "drizzle-orm"; +import { and, eq } from "drizzle-orm"; + +import { db } from "@/db/adapter"; +import type { TInsertSettlementSchema } from "@/db/schemas/settlement.model"; +import settlementModel from "@/db/schemas/settlement.model"; + +export async function updateSettlementRepository( + payload: TInsertSettlementSchema, + settlementId: string, +) { + const whereConditions: SQL[] = [ + eq(settlementModel.id, settlementId), + eq(settlementModel.senderId, payload.senderId), + eq(settlementModel.receiverId, payload.receiverId), + ]; + + if (payload.groupId) { + whereConditions.push(eq(settlementModel.groupId, payload.groupId)); + } + + const [settlement] = await db + .update(settlementModel) + .set({ + amount: payload.amount, + }) + .where(and(...whereConditions)); + + return settlement; +} diff --git a/src/modules/settlements/settlements.route.ts b/src/modules/settlements/settlements.route.ts new file mode 100644 index 0000000..8b23868 --- /dev/null +++ b/src/modules/settlements/settlements.route.ts @@ -0,0 +1,78 @@ +import { createRoute, z } from "@hono/zod-openapi"; + +import jsonContentRequired from "@/common/helpers/json-content-required.helper"; +import { jsonContent } from "@/common/helpers/json-content.helper"; +import { + authMiddleware, + requireAuth, +} from "@/common/middlewares/auth.middleware"; +import { + AUTHORIZATION_ERROR_MESSAGE, + FORBIDDEN_ERROR_MESSAGE, + INTERNAL_SERVER_ERROR_MESSAGE, +} from "@/common/utils/constants"; +import * as HTTPStatusCodes from "@/common/utils/http-status-codes.util"; +import { idSchema } from "@/db/schemas/id.model"; +import { insertSettlementSchema } from "@/db/schemas/settlement.model"; + +const tags = ["Settlements"]; + +export const updateSettlementRoute = createRoute({ + tags, + method: "patch", + path: "/settlements/:settlementId", + summary: "Update settlements by ID", + middleware: [authMiddleware(), requireAuth()] as const, + request: { + params: z.object({ + settlementId: idSchema, + }), + body: jsonContentRequired( + insertSettlementSchema.omit({ + id: true, + createdAt: true, + updatedAt: true, + }), + "Settlement update", + ), + }, + responses: { + [HTTPStatusCodes.OK]: jsonContent( + z.object({ + success: z.boolean().default(true), + message: z.string(), + }), + "Settlement updated successfully", + ), + [HTTPStatusCodes.NOT_FOUND]: jsonContent( + z.object({ + success: z.boolean().default(false), + message: z.string(), + }), + "Settlement with id does not exist", + ), + [HTTPStatusCodes.UNAUTHORIZED]: jsonContent( + z.object({ + success: z.boolean().default(false), + message: z.string(), + }), + AUTHORIZATION_ERROR_MESSAGE, + ), + [HTTPStatusCodes.FORBIDDEN]: jsonContent( + z.object({ + success: z.boolean().default(false), + message: z.string(), + }), + FORBIDDEN_ERROR_MESSAGE, + ), + [HTTPStatusCodes.INTERNAL_SERVER_ERROR]: jsonContent( + z.object({ + success: z.boolean().default(false), + message: z.string(), + }), + INTERNAL_SERVER_ERROR_MESSAGE, + ), + }, +}); + +export type IUpdateSettlementsRoute = typeof updateSettlementRoute; From a24145f1392760136e498b9c04e2b09ee00b8f5b Mon Sep 17 00:00:00 2001 From: Shivam Vijaywargi Date: Tue, 11 Feb 2025 21:09:40 +0530 Subject: [PATCH 2/4] =?UTF-8?q?test(settlements):=20add=20test=20case=20fo?= =?UTF-8?q?r=20update=20settlements=20endpoint=F0=9F=A7=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/settlements/settlements.test.ts | 92 +++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/modules/settlements/settlements.test.ts diff --git a/src/modules/settlements/settlements.test.ts b/src/modules/settlements/settlements.test.ts new file mode 100644 index 0000000..47146c4 --- /dev/null +++ b/src/modules/settlements/settlements.test.ts @@ -0,0 +1,92 @@ +import { beforeAll, describe, expect, it } from "bun:test"; +import { testClient } from "hono/testing"; + +import { AuthRoles } from "@/common/enums"; +import { createApp } from "@/common/lib/create-app.lib"; +import { AUTHORIZATION_ERROR_MESSAGE } from "@/common/utils/constants"; +import { createTestUser } from "@/common/utils/test.util"; +import env from "@/env"; + +import { settlementsRouter } from "./settlements.index"; + +if (env.NODE_ENV !== "test") { + throw new Error("NODE_ENV must be 'test'"); +} + +const settlementsClient = testClient(createApp().route("/", settlementsRouter)); + +describe("settlements", () => { + let userSessionToken = ""; + let adminSessionToken = ""; + const settlementId = ""; + + beforeAll(async () => { + const testUser = await createTestUser({ + email: "settlements@sample.com", + password: "12345678", + role: AuthRoles.USER, + fullName: "Test User", + }); + + userSessionToken = testUser.session; + + const adminUser = await createTestUser({ + email: "settlementsAdmin@sample.com", + password: "12345678", + role: AuthRoles.ADMIN, + fullName: "Test Admin", + }); + + adminSessionToken = adminUser.session; + }); + + describe("PATCH /settlements/:settlementId", () => { + it("should return 404 when settlement with given id not found", async () => { + const response = await settlementsClient.settlements[ + ":settlementId" + ].$patch({ + param: { + settlementId, + }, + json: { + amount: 100, + receiverId: "123", + senderId: "456", + }, + }); + + expect(response.status).toBe(404); + + if (response.status === 404) { + const json = await response.json(); + + expect(json.success).toBe(false); + expect(json.message).toBe("Settlement not found"); + } + }); + + it("should return 401 when user is not logged in", async () => { + const response = await settlementsClient.settlements[ + ":settlementId" + ].$patch({ + param: { + settlementId, + }, + json: { + amount: 100, + receiverId: "123", + senderId: "456", + }, + }); + + expect(response.status).toBe(401); + + if (response.status === 401) { + const json = await response.json(); + + expect(json.success).toBe(false); + expect(json.message).toBe(AUTHORIZATION_ERROR_MESSAGE); + } + }); + }); +}); From 13f84722282da3b701b4bb59378eb7b402b36b45 Mon Sep 17 00:00:00 2001 From: Shivam Vijaywargi Date: Tue, 11 Feb 2025 21:25:38 +0530 Subject: [PATCH 3/4] =?UTF-8?q?test(settlement):=20fix=20failing=20test=20?= =?UTF-8?q?cases=F0=9F=A7=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/settlements/settlements.test.ts | 49 +++++++++++++-------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/modules/settlements/settlements.test.ts b/src/modules/settlements/settlements.test.ts index 47146c4..7906919 100644 --- a/src/modules/settlements/settlements.test.ts +++ b/src/modules/settlements/settlements.test.ts @@ -17,8 +17,8 @@ const settlementsClient = testClient(createApp().route("/", settlementsRouter)); describe("settlements", () => { let userSessionToken = ""; - let adminSessionToken = ""; - const settlementId = ""; + // let adminSessionToken = ""; + const settlementId = "non-existent-id-thirty-two-character"; beforeAll(async () => { const testUser = await createTestUser({ @@ -30,30 +30,39 @@ describe("settlements", () => { userSessionToken = testUser.session; - const adminUser = await createTestUser({ - email: "settlementsAdmin@sample.com", - password: "12345678", - role: AuthRoles.ADMIN, - fullName: "Test Admin", - }); + // const adminUser = await createTestUser({ + // email: "settlementsAdmin@sample.com", + // password: "12345678", + // role: AuthRoles.ADMIN, + // fullName: "Test Admin", + // }); - adminSessionToken = adminUser.session; + // adminSessionToken = adminUser.session; }); describe("PATCH /settlements/:settlementId", () => { it("should return 404 when settlement with given id not found", async () => { const response = await settlementsClient.settlements[ ":settlementId" - ].$patch({ - param: { - settlementId, + ].$patch( + { + param: { + settlementId, + }, + json: { + amount: 100, + receiverId: + "123456789123456789123456789123456789123456789123456789123121", + senderId: + "123456789123456789123456789123456789123456789123456789123122", + }, }, - json: { - amount: 100, - receiverId: "123", - senderId: "456", + { + headers: { + session: userSessionToken, + }, }, - }); + ); expect(response.status).toBe(404); @@ -74,8 +83,10 @@ describe("settlements", () => { }, json: { amount: 100, - receiverId: "123", - senderId: "456", + receiverId: + "123456789123456789123456789123456789123456789123456789123121", + senderId: + "123456789123456789123456789123456789123456789123456789123122", }, }); From 0d395934ca533f7085d9237a546b0fafc2d757b5 Mon Sep 17 00:00:00 2001 From: Shivam Vijaywargi Date: Thu, 13 Feb 2025 22:23:43 +0530 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20update=20settlement=20logic,=20combi?= =?UTF-8?q?ne=20migrations=20into=20one,=20sender,=20receiver=20validation?= =?UTF-8?q?=F0=9F=90=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/migrations/0000_glorious_thing.sql | 127 +++ src/db/migrations/0000_natural_mephisto.sql | 176 ---- src/db/migrations/0001_parallel_red_hulk.sql | 7 - src/db/migrations/0002_safe_cobalt_man.sql | 11 - .../migrations/0003_bored_captain_stacy.sql | 1 - src/db/migrations/meta/0000_snapshot.json | 91 +- src/db/migrations/meta/0001_snapshot.json | 848 ----------------- src/db/migrations/meta/0002_snapshot.json | 898 ------------------ src/db/migrations/meta/0003_snapshot.json | 898 ------------------ src/db/migrations/meta/_journal.json | 25 +- src/db/schemas/settlement.model.ts | 12 +- .../settlements/settlements.repository.ts | 55 +- 12 files changed, 259 insertions(+), 2890 deletions(-) create mode 100644 src/db/migrations/0000_glorious_thing.sql delete mode 100644 src/db/migrations/0000_natural_mephisto.sql delete mode 100644 src/db/migrations/0001_parallel_red_hulk.sql delete mode 100644 src/db/migrations/0002_safe_cobalt_man.sql delete mode 100644 src/db/migrations/0003_bored_captain_stacy.sql delete mode 100644 src/db/migrations/meta/0001_snapshot.json delete mode 100644 src/db/migrations/meta/0002_snapshot.json delete mode 100644 src/db/migrations/meta/0003_snapshot.json diff --git a/src/db/migrations/0000_glorious_thing.sql b/src/db/migrations/0000_glorious_thing.sql new file mode 100644 index 0000000..38b4d27 --- /dev/null +++ b/src/db/migrations/0000_glorious_thing.sql @@ -0,0 +1,127 @@ +CREATE TYPE "public"."activityType" AS ENUM('category_created', 'category_updated', 'category_deleted', 'group_created', 'group_deleted', 'group_updated', 'group_member_added', 'group_member_removed', 'expense_added', 'expense_updated', 'expense_deleted');--> statement-breakpoint +CREATE TYPE "public"."splitType" AS ENUM('even', 'uneven', 'proportional');--> statement-breakpoint +CREATE TYPE "public"."status" AS ENUM('settled', 'unsettled');--> statement-breakpoint +CREATE TYPE "public"."role" AS ENUM('user', 'admin');--> statement-breakpoint +CREATE TABLE "account" ( + "id" varchar(60) PRIMARY KEY NOT NULL, + "provider_id" varchar(255) NOT NULL, + "provider_account_id" varchar(255) NOT NULL, + "user_id" varchar(60) NOT NULL, + "access_token" varchar(255), + "refresh_token" varchar(255), + "id_token" varchar(255), + "expires_at" timestamp, + "password" varchar(255), + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + CONSTRAINT "account_userId_providerId_unique" UNIQUE("user_id","provider_id") +); +--> statement-breakpoint +CREATE TABLE "activity" ( + "id" varchar(60) PRIMARY KEY NOT NULL, + "type" varchar(60) NOT NULL, + "metadata" jsonb NOT NULL, + "group_id" varchar(60), + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "category" ( + "id" varchar(60) PRIMARY KEY NOT NULL, + "name" varchar(255) NOT NULL, + "description" text, + "user_id" varchar(60), + "is_active" boolean DEFAULT true NOT NULL, + "icon" varchar(255), + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "expense" ( + "id" varchar(60) PRIMARY KEY NOT NULL, + "payer_id" varchar(60) NOT NULL, + "creator_id" varchar(60) NOT NULL, + "category_id" varchar(60), + "group_id" varchar(60), + "amount" real NOT NULL, + "currency" varchar(3) NOT NULL, + "split_type" "splitType", + "description" text, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "group" ( + "id" varchar(60) PRIMARY KEY NOT NULL, + "name" varchar(255) NOT NULL, + "creator_id" varchar(60) NOT NULL, + "status" "status" DEFAULT 'unsettled', + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "session" ( + "id" varchar(80) PRIMARY KEY NOT NULL, + "expires_at" timestamp NOT NULL, + "ip_address" varchar(255), + "user_agent" varchar(255), + "user_id" varchar NOT NULL +); +--> statement-breakpoint +CREATE TABLE "split" ( + "id" varchar(60) PRIMARY KEY NOT NULL, + "user_id" varchar(60) NOT NULL, + "expense_id" varchar(60) NOT NULL, + "amount" real NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "users" ( + "id" varchar(60) PRIMARY KEY NOT NULL, + "email" varchar(255) NOT NULL, + "email_verified" boolean DEFAULT false, + "full_name" varchar(255), + "role" "role" DEFAULT 'user', + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + CONSTRAINT "users_email_unique" UNIQUE("email") +); +--> statement-breakpoint +CREATE TABLE "settlement" ( + "id" varchar(60) PRIMARY KEY NOT NULL, + "sender_id" varchar(60) NOT NULL, + "receiver_id" varchar(60) NOT NULL, + "group_id" varchar(60), + "amount" real NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "users_to_groups" ( + "user_id" varchar(60) NOT NULL, + "group_id" varchar(60) NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + CONSTRAINT "users_to_groups_user_id_group_id_pk" PRIMARY KEY("user_id","group_id") +); +--> statement-breakpoint +ALTER TABLE "account" ADD CONSTRAINT "account_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "activity" ADD CONSTRAINT "activity_group_id_group_id_fk" FOREIGN KEY ("group_id") REFERENCES "public"."group"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "category" ADD CONSTRAINT "category_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "expense" ADD CONSTRAINT "expense_payer_id_users_id_fk" FOREIGN KEY ("payer_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "expense" ADD CONSTRAINT "expense_creator_id_users_id_fk" FOREIGN KEY ("creator_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "expense" ADD CONSTRAINT "expense_category_id_category_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."category"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "expense" ADD CONSTRAINT "expense_group_id_group_id_fk" FOREIGN KEY ("group_id") REFERENCES "public"."group"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "group" ADD CONSTRAINT "group_creator_id_users_id_fk" FOREIGN KEY ("creator_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "session" ADD CONSTRAINT "session_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "split" ADD CONSTRAINT "split_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "split" ADD CONSTRAINT "split_expense_id_expense_id_fk" FOREIGN KEY ("expense_id") REFERENCES "public"."expense"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "users_to_groups" ADD CONSTRAINT "users_to_groups_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "users_to_groups" ADD CONSTRAINT "users_to_groups_group_id_group_id_fk" FOREIGN KEY ("group_id") REFERENCES "public"."group"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "unique_name_userId_idx" ON "category" USING btree (lower("name"),"user_id");--> statement-breakpoint +CREATE INDEX "search_index" ON "category" USING gin (( + setweight(to_tsvector('english', "name"), 'A') || + setweight(to_tsvector('english', "description"), 'B') + ));--> statement-breakpoint +CREATE UNIQUE INDEX "unique_email_idx" ON "users" USING btree (lower("email")); \ No newline at end of file diff --git a/src/db/migrations/0000_natural_mephisto.sql b/src/db/migrations/0000_natural_mephisto.sql deleted file mode 100644 index a21ddd9..0000000 --- a/src/db/migrations/0000_natural_mephisto.sql +++ /dev/null @@ -1,176 +0,0 @@ -CREATE TYPE "public"."activityType" AS ENUM('category_created', 'category_updated', 'category_deleted', 'group_created', 'group_deleted', 'group_updated', 'group_member_added', 'group_member_removed', 'expense_added', 'expense_updated', 'expense_deleted');--> statement-breakpoint -CREATE TYPE "public"."splitType" AS ENUM('even', 'uneven', 'proportional');--> statement-breakpoint -CREATE TYPE "public"."status" AS ENUM('settled', 'unsettled');--> statement-breakpoint -CREATE TYPE "public"."role" AS ENUM('user', 'admin');--> statement-breakpoint -CREATE TABLE IF NOT EXISTS "account" ( - "id" varchar(60) PRIMARY KEY NOT NULL, - "provider_id" varchar(255) NOT NULL, - "provider_account_id" varchar(255) NOT NULL, - "user_id" varchar(60) NOT NULL, - "access_token" varchar(255), - "refresh_token" varchar(255), - "id_token" varchar(255), - "expires_at" timestamp, - "password" varchar(255), - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "account_userId_providerId_unique" UNIQUE("user_id","provider_id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "activity" ( - "id" varchar(60) PRIMARY KEY NOT NULL, - "type" varchar(60) NOT NULL, - "metadata" jsonb NOT NULL, - "group_id" varchar(60), - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "category" ( - "id" varchar(60) PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "description" text, - "user_id" varchar(60), - "is_active" boolean DEFAULT true NOT NULL, - "icon" varchar(255), - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "expense" ( - "id" varchar(60) PRIMARY KEY NOT NULL, - "payer_id" varchar(60) NOT NULL, - "category_id" varchar(60) NOT NULL, - "group_id" varchar(60), - "amount" real NOT NULL, - "currency" varchar(3) NOT NULL, - "split_type" "splitType" NOT NULL, - "description" text, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "group" ( - "id" varchar(60) PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "creator_id" varchar(60) NOT NULL, - "status" "status" DEFAULT 'unsettled', - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "session" ( - "id" varchar(80) PRIMARY KEY NOT NULL, - "expires_at" timestamp NOT NULL, - "ip_address" varchar(255), - "user_agent" varchar(255), - "user_id" varchar NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "split" ( - "id" varchar(60) PRIMARY KEY NOT NULL, - "user_id" varchar(60) NOT NULL, - "expense_id" varchar(60) NOT NULL, - "amount" real NOT NULL, - "is_settled" boolean DEFAULT false, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "users" ( - "id" varchar(60) PRIMARY KEY NOT NULL, - "email" varchar(255) NOT NULL, - "email_verified" boolean DEFAULT false, - "full_name" varchar(255), - "role" "role" DEFAULT 'user', - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "users_email_unique" UNIQUE("email") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "users_to_groups" ( - "user_id" varchar(60) NOT NULL, - "group_id" varchar(60) NOT NULL, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "users_to_groups_user_id_group_id_pk" PRIMARY KEY("user_id","group_id") -); ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "account" ADD CONSTRAINT "account_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "activity" ADD CONSTRAINT "activity_group_id_group_id_fk" FOREIGN KEY ("group_id") REFERENCES "public"."group"("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_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "expense" ADD CONSTRAINT "expense_payer_id_users_id_fk" FOREIGN KEY ("payer_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "expense" ADD CONSTRAINT "expense_category_id_category_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."category"("id") ON DELETE cascade ON UPDATE cascade; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "expense" ADD CONSTRAINT "expense_group_id_group_id_fk" FOREIGN KEY ("group_id") REFERENCES "public"."group"("id") ON DELETE cascade ON UPDATE cascade; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "group" ADD CONSTRAINT "group_creator_id_users_id_fk" FOREIGN KEY ("creator_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "session" ADD CONSTRAINT "session_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "split" ADD CONSTRAINT "split_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "split" ADD CONSTRAINT "split_expense_id_expense_id_fk" FOREIGN KEY ("expense_id") REFERENCES "public"."expense"("id") ON DELETE cascade ON UPDATE cascade; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "users_to_groups" ADD CONSTRAINT "users_to_groups_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "users_to_groups" ADD CONSTRAINT "users_to_groups_group_id_group_id_fk" FOREIGN KEY ("group_id") REFERENCES "public"."group"("id") ON DELETE no action ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -CREATE UNIQUE INDEX IF NOT EXISTS "unique_name_userId_idx" ON "category" USING btree (lower("name"),"user_id");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "search_index" ON "category" USING gin (( - setweight(to_tsvector('english', "name"), 'A') || - setweight(to_tsvector('english', "description"), 'B') - ));--> statement-breakpoint -CREATE UNIQUE INDEX IF NOT EXISTS "unique_email_idx" ON "users" USING btree (lower("email")); \ No newline at end of file diff --git a/src/db/migrations/0001_parallel_red_hulk.sql b/src/db/migrations/0001_parallel_red_hulk.sql deleted file mode 100644 index 65b76c4..0000000 --- a/src/db/migrations/0001_parallel_red_hulk.sql +++ /dev/null @@ -1,7 +0,0 @@ -ALTER TABLE "expense" ALTER COLUMN "category_id" DROP NOT NULL;--> statement-breakpoint -ALTER TABLE "expense" ADD COLUMN "creator_id" varchar(60) NOT NULL;--> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "expense" ADD CONSTRAINT "expense_creator_id_users_id_fk" FOREIGN KEY ("creator_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE cascade; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; diff --git a/src/db/migrations/0002_safe_cobalt_man.sql b/src/db/migrations/0002_safe_cobalt_man.sql deleted file mode 100644 index ac59638..0000000 --- a/src/db/migrations/0002_safe_cobalt_man.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE "settlement" ( - "id" varchar(60) PRIMARY KEY NOT NULL, - "sender_id" varchar(60) NOT NULL, - "receiver_id" varchar(60) NOT NULL, - "group_id" varchar(60), - "amount" real NOT NULL, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL -); ---> statement-breakpoint -ALTER TABLE "split" DROP COLUMN "is_settled"; \ No newline at end of file diff --git a/src/db/migrations/0003_bored_captain_stacy.sql b/src/db/migrations/0003_bored_captain_stacy.sql deleted file mode 100644 index 8bea570..0000000 --- a/src/db/migrations/0003_bored_captain_stacy.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "expense" ALTER COLUMN "split_type" DROP NOT NULL; \ No newline at end of file diff --git a/src/db/migrations/meta/0000_snapshot.json b/src/db/migrations/meta/0000_snapshot.json index 8a25fae..10b990a 100644 --- a/src/db/migrations/meta/0000_snapshot.json +++ b/src/db/migrations/meta/0000_snapshot.json @@ -1,5 +1,5 @@ { - "id": "96948455-b2cc-46ab-9feb-e58e24a224ed", + "id": "4e2657ae-b676-410a-a3b3-52e34a789ae0", "prevId": "00000000-0000-0000-0000-000000000000", "version": "7", "dialect": "postgresql", @@ -304,11 +304,17 @@ "primaryKey": false, "notNull": true }, + "creator_id": { + "name": "creator_id", + "type": "varchar(60)", + "primaryKey": false, + "notNull": true + }, "category_id": { "name": "category_id", "type": "varchar(60)", "primaryKey": false, - "notNull": true + "notNull": false }, "group_id": { "name": "group_id", @@ -333,7 +339,7 @@ "type": "splitType", "typeSchema": "public", "primaryKey": false, - "notNull": true + "notNull": false }, "description": { "name": "description", @@ -371,6 +377,19 @@ "onDelete": "cascade", "onUpdate": "cascade" }, + "expense_creator_id_users_id_fk": { + "name": "expense_creator_id_users_id_fk", + "tableFrom": "expense", + "tableTo": "users", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, "expense_category_id_category_id_fk": { "name": "expense_category_id_category_id_fk", "tableFrom": "expense", @@ -556,13 +575,6 @@ "primaryKey": false, "notNull": true }, - "is_settled": { - "name": "is_settled", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, "created_at": { "name": "created_at", "type": "timestamp", @@ -697,6 +709,63 @@ "checkConstraints": {}, "isRLSEnabled": false }, + "public.settlement": { + "name": "settlement", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(60)", + "primaryKey": true, + "notNull": true + }, + "sender_id": { + "name": "sender_id", + "type": "varchar(60)", + "primaryKey": false, + "notNull": true + }, + "receiver_id": { + "name": "receiver_id", + "type": "varchar(60)", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "varchar(60)", + "primaryKey": false, + "notNull": false + }, + "amount": { + "name": "amount", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, "public.users_to_groups": { "name": "users_to_groups", "schema": "", @@ -826,4 +895,4 @@ "schemas": {}, "tables": {} } -} +} \ No newline at end of file diff --git a/src/db/migrations/meta/0001_snapshot.json b/src/db/migrations/meta/0001_snapshot.json deleted file mode 100644 index bcf4681..0000000 --- a/src/db/migrations/meta/0001_snapshot.json +++ /dev/null @@ -1,848 +0,0 @@ -{ - "id": "ccbee261-6d60-412b-88c5-7a8908cfbd6f", - "prevId": "96948455-b2cc-46ab-9feb-e58e24a224ed", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.account": { - "name": "account", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "provider_id": { - "name": "provider_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "provider_account_id": { - "name": "provider_account_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "access_token": { - "name": "access_token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "id_token": { - "name": "id_token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "account_user_id_users_id_fk": { - "name": "account_user_id_users_id_fk", - "tableFrom": "account", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "account_userId_providerId_unique": { - "name": "account_userId_providerId_unique", - "nullsNotDistinct": false, - "columns": [ - "user_id", - "provider_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.activity": { - "name": "activity", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "type": { - "name": "type", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "activity_group_id_group_id_fk": { - "name": "activity_group_id_group_id_fk", - "tableFrom": "activity", - "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.category": { - "name": "category", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "is_active": { - "name": "is_active", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "icon": { - "name": "icon", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "unique_name_userId_idx": { - "name": "unique_name_userId_idx", - "columns": [ - { - "expression": "lower(\"name\")", - "asc": true, - "isExpression": true, - "nulls": "last" - }, - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "search_index": { - "name": "search_index", - "columns": [ - { - "expression": "(\n setweight(to_tsvector('english', \"name\"), 'A') ||\n setweight(to_tsvector('english', \"description\"), 'B')\n )", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "gin", - "with": {} - } - }, - "foreignKeys": { - "category_user_id_users_id_fk": { - "name": "category_user_id_users_id_fk", - "tableFrom": "category", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.expense": { - "name": "expense", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "payer_id": { - "name": "payer_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "category_id": { - "name": "category_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "real", - "primaryKey": false, - "notNull": true - }, - "currency": { - "name": "currency", - "type": "varchar(3)", - "primaryKey": false, - "notNull": true - }, - "split_type": { - "name": "split_type", - "type": "splitType", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "expense_payer_id_users_id_fk": { - "name": "expense_payer_id_users_id_fk", - "tableFrom": "expense", - "tableTo": "users", - "columnsFrom": [ - "payer_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "expense_creator_id_users_id_fk": { - "name": "expense_creator_id_users_id_fk", - "tableFrom": "expense", - "tableTo": "users", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "expense_category_id_category_id_fk": { - "name": "expense_category_id_category_id_fk", - "tableFrom": "expense", - "tableTo": "category", - "columnsFrom": [ - "category_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "expense_group_id_group_id_fk": { - "name": "expense_group_id_group_id_fk", - "tableFrom": "expense", - "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.group": { - "name": "group", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "status", - "typeSchema": "public", - "primaryKey": false, - "notNull": false, - "default": "'unsettled'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "group_creator_id_users_id_fk": { - "name": "group_creator_id_users_id_fk", - "tableFrom": "group", - "tableTo": "users", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(80)", - "primaryKey": true, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "ip_address": { - "name": "ip_address", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "user_agent": { - "name": "user_agent", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "varchar", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "session_user_id_users_id_fk": { - "name": "session_user_id_users_id_fk", - "tableFrom": "session", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.split": { - "name": "split", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "expense_id": { - "name": "expense_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "amount": { - "name": "amount", - "type": "real", - "primaryKey": false, - "notNull": true - }, - "is_settled": { - "name": "is_settled", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "split_user_id_users_id_fk": { - "name": "split_user_id_users_id_fk", - "tableFrom": "split", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "split_expense_id_expense_id_fk": { - "name": "split_expense_id_expense_id_fk", - "tableFrom": "split", - "tableTo": "expense", - "columnsFrom": [ - "expense_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.users": { - "name": "users", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email_verified": { - "name": "email_verified", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "full_name": { - "name": "full_name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "role": { - "name": "role", - "type": "role", - "typeSchema": "public", - "primaryKey": false, - "notNull": false, - "default": "'user'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "unique_email_idx": { - "name": "unique_email_idx", - "columns": [ - { - "expression": "lower(\"email\")", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "users_email_unique": { - "name": "users_email_unique", - "nullsNotDistinct": false, - "columns": [ - "email" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.users_to_groups": { - "name": "users_to_groups", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "users_to_groups_user_id_users_id_fk": { - "name": "users_to_groups_user_id_users_id_fk", - "tableFrom": "users_to_groups", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "users_to_groups_group_id_group_id_fk": { - "name": "users_to_groups_group_id_group_id_fk", - "tableFrom": "users_to_groups", - "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "users_to_groups_user_id_group_id_pk": { - "name": "users_to_groups_user_id_group_id_pk", - "columns": [ - "user_id", - "group_id" - ] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": { - "public.activityType": { - "name": "activityType", - "schema": "public", - "values": [ - "category_created", - "category_updated", - "category_deleted", - "group_created", - "group_deleted", - "group_updated", - "group_member_added", - "group_member_removed", - "expense_added", - "expense_updated", - "expense_deleted" - ] - }, - "public.splitType": { - "name": "splitType", - "schema": "public", - "values": [ - "even", - "uneven", - "proportional" - ] - }, - "public.status": { - "name": "status", - "schema": "public", - "values": [ - "settled", - "unsettled" - ] - }, - "public.role": { - "name": "role", - "schema": "public", - "values": [ - "user", - "admin" - ] - } - }, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/src/db/migrations/meta/0002_snapshot.json b/src/db/migrations/meta/0002_snapshot.json deleted file mode 100644 index c629d4b..0000000 --- a/src/db/migrations/meta/0002_snapshot.json +++ /dev/null @@ -1,898 +0,0 @@ -{ - "id": "86646472-c312-42fa-aa20-db71c5363681", - "prevId": "ccbee261-6d60-412b-88c5-7a8908cfbd6f", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.account": { - "name": "account", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "provider_id": { - "name": "provider_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "provider_account_id": { - "name": "provider_account_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "access_token": { - "name": "access_token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "id_token": { - "name": "id_token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "account_user_id_users_id_fk": { - "name": "account_user_id_users_id_fk", - "tableFrom": "account", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "account_userId_providerId_unique": { - "name": "account_userId_providerId_unique", - "nullsNotDistinct": false, - "columns": [ - "user_id", - "provider_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.activity": { - "name": "activity", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "type": { - "name": "type", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "activity_group_id_group_id_fk": { - "name": "activity_group_id_group_id_fk", - "tableFrom": "activity", - "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.category": { - "name": "category", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "is_active": { - "name": "is_active", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "icon": { - "name": "icon", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "unique_name_userId_idx": { - "name": "unique_name_userId_idx", - "columns": [ - { - "expression": "lower(\"name\")", - "asc": true, - "isExpression": true, - "nulls": "last" - }, - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "search_index": { - "name": "search_index", - "columns": [ - { - "expression": "(\n setweight(to_tsvector('english', \"name\"), 'A') ||\n setweight(to_tsvector('english', \"description\"), 'B')\n )", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "gin", - "with": {} - } - }, - "foreignKeys": { - "category_user_id_users_id_fk": { - "name": "category_user_id_users_id_fk", - "tableFrom": "category", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.expense": { - "name": "expense", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "payer_id": { - "name": "payer_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "category_id": { - "name": "category_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "real", - "primaryKey": false, - "notNull": true - }, - "currency": { - "name": "currency", - "type": "varchar(3)", - "primaryKey": false, - "notNull": true - }, - "split_type": { - "name": "split_type", - "type": "splitType", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "expense_payer_id_users_id_fk": { - "name": "expense_payer_id_users_id_fk", - "tableFrom": "expense", - "tableTo": "users", - "columnsFrom": [ - "payer_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "expense_creator_id_users_id_fk": { - "name": "expense_creator_id_users_id_fk", - "tableFrom": "expense", - "tableTo": "users", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "expense_category_id_category_id_fk": { - "name": "expense_category_id_category_id_fk", - "tableFrom": "expense", - "tableTo": "category", - "columnsFrom": [ - "category_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "expense_group_id_group_id_fk": { - "name": "expense_group_id_group_id_fk", - "tableFrom": "expense", - "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.group": { - "name": "group", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "status", - "typeSchema": "public", - "primaryKey": false, - "notNull": false, - "default": "'unsettled'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "group_creator_id_users_id_fk": { - "name": "group_creator_id_users_id_fk", - "tableFrom": "group", - "tableTo": "users", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(80)", - "primaryKey": true, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "ip_address": { - "name": "ip_address", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "user_agent": { - "name": "user_agent", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "varchar", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "session_user_id_users_id_fk": { - "name": "session_user_id_users_id_fk", - "tableFrom": "session", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.split": { - "name": "split", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "expense_id": { - "name": "expense_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "amount": { - "name": "amount", - "type": "real", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "split_user_id_users_id_fk": { - "name": "split_user_id_users_id_fk", - "tableFrom": "split", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "split_expense_id_expense_id_fk": { - "name": "split_expense_id_expense_id_fk", - "tableFrom": "split", - "tableTo": "expense", - "columnsFrom": [ - "expense_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.users": { - "name": "users", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email_verified": { - "name": "email_verified", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "full_name": { - "name": "full_name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "role": { - "name": "role", - "type": "role", - "typeSchema": "public", - "primaryKey": false, - "notNull": false, - "default": "'user'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "unique_email_idx": { - "name": "unique_email_idx", - "columns": [ - { - "expression": "lower(\"email\")", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "users_email_unique": { - "name": "users_email_unique", - "nullsNotDistinct": false, - "columns": [ - "email" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.settlement": { - "name": "settlement", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "sender_id": { - "name": "sender_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "receiver_id": { - "name": "receiver_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "real", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.users_to_groups": { - "name": "users_to_groups", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "users_to_groups_user_id_users_id_fk": { - "name": "users_to_groups_user_id_users_id_fk", - "tableFrom": "users_to_groups", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "users_to_groups_group_id_group_id_fk": { - "name": "users_to_groups_group_id_group_id_fk", - "tableFrom": "users_to_groups", - "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "users_to_groups_user_id_group_id_pk": { - "name": "users_to_groups_user_id_group_id_pk", - "columns": [ - "user_id", - "group_id" - ] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": { - "public.activityType": { - "name": "activityType", - "schema": "public", - "values": [ - "category_created", - "category_updated", - "category_deleted", - "group_created", - "group_deleted", - "group_updated", - "group_member_added", - "group_member_removed", - "expense_added", - "expense_updated", - "expense_deleted" - ] - }, - "public.splitType": { - "name": "splitType", - "schema": "public", - "values": [ - "even", - "uneven", - "proportional" - ] - }, - "public.status": { - "name": "status", - "schema": "public", - "values": [ - "settled", - "unsettled" - ] - }, - "public.role": { - "name": "role", - "schema": "public", - "values": [ - "user", - "admin" - ] - } - }, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/src/db/migrations/meta/0003_snapshot.json b/src/db/migrations/meta/0003_snapshot.json deleted file mode 100644 index 7e6e479..0000000 --- a/src/db/migrations/meta/0003_snapshot.json +++ /dev/null @@ -1,898 +0,0 @@ -{ - "id": "40f79688-973d-421e-8646-926a6e218997", - "prevId": "86646472-c312-42fa-aa20-db71c5363681", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.account": { - "name": "account", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "provider_id": { - "name": "provider_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "provider_account_id": { - "name": "provider_account_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "access_token": { - "name": "access_token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "id_token": { - "name": "id_token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "account_user_id_users_id_fk": { - "name": "account_user_id_users_id_fk", - "tableFrom": "account", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "account_userId_providerId_unique": { - "name": "account_userId_providerId_unique", - "nullsNotDistinct": false, - "columns": [ - "user_id", - "provider_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.activity": { - "name": "activity", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "type": { - "name": "type", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "activity_group_id_group_id_fk": { - "name": "activity_group_id_group_id_fk", - "tableFrom": "activity", - "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.category": { - "name": "category", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "is_active": { - "name": "is_active", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "icon": { - "name": "icon", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "unique_name_userId_idx": { - "name": "unique_name_userId_idx", - "columns": [ - { - "expression": "lower(\"name\")", - "asc": true, - "isExpression": true, - "nulls": "last" - }, - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "search_index": { - "name": "search_index", - "columns": [ - { - "expression": "(\n setweight(to_tsvector('english', \"name\"), 'A') ||\n setweight(to_tsvector('english', \"description\"), 'B')\n )", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "gin", - "with": {} - } - }, - "foreignKeys": { - "category_user_id_users_id_fk": { - "name": "category_user_id_users_id_fk", - "tableFrom": "category", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.expense": { - "name": "expense", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "payer_id": { - "name": "payer_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "category_id": { - "name": "category_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "real", - "primaryKey": false, - "notNull": true - }, - "currency": { - "name": "currency", - "type": "varchar(3)", - "primaryKey": false, - "notNull": true - }, - "split_type": { - "name": "split_type", - "type": "splitType", - "typeSchema": "public", - "primaryKey": false, - "notNull": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "expense_payer_id_users_id_fk": { - "name": "expense_payer_id_users_id_fk", - "tableFrom": "expense", - "tableTo": "users", - "columnsFrom": [ - "payer_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "expense_creator_id_users_id_fk": { - "name": "expense_creator_id_users_id_fk", - "tableFrom": "expense", - "tableTo": "users", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "expense_category_id_category_id_fk": { - "name": "expense_category_id_category_id_fk", - "tableFrom": "expense", - "tableTo": "category", - "columnsFrom": [ - "category_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "expense_group_id_group_id_fk": { - "name": "expense_group_id_group_id_fk", - "tableFrom": "expense", - "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.group": { - "name": "group", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "status", - "typeSchema": "public", - "primaryKey": false, - "notNull": false, - "default": "'unsettled'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "group_creator_id_users_id_fk": { - "name": "group_creator_id_users_id_fk", - "tableFrom": "group", - "tableTo": "users", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(80)", - "primaryKey": true, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "ip_address": { - "name": "ip_address", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "user_agent": { - "name": "user_agent", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "varchar", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "session_user_id_users_id_fk": { - "name": "session_user_id_users_id_fk", - "tableFrom": "session", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.split": { - "name": "split", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "expense_id": { - "name": "expense_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "amount": { - "name": "amount", - "type": "real", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "split_user_id_users_id_fk": { - "name": "split_user_id_users_id_fk", - "tableFrom": "split", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "split_expense_id_expense_id_fk": { - "name": "split_expense_id_expense_id_fk", - "tableFrom": "split", - "tableTo": "expense", - "columnsFrom": [ - "expense_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.users": { - "name": "users", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email_verified": { - "name": "email_verified", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "full_name": { - "name": "full_name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "role": { - "name": "role", - "type": "role", - "typeSchema": "public", - "primaryKey": false, - "notNull": false, - "default": "'user'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "unique_email_idx": { - "name": "unique_email_idx", - "columns": [ - { - "expression": "lower(\"email\")", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "users_email_unique": { - "name": "users_email_unique", - "nullsNotDistinct": false, - "columns": [ - "email" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.settlement": { - "name": "settlement", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(60)", - "primaryKey": true, - "notNull": true - }, - "sender_id": { - "name": "sender_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "receiver_id": { - "name": "receiver_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "real", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.users_to_groups": { - "name": "users_to_groups", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "group_id": { - "name": "group_id", - "type": "varchar(60)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "users_to_groups_user_id_users_id_fk": { - "name": "users_to_groups_user_id_users_id_fk", - "tableFrom": "users_to_groups", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "users_to_groups_group_id_group_id_fk": { - "name": "users_to_groups_group_id_group_id_fk", - "tableFrom": "users_to_groups", - "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "users_to_groups_user_id_group_id_pk": { - "name": "users_to_groups_user_id_group_id_pk", - "columns": [ - "user_id", - "group_id" - ] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": { - "public.activityType": { - "name": "activityType", - "schema": "public", - "values": [ - "category_created", - "category_updated", - "category_deleted", - "group_created", - "group_deleted", - "group_updated", - "group_member_added", - "group_member_removed", - "expense_added", - "expense_updated", - "expense_deleted" - ] - }, - "public.splitType": { - "name": "splitType", - "schema": "public", - "values": [ - "even", - "uneven", - "proportional" - ] - }, - "public.status": { - "name": "status", - "schema": "public", - "values": [ - "settled", - "unsettled" - ] - }, - "public.role": { - "name": "role", - "schema": "public", - "values": [ - "user", - "admin" - ] - } - }, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/src/db/migrations/meta/_journal.json b/src/db/migrations/meta/_journal.json index 713c821..dc0f431 100644 --- a/src/db/migrations/meta/_journal.json +++ b/src/db/migrations/meta/_journal.json @@ -5,29 +5,8 @@ { "idx": 0, "version": "7", - "when": 1733501291825, - "tag": "0000_natural_mephisto", - "breakpoints": true - }, - { - "idx": 1, - "version": "7", - "when": 1733737956040, - "tag": "0001_parallel_red_hulk", - "breakpoints": true - }, - { - "idx": 2, - "version": "7", - "when": 1735924524798, - "tag": "0002_safe_cobalt_man", - "breakpoints": true - }, - { - "idx": 3, - "version": "7", - "when": 1736070259247, - "tag": "0003_bored_captain_stacy", + "when": 1739382409314, + "tag": "0000_glorious_thing", "breakpoints": true } ] diff --git a/src/db/schemas/settlement.model.ts b/src/db/schemas/settlement.model.ts index 16de5fb..efa4c40 100644 --- a/src/db/schemas/settlement.model.ts +++ b/src/db/schemas/settlement.model.ts @@ -26,17 +26,17 @@ export const selectSettlementSchema = createSelectSchema(settlementModel, { id: schema => schema.id.describe("Unique identifier for the settlement"), senderId: schema => schema.senderId - .min(60) + .min(36) .max(60) .describe("Reference to the user who is payer"), receiverId: schema => schema.receiverId - .min(60) + .min(36) .max(60) .describe("Reference to the user who is ower "), groupId: schema => schema.groupId - .min(60) + .min(36) .max(60) .describe("Reference to the group the settlement belongs to"), amount: schema => schema.amount.describe("Amount of the settlement"), @@ -50,17 +50,17 @@ export const insertSettlementSchema = createInsertSchema(settlementModel, { id: schema => schema.id.describe("Unique identifier for the settlement"), senderId: schema => schema.senderId - .min(60) + .min(36) .max(60) .describe("Reference to the user who is payer"), receiverId: schema => schema.receiverId - .min(60) + .min(36) .max(60) .describe("Reference to the user who is ower "), groupId: schema => schema.groupId - .min(60) + .min(36) .max(60) .describe("Reference to the group the settlement belongs to"), amount: schema => schema.amount.describe("Amount of the settlement"), diff --git a/src/modules/settlements/settlements.repository.ts b/src/modules/settlements/settlements.repository.ts index 21a9683..6e8c0fc 100644 --- a/src/modules/settlements/settlements.repository.ts +++ b/src/modules/settlements/settlements.repository.ts @@ -1,5 +1,4 @@ -import type { SQL } from "drizzle-orm"; -import { and, eq } from "drizzle-orm"; +import { and, eq, or } from "drizzle-orm"; import { db } from "@/db/adapter"; import type { TInsertSettlementSchema } from "@/db/schemas/settlement.model"; @@ -9,22 +8,56 @@ export async function updateSettlementRepository( payload: TInsertSettlementSchema, settlementId: string, ) { - const whereConditions: SQL[] = [ + const whereConditions = [ eq(settlementModel.id, settlementId), - eq(settlementModel.senderId, payload.senderId), - eq(settlementModel.receiverId, payload.receiverId), + and( + or( + eq(settlementModel.senderId, payload.senderId), + eq(settlementModel.senderId, payload.receiverId), + ), + or( + eq(settlementModel.receiverId, payload.senderId), + eq(settlementModel.receiverId, payload.receiverId), + ), + ), ]; - if (payload.groupId) { + if (payload?.groupId) { whereConditions.push(eq(settlementModel.groupId, payload.groupId)); } const [settlement] = await db - .update(settlementModel) - .set({ - amount: payload.amount, - }) + .select() + .from(settlementModel) .where(and(...whereConditions)); - return settlement; + const finalAmount = settlement?.amount - payload.amount; + + if (finalAmount > 0) { + const [updatedSettlement] = await db + .update(settlementModel) + .set({ + amount: finalAmount, + }) + .where(and(...whereConditions)) + .returning(); + + return updatedSettlement; + } + + if (finalAmount < 0) { + const updateData = { + amount: -finalAmount, + receiverId: payload.senderId, + senderId: payload.receiverId, + }; + + const [updatedSettlement] = await db + .update(settlementModel) + .set(updateData) + .where(and(...whereConditions)) + .returning(); + + return updatedSettlement; + } }