From cbdf48a0599f16246e84851f5be924803decdd32 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Wed, 25 Feb 2026 18:54:07 -0500 Subject: [PATCH] add drizzle schema --- drizzle/relations.ts | 49 ++++++++++++---- drizzle/schema.ts | 135 +++++++++++++++++++++++++++---------------- 2 files changed, 124 insertions(+), 60 deletions(-) diff --git a/drizzle/relations.ts b/drizzle/relations.ts index c6db789a..87c4981e 100644 --- a/drizzle/relations.ts +++ b/drizzle/relations.ts @@ -1,5 +1,5 @@ import { relations } from "drizzle-orm/relations"; -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"; +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"; export const notificationsRelations = relations(notifications, ({one}) => ({ identity: one(identities, { @@ -12,7 +12,9 @@ export const identitiesRelations = relations(identities, ({one, many}) => ({ notifications: many(notifications), publications: many(publications), email_auth_tokens: many(email_auth_tokens), + recommends_on_documents: many(recommends_on_documents), bsky_profiles: many(bsky_profiles), + user_subscriptions: many(user_subscriptions), permission_token: one(permission_tokens, { fields: [identities.home_page], references: [permission_tokens.id] @@ -36,6 +38,7 @@ export const identitiesRelations = relations(identities, ({one, many}) => ({ publication_domains: many(publication_domains), publication_subscriptions: many(publication_subscriptions), site_standard_subscriptions: many(site_standard_subscriptions), + user_entitlements: many(user_entitlements), })); export const publicationsRelations = relations(publications, ({one, many}) => ({ @@ -63,6 +66,7 @@ export const comments_on_documentsRelations = relations(comments_on_documents, ( export const documentsRelations = relations(documents, ({many}) => ({ comments_on_documents: many(comments_on_documents), + recommends_on_documents: many(recommends_on_documents), documents_in_publications: many(documents_in_publications), document_mentions_in_bskies: many(document_mentions_in_bsky), leaflets_to_documents: many(leaflets_to_documents), @@ -113,6 +117,17 @@ export const email_auth_tokensRelations = relations(email_auth_tokens, ({one}) = }), })); +export const recommends_on_documentsRelations = relations(recommends_on_documents, ({one}) => ({ + document: one(documents, { + fields: [recommends_on_documents.document], + references: [documents.uri] + }), + identity: one(identities, { + fields: [recommends_on_documents.recommender_did], + references: [identities.atp_did] + }), +})); + export const poll_votes_on_entityRelations = relations(poll_votes_on_entity, ({one}) => ({ entity_option_entity: one(entities, { fields: [poll_votes_on_entity.option_entity], @@ -140,11 +155,18 @@ export const permission_tokensRelations = relations(permission_tokens, ({one, ma }), email_subscriptions_to_entities: many(email_subscriptions_to_entity), permission_token_on_homepages: many(permission_token_on_homepage), - leaflets_to_documents: many(leaflets_to_documents), permission_token_rights: many(permission_token_rights), + leaflets_to_documents: many(leaflets_to_documents), leaflets_in_publications: many(leaflets_in_publications), })); +export const user_subscriptionsRelations = relations(user_subscriptions, ({one}) => ({ + identity: one(identities, { + fields: [user_subscriptions.identity_id], + references: [identities.id] + }), +})); + export const phone_rsvps_to_entityRelations = relations(phone_rsvps_to_entity, ({one}) => ({ entity: one(entities, { fields: [phone_rsvps_to_entity.entity], @@ -332,14 +354,10 @@ export const site_standard_subscriptionsRelations = relations(site_standard_subs }), })); -export const leaflets_to_documentsRelations = relations(leaflets_to_documents, ({one}) => ({ - document: one(documents, { - fields: [leaflets_to_documents.document], - references: [documents.uri] - }), - permission_token: one(permission_tokens, { - fields: [leaflets_to_documents.leaflet], - references: [permission_tokens.id] +export const user_entitlementsRelations = relations(user_entitlements, ({one}) => ({ + identity: one(identities, { + fields: [user_entitlements.identity_id], + references: [identities.id] }), })); @@ -354,6 +372,17 @@ export const permission_token_rightsRelations = relations(permission_token_right }), })); +export const leaflets_to_documentsRelations = relations(leaflets_to_documents, ({one}) => ({ + document: one(documents, { + fields: [leaflets_to_documents.document], + references: [documents.uri] + }), + permission_token: one(permission_tokens, { + fields: [leaflets_to_documents.leaflet], + references: [permission_tokens.id] + }), +})); + export const leaflets_in_publicationsRelations = relations(leaflets_in_publications, ({one}) => ({ document: one(documents, { fields: [leaflets_in_publications.doc], diff --git a/drizzle/schema.ts b/drizzle/schema.ts index 62743d02..2f44c62c 100644 --- a/drizzle/schema.ts +++ b/drizzle/schema.ts @@ -1,4 +1,4 @@ -import { pgTable, pgEnum, text, jsonb, foreignKey, timestamp, boolean, uuid, index, bigint, unique, uniqueIndex, smallint, primaryKey, integer } from "drizzle-orm/pg-core" +import { pgTable, pgEnum, text, jsonb, foreignKey, timestamp, boolean, uuid, index, bigint, uniqueIndex, unique, smallint, integer, primaryKey } from "drizzle-orm/pg-core" import { sql } from "drizzle-orm" export const aal_level = pgEnum("aal_level", ['aal1', 'aal2', 'aal3']) @@ -50,6 +50,11 @@ export const comments_on_documents = pgTable("comments_on_documents", { document: text("document").references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ), indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), profile: text("profile").references(() => bsky_profiles.did, { onDelete: "set null", onUpdate: "cascade" } ), +}, +(table) => { + return { + document_idx: index("comments_on_documents_document_idx").on(table.document), + } }); export const entities = pgTable("entities", { @@ -107,6 +112,21 @@ export const bsky_posts = pgTable("bsky_posts", { cid: text("cid").notNull(), }); +export const recommends_on_documents = pgTable("recommends_on_documents", { + uri: text("uri").primaryKey().notNull(), + record: jsonb("record").notNull(), + document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ), + recommender_did: text("recommender_did").notNull().references(() => identities.atp_did, { onDelete: "cascade", onUpdate: "cascade" } ), + indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), +}, +(table) => { + return { + document_idx: index("recommends_on_documents_document_idx").on(table.document), + recommender_did_idx: index("recommends_on_documents_recommender_did_idx").on(table.recommender_did), + recommender_document_idx: uniqueIndex("recommends_on_documents_recommender_document_idx").on(table.document, table.recommender_did), + } +}); + export const bsky_profiles = pgTable("bsky_profiles", { did: text("did").primaryKey().notNull().references(() => identities.atp_did, { onDelete: "cascade" } ), record: jsonb("record").notNull(), @@ -133,6 +153,23 @@ export const permission_tokens = pgTable("permission_tokens", { blocked_by_admin: boolean("blocked_by_admin"), }); +export const user_subscriptions = pgTable("user_subscriptions", { + identity_id: uuid("identity_id").primaryKey().notNull().references(() => identities.id, { onDelete: "cascade" } ), + stripe_customer_id: text("stripe_customer_id").notNull(), + stripe_subscription_id: text("stripe_subscription_id"), + plan: text("plan"), + status: text("status"), + current_period_end: timestamp("current_period_end", { withTimezone: true, mode: 'string' }), + created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), + updated_at: timestamp("updated_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), +}, +(table) => { + return { + stripe_customer_id_key: uniqueIndex("user_subscriptions_stripe_customer_id_key").on(table.stripe_customer_id), + stripe_subscription_id_key: uniqueIndex("user_subscriptions_stripe_subscription_id_key").on(table.stripe_subscription_id), + } +}); + export const identities = pgTable("identities", { id: uuid("id").defaultRandom().primaryKey().notNull(), created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), @@ -221,13 +258,6 @@ export const email_subscriptions_to_entity = pgTable("email_subscriptions_to_ent confirmation_code: text("confirmation_code").notNull(), }); -export const documents = pgTable("documents", { - uri: text("uri").primaryKey().notNull(), - data: jsonb("data").notNull(), - indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), - bsky_like_count: integer("bsky_like_count").default(0).notNull(), -}); - export const atp_poll_votes = pgTable("atp_poll_votes", { uri: text("uri").primaryKey().notNull(), record: jsonb("record").notNull(), @@ -243,6 +273,23 @@ export const atp_poll_votes = pgTable("atp_poll_votes", { } }); +export const documents = pgTable("documents", { + uri: text("uri").primaryKey().notNull(), + data: jsonb("data").notNull(), + indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), + sort_date: timestamp("sort_date", { withTimezone: true, mode: 'string' }), + bsky_like_count: integer("bsky_like_count").default(0).notNull(), + recommend_count: integer("recommend_count").default(0).notNull(), + indexed: boolean("indexed").default(false).notNull(), +}, +(table) => { + return { + sort_date_idx: index("documents_sort_date_idx").on(table.uri, table.sort_date), + indexed_at_idx: index("documents_indexed_at_idx").on(table.indexed_at), + idx_documents_ranking: index("idx_documents_ranking").on(table.uri, table.sort_date, table.bsky_like_count, table.recommend_count), + } +}); + export const atp_poll_records = pgTable("atp_poll_records", { uri: text("uri").primaryKey().notNull(), cid: text("cid").notNull(), @@ -295,6 +342,7 @@ export const documents_in_publications = pgTable("documents_in_publications", { (table) => { return { publication_idx: index("documents_in_publications_publication_idx").on(table.publication), + document_idx: index("documents_in_publications_document_idx").on(table.document), documents_in_publications_pkey: primaryKey({ columns: [table.publication, table.document], name: "documents_in_publications_pkey"}), } }); @@ -307,6 +355,7 @@ export const document_mentions_in_bsky = pgTable("document_mentions_in_bsky", { }, (table) => { return { + document_idx: index("document_mentions_in_bsky_document_idx").on(table.document), document_mentions_in_bsky_pkey: primaryKey({ columns: [table.uri, table.document], name: "document_mentions_in_bsky_pkey"}), } }); @@ -365,18 +414,19 @@ export const site_standard_subscriptions = pgTable("site_standard_subscriptions" } }); -export const leaflets_to_documents = pgTable("leaflets_to_documents", { - leaflet: uuid("leaflet").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ), - document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ), - created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), - title: text("title").default('').notNull(), - description: text("description").default('').notNull(), - tags: text("tags").default('RRAY[').array(), - cover_image: text("cover_image"), +export const user_entitlements = pgTable("user_entitlements", { + identity_id: uuid("identity_id").notNull().references(() => identities.id, { onDelete: "cascade" } ), + entitlement_key: text("entitlement_key").notNull(), + granted_at: timestamp("granted_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), + expires_at: timestamp("expires_at", { withTimezone: true, mode: 'string' }), + source: text("source"), + metadata: jsonb("metadata"), }, (table) => { return { - leaflets_to_documents_pkey: primaryKey({ columns: [table.leaflet, table.document], name: "leaflets_to_documents_pkey"}), + identity_id_idx: index("user_entitlements_identity_id_idx").on(table.identity_id), + expires_at_idx: index("user_entitlements_expires_at_idx").on(table.expires_at), + user_entitlements_pkey: primaryKey({ columns: [table.identity_id, table.entitlement_key], name: "user_entitlements_pkey"}), } }); @@ -397,6 +447,22 @@ export const permission_token_rights = pgTable("permission_token_rights", { } }); +export const leaflets_to_documents = pgTable("leaflets_to_documents", { + leaflet: uuid("leaflet").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ), + document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ), + created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), + title: text("title").default('').notNull(), + description: text("description").default('').notNull(), + tags: text("tags").default('RRAY[').array(), + cover_image: text("cover_image"), + preferences: jsonb("preferences"), +}, +(table) => { + return { + leaflets_to_documents_pkey: primaryKey({ columns: [table.leaflet, table.document], name: "leaflets_to_documents_pkey"}), + } +}); + export const leaflets_in_publications = pgTable("leaflets_in_publications", { publication: text("publication").notNull().references(() => publications.uri, { onDelete: "cascade" } ), doc: text("doc").default('').references(() => documents.uri, { onDelete: "set null" } ), @@ -406,44 +472,13 @@ export const leaflets_in_publications = pgTable("leaflets_in_publications", { archived: boolean("archived"), tags: text("tags").default('RRAY[').array(), cover_image: text("cover_image"), + preferences: jsonb("preferences"), }, (table) => { return { leaflet_idx: index("leaflets_in_publications_leaflet_idx").on(table.leaflet), publication_idx: index("leaflets_in_publications_publication_idx").on(table.publication), + doc_idx: index("leaflets_in_publications_doc_idx").on(table.doc), leaflets_in_publications_pkey: primaryKey({ columns: [table.publication, table.leaflet], name: "leaflets_in_publications_pkey"}), } -}); - -export const user_subscriptions = pgTable("user_subscriptions", { - identity_id: uuid("identity_id").primaryKey().notNull().references(() => identities.id, { onDelete: "cascade" }), - stripe_customer_id: text("stripe_customer_id").notNull(), - stripe_subscription_id: text("stripe_subscription_id"), - plan: text("plan"), - status: text("status"), - current_period_end: timestamp("current_period_end", { withTimezone: true, mode: 'string' }), - created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), - updated_at: timestamp("updated_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), -}, -(table) => { - return { - user_subscriptions_stripe_customer_id_key: unique("user_subscriptions_stripe_customer_id_key").on(table.stripe_customer_id), - user_subscriptions_stripe_subscription_id_key: unique("user_subscriptions_stripe_subscription_id_key").on(table.stripe_subscription_id), - } -}); - -export const user_entitlements = pgTable("user_entitlements", { - identity_id: uuid("identity_id").notNull().references(() => identities.id, { onDelete: "cascade" }), - entitlement_key: text("entitlement_key").notNull(), - granted_at: timestamp("granted_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), - expires_at: timestamp("expires_at", { withTimezone: true, mode: 'string' }), - source: text("source"), - metadata: jsonb("metadata"), -}, -(table) => { - return { - identity_id_idx: index("user_entitlements_identity_id_idx").on(table.identity_id), - expires_at_idx: index("user_entitlements_expires_at_idx").on(table.expires_at), - user_entitlements_pkey: primaryKey({ columns: [table.identity_id, table.entitlement_key], name: "user_entitlements_pkey"}), - } }); \ No newline at end of file -- 2.51.2