@contentgrowth/content-auth 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,167 @@
1
+ import { sqliteTable, text, integer, index, primaryKey } from "drizzle-orm/sqlite-core";
2
+ import { sql, relations } from "drizzle-orm";
3
+
4
+ // ==========================================
5
+ // @contentgrowth/content-auth - Drizzle Schema Template
6
+ // ==========================================
7
+ //
8
+ // USAGE:
9
+ // 1. Copy this file to your project's src/db/ folder
10
+ // 2. Add your application-specific tables after the auth tables
11
+ // 3. Run: npm run db:generate (to create migrations)
12
+ // 4. Run: npm run dev (to apply migrations)
13
+ //
14
+ // EXTENDING TABLES:
15
+ // You can add extra columns to any table for your business needs.
16
+ // Just ensure you keep ALL the columns defined here - they are required
17
+ // by Better Auth to function correctly.
18
+ //
19
+ // ==========================================
20
+
21
+ // ==========================================
22
+ // Core Authentication Tables
23
+ // ==========================================
24
+
25
+ /**
26
+ * Users - Core identity table
27
+ */
28
+ export const users = sqliteTable("users", {
29
+ id: text("id").primaryKey(),
30
+ name: text("name").notNull(),
31
+ email: text("email").notNull().unique(),
32
+ emailVerified: integer("emailVerified", { mode: "boolean" }).notNull(),
33
+ image: text("image"),
34
+ createdAt: integer("createdAt", { mode: "timestamp" }).notNull(),
35
+ updatedAt: integer("updatedAt", { mode: "timestamp" }).notNull(),
36
+ });
37
+
38
+ /**
39
+ * Sessions - Active user sessions
40
+ */
41
+ export const sessions = sqliteTable("sessions", {
42
+ id: text("id").primaryKey(),
43
+ expiresAt: integer("expiresAt", { mode: "timestamp" }).notNull(),
44
+ token: text("token").notNull().unique(),
45
+ createdAt: integer("createdAt", { mode: "timestamp" }).notNull(),
46
+ updatedAt: integer("updatedAt", { mode: "timestamp" }).notNull(),
47
+ ipAddress: text("ipAddress"),
48
+ userAgent: text("userAgent"),
49
+ userId: text("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
50
+ activeOrganizationId: text("activeOrganizationId"),
51
+ });
52
+
53
+ /**
54
+ * Accounts - OAuth/Credential providers
55
+ */
56
+ export const accounts = sqliteTable("accounts", {
57
+ id: text("id").primaryKey(),
58
+ accountId: text("accountId").notNull(),
59
+ providerId: text("providerId").notNull(),
60
+ userId: text("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
61
+ accessToken: text("accessToken"),
62
+ refreshToken: text("refreshToken"),
63
+ idToken: text("idToken"),
64
+ accessTokenExpiresAt: integer("accessTokenExpiresAt", { mode: "timestamp" }),
65
+ refreshTokenExpiresAt: integer("refreshTokenExpiresAt", { mode: "timestamp" }),
66
+ scope: text("scope"),
67
+ password: text("password"),
68
+ createdAt: integer("createdAt", { mode: "timestamp" }).notNull(),
69
+ updatedAt: integer("updatedAt", { mode: "timestamp" }).notNull(),
70
+ });
71
+
72
+ /**
73
+ * Verifications - Email/Token verification
74
+ */
75
+ export const verifications = sqliteTable("verifications", {
76
+ id: text("id").primaryKey(),
77
+ identifier: text("identifier").notNull(),
78
+ value: text("value").notNull(),
79
+ expiresAt: integer("expiresAt", { mode: "timestamp" }).notNull(),
80
+ createdAt: integer("createdAt", { mode: "timestamp" }),
81
+ updatedAt: integer("updatedAt", { mode: "timestamp" }),
82
+ });
83
+
84
+ // ==========================================
85
+ // Organizations Plugin Tables
86
+ // ==========================================
87
+
88
+ /**
89
+ * Organizations - Multi-tenant support
90
+ */
91
+ export const organizations = sqliteTable("organizations", {
92
+ id: text("id").primaryKey(),
93
+ name: text("name").notNull(),
94
+ slug: text("slug").unique(),
95
+ logo: text("logo"),
96
+ createdAt: integer("createdAt", { mode: "timestamp" }).notNull(),
97
+ metadata: text("metadata"), // JSON: { domain, is_verified, verification_source, etc. }
98
+ });
99
+
100
+ /**
101
+ * Members - Organization membership
102
+ */
103
+ export const members = sqliteTable("members", {
104
+ id: text("id").primaryKey(),
105
+ organizationId: text("organizationId").notNull().references(() => organizations.id, { onDelete: "cascade" }),
106
+ userId: text("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
107
+ role: text("role").notNull(), // 'owner', 'admin', 'member'
108
+ createdAt: integer("createdAt", { mode: "timestamp" }).notNull(),
109
+ });
110
+
111
+ /**
112
+ * Invitations - Pending org invitations
113
+ */
114
+ export const invitations = sqliteTable("invitations", {
115
+ id: text("id").primaryKey(),
116
+ organizationId: text("organizationId").notNull().references(() => organizations.id, { onDelete: "cascade" }),
117
+ email: text("email").notNull(),
118
+ role: text("role"),
119
+ status: text("status").notNull(), // 'pending', 'accepted', 'rejected', 'expired'
120
+ expiresAt: integer("expiresAt", { mode: "timestamp" }).notNull(),
121
+ inviterId: text("inviterId").notNull().references(() => users.id, { onDelete: "cascade" }),
122
+ });
123
+
124
+ // ==========================================
125
+ // Relations
126
+ // ==========================================
127
+
128
+ export const usersRelations = relations(users, ({ many }) => ({
129
+ sessions: many(sessions),
130
+ accounts: many(accounts),
131
+ members: many(members),
132
+ }));
133
+
134
+ export const sessionsRelations = relations(sessions, ({ one }) => ({
135
+ user: one(users, { fields: [sessions.userId], references: [users.id] }),
136
+ }));
137
+
138
+ export const accountsRelations = relations(accounts, ({ one }) => ({
139
+ user: one(users, { fields: [accounts.userId], references: [users.id] }),
140
+ }));
141
+
142
+ export const organizationsRelations = relations(organizations, ({ many }) => ({
143
+ members: many(members),
144
+ invitations: many(invitations),
145
+ }));
146
+
147
+ export const membersRelations = relations(members, ({ one }) => ({
148
+ organization: one(organizations, { fields: [members.organizationId], references: [organizations.id] }),
149
+ user: one(users, { fields: [members.userId], references: [users.id] }),
150
+ }));
151
+
152
+ export const invitationsRelations = relations(invitations, ({ one }) => ({
153
+ organization: one(organizations, { fields: [invitations.organizationId], references: [organizations.id] }),
154
+ inviter: one(users, { fields: [invitations.inviterId], references: [users.id] }),
155
+ }));
156
+
157
+ // ==========================================
158
+ // YOUR APPLICATION TABLES GO BELOW
159
+ // ==========================================
160
+ // Example:
161
+ //
162
+ // export const myEntity = sqliteTable("my_entity", {
163
+ // id: text("id").primaryKey(),
164
+ // orgId: text("org_id").notNull().references(() => organizations.id, { onDelete: "cascade" }),
165
+ // name: text("name").notNull(),
166
+ // createdAt: integer("created_at", { mode: "timestamp" }).default(sql`(strftime('%s', 'now'))`),
167
+ // });