social bookmarking for atproto
1/*
2 * clippr: a social bookmarking service for the AT Protocol
3 * Copyright (c) 2025 clippr contributors.
4 * SPDX-License-Identifier: AGPL-3.0-only
5 */
6
7import { int, sqliteTable, text } from "drizzle-orm/sqlite-core";
8import { sql } from "drizzle-orm";
9import type { TagRef } from "../api/types.js";
10
11// WebStorm keeps throwing errors with the default statements as it wants
12// an actual SQLite query, despite being valid. Sucks.
13export const clipsTable = sqliteTable("clips", {
14 id: int("id").primaryKey({ autoIncrement: true }),
15 timestamp: int("time_us", { mode: "timestamp_ms" })
16 .notNull()
17 .default(sql`(unixepoch() * 1000)`),
18 did: text("did").notNull(),
19 recordKey: text("rkey").notNull(),
20 cid: text("cid").notNull(),
21 url: text("url").notNull(),
22 title: text("title").notNull(),
23 description: text("description").notNull(),
24 unlisted: int("unlisted", { mode: "boolean" }).notNull(),
25 notes: text("notes"),
26 tags: text("tags", { mode: "json" })
27 .$type<TagRef[]>()
28 .default(sql`'[]'`),
29 unread: int("unread", { mode: "boolean" }),
30 languages: text("languages", { mode: "json" })
31 .$type<string[]>()
32 .default(sql`'[]'`),
33 createdAt: int("createdAt", { mode: "timestamp_ms" })
34 .notNull()
35 .default(sql`(unixepoch() * 1000)`),
36 indexedAt: int("indexedAt", { mode: "timestamp_ms" })
37 .notNull()
38 .default(sql`(unixepoch() * 1000)`),
39});
40
41export const tagsTable = sqliteTable("tags", {
42 id: int("id").primaryKey({ autoIncrement: true }),
43 timestamp: int("time_us", { mode: "timestamp_ms" })
44 .notNull()
45 .default(sql`(unixepoch() * 1000)`),
46 did: text("did").notNull(),
47 recordKey: text("rkey").notNull(),
48 cid: text("cid").notNull(),
49 name: text("name").notNull(),
50 description: text("description"),
51 color: text("color"),
52 createdAt: int("createdAt", { mode: "timestamp_ms" })
53 .notNull()
54 .default(sql`(unixepoch() * 1000)`),
55 indexedAt: int("indexedAt", { mode: "timestamp_ms" })
56 .notNull()
57 .default(sql`(unixepoch() * 1000)`),
58});
59
60export const usersTable = sqliteTable("profiles", {
61 id: int("id").primaryKey({ autoIncrement: true }),
62 timestamp: int("time_us", { mode: "timestamp_ms" })
63 .notNull()
64 .default(sql`(unixepoch() * 1000)`),
65 did: text("did").notNull().unique(),
66 cid: text("cid").notNull(),
67 displayName: text("displayName").notNull(),
68 description: text("description"),
69 avatar: text("avatar"),
70 createdAt: int("createdAt", { mode: "timestamp_ms" })
71 .notNull()
72 .default(sql`(unixepoch() * 1000)`),
73});
74
75export const preferencesTable = sqliteTable("preferences", {
76 id: int("id").primaryKey({ autoIncrement: true }),
77 did: text("did").notNull().unique(),
78 handle: text("handle").notNull(),
79 publishingScopesPref: text("publishingScopesPref", { mode: "json" })
80 .$type<string[]>()
81 .default(sql`'[]'`),
82 lastModified: int("lastModified", { mode: "timestamp_ms" })
83 .notNull()
84 .default(sql`(unixepoch() * 1000)`),
85});