a tool for shared writing and social publishing
at feature/reader 283 lines 15 kB view raw
1import { pgTable, pgEnum, text, jsonb, foreignKey, timestamp, uuid, bigint, boolean, unique, uniqueIndex, smallint, primaryKey } from "drizzle-orm/pg-core" 2 import { sql } from "drizzle-orm" 3 4export const aal_level = pgEnum("aal_level", ['aal1', 'aal2', 'aal3']) 5export const code_challenge_method = pgEnum("code_challenge_method", ['s256', 'plain']) 6export const factor_status = pgEnum("factor_status", ['unverified', 'verified']) 7export const factor_type = pgEnum("factor_type", ['totp', 'webauthn']) 8export const one_time_token_type = pgEnum("one_time_token_type", ['confirmation_token', 'reauthentication_token', 'recovery_token', 'email_change_token_new', 'email_change_token_current', 'phone_change_token']) 9export const request_status = pgEnum("request_status", ['PENDING', 'SUCCESS', 'ERROR']) 10export const key_status = pgEnum("key_status", ['default', 'valid', 'invalid', 'expired']) 11export const key_type = pgEnum("key_type", ['aead-ietf', 'aead-det', 'hmacsha512', 'hmacsha256', 'auth', 'shorthash', 'generichash', 'kdf', 'secretbox', 'secretstream', 'stream_xchacha20']) 12export const rsvp_status = pgEnum("rsvp_status", ['GOING', 'NOT_GOING', 'MAYBE']) 13export const action = pgEnum("action", ['INSERT', 'UPDATE', 'DELETE', 'TRUNCATE', 'ERROR']) 14export const equality_op = pgEnum("equality_op", ['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'in']) 15 16 17export const oauth_state_store = pgTable("oauth_state_store", { 18 key: text("key").primaryKey().notNull(), 19 state: jsonb("state").notNull(), 20}); 21 22export const oauth_session_store = pgTable("oauth_session_store", { 23 key: text("key").primaryKey().notNull(), 24 session: jsonb("session").notNull(), 25}); 26 27export const bsky_profiles = pgTable("bsky_profiles", { 28 did: text("did").primaryKey().notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 29 record: jsonb("record").notNull(), 30 indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 31 handle: text("handle"), 32}); 33 34export const publications = pgTable("publications", { 35 uri: text("uri").primaryKey().notNull(), 36 indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 37 name: text("name").notNull(), 38 identity_did: text("identity_did").notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 39 record: jsonb("record"), 40}); 41 42export const bsky_posts = pgTable("bsky_posts", { 43 uri: text("uri").primaryKey().notNull(), 44 indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 45 post_view: jsonb("post_view").notNull(), 46 cid: text("cid").notNull(), 47}); 48 49export const comments_on_documents = pgTable("comments_on_documents", { 50 uri: text("uri").primaryKey().notNull(), 51 record: jsonb("record").notNull(), 52 document: text("document").references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ), 53 indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 54 profile: text("profile").references(() => bsky_profiles.did, { onDelete: "set null", onUpdate: "cascade" } ), 55}); 56 57export const facts = pgTable("facts", { 58 id: uuid("id").primaryKey().notNull(), 59 entity: uuid("entity").notNull().references(() => entities.id, { onDelete: "cascade", onUpdate: "restrict" } ), 60 attribute: text("attribute").notNull(), 61 data: jsonb("data").notNull(), 62 created_at: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(), 63 updated_at: timestamp("updated_at", { mode: 'string' }), 64 // You can use { mode: "bigint" } if numbers are exceeding js number limitations 65 version: bigint("version", { mode: "number" }).default(0).notNull(), 66}); 67 68export const documents = pgTable("documents", { 69 uri: text("uri").primaryKey().notNull(), 70 data: jsonb("data").notNull(), 71 indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 72}); 73 74export const replicache_clients = pgTable("replicache_clients", { 75 client_id: text("client_id").primaryKey().notNull(), 76 client_group: text("client_group").notNull(), 77 // You can use { mode: "bigint" } if numbers are exceeding js number limitations 78 last_mutation: bigint("last_mutation", { mode: "number" }).notNull(), 79}); 80 81export const entities = pgTable("entities", { 82 id: uuid("id").primaryKey().notNull(), 83 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 84 set: uuid("set").notNull().references(() => entity_sets.id, { onDelete: "cascade", onUpdate: "cascade" } ), 85}); 86 87export const entity_sets = pgTable("entity_sets", { 88 id: uuid("id").defaultRandom().primaryKey().notNull(), 89 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 90}); 91 92export const permission_tokens = pgTable("permission_tokens", { 93 id: uuid("id").defaultRandom().primaryKey().notNull(), 94 root_entity: uuid("root_entity").notNull().references(() => entities.id, { onDelete: "cascade", onUpdate: "cascade" } ), 95 blocked_by_admin: boolean("blocked_by_admin"), 96}); 97 98export const identities = pgTable("identities", { 99 id: uuid("id").defaultRandom().primaryKey().notNull(), 100 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 101 home_page: uuid("home_page").notNull().references(() => permission_tokens.id, { onDelete: "cascade" } ), 102 email: text("email"), 103 atp_did: text("atp_did"), 104 interface_state: jsonb("interface_state"), 105}, 106(table) => { 107 return { 108 identities_email_key: unique("identities_email_key").on(table.email), 109 identities_atp_did_key: unique("identities_atp_did_key").on(table.atp_did), 110 } 111}); 112 113export const email_subscriptions_to_entity = pgTable("email_subscriptions_to_entity", { 114 id: uuid("id").defaultRandom().primaryKey().notNull(), 115 entity: uuid("entity").notNull().references(() => entities.id, { onDelete: "cascade" } ), 116 email: text("email").notNull(), 117 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 118 token: uuid("token").notNull().references(() => permission_tokens.id, { onDelete: "cascade" } ), 119 confirmed: boolean("confirmed").default(false).notNull(), 120 confirmation_code: text("confirmation_code").notNull(), 121}); 122 123export const email_auth_tokens = pgTable("email_auth_tokens", { 124 id: uuid("id").defaultRandom().primaryKey().notNull(), 125 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 126 confirmed: boolean("confirmed").default(false).notNull(), 127 email: text("email"), 128 confirmation_code: text("confirmation_code").notNull(), 129 identity: uuid("identity").references(() => identities.id, { onDelete: "cascade", onUpdate: "cascade" } ), 130}); 131 132export const phone_number_auth_tokens = pgTable("phone_number_auth_tokens", { 133 id: uuid("id").defaultRandom().primaryKey().notNull(), 134 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 135 confirmed: boolean("confirmed").default(false).notNull(), 136 confirmation_code: text("confirmation_code").notNull(), 137 phone_number: text("phone_number").notNull(), 138 country_code: text("country_code").notNull(), 139}); 140 141export const custom_domains = pgTable("custom_domains", { 142 domain: text("domain").primaryKey().notNull(), 143 identity: text("identity").default('').references(() => identities.email, { onDelete: "cascade", onUpdate: "cascade" } ), 144 confirmed: boolean("confirmed").notNull(), 145 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 146 identity_id: uuid("identity_id").references(() => identities.id, { onDelete: "cascade" } ), 147}); 148 149export const phone_rsvps_to_entity = pgTable("phone_rsvps_to_entity", { 150 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 151 phone_number: text("phone_number").notNull(), 152 country_code: text("country_code").notNull(), 153 status: rsvp_status("status").notNull(), 154 id: uuid("id").defaultRandom().primaryKey().notNull(), 155 entity: uuid("entity").notNull().references(() => entities.id, { onDelete: "cascade", onUpdate: "cascade" } ), 156 name: text("name").default('').notNull(), 157 plus_ones: smallint("plus_ones").default(0).notNull(), 158}, 159(table) => { 160 return { 161 unique_phone_number_entities: uniqueIndex("unique_phone_number_entities").on(table.phone_number, table.entity), 162 } 163}); 164 165export const custom_domain_routes = pgTable("custom_domain_routes", { 166 id: uuid("id").defaultRandom().primaryKey().notNull(), 167 domain: text("domain").notNull().references(() => custom_domains.domain), 168 route: text("route").notNull(), 169 edit_permission_token: uuid("edit_permission_token").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ), 170 view_permission_token: uuid("view_permission_token").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ), 171 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 172}, 173(table) => { 174 return { 175 custom_domain_routes_domain_route_key: unique("custom_domain_routes_domain_route_key").on(table.domain, table.route), 176 } 177}); 178 179export const poll_votes_on_entity = pgTable("poll_votes_on_entity", { 180 id: uuid("id").defaultRandom().primaryKey().notNull(), 181 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 182 poll_entity: uuid("poll_entity").notNull().references(() => entities.id, { onDelete: "cascade", onUpdate: "cascade" } ), 183 option_entity: uuid("option_entity").notNull().references(() => entities.id, { onDelete: "cascade", onUpdate: "cascade" } ), 184 voter_token: uuid("voter_token").notNull(), 185}); 186 187export const subscribers_to_publications = pgTable("subscribers_to_publications", { 188 identity: text("identity").notNull().references(() => identities.email, { onUpdate: "cascade" } ), 189 publication: text("publication").notNull().references(() => publications.uri), 190 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 191}, 192(table) => { 193 return { 194 subscribers_to_publications_pkey: primaryKey({ columns: [table.identity, table.publication], name: "subscribers_to_publications_pkey"}), 195 } 196}); 197 198export const document_mentions_in_bsky = pgTable("document_mentions_in_bsky", { 199 uri: text("uri").notNull().references(() => bsky_posts.uri, { onDelete: "cascade" } ), 200 link: text("link").notNull(), 201 document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade" } ), 202}, 203(table) => { 204 return { 205 document_mentions_in_bsky_pkey: primaryKey({ columns: [table.uri, table.document], name: "document_mentions_in_bsky_pkey"}), 206 } 207}); 208 209export const permission_token_on_homepage = pgTable("permission_token_on_homepage", { 210 token: uuid("token").notNull().references(() => permission_tokens.id, { onDelete: "cascade" } ), 211 identity: uuid("identity").notNull().references(() => identities.id, { onDelete: "cascade" } ), 212 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 213}, 214(table) => { 215 return { 216 permission_token_creator_pkey: primaryKey({ columns: [table.token, table.identity], name: "permission_token_creator_pkey"}), 217 } 218}); 219 220export const documents_in_publications = pgTable("documents_in_publications", { 221 publication: text("publication").notNull().references(() => publications.uri, { onDelete: "cascade" } ), 222 document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade" } ), 223 indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 224}, 225(table) => { 226 return { 227 documents_in_publications_pkey: primaryKey({ columns: [table.publication, table.document], name: "documents_in_publications_pkey"}), 228 } 229}); 230 231export const publication_domains = pgTable("publication_domains", { 232 publication: text("publication").notNull().references(() => publications.uri, { onDelete: "cascade" } ), 233 domain: text("domain").notNull().references(() => custom_domains.domain, { onDelete: "cascade" } ), 234 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 235 identity: text("identity").notNull().references(() => identities.atp_did, { onDelete: "cascade", onUpdate: "cascade" } ), 236}, 237(table) => { 238 return { 239 publication_domains_pkey: primaryKey({ columns: [table.publication, table.domain], name: "publication_domains_pkey"}), 240 } 241}); 242 243export const publication_subscriptions = pgTable("publication_subscriptions", { 244 publication: text("publication").notNull().references(() => publications.uri, { onDelete: "cascade" } ), 245 identity: text("identity").notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 246 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 247 record: jsonb("record").notNull(), 248 uri: text("uri").notNull(), 249}, 250(table) => { 251 return { 252 publication_subscriptions_pkey: primaryKey({ columns: [table.publication, table.identity], name: "publication_subscriptions_pkey"}), 253 publication_subscriptions_uri_key: unique("publication_subscriptions_uri_key").on(table.uri), 254 } 255}); 256 257export const leaflets_in_publications = pgTable("leaflets_in_publications", { 258 publication: text("publication").notNull().references(() => publications.uri, { onDelete: "cascade" } ), 259 doc: text("doc").default('').references(() => documents.uri, { onDelete: "set null" } ), 260 leaflet: uuid("leaflet").notNull().references(() => permission_tokens.id, { onDelete: "cascade" } ), 261 description: text("description").default('').notNull(), 262 title: text("title").default('').notNull(), 263}, 264(table) => { 265 return { 266 leaflets_in_publications_pkey: primaryKey({ columns: [table.publication, table.leaflet], name: "leaflets_in_publications_pkey"}), 267 } 268}); 269 270export const permission_token_rights = pgTable("permission_token_rights", { 271 token: uuid("token").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ), 272 entity_set: uuid("entity_set").notNull().references(() => entity_sets.id, { onDelete: "cascade", onUpdate: "cascade" } ), 273 read: boolean("read").default(false).notNull(), 274 write: boolean("write").default(false).notNull(), 275 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 276 create_token: boolean("create_token").default(false).notNull(), 277 change_entity_set: boolean("change_entity_set").default(false).notNull(), 278}, 279(table) => { 280 return { 281 permission_token_rights_pkey: primaryKey({ columns: [table.token, table.entity_set], name: "permission_token_rights_pkey"}), 282 } 283});