phase 0 & 1 ✅, onto the next logic
This commit is contained in:
56
packages/db/migrations/0002_massive_captain_britain.sql
Normal file
56
packages/db/migrations/0002_massive_captain_britain.sql
Normal file
@@ -0,0 +1,56 @@
|
||||
CREATE TABLE "mobile_device" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"external_device_id" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"manufacturer" text NOT NULL,
|
||||
"model" text NOT NULL,
|
||||
"android_version" text NOT NULL,
|
||||
"owner_user_id" text NOT NULL,
|
||||
"last_ping_at" timestamp,
|
||||
"created_at" timestamp NOT NULL,
|
||||
"updated_at" timestamp NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "mobile_media_asset" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"device_id" integer NOT NULL,
|
||||
"external_media_id" text,
|
||||
"file_id" text NOT NULL,
|
||||
"mime_type" text NOT NULL,
|
||||
"filename" text,
|
||||
"captured_at" timestamp,
|
||||
"size_bytes" integer,
|
||||
"hash" text,
|
||||
"metadata" json,
|
||||
"created_at" timestamp NOT NULL,
|
||||
"updated_at" timestamp NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "mobile_sms" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"device_id" integer NOT NULL,
|
||||
"external_message_id" text,
|
||||
"sender" text NOT NULL,
|
||||
"recipient" text,
|
||||
"body" text NOT NULL,
|
||||
"sent_at" timestamp NOT NULL,
|
||||
"received_at" timestamp,
|
||||
"dedup_hash" text NOT NULL,
|
||||
"raw_payload" json,
|
||||
"created_at" timestamp NOT NULL,
|
||||
"updated_at" timestamp NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "mobile_device" ADD CONSTRAINT "mobile_device_owner_user_id_user_id_fk" FOREIGN KEY ("owner_user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "mobile_media_asset" ADD CONSTRAINT "mobile_media_asset_device_id_mobile_device_id_fk" FOREIGN KEY ("device_id") REFERENCES "public"."mobile_device"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "mobile_media_asset" ADD CONSTRAINT "mobile_media_asset_file_id_file_id_fk" FOREIGN KEY ("file_id") REFERENCES "public"."file"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "mobile_sms" ADD CONSTRAINT "mobile_sms_device_id_mobile_device_id_fk" FOREIGN KEY ("device_id") REFERENCES "public"."mobile_device"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "mobile_device_external_device_id_uq" ON "mobile_device" USING btree ("external_device_id");--> statement-breakpoint
|
||||
CREATE INDEX "mobile_device_owner_user_id_idx" ON "mobile_device" USING btree ("owner_user_id");--> statement-breakpoint
|
||||
CREATE INDEX "mobile_device_last_ping_at_idx" ON "mobile_device" USING btree ("last_ping_at");--> statement-breakpoint
|
||||
CREATE INDEX "mobile_media_asset_device_created_at_idx" ON "mobile_media_asset" USING btree ("device_id","created_at");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "mobile_media_asset_device_external_media_uq" ON "mobile_media_asset" USING btree ("device_id","external_media_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "mobile_media_asset_file_id_uq" ON "mobile_media_asset" USING btree ("file_id");--> statement-breakpoint
|
||||
CREATE INDEX "mobile_sms_device_sent_at_idx" ON "mobile_sms" USING btree ("device_id","sent_at");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "mobile_sms_device_dedup_hash_uq" ON "mobile_sms" USING btree ("device_id","dedup_hash");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "mobile_sms_device_external_msg_uq" ON "mobile_sms" USING btree ("device_id","external_message_id");
|
||||
1386
packages/db/migrations/meta/0002_snapshot.json
Normal file
1386
packages/db/migrations/meta/0002_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,13 @@
|
||||
"when": 1772335785371,
|
||||
"tag": "0001_silly_venus",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1772338633827,
|
||||
"tag": "0002_massive_captain_britain",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
import { user } from "./better.auth.schema";
|
||||
import { relations } from "drizzle-orm";
|
||||
|
||||
// Add this to your existing schema file
|
||||
export const file = pgTable("file", {
|
||||
id: text("id").primaryKey(), // UUID
|
||||
|
||||
|
||||
@@ -2,3 +2,4 @@ export * from "./auth.schema";
|
||||
export * from "./better.auth.schema";
|
||||
export * from "./file.schema";
|
||||
export * from "./general.schema";
|
||||
export * from "./mobile.device.schema";
|
||||
|
||||
145
packages/db/schema/mobile.device.schema.ts
Normal file
145
packages/db/schema/mobile.device.schema.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import {
|
||||
index,
|
||||
integer,
|
||||
json,
|
||||
pgTable,
|
||||
serial,
|
||||
text,
|
||||
timestamp,
|
||||
uniqueIndex,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { user } from "./better.auth.schema";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { file } from "./file.schema";
|
||||
|
||||
export const mobileDevice = pgTable(
|
||||
"mobile_device",
|
||||
{
|
||||
id: serial("id").primaryKey(),
|
||||
externalDeviceId: text("external_device_id").notNull(),
|
||||
name: text("name").notNull(),
|
||||
manufacturer: text("manufacturer").notNull(),
|
||||
model: text("model").notNull(),
|
||||
androidVersion: text("android_version").notNull(),
|
||||
ownerUserId: text("owner_user_id")
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: "cascade" }),
|
||||
lastPingAt: timestamp("last_ping_at"),
|
||||
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
},
|
||||
(table) => ({
|
||||
externalDeviceUniqueIdx: uniqueIndex(
|
||||
"mobile_device_external_device_id_uq",
|
||||
).on(table.externalDeviceId),
|
||||
ownerUserIdx: index("mobile_device_owner_user_id_idx").on(
|
||||
table.ownerUserId,
|
||||
),
|
||||
lastPingIdx: index("mobile_device_last_ping_at_idx").on(
|
||||
table.lastPingAt,
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
export const mobileSMS = pgTable(
|
||||
"mobile_sms",
|
||||
{
|
||||
id: serial("id").primaryKey(),
|
||||
deviceId: integer("device_id")
|
||||
.notNull()
|
||||
.references(() => mobileDevice.id, { onDelete: "cascade" }),
|
||||
externalMessageId: text("external_message_id"),
|
||||
sender: text("sender").notNull(),
|
||||
recipient: text("recipient"),
|
||||
body: text("body").notNull(),
|
||||
sentAt: timestamp("sent_at").notNull(),
|
||||
receivedAt: timestamp("received_at"),
|
||||
dedupHash: text("dedup_hash").notNull(),
|
||||
rawPayload: json("raw_payload").$type<Record<string, any>>(),
|
||||
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
},
|
||||
(table) => ({
|
||||
deviceSentIdx: index("mobile_sms_device_sent_at_idx").on(
|
||||
table.deviceId,
|
||||
table.sentAt,
|
||||
),
|
||||
dedupHashUniqueIdx: uniqueIndex("mobile_sms_device_dedup_hash_uq").on(
|
||||
table.deviceId,
|
||||
table.dedupHash,
|
||||
),
|
||||
externalMessageUniqueIdx: uniqueIndex(
|
||||
"mobile_sms_device_external_msg_uq",
|
||||
).on(table.deviceId, table.externalMessageId),
|
||||
}),
|
||||
);
|
||||
|
||||
export const mobileMediaAsset = pgTable(
|
||||
"mobile_media_asset",
|
||||
{
|
||||
id: serial("id").primaryKey(),
|
||||
deviceId: integer("device_id")
|
||||
.notNull()
|
||||
.references(() => mobileDevice.id, { onDelete: "cascade" }),
|
||||
externalMediaId: text("external_media_id"),
|
||||
fileId: text("file_id")
|
||||
.notNull()
|
||||
.references(() => file.id, { onDelete: "cascade" }),
|
||||
mimeType: text("mime_type").notNull(),
|
||||
filename: text("filename"),
|
||||
capturedAt: timestamp("captured_at"),
|
||||
sizeBytes: integer("size_bytes"),
|
||||
hash: text("hash"),
|
||||
metadata: json("metadata").$type<Record<string, any>>(),
|
||||
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
},
|
||||
(table) => ({
|
||||
deviceCreatedIdx: index("mobile_media_asset_device_created_at_idx").on(
|
||||
table.deviceId,
|
||||
table.createdAt,
|
||||
),
|
||||
externalMediaUniqueIdx: uniqueIndex(
|
||||
"mobile_media_asset_device_external_media_uq",
|
||||
).on(table.deviceId, table.externalMediaId),
|
||||
fileUniqueIdx: uniqueIndex("mobile_media_asset_file_id_uq").on(
|
||||
table.fileId,
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
export const mobileDeviceRelations = relations(
|
||||
mobileDevice,
|
||||
({ one, many }) => ({
|
||||
owner: one(user, {
|
||||
fields: [mobileDevice.ownerUserId],
|
||||
references: [user.id],
|
||||
}),
|
||||
sms: many(mobileSMS),
|
||||
mediaAssets: many(mobileMediaAsset),
|
||||
}),
|
||||
);
|
||||
|
||||
export const mobileSMSRelations = relations(mobileSMS, ({ one }) => ({
|
||||
device: one(mobileDevice, {
|
||||
fields: [mobileSMS.deviceId],
|
||||
references: [mobileDevice.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const mobileMediaAssetRelations = relations(
|
||||
mobileMediaAsset,
|
||||
({ one }) => ({
|
||||
device: one(mobileDevice, {
|
||||
fields: [mobileMediaAsset.deviceId],
|
||||
references: [mobileDevice.id],
|
||||
}),
|
||||
file: one(file, {
|
||||
fields: [mobileMediaAsset.fileId],
|
||||
references: [file.id],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
Reference in New Issue
Block a user