tangled
alpha
login
or
join now
leaflet.pub
/
leaflet
289
fork
atom
a tool for shared writing and social publishing
289
fork
atom
overview
issues
27
pulls
pipelines
add drizzle schema
awarm.space
2 weeks ago
cbdf48a0
5a6b1d4f
+124
-60
2 changed files
expand all
collapse all
unified
split
drizzle
relations.ts
schema.ts
+39
-10
drizzle/relations.ts
···
1
1
import { relations } from "drizzle-orm/relations";
2
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
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
15
+
recommends_on_documents: many(recommends_on_documents),
15
16
bsky_profiles: many(bsky_profiles),
17
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
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
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
120
+
export const recommends_on_documentsRelations = relations(recommends_on_documents, ({one}) => ({
121
121
+
document: one(documents, {
122
122
+
fields: [recommends_on_documents.document],
123
123
+
references: [documents.uri]
124
124
+
}),
125
125
+
identity: one(identities, {
126
126
+
fields: [recommends_on_documents.recommender_did],
127
127
+
references: [identities.atp_did]
128
128
+
}),
129
129
+
}));
130
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
143
-
leaflets_to_documents: many(leaflets_to_documents),
144
158
permission_token_rights: many(permission_token_rights),
159
159
+
leaflets_to_documents: many(leaflets_to_documents),
145
160
leaflets_in_publications: many(leaflets_in_publications),
146
161
}));
147
162
163
163
+
export const user_subscriptionsRelations = relations(user_subscriptions, ({one}) => ({
164
164
+
identity: one(identities, {
165
165
+
fields: [user_subscriptions.identity_id],
166
166
+
references: [identities.id]
167
167
+
}),
168
168
+
}));
169
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
335
-
export const leaflets_to_documentsRelations = relations(leaflets_to_documents, ({one}) => ({
336
336
-
document: one(documents, {
337
337
-
fields: [leaflets_to_documents.document],
338
338
-
references: [documents.uri]
339
339
-
}),
340
340
-
permission_token: one(permission_tokens, {
341
341
-
fields: [leaflets_to_documents.leaflet],
342
342
-
references: [permission_tokens.id]
357
357
+
export const user_entitlementsRelations = relations(user_entitlements, ({one}) => ({
358
358
+
identity: one(identities, {
359
359
+
fields: [user_entitlements.identity_id],
360
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
371
+
references: [permission_tokens.id]
372
372
+
}),
373
373
+
}));
374
374
+
375
375
+
export const leaflets_to_documentsRelations = relations(leaflets_to_documents, ({one}) => ({
376
376
+
document: one(documents, {
377
377
+
fields: [leaflets_to_documents.document],
378
378
+
references: [documents.uri]
379
379
+
}),
380
380
+
permission_token: one(permission_tokens, {
381
381
+
fields: [leaflets_to_documents.leaflet],
353
382
references: [permission_tokens.id]
354
383
}),
355
384
}));
+85
-50
drizzle/schema.ts
···
1
1
-
import { pgTable, pgEnum, text, jsonb, foreignKey, timestamp, boolean, uuid, index, bigint, unique, uniqueIndex, smallint, primaryKey, integer } from "drizzle-orm/pg-core"
1
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
53
+
},
54
54
+
(table) => {
55
55
+
return {
56
56
+
document_idx: index("comments_on_documents_document_idx").on(table.document),
57
57
+
}
53
58
});
54
59
55
60
export const entities = pgTable("entities", {
···
107
112
cid: text("cid").notNull(),
108
113
});
109
114
115
115
+
export const recommends_on_documents = pgTable("recommends_on_documents", {
116
116
+
uri: text("uri").primaryKey().notNull(),
117
117
+
record: jsonb("record").notNull(),
118
118
+
document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ),
119
119
+
recommender_did: text("recommender_did").notNull().references(() => identities.atp_did, { onDelete: "cascade", onUpdate: "cascade" } ),
120
120
+
indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
121
121
+
},
122
122
+
(table) => {
123
123
+
return {
124
124
+
document_idx: index("recommends_on_documents_document_idx").on(table.document),
125
125
+
recommender_did_idx: index("recommends_on_documents_recommender_did_idx").on(table.recommender_did),
126
126
+
recommender_document_idx: uniqueIndex("recommends_on_documents_recommender_document_idx").on(table.document, table.recommender_did),
127
127
+
}
128
128
+
});
129
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
156
+
export const user_subscriptions = pgTable("user_subscriptions", {
157
157
+
identity_id: uuid("identity_id").primaryKey().notNull().references(() => identities.id, { onDelete: "cascade" } ),
158
158
+
stripe_customer_id: text("stripe_customer_id").notNull(),
159
159
+
stripe_subscription_id: text("stripe_subscription_id"),
160
160
+
plan: text("plan"),
161
161
+
status: text("status"),
162
162
+
current_period_end: timestamp("current_period_end", { withTimezone: true, mode: 'string' }),
163
163
+
created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
164
164
+
updated_at: timestamp("updated_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
165
165
+
},
166
166
+
(table) => {
167
167
+
return {
168
168
+
stripe_customer_id_key: uniqueIndex("user_subscriptions_stripe_customer_id_key").on(table.stripe_customer_id),
169
169
+
stripe_subscription_id_key: uniqueIndex("user_subscriptions_stripe_subscription_id_key").on(table.stripe_subscription_id),
170
170
+
}
171
171
+
});
172
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
224
-
export const documents = pgTable("documents", {
225
225
-
uri: text("uri").primaryKey().notNull(),
226
226
-
data: jsonb("data").notNull(),
227
227
-
indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
228
228
-
bsky_like_count: integer("bsky_like_count").default(0).notNull(),
229
229
-
});
230
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
276
+
export const documents = pgTable("documents", {
277
277
+
uri: text("uri").primaryKey().notNull(),
278
278
+
data: jsonb("data").notNull(),
279
279
+
indexed_at: timestamp("indexed_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
280
280
+
sort_date: timestamp("sort_date", { withTimezone: true, mode: 'string' }),
281
281
+
bsky_like_count: integer("bsky_like_count").default(0).notNull(),
282
282
+
recommend_count: integer("recommend_count").default(0).notNull(),
283
283
+
indexed: boolean("indexed").default(false).notNull(),
284
284
+
},
285
285
+
(table) => {
286
286
+
return {
287
287
+
sort_date_idx: index("documents_sort_date_idx").on(table.uri, table.sort_date),
288
288
+
indexed_at_idx: index("documents_indexed_at_idx").on(table.indexed_at),
289
289
+
idx_documents_ranking: index("idx_documents_ranking").on(table.uri, table.sort_date, table.bsky_like_count, table.recommend_count),
290
290
+
}
291
291
+
});
292
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
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
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
368
-
export const leaflets_to_documents = pgTable("leaflets_to_documents", {
369
369
-
leaflet: uuid("leaflet").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ),
370
370
-
document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ),
371
371
-
created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
372
372
-
title: text("title").default('').notNull(),
373
373
-
description: text("description").default('').notNull(),
374
374
-
tags: text("tags").default('RRAY[').array(),
375
375
-
cover_image: text("cover_image"),
417
417
+
export const user_entitlements = pgTable("user_entitlements", {
418
418
+
identity_id: uuid("identity_id").notNull().references(() => identities.id, { onDelete: "cascade" } ),
419
419
+
entitlement_key: text("entitlement_key").notNull(),
420
420
+
granted_at: timestamp("granted_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
421
421
+
expires_at: timestamp("expires_at", { withTimezone: true, mode: 'string' }),
422
422
+
source: text("source"),
423
423
+
metadata: jsonb("metadata"),
376
424
},
377
425
(table) => {
378
426
return {
379
379
-
leaflets_to_documents_pkey: primaryKey({ columns: [table.leaflet, table.document], name: "leaflets_to_documents_pkey"}),
427
427
+
identity_id_idx: index("user_entitlements_identity_id_idx").on(table.identity_id),
428
428
+
expires_at_idx: index("user_entitlements_expires_at_idx").on(table.expires_at),
429
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
450
+
export const leaflets_to_documents = pgTable("leaflets_to_documents", {
451
451
+
leaflet: uuid("leaflet").notNull().references(() => permission_tokens.id, { onDelete: "cascade", onUpdate: "cascade" } ),
452
452
+
document: text("document").notNull().references(() => documents.uri, { onDelete: "cascade", onUpdate: "cascade" } ),
453
453
+
created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
454
454
+
title: text("title").default('').notNull(),
455
455
+
description: text("description").default('').notNull(),
456
456
+
tags: text("tags").default('RRAY[').array(),
457
457
+
cover_image: text("cover_image"),
458
458
+
preferences: jsonb("preferences"),
459
459
+
},
460
460
+
(table) => {
461
461
+
return {
462
462
+
leaflets_to_documents_pkey: primaryKey({ columns: [table.leaflet, table.document], name: "leaflets_to_documents_pkey"}),
463
463
+
}
464
464
+
});
465
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
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
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
415
-
}
416
416
-
});
417
417
-
418
418
-
export const user_subscriptions = pgTable("user_subscriptions", {
419
419
-
identity_id: uuid("identity_id").primaryKey().notNull().references(() => identities.id, { onDelete: "cascade" }),
420
420
-
stripe_customer_id: text("stripe_customer_id").notNull(),
421
421
-
stripe_subscription_id: text("stripe_subscription_id"),
422
422
-
plan: text("plan"),
423
423
-
status: text("status"),
424
424
-
current_period_end: timestamp("current_period_end", { withTimezone: true, mode: 'string' }),
425
425
-
created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
426
426
-
updated_at: timestamp("updated_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
427
427
-
},
428
428
-
(table) => {
429
429
-
return {
430
430
-
user_subscriptions_stripe_customer_id_key: unique("user_subscriptions_stripe_customer_id_key").on(table.stripe_customer_id),
431
431
-
user_subscriptions_stripe_subscription_id_key: unique("user_subscriptions_stripe_subscription_id_key").on(table.stripe_subscription_id),
432
432
-
}
433
433
-
});
434
434
-
435
435
-
export const user_entitlements = pgTable("user_entitlements", {
436
436
-
identity_id: uuid("identity_id").notNull().references(() => identities.id, { onDelete: "cascade" }),
437
437
-
entitlement_key: text("entitlement_key").notNull(),
438
438
-
granted_at: timestamp("granted_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
439
439
-
expires_at: timestamp("expires_at", { withTimezone: true, mode: 'string' }),
440
440
-
source: text("source"),
441
441
-
metadata: jsonb("metadata"),
442
442
-
},
443
443
-
(table) => {
444
444
-
return {
445
445
-
identity_id_idx: index("user_entitlements_identity_id_idx").on(table.identity_id),
446
446
-
expires_at_idx: index("user_entitlements_expires_at_idx").on(table.expires_at),
447
447
-
user_entitlements_pkey: primaryKey({ columns: [table.identity_id, table.entitlement_key], name: "user_entitlements_pkey"}),
448
483
}
449
484
});