summaryrefslogtreecommitdiff
path: root/src/db/schema.ts
blob: ed2e36b11a96cdd6f55ac9ae8104b07f1004b7bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { integer, pgTable, varchar, boolean, text, pgEnum } from "drizzle-orm/pg-core";
import { defineRelations, sql } from "drizzle-orm";

export const galleryScanningMode = pgEnum("galleryScanningMode", ["delete", "notify", "none"]); 

/** Parent user accounts with email auth and push notification tokens */
export const users = pgTable("users", {
  id: integer().primaryKey().generatedAlwaysAsIdentity(),
  email: varchar({ length: 255 }).notNull().unique(),
  password: varchar({ length: 255 }).notNull(),
  emailVerified: boolean().default(false),
  emailCode: varchar({ length: 6 }).notNull(),
  pushTokens: text("push_tokens")
    .array()
    .default(sql`'{}'::text[]`),
});

/** Child devices linked to parent accounts for monitoring */
export const linkedDevices = pgTable("linkedDevices", {
  id: integer().primaryKey().generatedAlwaysAsIdentity(),
  nickname: varchar({ length: 255 }).notNull().default("New Device"),
  parentId: integer("parent_id").notNull(),
  lastOnline: integer("last_online"),

  devEnabled: boolean().default(false),
});

/** Safety and monitoring settings for each child device */
export const deviceConfig = pgTable("deviceConfig", {
  id: integer().primaryKey().generatedAlwaysAsIdentity(),
  deviceId: integer("device_id").notNull().unique(),
  disableBuddy: boolean("disable_buddy").notNull().default(false),
  blockAdultSites: boolean("block_adult_sites").notNull().default(true),
  familyLinkAntiCircumvention: boolean("family_link_anti_circumvention")
    .notNull()
    .default(false),
  blockStrangers: boolean("block_strangers").notNull().default(false),
  notifyDangerousMessages: boolean("notify_dangerous_messages")
    .notNull()
    .default(true),
  notifyNewContactAdded: boolean("notify_new_contact_added")
    .notNull()
    .default(true),
});

/** Stores flagged messages and content alerts for parent review */
export const alerts = pgTable("alerts", {
  id: integer().primaryKey().generatedAlwaysAsIdentity(),
  deviceId: integer("device_id").notNull(),
  parentId: integer("parent_id").notNull(),
  category: varchar({ length: 50 }),
  title: varchar({ length: 255 }).notNull(),
  message: text().notNull(),
  summary: text().notNull(),
  confidence: integer().notNull(),
  packageName: varchar({ length: 255 }),
  timestamp: integer().notNull(),
  read: boolean().notNull().default(false),
});

export const relations = defineRelations(
  { users, linkedDevices, deviceConfig, alerts },
  (r) => ({
    users: {
      linkedDevices: r.many.linkedDevices(),
      alerts: r.many.alerts(),
    },
    linkedDevices: {
      parent: r.one.users({
        from: r.linkedDevices.parentId,
        to: r.users.id,
      }),
      config: r.one.deviceConfig({
        from: r.linkedDevices.id,
        to: r.deviceConfig.deviceId,
      }),
      alerts: r.many.alerts(),
    },
    deviceConfig: {
      device: r.one.linkedDevices({
        from: r.deviceConfig.deviceId,
        to: r.linkedDevices.id,
      }),
    },
    alerts: {
      parent: r.one.users({
        from: r.alerts.parentId,
        to: r.users.id,
      }),
      device: r.one.linkedDevices({
        from: r.alerts.deviceId,
        to: r.linkedDevices.id,
      }),
    },
  }),
);