a tool for shared writing and social publishing

add indexed_at to bsky mentions of documents

+219 -182
+96 -96
drizzle/relations.ts
··· 1 import { relations } from "drizzle-orm/relations"; 2 - import { identities, bsky_profiles, publications, documents, comments_on_documents, entities, facts, entity_sets, permission_tokens, email_subscriptions_to_entity, email_auth_tokens, custom_domains, phone_rsvps_to_entity, custom_domain_routes, poll_votes_on_entity, bsky_follows, subscribers_to_publications, document_mentions_in_bsky, bsky_posts, permission_token_on_homepage, documents_in_publications, publication_domains, publication_subscriptions, leaflets_in_publications, permission_token_rights } from "./schema"; 3 4 - export const bsky_profilesRelations = relations(bsky_profiles, ({one, many}) => ({ 5 identity: one(identities, { 6 - fields: [bsky_profiles.did], 7 references: [identities.atp_did] 8 }), 9 - comments_on_documents: many(comments_on_documents), 10 })); 11 12 export const identitiesRelations = relations(identities, ({one, many}) => ({ 13 bsky_profiles: many(bsky_profiles), 14 - publications: many(publications), 15 permission_token: one(permission_tokens, { 16 fields: [identities.home_page], 17 references: [permission_tokens.id] 18 }), 19 - email_auth_tokens: many(email_auth_tokens), 20 custom_domains_identity: many(custom_domains, { 21 relationName: "custom_domains_identity_identities_email" 22 }), ··· 35 publication_subscriptions: many(publication_subscriptions), 36 })); 37 38 - export const publicationsRelations = relations(publications, ({one, many}) => ({ 39 - identity: one(identities, { 40 - fields: [publications.identity_did], 41 - references: [identities.atp_did] 42 - }), 43 - subscribers_to_publications: many(subscribers_to_publications), 44 - documents_in_publications: many(documents_in_publications), 45 - publication_domains: many(publication_domains), 46 - publication_subscriptions: many(publication_subscriptions), 47 - leaflets_in_publications: many(leaflets_in_publications), 48 - })); 49 - 50 export const comments_on_documentsRelations = relations(comments_on_documents, ({one}) => ({ 51 document: one(documents, { 52 fields: [comments_on_documents.document], ··· 60 61 export const documentsRelations = relations(documents, ({many}) => ({ 62 comments_on_documents: many(comments_on_documents), 63 - document_mentions_in_bskies: many(document_mentions_in_bsky), 64 documents_in_publications: many(documents_in_publications), 65 leaflets_in_publications: many(leaflets_in_publications), 66 })); 67 68 - export const factsRelations = relations(facts, ({one}) => ({ 69 - entity: one(entities, { 70 - fields: [facts.entity], 71 - references: [entities.id] 72 }), 73 })); 74 75 export const entitiesRelations = relations(entities, ({one, many}) => ({ 76 - facts: many(facts), 77 entity_set: one(entity_sets, { 78 fields: [entities.set], 79 references: [entity_sets.id] 80 }), 81 - permission_tokens: many(permission_tokens), 82 - email_subscriptions_to_entities: many(email_subscriptions_to_entity), 83 - phone_rsvps_to_entities: many(phone_rsvps_to_entity), 84 poll_votes_on_entities_option_entity: many(poll_votes_on_entity, { 85 relationName: "poll_votes_on_entity_option_entity_entities_id" 86 }), 87 poll_votes_on_entities_poll_entity: many(poll_votes_on_entity, { 88 relationName: "poll_votes_on_entity_poll_entity_entities_id" 89 }), 90 })); 91 92 export const entity_setsRelations = relations(entity_sets, ({many}) => ({ ··· 94 permission_token_rights: many(permission_token_rights), 95 })); 96 97 export const permission_tokensRelations = relations(permission_tokens, ({one, many}) => ({ 98 entity: one(entities, { 99 fields: [permission_tokens.root_entity], 100 references: [entities.id] 101 }), 102 identities: many(identities), 103 - email_subscriptions_to_entities: many(email_subscriptions_to_entity), 104 custom_domain_routes_edit_permission_token: many(custom_domain_routes, { 105 relationName: "custom_domain_routes_edit_permission_token_permission_tokens_id" 106 }), 107 custom_domain_routes_view_permission_token: many(custom_domain_routes, { 108 relationName: "custom_domain_routes_view_permission_token_permission_tokens_id" 109 }), 110 permission_token_on_homepages: many(permission_token_on_homepage), 111 leaflets_in_publications: many(leaflets_in_publications), 112 permission_token_rights: many(permission_token_rights), 113 })); 114 115 - export const email_subscriptions_to_entityRelations = relations(email_subscriptions_to_entity, ({one}) => ({ 116 - entity: one(entities, { 117 - fields: [email_subscriptions_to_entity.entity], 118 - references: [entities.id] 119 - }), 120 - permission_token: one(permission_tokens, { 121 - fields: [email_subscriptions_to_entity.token], 122 - references: [permission_tokens.id] 123 - }), 124 - })); 125 - 126 - export const email_auth_tokensRelations = relations(email_auth_tokens, ({one}) => ({ 127 - identity: one(identities, { 128 - fields: [email_auth_tokens.identity], 129 - references: [identities.id] 130 - }), 131 - })); 132 - 133 - export const custom_domainsRelations = relations(custom_domains, ({one, many}) => ({ 134 - identity_identity: one(identities, { 135 - fields: [custom_domains.identity], 136 - references: [identities.email], 137 - relationName: "custom_domains_identity_identities_email" 138 - }), 139 - identity_identity_id: one(identities, { 140 - fields: [custom_domains.identity_id], 141 - references: [identities.id], 142 - relationName: "custom_domains_identity_id_identities_id" 143 - }), 144 - custom_domain_routes: many(custom_domain_routes), 145 - publication_domains: many(publication_domains), 146 - })); 147 - 148 export const phone_rsvps_to_entityRelations = relations(phone_rsvps_to_entity, ({one}) => ({ 149 entity: one(entities, { 150 fields: [phone_rsvps_to_entity.entity], ··· 169 }), 170 })); 171 172 - export const poll_votes_on_entityRelations = relations(poll_votes_on_entity, ({one}) => ({ 173 - entity_option_entity: one(entities, { 174 - fields: [poll_votes_on_entity.option_entity], 175 - references: [entities.id], 176 - relationName: "poll_votes_on_entity_option_entity_entities_id" 177 }), 178 - entity_poll_entity: one(entities, { 179 - fields: [poll_votes_on_entity.poll_entity], 180 - references: [entities.id], 181 - relationName: "poll_votes_on_entity_poll_entity_entities_id" 182 }), 183 })); 184 ··· 206 }), 207 })); 208 209 - export const document_mentions_in_bskyRelations = relations(document_mentions_in_bsky, ({one}) => ({ 210 - document: one(documents, { 211 - fields: [document_mentions_in_bsky.document], 212 - references: [documents.uri] 213 - }), 214 - bsky_post: one(bsky_posts, { 215 - fields: [document_mentions_in_bsky.uri], 216 - references: [bsky_posts.uri] 217 - }), 218 - })); 219 - 220 - export const bsky_postsRelations = relations(bsky_posts, ({many}) => ({ 221 - document_mentions_in_bskies: many(document_mentions_in_bsky), 222 - })); 223 - 224 export const permission_token_on_homepageRelations = relations(permission_token_on_homepage, ({one}) => ({ 225 identity: one(identities, { 226 fields: [permission_token_on_homepage.identity], ··· 243 }), 244 })); 245 246 export const publication_domainsRelations = relations(publication_domains, ({one}) => ({ 247 custom_domain: one(custom_domains, { 248 fields: [publication_domains.domain], ··· 258 }), 259 })); 260 261 - export const publication_subscriptionsRelations = relations(publication_subscriptions, ({one}) => ({ 262 - identity: one(identities, { 263 - fields: [publication_subscriptions.identity], 264 - references: [identities.atp_did] 265 - }), 266 - publication: one(publications, { 267 - fields: [publication_subscriptions.publication], 268 - references: [publications.uri] 269 - }), 270 - })); 271 - 272 export const leaflets_in_publicationsRelations = relations(leaflets_in_publications, ({one}) => ({ 273 document: one(documents, { 274 fields: [leaflets_in_publications.doc], ··· 280 }), 281 publication: one(publications, { 282 fields: [leaflets_in_publications.publication], 283 references: [publications.uri] 284 }), 285 }));
··· 1 import { relations } from "drizzle-orm/relations"; 2 + import { identities, publications, documents, comments_on_documents, bsky_profiles, entity_sets, entities, facts, email_auth_tokens, poll_votes_on_entity, permission_tokens, phone_rsvps_to_entity, custom_domains, custom_domain_routes, email_subscriptions_to_entity, bsky_follows, subscribers_to_publications, permission_token_on_homepage, documents_in_publications, document_mentions_in_bsky, bsky_posts, publication_domains, leaflets_in_publications, publication_subscriptions, permission_token_rights } from "./schema"; 3 4 + export const publicationsRelations = relations(publications, ({one, many}) => ({ 5 identity: one(identities, { 6 + fields: [publications.identity_did], 7 references: [identities.atp_did] 8 }), 9 + subscribers_to_publications: many(subscribers_to_publications), 10 + documents_in_publications: many(documents_in_publications), 11 + publication_domains: many(publication_domains), 12 + leaflets_in_publications: many(leaflets_in_publications), 13 + publication_subscriptions: many(publication_subscriptions), 14 })); 15 16 export const identitiesRelations = relations(identities, ({one, many}) => ({ 17 + publications: many(publications), 18 + email_auth_tokens: many(email_auth_tokens), 19 bsky_profiles: many(bsky_profiles), 20 permission_token: one(permission_tokens, { 21 fields: [identities.home_page], 22 references: [permission_tokens.id] 23 }), 24 custom_domains_identity: many(custom_domains, { 25 relationName: "custom_domains_identity_identities_email" 26 }), ··· 39 publication_subscriptions: many(publication_subscriptions), 40 })); 41 42 export const comments_on_documentsRelations = relations(comments_on_documents, ({one}) => ({ 43 document: one(documents, { 44 fields: [comments_on_documents.document], ··· 52 53 export const documentsRelations = relations(documents, ({many}) => ({ 54 comments_on_documents: many(comments_on_documents), 55 documents_in_publications: many(documents_in_publications), 56 + document_mentions_in_bskies: many(document_mentions_in_bsky), 57 leaflets_in_publications: many(leaflets_in_publications), 58 })); 59 60 + export const bsky_profilesRelations = relations(bsky_profiles, ({one, many}) => ({ 61 + comments_on_documents: many(comments_on_documents), 62 + identity: one(identities, { 63 + fields: [bsky_profiles.did], 64 + references: [identities.atp_did] 65 }), 66 })); 67 68 export const entitiesRelations = relations(entities, ({one, many}) => ({ 69 entity_set: one(entity_sets, { 70 fields: [entities.set], 71 references: [entity_sets.id] 72 }), 73 + facts: many(facts), 74 poll_votes_on_entities_option_entity: many(poll_votes_on_entity, { 75 relationName: "poll_votes_on_entity_option_entity_entities_id" 76 }), 77 poll_votes_on_entities_poll_entity: many(poll_votes_on_entity, { 78 relationName: "poll_votes_on_entity_poll_entity_entities_id" 79 }), 80 + permission_tokens: many(permission_tokens), 81 + phone_rsvps_to_entities: many(phone_rsvps_to_entity), 82 + email_subscriptions_to_entities: many(email_subscriptions_to_entity), 83 })); 84 85 export const entity_setsRelations = relations(entity_sets, ({many}) => ({ ··· 87 permission_token_rights: many(permission_token_rights), 88 })); 89 90 + export const factsRelations = relations(facts, ({one}) => ({ 91 + entity: one(entities, { 92 + fields: [facts.entity], 93 + references: [entities.id] 94 + }), 95 + })); 96 + 97 + export const email_auth_tokensRelations = relations(email_auth_tokens, ({one}) => ({ 98 + identity: one(identities, { 99 + fields: [email_auth_tokens.identity], 100 + references: [identities.id] 101 + }), 102 + })); 103 + 104 + export const poll_votes_on_entityRelations = relations(poll_votes_on_entity, ({one}) => ({ 105 + entity_option_entity: one(entities, { 106 + fields: [poll_votes_on_entity.option_entity], 107 + references: [entities.id], 108 + relationName: "poll_votes_on_entity_option_entity_entities_id" 109 + }), 110 + entity_poll_entity: one(entities, { 111 + fields: [poll_votes_on_entity.poll_entity], 112 + references: [entities.id], 113 + relationName: "poll_votes_on_entity_poll_entity_entities_id" 114 + }), 115 + })); 116 + 117 export const permission_tokensRelations = relations(permission_tokens, ({one, many}) => ({ 118 entity: one(entities, { 119 fields: [permission_tokens.root_entity], 120 references: [entities.id] 121 }), 122 identities: many(identities), 123 custom_domain_routes_edit_permission_token: many(custom_domain_routes, { 124 relationName: "custom_domain_routes_edit_permission_token_permission_tokens_id" 125 }), 126 custom_domain_routes_view_permission_token: many(custom_domain_routes, { 127 relationName: "custom_domain_routes_view_permission_token_permission_tokens_id" 128 }), 129 + email_subscriptions_to_entities: many(email_subscriptions_to_entity), 130 permission_token_on_homepages: many(permission_token_on_homepage), 131 leaflets_in_publications: many(leaflets_in_publications), 132 permission_token_rights: many(permission_token_rights), 133 })); 134 135 export const phone_rsvps_to_entityRelations = relations(phone_rsvps_to_entity, ({one}) => ({ 136 entity: one(entities, { 137 fields: [phone_rsvps_to_entity.entity], ··· 156 }), 157 })); 158 159 + export const custom_domainsRelations = relations(custom_domains, ({one, many}) => ({ 160 + custom_domain_routes: many(custom_domain_routes), 161 + identity_identity: one(identities, { 162 + fields: [custom_domains.identity], 163 + references: [identities.email], 164 + relationName: "custom_domains_identity_identities_email" 165 }), 166 + identity_identity_id: one(identities, { 167 + fields: [custom_domains.identity_id], 168 + references: [identities.id], 169 + relationName: "custom_domains_identity_id_identities_id" 170 + }), 171 + publication_domains: many(publication_domains), 172 + })); 173 + 174 + export const email_subscriptions_to_entityRelations = relations(email_subscriptions_to_entity, ({one}) => ({ 175 + entity: one(entities, { 176 + fields: [email_subscriptions_to_entity.entity], 177 + references: [entities.id] 178 + }), 179 + permission_token: one(permission_tokens, { 180 + fields: [email_subscriptions_to_entity.token], 181 + references: [permission_tokens.id] 182 }), 183 })); 184 ··· 206 }), 207 })); 208 209 export const permission_token_on_homepageRelations = relations(permission_token_on_homepage, ({one}) => ({ 210 identity: one(identities, { 211 fields: [permission_token_on_homepage.identity], ··· 228 }), 229 })); 230 231 + export const document_mentions_in_bskyRelations = relations(document_mentions_in_bsky, ({one}) => ({ 232 + document: one(documents, { 233 + fields: [document_mentions_in_bsky.document], 234 + references: [documents.uri] 235 + }), 236 + bsky_post: one(bsky_posts, { 237 + fields: [document_mentions_in_bsky.uri], 238 + references: [bsky_posts.uri] 239 + }), 240 + })); 241 + 242 + export const bsky_postsRelations = relations(bsky_posts, ({many}) => ({ 243 + document_mentions_in_bskies: many(document_mentions_in_bsky), 244 + })); 245 + 246 export const publication_domainsRelations = relations(publication_domains, ({one}) => ({ 247 custom_domain: one(custom_domains, { 248 fields: [publication_domains.domain], ··· 258 }), 259 })); 260 261 export const leaflets_in_publicationsRelations = relations(leaflets_in_publications, ({one}) => ({ 262 document: one(documents, { 263 fields: [leaflets_in_publications.doc], ··· 269 }), 270 publication: one(publications, { 271 fields: [leaflets_in_publications.publication], 272 + references: [publications.uri] 273 + }), 274 + })); 275 + 276 + export const publication_subscriptionsRelations = relations(publication_subscriptions, ({one}) => ({ 277 + identity: one(identities, { 278 + fields: [publication_subscriptions.identity], 279 + references: [identities.atp_did] 280 + }), 281 + publication: one(publications, { 282 + fields: [publication_subscriptions.publication], 283 references: [publications.uri] 284 }), 285 }));
+119 -86
drizzle/schema.ts
··· 1 - import { 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 4 export const aal_level = pgEnum("aal_level", ['aal1', 'aal2', 'aal3']) 5 export const code_challenge_method = pgEnum("code_challenge_method", ['s256', 'plain']) 6 export const factor_status = pgEnum("factor_status", ['unverified', 'verified']) 7 - export const factor_type = pgEnum("factor_type", ['totp', 'webauthn']) 8 export 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']) 9 - export const request_status = pgEnum("request_status", ['PENDING', 'SUCCESS', 'ERROR']) 10 export const key_status = pgEnum("key_status", ['default', 'valid', 'invalid', 'expired']) 11 export const key_type = pgEnum("key_type", ['aead-ietf', 'aead-det', 'hmacsha512', 'hmacsha256', 'auth', 'shorthash', 'generichash', 'kdf', 'secretbox', 'secretstream', 'stream_xchacha20']) 12 export const rsvp_status = pgEnum("rsvp_status", ['GOING', 'NOT_GOING', 'MAYBE']) 13 export const action = pgEnum("action", ['INSERT', 'UPDATE', 'DELETE', 'TRUNCATE', 'ERROR']) 14 export const equality_op = pgEnum("equality_op", ['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'in']) 15 16 17 export const oauth_state_store = pgTable("oauth_state_store", { ··· 19 state: jsonb("state").notNull(), 20 }); 21 22 - export const oauth_session_store = pgTable("oauth_session_store", { 23 - key: text("key").primaryKey().notNull(), 24 - session: jsonb("session").notNull(), 25 - }); 26 - 27 - export 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 - 34 export 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 - 42 - export 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 49 export const comments_on_documents = pgTable("comments_on_documents", { ··· 54 profile: text("profile").references(() => bsky_profiles.did, { onDelete: "set null", onUpdate: "cascade" } ), 55 }); 56 57 export const facts = pgTable("facts", { 58 id: uuid("id").primaryKey().notNull(), 59 entity: uuid("entity").notNull().references(() => entities.id, { onDelete: "cascade", onUpdate: "restrict" } ), ··· 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 - 68 - export 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 74 export const replicache_clients = pgTable("replicache_clients", { ··· 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 81 - export 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 87 export 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 92 export const permission_tokens = pgTable("permission_tokens", { ··· 110 } 111 }); 112 113 - export 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 - 123 - export 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 - 132 export 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(), ··· 136 confirmation_code: text("confirmation_code").notNull(), 137 phone_number: text("phone_number").notNull(), 138 country_code: text("country_code").notNull(), 139 - }); 140 - 141 - export 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 149 export const phone_rsvps_to_entity = pgTable("phone_rsvps_to_entity", { ··· 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 179 - export 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 187 export const bsky_follows = pgTable("bsky_follows", { 188 - identity: text("identity").default('').notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 189 follows: text("follows").notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 190 }, 191 (table) => { ··· 205 } 206 }); 207 208 - export const document_mentions_in_bsky = pgTable("document_mentions_in_bsky", { 209 - uri: text("uri").notNull().references(() => bsky_posts.uri, { onDelete: "cascade" } ), 210 - link: text("link").notNull(), 211 - document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade" } ), 212 - }, 213 - (table) => { 214 - return { 215 - document_mentions_in_bsky_pkey: primaryKey({ columns: [table.uri, table.document], name: "document_mentions_in_bsky_pkey"}), 216 - } 217 - }); 218 - 219 export const permission_token_on_homepage = pgTable("permission_token_on_homepage", { 220 token: uuid("token").notNull().references(() => permission_tokens.id, { onDelete: "cascade" } ), 221 identity: uuid("identity").notNull().references(() => identities.id, { onDelete: "cascade" } ), ··· 234 }, 235 (table) => { 236 return { 237 documents_in_publications_pkey: primaryKey({ columns: [table.publication, table.document], name: "documents_in_publications_pkey"}), 238 } 239 }); 240 241 - export const publication_domains = pgTable("publication_domains", { 242 - publication: text("publication").notNull().references(() => publications.uri, { onDelete: "cascade" } ), 243 - domain: text("domain").notNull().references(() => custom_domains.domain, { onDelete: "cascade" } ), 244 - created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 245 - identity: text("identity").notNull().references(() => identities.atp_did, { onDelete: "cascade", onUpdate: "cascade" } ), 246 }, 247 (table) => { 248 return { 249 - publication_domains_pkey: primaryKey({ columns: [table.publication, table.domain], name: "publication_domains_pkey"}), 250 } 251 }); 252 253 - export const publication_subscriptions = pgTable("publication_subscriptions", { 254 publication: text("publication").notNull().references(() => publications.uri, { onDelete: "cascade" } ), 255 - identity: text("identity").notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 256 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 257 - record: jsonb("record").notNull(), 258 - uri: text("uri").notNull(), 259 }, 260 (table) => { 261 return { 262 - publication_subscriptions_pkey: primaryKey({ columns: [table.publication, table.identity], name: "publication_subscriptions_pkey"}), 263 - publication_subscriptions_uri_key: unique("publication_subscriptions_uri_key").on(table.uri), 264 } 265 }); 266 ··· 273 }, 274 (table) => { 275 return { 276 leaflets_in_publications_pkey: primaryKey({ columns: [table.publication, table.leaflet], name: "leaflets_in_publications_pkey"}), 277 } 278 }); 279 280 export const permission_token_rights = pgTable("permission_token_rights", { 281 token: uuid("token").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ), 282 entity_set: uuid("entity_set").notNull().references(() => entity_sets.id, { onDelete: "cascade", onUpdate: "cascade" } ), ··· 288 }, 289 (table) => { 290 return { 291 permission_token_rights_pkey: primaryKey({ columns: [table.token, table.entity_set], name: "permission_token_rights_pkey"}), 292 } 293 });
··· 1 + import { pgTable, pgEnum, text, jsonb, index, foreignKey, timestamp, uuid, bigint, boolean, unique, uniqueIndex, smallint, primaryKey } from "drizzle-orm/pg-core" 2 import { sql } from "drizzle-orm" 3 4 export const aal_level = pgEnum("aal_level", ['aal1', 'aal2', 'aal3']) 5 export const code_challenge_method = pgEnum("code_challenge_method", ['s256', 'plain']) 6 export const factor_status = pgEnum("factor_status", ['unverified', 'verified']) 7 + export const factor_type = pgEnum("factor_type", ['totp', 'webauthn', 'phone']) 8 + export const oauth_authorization_status = pgEnum("oauth_authorization_status", ['pending', 'approved', 'denied', 'expired']) 9 + export const oauth_client_type = pgEnum("oauth_client_type", ['public', 'confidential']) 10 + export const oauth_registration_type = pgEnum("oauth_registration_type", ['dynamic', 'manual']) 11 + export const oauth_response_type = pgEnum("oauth_response_type", ['code']) 12 export 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']) 13 export const key_status = pgEnum("key_status", ['default', 'valid', 'invalid', 'expired']) 14 export const key_type = pgEnum("key_type", ['aead-ietf', 'aead-det', 'hmacsha512', 'hmacsha256', 'auth', 'shorthash', 'generichash', 'kdf', 'secretbox', 'secretstream', 'stream_xchacha20']) 15 export const rsvp_status = pgEnum("rsvp_status", ['GOING', 'NOT_GOING', 'MAYBE']) 16 export const action = pgEnum("action", ['INSERT', 'UPDATE', 'DELETE', 'TRUNCATE', 'ERROR']) 17 export const equality_op = pgEnum("equality_op", ['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'in']) 18 + export const buckettype = pgEnum("buckettype", ['STANDARD', 'ANALYTICS']) 19 20 21 export const oauth_state_store = pgTable("oauth_state_store", { ··· 23 state: jsonb("state").notNull(), 24 }); 25 26 export const publications = pgTable("publications", { 27 uri: text("uri").primaryKey().notNull(), 28 indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 29 name: text("name").notNull(), 30 identity_did: text("identity_did").notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 31 record: jsonb("record"), 32 + }, 33 + (table) => { 34 + return { 35 + identity_did_idx: index("publications_identity_did_idx").on(table.identity_did), 36 + } 37 }); 38 39 export const comments_on_documents = pgTable("comments_on_documents", { ··· 44 profile: text("profile").references(() => bsky_profiles.did, { onDelete: "set null", onUpdate: "cascade" } ), 45 }); 46 47 + export const entities = pgTable("entities", { 48 + id: uuid("id").primaryKey().notNull(), 49 + created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 50 + set: uuid("set").notNull().references(() => entity_sets.id, { onDelete: "cascade", onUpdate: "cascade" } ), 51 + }, 52 + (table) => { 53 + return { 54 + set_idx: index("entities_set_idx").on(table.set), 55 + } 56 + }); 57 + 58 export const facts = pgTable("facts", { 59 id: uuid("id").primaryKey().notNull(), 60 entity: uuid("entity").notNull().references(() => entities.id, { onDelete: "cascade", onUpdate: "restrict" } ), ··· 64 updated_at: timestamp("updated_at", { mode: 'string' }), 65 // You can use { mode: "bigint" } if numbers are exceeding js number limitations 66 version: bigint("version", { mode: "number" }).default(0).notNull(), 67 + }, 68 + (table) => { 69 + return { 70 + entity_idx: index("facts_entity_idx").on(table.entity), 71 + } 72 }); 73 74 export const replicache_clients = pgTable("replicache_clients", { ··· 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 + (table) => { 81 + return { 82 + client_group_idx: index("replicache_clients_client_group_idx").on(table.client_group), 83 + } 84 }); 85 86 + export const email_auth_tokens = pgTable("email_auth_tokens", { 87 + id: uuid("id").defaultRandom().primaryKey().notNull(), 88 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 89 + confirmed: boolean("confirmed").default(false).notNull(), 90 + email: text("email"), 91 + confirmation_code: text("confirmation_code").notNull(), 92 + identity: uuid("identity").references(() => identities.id, { onDelete: "cascade", onUpdate: "cascade" } ), 93 + }); 94 + 95 + export const bsky_posts = pgTable("bsky_posts", { 96 + uri: text("uri").primaryKey().notNull(), 97 + indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 98 + post_view: jsonb("post_view").notNull(), 99 + cid: text("cid").notNull(), 100 + }); 101 + 102 + export const bsky_profiles = pgTable("bsky_profiles", { 103 + did: text("did").primaryKey().notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 104 + record: jsonb("record").notNull(), 105 + indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 106 + handle: text("handle"), 107 }); 108 109 export const entity_sets = pgTable("entity_sets", { 110 id: uuid("id").defaultRandom().primaryKey().notNull(), 111 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 112 + }); 113 + 114 + export const poll_votes_on_entity = pgTable("poll_votes_on_entity", { 115 + id: uuid("id").defaultRandom().primaryKey().notNull(), 116 + created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 117 + poll_entity: uuid("poll_entity").notNull().references(() => entities.id, { onDelete: "cascade", onUpdate: "cascade" } ), 118 + option_entity: uuid("option_entity").notNull().references(() => entities.id, { onDelete: "cascade", onUpdate: "cascade" } ), 119 + voter_token: uuid("voter_token").notNull(), 120 }); 121 122 export const permission_tokens = pgTable("permission_tokens", { ··· 140 } 141 }); 142 143 export const phone_number_auth_tokens = pgTable("phone_number_auth_tokens", { 144 id: uuid("id").defaultRandom().primaryKey().notNull(), 145 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), ··· 147 confirmation_code: text("confirmation_code").notNull(), 148 phone_number: text("phone_number").notNull(), 149 country_code: text("country_code").notNull(), 150 }); 151 152 export const phone_rsvps_to_entity = pgTable("phone_rsvps_to_entity", { ··· 175 }, 176 (table) => { 177 return { 178 + edit_permission_token_idx: index("custom_domain_routes_edit_permission_token_idx").on(table.edit_permission_token), 179 custom_domain_routes_domain_route_key: unique("custom_domain_routes_domain_route_key").on(table.domain, table.route), 180 } 181 }); 182 183 + export const custom_domains = pgTable("custom_domains", { 184 + domain: text("domain").primaryKey().notNull(), 185 + identity: text("identity").default('').references(() => identities.email, { onDelete: "cascade", onUpdate: "cascade" } ), 186 + confirmed: boolean("confirmed").notNull(), 187 + created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 188 + identity_id: uuid("identity_id").references(() => identities.id, { onDelete: "cascade" } ), 189 + }); 190 + 191 + export const email_subscriptions_to_entity = pgTable("email_subscriptions_to_entity", { 192 id: uuid("id").defaultRandom().primaryKey().notNull(), 193 + entity: uuid("entity").notNull().references(() => entities.id, { onDelete: "cascade" } ), 194 + email: text("email").notNull(), 195 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 196 + token: uuid("token").notNull().references(() => permission_tokens.id, { onDelete: "cascade" } ), 197 + confirmed: boolean("confirmed").default(false).notNull(), 198 + confirmation_code: text("confirmation_code").notNull(), 199 + }); 200 + 201 + export const documents = pgTable("documents", { 202 + uri: text("uri").primaryKey().notNull(), 203 + data: jsonb("data").notNull(), 204 + indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 205 + }); 206 + 207 + export const oauth_session_store = pgTable("oauth_session_store", { 208 + key: text("key").primaryKey().notNull(), 209 + session: jsonb("session").notNull(), 210 }); 211 212 export const bsky_follows = pgTable("bsky_follows", { 213 + identity: text("identity").notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 214 follows: text("follows").notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 215 }, 216 (table) => { ··· 230 } 231 }); 232 233 export const permission_token_on_homepage = pgTable("permission_token_on_homepage", { 234 token: uuid("token").notNull().references(() => permission_tokens.id, { onDelete: "cascade" } ), 235 identity: uuid("identity").notNull().references(() => identities.id, { onDelete: "cascade" } ), ··· 248 }, 249 (table) => { 250 return { 251 + publication_idx: index("documents_in_publications_publication_idx").on(table.publication), 252 documents_in_publications_pkey: primaryKey({ columns: [table.publication, table.document], name: "documents_in_publications_pkey"}), 253 } 254 }); 255 256 + export const document_mentions_in_bsky = pgTable("document_mentions_in_bsky", { 257 + uri: text("uri").notNull().references(() => bsky_posts.uri, { onDelete: "cascade" } ), 258 + link: text("link").notNull(), 259 + document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade" } ), 260 + indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 261 }, 262 (table) => { 263 return { 264 + document_mentions_in_bsky_pkey: primaryKey({ columns: [table.uri, table.document], name: "document_mentions_in_bsky_pkey"}), 265 } 266 }); 267 268 + export const publication_domains = pgTable("publication_domains", { 269 publication: text("publication").notNull().references(() => publications.uri, { onDelete: "cascade" } ), 270 + domain: text("domain").notNull().references(() => custom_domains.domain, { onDelete: "cascade" } ), 271 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 272 + identity: text("identity").notNull().references(() => identities.atp_did, { onDelete: "cascade", onUpdate: "cascade" } ), 273 }, 274 (table) => { 275 return { 276 + publication_idx: index("publication_domains_publication_idx").on(table.publication), 277 + publication_domains_pkey: primaryKey({ columns: [table.publication, table.domain], name: "publication_domains_pkey"}), 278 } 279 }); 280 ··· 287 }, 288 (table) => { 289 return { 290 + leaflet_idx: index("leaflets_in_publications_leaflet_idx").on(table.leaflet), 291 + publication_idx: index("leaflets_in_publications_publication_idx").on(table.publication), 292 leaflets_in_publications_pkey: primaryKey({ columns: [table.publication, table.leaflet], name: "leaflets_in_publications_pkey"}), 293 } 294 }); 295 296 + export const publication_subscriptions = pgTable("publication_subscriptions", { 297 + publication: text("publication").notNull().references(() => publications.uri, { onDelete: "cascade" } ), 298 + identity: text("identity").notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 299 + created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 300 + record: jsonb("record").notNull(), 301 + uri: text("uri").notNull(), 302 + }, 303 + (table) => { 304 + return { 305 + publication_idx: index("publication_subscriptions_publication_idx").on(table.publication), 306 + publication_subscriptions_pkey: primaryKey({ columns: [table.publication, table.identity], name: "publication_subscriptions_pkey"}), 307 + publication_subscriptions_uri_key: unique("publication_subscriptions_uri_key").on(table.uri), 308 + } 309 + }); 310 + 311 export const permission_token_rights = pgTable("permission_token_rights", { 312 token: uuid("token").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ), 313 entity_set: uuid("entity_set").notNull().references(() => entity_sets.id, { onDelete: "cascade", onUpdate: "cascade" } ), ··· 319 }, 320 (table) => { 321 return { 322 + token_idx: index("permission_token_rights_token_idx").on(table.token), 323 + entity_set_idx: index("permission_token_rights_entity_set_idx").on(table.entity_set), 324 permission_token_rights_pkey: primaryKey({ columns: [table.token, table.entity_set], name: "permission_token_rights_pkey"}), 325 } 326 });
+3
supabase/database.types.ts
··· 244 document_mentions_in_bsky: { 245 Row: { 246 document: string 247 link: string 248 uri: string 249 } 250 Insert: { 251 document: string 252 link: string 253 uri: string 254 } 255 Update: { 256 document?: string 257 link?: string 258 uri?: string 259 }
··· 244 document_mentions_in_bsky: { 245 Row: { 246 document: string 247 + indexed_at: string 248 link: string 249 uri: string 250 } 251 Insert: { 252 document: string 253 + indexed_at?: string 254 link: string 255 uri: string 256 } 257 Update: { 258 document?: string 259 + indexed_at?: string 260 link?: string 261 uri?: string 262 }
+1
supabase/migrations/20251017160632_add_indexed_at_to_document_mentions_in_bsky.sql
···
··· 1 + alter table "public"."document_mentions_in_bsky" add column "indexed_at" timestamp with time zone not null default now();