a tool for shared writing and social publishing

add drizzle schema

+124 -60
+39 -10
drizzle/relations.ts
··· 1 1 import { relations } from "drizzle-orm/relations"; 2 - import { identities, notifications, publications, documents, comments_on_documents, bsky_profiles, entity_sets, entities, facts, email_auth_tokens, poll_votes_on_entity, permission_tokens, phone_rsvps_to_entity, site_standard_publications, custom_domains, custom_domain_routes, site_standard_documents, email_subscriptions_to_entity, atp_poll_records, atp_poll_votes, bsky_follows, subscribers_to_publications, site_standard_documents_in_publications, documents_in_publications, document_mentions_in_bsky, bsky_posts, permission_token_on_homepage, publication_domains, publication_subscriptions, site_standard_subscriptions, leaflets_to_documents, permission_token_rights, leaflets_in_publications } from "./schema"; 2 + import { identities, notifications, publications, documents, comments_on_documents, bsky_profiles, entity_sets, entities, facts, email_auth_tokens, recommends_on_documents, poll_votes_on_entity, permission_tokens, user_subscriptions, phone_rsvps_to_entity, site_standard_publications, custom_domains, custom_domain_routes, site_standard_documents, email_subscriptions_to_entity, atp_poll_records, atp_poll_votes, bsky_follows, subscribers_to_publications, site_standard_documents_in_publications, documents_in_publications, document_mentions_in_bsky, bsky_posts, permission_token_on_homepage, publication_domains, publication_subscriptions, site_standard_subscriptions, user_entitlements, permission_token_rights, leaflets_to_documents, leaflets_in_publications } from "./schema"; 3 3 4 4 export const notificationsRelations = relations(notifications, ({one}) => ({ 5 5 identity: one(identities, { ··· 12 12 notifications: many(notifications), 13 13 publications: many(publications), 14 14 email_auth_tokens: many(email_auth_tokens), 15 + recommends_on_documents: many(recommends_on_documents), 15 16 bsky_profiles: many(bsky_profiles), 17 + user_subscriptions: many(user_subscriptions), 16 18 permission_token: one(permission_tokens, { 17 19 fields: [identities.home_page], 18 20 references: [permission_tokens.id] ··· 36 38 publication_domains: many(publication_domains), 37 39 publication_subscriptions: many(publication_subscriptions), 38 40 site_standard_subscriptions: many(site_standard_subscriptions), 41 + user_entitlements: many(user_entitlements), 39 42 })); 40 43 41 44 export const publicationsRelations = relations(publications, ({one, many}) => ({ ··· 63 66 64 67 export const documentsRelations = relations(documents, ({many}) => ({ 65 68 comments_on_documents: many(comments_on_documents), 69 + recommends_on_documents: many(recommends_on_documents), 66 70 documents_in_publications: many(documents_in_publications), 67 71 document_mentions_in_bskies: many(document_mentions_in_bsky), 68 72 leaflets_to_documents: many(leaflets_to_documents), ··· 113 117 }), 114 118 })); 115 119 120 + export const recommends_on_documentsRelations = relations(recommends_on_documents, ({one}) => ({ 121 + document: one(documents, { 122 + fields: [recommends_on_documents.document], 123 + references: [documents.uri] 124 + }), 125 + identity: one(identities, { 126 + fields: [recommends_on_documents.recommender_did], 127 + references: [identities.atp_did] 128 + }), 129 + })); 130 + 116 131 export const poll_votes_on_entityRelations = relations(poll_votes_on_entity, ({one}) => ({ 117 132 entity_option_entity: one(entities, { 118 133 fields: [poll_votes_on_entity.option_entity], ··· 140 155 }), 141 156 email_subscriptions_to_entities: many(email_subscriptions_to_entity), 142 157 permission_token_on_homepages: many(permission_token_on_homepage), 143 - leaflets_to_documents: many(leaflets_to_documents), 144 158 permission_token_rights: many(permission_token_rights), 159 + leaflets_to_documents: many(leaflets_to_documents), 145 160 leaflets_in_publications: many(leaflets_in_publications), 146 161 })); 147 162 163 + export const user_subscriptionsRelations = relations(user_subscriptions, ({one}) => ({ 164 + identity: one(identities, { 165 + fields: [user_subscriptions.identity_id], 166 + references: [identities.id] 167 + }), 168 + })); 169 + 148 170 export const phone_rsvps_to_entityRelations = relations(phone_rsvps_to_entity, ({one}) => ({ 149 171 entity: one(entities, { 150 172 fields: [phone_rsvps_to_entity.entity], ··· 332 354 }), 333 355 })); 334 356 335 - export const leaflets_to_documentsRelations = relations(leaflets_to_documents, ({one}) => ({ 336 - document: one(documents, { 337 - fields: [leaflets_to_documents.document], 338 - references: [documents.uri] 339 - }), 340 - permission_token: one(permission_tokens, { 341 - fields: [leaflets_to_documents.leaflet], 342 - references: [permission_tokens.id] 357 + export const user_entitlementsRelations = relations(user_entitlements, ({one}) => ({ 358 + identity: one(identities, { 359 + fields: [user_entitlements.identity_id], 360 + references: [identities.id] 343 361 }), 344 362 })); 345 363 ··· 350 368 }), 351 369 permission_token: one(permission_tokens, { 352 370 fields: [permission_token_rights.token], 371 + references: [permission_tokens.id] 372 + }), 373 + })); 374 + 375 + export const leaflets_to_documentsRelations = relations(leaflets_to_documents, ({one}) => ({ 376 + document: one(documents, { 377 + fields: [leaflets_to_documents.document], 378 + references: [documents.uri] 379 + }), 380 + permission_token: one(permission_tokens, { 381 + fields: [leaflets_to_documents.leaflet], 353 382 references: [permission_tokens.id] 354 383 }), 355 384 }));
+85 -50
drizzle/schema.ts
··· 1 - import { pgTable, pgEnum, text, jsonb, foreignKey, timestamp, boolean, uuid, index, bigint, unique, uniqueIndex, smallint, primaryKey, integer } from "drizzle-orm/pg-core" 1 + import { pgTable, pgEnum, text, jsonb, foreignKey, timestamp, boolean, uuid, index, bigint, uniqueIndex, unique, smallint, integer, primaryKey } from "drizzle-orm/pg-core" 2 2 import { sql } from "drizzle-orm" 3 3 4 4 export const aal_level = pgEnum("aal_level", ['aal1', 'aal2', 'aal3']) ··· 50 50 document: text("document").references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ), 51 51 indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 52 52 profile: text("profile").references(() => bsky_profiles.did, { onDelete: "set null", onUpdate: "cascade" } ), 53 + }, 54 + (table) => { 55 + return { 56 + document_idx: index("comments_on_documents_document_idx").on(table.document), 57 + } 53 58 }); 54 59 55 60 export const entities = pgTable("entities", { ··· 107 112 cid: text("cid").notNull(), 108 113 }); 109 114 115 + export const recommends_on_documents = pgTable("recommends_on_documents", { 116 + uri: text("uri").primaryKey().notNull(), 117 + record: jsonb("record").notNull(), 118 + document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ), 119 + recommender_did: text("recommender_did").notNull().references(() => identities.atp_did, { onDelete: "cascade", onUpdate: "cascade" } ), 120 + indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 121 + }, 122 + (table) => { 123 + return { 124 + document_idx: index("recommends_on_documents_document_idx").on(table.document), 125 + recommender_did_idx: index("recommends_on_documents_recommender_did_idx").on(table.recommender_did), 126 + recommender_document_idx: uniqueIndex("recommends_on_documents_recommender_document_idx").on(table.document, table.recommender_did), 127 + } 128 + }); 129 + 110 130 export const bsky_profiles = pgTable("bsky_profiles", { 111 131 did: text("did").primaryKey().notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), 112 132 record: jsonb("record").notNull(), ··· 133 153 blocked_by_admin: boolean("blocked_by_admin"), 134 154 }); 135 155 156 + export const user_subscriptions = pgTable("user_subscriptions", { 157 + identity_id: uuid("identity_id").primaryKey().notNull().references(() => identities.id, { onDelete: "cascade" } ), 158 + stripe_customer_id: text("stripe_customer_id").notNull(), 159 + stripe_subscription_id: text("stripe_subscription_id"), 160 + plan: text("plan"), 161 + status: text("status"), 162 + current_period_end: timestamp("current_period_end", { withTimezone: true, mode: 'string' }), 163 + created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 164 + updated_at: timestamp("updated_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 165 + }, 166 + (table) => { 167 + return { 168 + stripe_customer_id_key: uniqueIndex("user_subscriptions_stripe_customer_id_key").on(table.stripe_customer_id), 169 + stripe_subscription_id_key: uniqueIndex("user_subscriptions_stripe_subscription_id_key").on(table.stripe_subscription_id), 170 + } 171 + }); 172 + 136 173 export const identities = pgTable("identities", { 137 174 id: uuid("id").defaultRandom().primaryKey().notNull(), 138 175 created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), ··· 221 258 confirmation_code: text("confirmation_code").notNull(), 222 259 }); 223 260 224 - export const documents = pgTable("documents", { 225 - uri: text("uri").primaryKey().notNull(), 226 - data: jsonb("data").notNull(), 227 - indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 228 - bsky_like_count: integer("bsky_like_count").default(0).notNull(), 229 - }); 230 - 231 261 export const atp_poll_votes = pgTable("atp_poll_votes", { 232 262 uri: text("uri").primaryKey().notNull(), 233 263 record: jsonb("record").notNull(), ··· 243 273 } 244 274 }); 245 275 276 + export const documents = pgTable("documents", { 277 + uri: text("uri").primaryKey().notNull(), 278 + data: jsonb("data").notNull(), 279 + indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 280 + sort_date: timestamp("sort_date", { withTimezone: true, mode: 'string' }), 281 + bsky_like_count: integer("bsky_like_count").default(0).notNull(), 282 + recommend_count: integer("recommend_count").default(0).notNull(), 283 + indexed: boolean("indexed").default(false).notNull(), 284 + }, 285 + (table) => { 286 + return { 287 + sort_date_idx: index("documents_sort_date_idx").on(table.uri, table.sort_date), 288 + indexed_at_idx: index("documents_indexed_at_idx").on(table.indexed_at), 289 + idx_documents_ranking: index("idx_documents_ranking").on(table.uri, table.sort_date, table.bsky_like_count, table.recommend_count), 290 + } 291 + }); 292 + 246 293 export const atp_poll_records = pgTable("atp_poll_records", { 247 294 uri: text("uri").primaryKey().notNull(), 248 295 cid: text("cid").notNull(), ··· 295 342 (table) => { 296 343 return { 297 344 publication_idx: index("documents_in_publications_publication_idx").on(table.publication), 345 + document_idx: index("documents_in_publications_document_idx").on(table.document), 298 346 documents_in_publications_pkey: primaryKey({ columns: [table.publication, table.document], name: "documents_in_publications_pkey"}), 299 347 } 300 348 }); ··· 307 355 }, 308 356 (table) => { 309 357 return { 358 + document_idx: index("document_mentions_in_bsky_document_idx").on(table.document), 310 359 document_mentions_in_bsky_pkey: primaryKey({ columns: [table.uri, table.document], name: "document_mentions_in_bsky_pkey"}), 311 360 } 312 361 }); ··· 365 414 } 366 415 }); 367 416 368 - export const leaflets_to_documents = pgTable("leaflets_to_documents", { 369 - leaflet: uuid("leaflet").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ), 370 - document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ), 371 - created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 372 - title: text("title").default('').notNull(), 373 - description: text("description").default('').notNull(), 374 - tags: text("tags").default('RRAY[').array(), 375 - cover_image: text("cover_image"), 417 + export const user_entitlements = pgTable("user_entitlements", { 418 + identity_id: uuid("identity_id").notNull().references(() => identities.id, { onDelete: "cascade" } ), 419 + entitlement_key: text("entitlement_key").notNull(), 420 + granted_at: timestamp("granted_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 421 + expires_at: timestamp("expires_at", { withTimezone: true, mode: 'string' }), 422 + source: text("source"), 423 + metadata: jsonb("metadata"), 376 424 }, 377 425 (table) => { 378 426 return { 379 - leaflets_to_documents_pkey: primaryKey({ columns: [table.leaflet, table.document], name: "leaflets_to_documents_pkey"}), 427 + identity_id_idx: index("user_entitlements_identity_id_idx").on(table.identity_id), 428 + expires_at_idx: index("user_entitlements_expires_at_idx").on(table.expires_at), 429 + user_entitlements_pkey: primaryKey({ columns: [table.identity_id, table.entitlement_key], name: "user_entitlements_pkey"}), 380 430 } 381 431 }); 382 432 ··· 397 447 } 398 448 }); 399 449 450 + export const leaflets_to_documents = pgTable("leaflets_to_documents", { 451 + leaflet: uuid("leaflet").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ), 452 + document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ), 453 + created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 454 + title: text("title").default('').notNull(), 455 + description: text("description").default('').notNull(), 456 + tags: text("tags").default('RRAY[').array(), 457 + cover_image: text("cover_image"), 458 + preferences: jsonb("preferences"), 459 + }, 460 + (table) => { 461 + return { 462 + leaflets_to_documents_pkey: primaryKey({ columns: [table.leaflet, table.document], name: "leaflets_to_documents_pkey"}), 463 + } 464 + }); 465 + 400 466 export const leaflets_in_publications = pgTable("leaflets_in_publications", { 401 467 publication: text("publication").notNull().references(() => publications.uri, { onDelete: "cascade" } ), 402 468 doc: text("doc").default('').references(() => documents.uri, { onDelete: "set null" } ), ··· 406 472 archived: boolean("archived"), 407 473 tags: text("tags").default('RRAY[').array(), 408 474 cover_image: text("cover_image"), 475 + preferences: jsonb("preferences"), 409 476 }, 410 477 (table) => { 411 478 return { 412 479 leaflet_idx: index("leaflets_in_publications_leaflet_idx").on(table.leaflet), 413 480 publication_idx: index("leaflets_in_publications_publication_idx").on(table.publication), 481 + doc_idx: index("leaflets_in_publications_doc_idx").on(table.doc), 414 482 leaflets_in_publications_pkey: primaryKey({ columns: [table.publication, table.leaflet], name: "leaflets_in_publications_pkey"}), 415 - } 416 - }); 417 - 418 - export const user_subscriptions = pgTable("user_subscriptions", { 419 - identity_id: uuid("identity_id").primaryKey().notNull().references(() => identities.id, { onDelete: "cascade" }), 420 - stripe_customer_id: text("stripe_customer_id").notNull(), 421 - stripe_subscription_id: text("stripe_subscription_id"), 422 - plan: text("plan"), 423 - status: text("status"), 424 - current_period_end: timestamp("current_period_end", { withTimezone: true, mode: 'string' }), 425 - created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 426 - updated_at: timestamp("updated_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 427 - }, 428 - (table) => { 429 - return { 430 - user_subscriptions_stripe_customer_id_key: unique("user_subscriptions_stripe_customer_id_key").on(table.stripe_customer_id), 431 - user_subscriptions_stripe_subscription_id_key: unique("user_subscriptions_stripe_subscription_id_key").on(table.stripe_subscription_id), 432 - } 433 - }); 434 - 435 - export const user_entitlements = pgTable("user_entitlements", { 436 - identity_id: uuid("identity_id").notNull().references(() => identities.id, { onDelete: "cascade" }), 437 - entitlement_key: text("entitlement_key").notNull(), 438 - granted_at: timestamp("granted_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), 439 - expires_at: timestamp("expires_at", { withTimezone: true, mode: 'string' }), 440 - source: text("source"), 441 - metadata: jsonb("metadata"), 442 - }, 443 - (table) => { 444 - return { 445 - identity_id_idx: index("user_entitlements_identity_id_idx").on(table.identity_id), 446 - expires_at_idx: index("user_entitlements_expires_at_idx").on(table.expires_at), 447 - user_entitlements_pkey: primaryKey({ columns: [table.identity_id, table.entitlement_key], name: "user_entitlements_pkey"}), 448 483 } 449 484 });