Barazo AppView backend barazo.forum
at main 45 lines 1.9 kB view raw
1import { pgTable, text, timestamp, boolean, integer, index, jsonb } from 'drizzle-orm/pg-core' 2import { sql } from 'drizzle-orm' 3 4export const users = pgTable( 5 'users', 6 { 7 did: text('did').primaryKey(), 8 handle: text('handle').notNull(), 9 displayName: text('display_name'), 10 avatarUrl: text('avatar_url'), 11 bannerUrl: text('banner_url'), 12 bio: text('bio'), 13 role: text('role', { enum: ['user', 'moderator', 'admin'] }) 14 .notNull() 15 .default('user'), 16 isBanned: boolean('is_banned').notNull().default(false), 17 reputationScore: integer('reputation_score').notNull().default(0), 18 firstSeenAt: timestamp('first_seen_at', { withTimezone: true }).notNull().defaultNow(), 19 lastActiveAt: timestamp('last_active_at', { withTimezone: true }).notNull().defaultNow(), 20 declaredAge: integer('declared_age'), 21 maturityPref: text('maturity_pref', { 22 enum: ['safe', 'mature', 'adult'], 23 }) 24 .notNull() 25 .default('safe'), 26 /** Account creation date resolved from PLC directory on first encounter. */ 27 accountCreatedAt: timestamp('account_created_at', { withTimezone: true }), 28 followersCount: integer('followers_count').notNull().default(0), 29 followsCount: integer('follows_count').notNull().default(0), 30 atprotoPostsCount: integer('atproto_posts_count').notNull().default(0), 31 hasBlueskyProfile: boolean('has_bluesky_profile').notNull().default(false), 32 /** AT Protocol labels from the Bluesky AppView (self-applied and moderator-applied). */ 33 atprotoLabels: jsonb('atproto_labels') 34 .$type<Array<{ val: string; src: string; neg: boolean; cts: string }>>() 35 .notNull() 36 .default([]), 37 }, 38 (table) => [ 39 index('users_role_elevated_idx') 40 .on(table.role) 41 .where(sql`role IN ('moderator', 'admin')`), 42 index('users_handle_idx').on(table.handle), 43 index('users_account_created_at_idx').on(table.accountCreatedAt), 44 ] 45)