@intelligo-dev/core 1.0.0-beta.1 → 1.0.0-beta.14
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.
- package/NOTICE +6 -0
- package/README.md +102 -0
- package/dist/attachments/errors.d.ts +7 -0
- package/dist/attachments/errors.d.ts.map +1 -0
- package/dist/attachments/errors.js +11 -0
- package/dist/attachments/errors.js.map +1 -0
- package/dist/attachments/index.d.ts +8 -0
- package/dist/attachments/index.d.ts.map +1 -0
- package/dist/attachments/index.js +7 -0
- package/dist/attachments/index.js.map +1 -0
- package/dist/attachments/service.d.ts +45 -0
- package/dist/attachments/service.d.ts.map +1 -0
- package/dist/attachments/service.js +100 -0
- package/dist/attachments/service.js.map +1 -0
- package/dist/attachments/types.d.ts +6 -0
- package/dist/attachments/types.d.ts.map +1 -0
- package/dist/attachments/types.js +2 -0
- package/dist/attachments/types.js.map +1 -0
- package/dist/conversations/errors.d.ts +2 -8
- package/dist/conversations/errors.d.ts.map +1 -1
- package/dist/conversations/errors.js +2 -8
- package/dist/conversations/errors.js.map +1 -1
- package/dist/conversations/index.d.ts +4 -12
- package/dist/conversations/index.d.ts.map +1 -1
- package/dist/conversations/index.js +2 -11
- package/dist/conversations/index.js.map +1 -1
- package/dist/conversations/service.d.ts +49 -61
- package/dist/conversations/service.d.ts.map +1 -1
- package/dist/conversations/service.js +110 -83
- package/dist/conversations/service.js.map +1 -1
- package/dist/conversations/types.d.ts +1 -4
- package/dist/conversations/types.d.ts.map +1 -1
- package/dist/conversations/types.js +0 -3
- package/dist/conversations/types.js.map +1 -1
- package/dist/db/client.d.ts +21 -10
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +43 -18
- package/dist/db/client.js.map +1 -1
- package/dist/db/index.d.ts +3 -3
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +3 -7
- package/dist/db/index.js.map +1 -1
- package/dist/db/schema/agents.d.ts +14 -51
- package/dist/db/schema/agents.d.ts.map +1 -1
- package/dist/db/schema/agents.js +9 -21
- package/dist/db/schema/agents.js.map +1 -1
- package/dist/db/schema/ai.d.ts +86 -1556
- package/dist/db/schema/ai.d.ts.map +1 -1
- package/dist/db/schema/ai.js +32 -236
- package/dist/db/schema/ai.js.map +1 -1
- package/dist/db/schema/auth.d.ts +5 -34
- package/dist/db/schema/auth.d.ts.map +1 -1
- package/dist/db/schema/auth.js +25 -56
- package/dist/db/schema/auth.js.map +1 -1
- package/dist/db/schema/billing.d.ts +339 -105
- package/dist/db/schema/billing.d.ts.map +1 -1
- package/dist/db/schema/billing.js +99 -58
- package/dist/db/schema/billing.js.map +1 -1
- package/dist/db/schema/feature-flags.d.ts +3 -12
- package/dist/db/schema/feature-flags.d.ts.map +1 -1
- package/dist/db/schema/feature-flags.js +3 -12
- package/dist/db/schema/feature-flags.js.map +1 -1
- package/dist/db/schema/identity.d.ts +12 -274
- package/dist/db/schema/identity.d.ts.map +1 -1
- package/dist/db/schema/identity.js +19 -104
- package/dist/db/schema/identity.js.map +1 -1
- package/dist/db/schema/index.d.ts +8 -15
- package/dist/db/schema/index.d.ts.map +1 -1
- package/dist/db/schema/index.js +12 -42
- package/dist/db/schema/index.js.map +1 -1
- package/dist/db/schema/notifications.d.ts +3 -17
- package/dist/db/schema/notifications.d.ts.map +1 -1
- package/dist/db/schema/notifications.js +3 -17
- package/dist/db/schema/notifications.js.map +1 -1
- package/dist/db/schema/usage.d.ts +94 -77
- package/dist/db/schema/usage.d.ts.map +1 -1
- package/dist/db/schema/usage.js +59 -89
- package/dist/db/schema/usage.js.map +1 -1
- package/dist/db/validate.d.ts +2 -11
- package/dist/db/validate.d.ts.map +1 -1
- package/dist/db/validate.js +6 -17
- package/dist/db/validate.js.map +1 -1
- package/dist/db/workspace-queries.d.ts +5 -29
- package/dist/db/workspace-queries.d.ts.map +1 -1
- package/dist/db/workspace-queries.js +5 -29
- package/dist/db/workspace-queries.js.map +1 -1
- package/dist/documents/classifier.d.ts +5 -12
- package/dist/documents/classifier.d.ts.map +1 -1
- package/dist/documents/classifier.js +16 -16
- package/dist/documents/classifier.js.map +1 -1
- package/dist/documents/errors.d.ts +2 -10
- package/dist/documents/errors.d.ts.map +1 -1
- package/dist/documents/errors.js +2 -10
- package/dist/documents/errors.js.map +1 -1
- package/dist/documents/index.d.ts +4 -13
- package/dist/documents/index.d.ts.map +1 -1
- package/dist/documents/index.js +3 -12
- package/dist/documents/index.js.map +1 -1
- package/dist/documents/service.d.ts +19 -26
- package/dist/documents/service.d.ts.map +1 -1
- package/dist/documents/service.js +44 -38
- package/dist/documents/service.js.map +1 -1
- package/dist/documents/types.d.ts +6 -10
- package/dist/documents/types.d.ts.map +1 -1
- package/dist/documents/types.js +0 -3
- package/dist/documents/types.js.map +1 -1
- package/dist/email/brand.d.ts +17 -0
- package/dist/email/brand.d.ts.map +1 -0
- package/dist/email/brand.js +9 -0
- package/dist/email/brand.js.map +1 -0
- package/dist/email/index.d.ts +4 -4
- package/dist/email/index.js +4 -4
- package/dist/email/provider.d.ts +1 -7
- package/dist/email/provider.d.ts.map +1 -1
- package/dist/email/provider.js +10 -19
- package/dist/email/provider.js.map +1 -1
- package/dist/email/send.d.ts +12 -12
- package/dist/email/send.d.ts.map +1 -1
- package/dist/email/send.js +5 -19
- package/dist/email/send.js.map +1 -1
- package/dist/email/senders.d.ts +17 -30
- package/dist/email/senders.d.ts.map +1 -1
- package/dist/email/senders.js +33 -47
- package/dist/email/senders.js.map +1 -1
- package/dist/email/templates/base-layout.d.ts +1 -1
- package/dist/email/templates/base-layout.d.ts.map +1 -1
- package/dist/email/templates/base-layout.js +4 -6
- package/dist/email/templates/base-layout.js.map +1 -1
- package/dist/email/templates/index.d.ts +10 -10
- package/dist/email/templates/index.d.ts.map +1 -1
- package/dist/email/templates/index.js +10 -16
- package/dist/email/templates/index.js.map +1 -1
- package/dist/email/templates/password-reset.d.ts +2 -2
- package/dist/email/templates/password-reset.d.ts.map +1 -1
- package/dist/email/templates/password-reset.js +10 -22
- package/dist/email/templates/password-reset.js.map +1 -1
- package/dist/email/templates/payment-failed.d.ts +2 -2
- package/dist/email/templates/payment-failed.d.ts.map +1 -1
- package/dist/email/templates/payment-failed.js +11 -24
- package/dist/email/templates/payment-failed.js.map +1 -1
- package/dist/email/templates/quota-warning.d.ts +4 -4
- package/dist/email/templates/quota-warning.d.ts.map +1 -1
- package/dist/email/templates/quota-warning.js +19 -39
- package/dist/email/templates/quota-warning.js.map +1 -1
- package/dist/email/templates/subscription-confirmed.d.ts +2 -2
- package/dist/email/templates/subscription-confirmed.d.ts.map +1 -1
- package/dist/email/templates/subscription-confirmed.js +13 -28
- package/dist/email/templates/subscription-confirmed.js.map +1 -1
- package/dist/email/templates/trial-expiry.d.ts +2 -2
- package/dist/email/templates/trial-expiry.d.ts.map +1 -1
- package/dist/email/templates/trial-expiry.js +12 -36
- package/dist/email/templates/trial-expiry.js.map +1 -1
- package/dist/email/templates/trial-warning.d.ts +2 -2
- package/dist/email/templates/trial-warning.d.ts.map +1 -1
- package/dist/email/templates/trial-warning.js +15 -32
- package/dist/email/templates/trial-warning.js.map +1 -1
- package/dist/email/templates/verify-email.d.ts +2 -2
- package/dist/email/templates/verify-email.d.ts.map +1 -1
- package/dist/email/templates/verify-email.js +10 -22
- package/dist/email/templates/verify-email.js.map +1 -1
- package/dist/email/templates/welcome.d.ts +2 -2
- package/dist/email/templates/welcome.d.ts.map +1 -1
- package/dist/email/templates/welcome.js +13 -20
- package/dist/email/templates/welcome.js.map +1 -1
- package/dist/email/templates/workspace-invitation.d.ts +2 -2
- package/dist/email/templates/workspace-invitation.d.ts.map +1 -1
- package/dist/email/templates/workspace-invitation.js +12 -26
- package/dist/email/templates/workspace-invitation.js.map +1 -1
- package/dist/env.d.ts +5 -10
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +41 -31
- package/dist/env.js.map +1 -1
- package/dist/identity/audit.d.ts +11 -24
- package/dist/identity/audit.d.ts.map +1 -1
- package/dist/identity/audit.js +13 -27
- package/dist/identity/audit.js.map +1 -1
- package/dist/identity/errors.d.ts +4 -12
- package/dist/identity/errors.d.ts.map +1 -1
- package/dist/identity/errors.js +2 -8
- package/dist/identity/errors.js.map +1 -1
- package/dist/identity/index.d.ts +6 -13
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/identity/index.js +5 -12
- package/dist/identity/index.js.map +1 -1
- package/dist/identity/service.d.ts +29 -47
- package/dist/identity/service.d.ts.map +1 -1
- package/dist/identity/service.js +107 -79
- package/dist/identity/service.js.map +1 -1
- package/dist/identity/types.d.ts +28 -4
- package/dist/identity/types.d.ts.map +1 -1
- package/dist/identity/types.js +0 -3
- package/dist/identity/types.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -10
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +7 -18
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +45 -49
- package/dist/logger.js.map +1 -1
- package/dist/money.d.ts +95 -0
- package/dist/money.d.ts.map +1 -0
- package/dist/money.js +208 -0
- package/dist/money.js.map +1 -0
- package/dist/notifications/index.d.ts +9 -43
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +9 -49
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/triggers.d.ts +9 -32
- package/dist/notifications/triggers.d.ts.map +1 -1
- package/dist/notifications/triggers.js +21 -58
- package/dist/notifications/triggers.js.map +1 -1
- package/dist/notifications/types.d.ts +6 -8
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/notifications/types.js +0 -9
- package/dist/notifications/types.js.map +1 -1
- package/dist/prompt.d.ts +38 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +118 -0
- package/dist/prompt.js.map +1 -0
- package/dist/registry.d.ts +32 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +60 -0
- package/dist/registry.js.map +1 -0
- package/dist/request-context.d.ts +49 -0
- package/dist/request-context.d.ts.map +1 -0
- package/dist/request-context.js +100 -0
- package/dist/request-context.js.map +1 -0
- package/dist/storage/index.d.ts +65 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +109 -0
- package/dist/storage/index.js.map +1 -0
- package/package.json +74 -24
- package/src/attachments/errors.ts +18 -0
- package/src/attachments/index.ts +22 -0
- package/src/attachments/service.ts +178 -0
- package/src/attachments/types.ts +6 -0
- package/src/conversations/errors.ts +45 -0
- package/src/conversations/index.ts +39 -0
- package/src/conversations/service.ts +594 -0
- package/src/conversations/types.ts +15 -0
- package/src/db/client.ts +91 -0
- package/src/db/index.ts +3 -0
- package/src/db/migrations/0000_baseline.sql +652 -0
- package/src/db/migrations/0001_reconcile_chain_built_databases.sql +53 -0
- package/src/db/migrations/0002_webhook_claim_lease.sql +1 -0
- package/src/db/migrations/0003_local_payments.sql +18 -0
- package/src/db/migrations/README.md +103 -36
- package/src/db/migrations/legacy-chain.json +206 -0
- package/src/db/migrations/meta/0000_snapshot.json +4182 -157
- package/src/db/migrations/meta/0002_snapshot.json +2478 -368
- package/src/db/migrations/meta/0003_snapshot.json +2567 -554
- package/src/db/migrations/meta/_journal.json +8 -274
- package/src/db/schema/agents.ts +57 -0
- package/src/db/schema/ai.ts +174 -0
- package/src/db/schema/auth.ts +183 -0
- package/src/db/schema/billing.ts +245 -0
- package/src/db/schema/feature-flags.ts +20 -0
- package/src/db/schema/identity.ts +250 -0
- package/src/db/schema/index.ts +12 -0
- package/src/db/schema/notifications.ts +31 -0
- package/src/db/schema/usage.ts +269 -0
- package/src/db/validate.ts +63 -0
- package/src/db/workspace-queries.ts +64 -0
- package/src/documents/classifier.ts +61 -0
- package/src/documents/errors.ts +44 -0
- package/src/documents/index.ts +24 -0
- package/src/documents/service.ts +256 -0
- package/src/documents/types.ts +24 -0
- package/src/email/brand.ts +24 -0
- package/src/email/index.ts +19 -0
- package/src/email/provider.ts +278 -0
- package/src/email/send.ts +169 -0
- package/src/email/senders.ts +292 -0
- package/src/email/templates/base-layout.tsx +145 -0
- package/src/email/templates/index.ts +28 -0
- package/src/email/templates/password-reset.tsx +72 -0
- package/src/email/templates/payment-failed.tsx +77 -0
- package/src/email/templates/quota-warning.tsx +118 -0
- package/src/email/templates/subscription-confirmed.tsx +91 -0
- package/src/email/templates/trial-expiry.tsx +124 -0
- package/src/email/templates/trial-warning.tsx +104 -0
- package/src/email/templates/verify-email.tsx +72 -0
- package/src/email/templates/welcome.tsx +64 -0
- package/src/email/templates/workspace-invitation.tsx +105 -0
- package/src/env.ts +180 -0
- package/src/identity/audit.ts +65 -0
- package/src/identity/errors.ts +44 -0
- package/src/identity/index.ts +29 -0
- package/src/identity/service.ts +303 -0
- package/src/identity/types.ts +58 -0
- package/src/index.ts +4 -0
- package/src/logger.ts +198 -0
- package/src/money.ts +270 -0
- package/src/notifications/index.ts +112 -0
- package/src/notifications/triggers.ts +158 -0
- package/src/notifications/types.ts +26 -0
- package/src/prompt.ts +142 -0
- package/src/registry.ts +75 -0
- package/src/request-context.ts +137 -0
- package/src/storage/index.ts +153 -0
- package/dist/db/schema/rag.d.ts +0 -171
- package/dist/db/schema/rag.d.ts.map +0 -1
- package/dist/db/schema/rag.js +0 -42
- package/dist/db/schema/rag.js.map +0 -1
- package/src/db/migrations/0000_sharp_night_nurse.sql +0 -52
- package/src/db/migrations/0001_hesitant_vapor.sql +0 -40
- package/src/db/migrations/0002_numerous_lady_vermin.sql +0 -235
- package/src/db/migrations/0003_mighty_jean_grey.sql +0 -37
- package/src/db/migrations/0004_cynical_grandmaster.sql +0 -2
- package/src/db/migrations/0005_careful_switch.sql +0 -8
- package/src/db/migrations/0006_tense_blue_marvel.sql +0 -16
- package/src/db/migrations/0007_next_squadron_sinister.sql +0 -1
- package/src/db/migrations/0008_powerful_scream.sql +0 -39
- package/src/db/migrations/0009_sad_ink.sql +0 -1
- package/src/db/migrations/0010_shocking_omega_flight.sql +0 -2
- package/src/db/migrations/0011_ambiguous_otto_octavius.sql +0 -151
- package/src/db/migrations/0011_hnsw_vector_index.sql +0 -17
- package/src/db/migrations/0012_user_profiles.sql +0 -30
- package/src/db/migrations/0013_trending_seasonal_columns.sql +0 -9
- package/src/db/migrations/0014_add_product_type_to_agents.sql +0 -6
- package/src/db/migrations/0015_new_v1_tables.sql +0 -149
- package/src/db/migrations/0016_document_types.sql +0 -30
- package/src/db/migrations/0017_document_metadata.sql +0 -2
- package/src/db/migrations/0018_identity_graph.sql +0 -200
- package/src/db/migrations/0019_db_driven_prompts.sql +0 -20
- package/src/db/migrations/0020_pending_extractions.sql +0 -35
- package/src/db/migrations/0021_rag_documents.sql +0 -39
- package/src/db/migrations/0022_user_quotas_usage_jsonb.sql +0 -70
- package/src/db/migrations/0023_user_facts_user_scoped_unique.sql +0 -17
- package/src/db/migrations/0024_user_memories_hnsw.sql +0 -23
- package/src/db/migrations/0025_audit_trigger_errcode.sql +0 -21
- package/src/db/migrations/0026_user_profile_snapshots_composite_pk.sql +0 -17
- package/src/db/migrations/0027_billing_settings_mnt_columns.sql +0 -54
- package/src/db/migrations/0028_trial_credits_normalized_email.sql +0 -37
- package/src/db/migrations/0029_usage_records_conversation_idx.sql +0 -13
- package/src/db/migrations/0030_pending_extractions_composite_idx.sql +0 -11
- package/src/db/migrations/0031_rag_documents_hnsw.sql +0 -16
- package/src/db/migrations/0032_rate_limit_unique_idx.sql +0 -16
- package/src/db/migrations/0033_pending_extractions_partial_idx.sql +0 -18
- package/src/db/migrations/0034_rate_limit_count.sql +0 -9
- package/src/db/migrations/0035_credit_reservations.sql +0 -24
- package/src/db/migrations/0036_executions_audit_jobs.sql +0 -96
- package/src/db/migrations/0037_rate_limit_minute_bucket.sql +0 -46
- package/src/db/migrations/0038_user_quotas_generic_usage.sql +0 -25
- package/src/db/migrations/0039_platform_admin_impersonation.sql +0 -27
- package/src/db/migrations/0040_ee_audit_chain.sql +0 -23
- package/src/db/migrations/meta/0001_snapshot.json +0 -631
- package/src/db/migrations/meta/0004_snapshot.json +0 -2500
- package/src/db/migrations/meta/0005_snapshot.json +0 -2548
- package/src/db/migrations/meta/0006_snapshot.json +0 -2650
- package/src/db/migrations/meta/0007_snapshot.json +0 -2657
- package/src/db/migrations/meta/0008_snapshot.json +0 -2719
- package/src/db/migrations/meta/0009_snapshot.json +0 -2726
- package/src/db/migrations/meta/0010_snapshot.json +0 -2739
- package/src/db/migrations/meta/0011_snapshot.json +0 -3886
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Better-Auth's tables. Table and column names must match what its Drizzle
|
|
3
|
+
* adapter expects.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { sql } from "drizzle-orm";
|
|
7
|
+
import {
|
|
8
|
+
pgTable,
|
|
9
|
+
text,
|
|
10
|
+
timestamp,
|
|
11
|
+
boolean,
|
|
12
|
+
index,
|
|
13
|
+
uniqueIndex,
|
|
14
|
+
} from "drizzle-orm/pg-core";
|
|
15
|
+
|
|
16
|
+
export const users = pgTable(
|
|
17
|
+
"users",
|
|
18
|
+
{
|
|
19
|
+
id: text("id").primaryKey(),
|
|
20
|
+
name: text("name").notNull(),
|
|
21
|
+
email: text("email").notNull().unique(),
|
|
22
|
+
emailVerified: boolean("email_verified").notNull().default(false),
|
|
23
|
+
image: text("image"),
|
|
24
|
+
deletedAt: timestamp("deleted_at"), // Soft delete: null = active, timestamp = deleted
|
|
25
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
26
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
27
|
+
onboardingCompleted: boolean("onboarding_completed")
|
|
28
|
+
.notNull()
|
|
29
|
+
.default(false),
|
|
30
|
+
onboardingStep: text("onboarding_step"), // Current step if incomplete: "workspace" | "language" | "product"
|
|
31
|
+
preferredLanguage: text("preferred_language").notNull().default("en"), // a locale the app ships, e.g. "en"
|
|
32
|
+
/**
|
|
33
|
+
* Platform role, not a workspace role — "platform-admin" or null. Grants
|
|
34
|
+
* the operational console and impersonation. PLATFORM_ADMIN_EMAILS seeds
|
|
35
|
+
* it: requirePlatformAdmin promotes an allowlisted user on first use.
|
|
36
|
+
*/
|
|
37
|
+
role: text("role"),
|
|
38
|
+
/** Required by Better-Auth's admin plugin schema; unused otherwise. */
|
|
39
|
+
banned: boolean("banned").notNull().default(false),
|
|
40
|
+
banReason: text("ban_reason"),
|
|
41
|
+
banExpires: timestamp("ban_expires"),
|
|
42
|
+
},
|
|
43
|
+
(table) => [
|
|
44
|
+
// Finding the platform admins: a handful of rows among many.
|
|
45
|
+
index("users_role_idx")
|
|
46
|
+
.on(table.role)
|
|
47
|
+
.where(sql`${table.role} IS NOT NULL`),
|
|
48
|
+
]
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
export const sessions = pgTable(
|
|
52
|
+
"sessions",
|
|
53
|
+
{
|
|
54
|
+
id: text("id").primaryKey(),
|
|
55
|
+
userId: text("user_id")
|
|
56
|
+
.notNull()
|
|
57
|
+
.references(() => users.id, { onDelete: "cascade" }),
|
|
58
|
+
token: text("token").notNull().unique(),
|
|
59
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
60
|
+
ipAddress: text("ip_address"),
|
|
61
|
+
userAgent: text("user_agent"),
|
|
62
|
+
/**
|
|
63
|
+
* Set on a session created by an admin acting as this user, so
|
|
64
|
+
* impersonation stays visible on the session and in the audit trail.
|
|
65
|
+
*/
|
|
66
|
+
impersonatedBy: text("impersonated_by"),
|
|
67
|
+
/**
|
|
68
|
+
* The organization plugin's active workspace. Without this column its
|
|
69
|
+
* set-active writes are silently dropped and workspace switching never
|
|
70
|
+
* persists.
|
|
71
|
+
*/
|
|
72
|
+
activeOrganizationId: text("active_organization_id"),
|
|
73
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
74
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
75
|
+
},
|
|
76
|
+
(table) => [index("sessions_user_id_idx").on(table.userId)]
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
/** OAuth provider connections and password credentials. */
|
|
80
|
+
export const accounts = pgTable(
|
|
81
|
+
"accounts",
|
|
82
|
+
{
|
|
83
|
+
id: text("id").primaryKey(),
|
|
84
|
+
userId: text("user_id")
|
|
85
|
+
.notNull()
|
|
86
|
+
.references(() => users.id, { onDelete: "cascade" }),
|
|
87
|
+
accountId: text("account_id").notNull(),
|
|
88
|
+
providerId: text("provider_id").notNull(),
|
|
89
|
+
accessToken: text("access_token"),
|
|
90
|
+
refreshToken: text("refresh_token"),
|
|
91
|
+
accessTokenExpiresAt: timestamp("access_token_expires_at"),
|
|
92
|
+
refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
|
|
93
|
+
scope: text("scope"),
|
|
94
|
+
idToken: text("id_token"),
|
|
95
|
+
password: text("password"),
|
|
96
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
97
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
98
|
+
},
|
|
99
|
+
(table) => [index("accounts_user_id_idx").on(table.userId)]
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
/** Email verification and password reset tokens. */
|
|
103
|
+
export const verifications = pgTable("verifications", {
|
|
104
|
+
id: text("id").primaryKey(),
|
|
105
|
+
identifier: text("identifier").notNull(),
|
|
106
|
+
value: text("value").notNull(),
|
|
107
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
108
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
109
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
/** Workspaces, managed by Better-Auth's organization plugin. */
|
|
113
|
+
export const organization = pgTable("organization", {
|
|
114
|
+
id: text("id").primaryKey(),
|
|
115
|
+
name: text("name").notNull(),
|
|
116
|
+
slug: text("slug").unique(),
|
|
117
|
+
logo: text("logo"),
|
|
118
|
+
metadata: text("metadata"),
|
|
119
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
120
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
export const member = pgTable(
|
|
124
|
+
"member",
|
|
125
|
+
{
|
|
126
|
+
id: text("id").primaryKey(),
|
|
127
|
+
organizationId: text("organization_id")
|
|
128
|
+
.notNull()
|
|
129
|
+
.references(() => organization.id, { onDelete: "cascade" }),
|
|
130
|
+
userId: text("user_id")
|
|
131
|
+
.notNull()
|
|
132
|
+
.references(() => users.id, { onDelete: "cascade" }),
|
|
133
|
+
role: text("role").notNull(),
|
|
134
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
135
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
136
|
+
},
|
|
137
|
+
(table) => [
|
|
138
|
+
index("member_organization_id_idx").on(table.organizationId),
|
|
139
|
+
index("member_user_id_idx").on(table.userId),
|
|
140
|
+
uniqueIndex("member_organization_user_uniq").on(
|
|
141
|
+
table.organizationId,
|
|
142
|
+
table.userId
|
|
143
|
+
),
|
|
144
|
+
]
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
export const invitation = pgTable(
|
|
148
|
+
"invitation",
|
|
149
|
+
{
|
|
150
|
+
id: text("id").primaryKey(),
|
|
151
|
+
organizationId: text("organization_id")
|
|
152
|
+
.notNull()
|
|
153
|
+
.references(() => organization.id, { onDelete: "cascade" }),
|
|
154
|
+
email: text("email").notNull(),
|
|
155
|
+
role: text("role").notNull(),
|
|
156
|
+
status: text("status").notNull(),
|
|
157
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
158
|
+
inviterId: text("inviter_id").references(() => users.id, {
|
|
159
|
+
onDelete: "set null",
|
|
160
|
+
}),
|
|
161
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
162
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
163
|
+
},
|
|
164
|
+
(table) => [
|
|
165
|
+
index("invitation_organization_id_idx").on(table.organizationId),
|
|
166
|
+
index("invitation_email_idx").on(table.email),
|
|
167
|
+
]
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
export type User = typeof users.$inferSelect;
|
|
171
|
+
export type InsertUser = typeof users.$inferInsert;
|
|
172
|
+
export type Session = typeof sessions.$inferSelect;
|
|
173
|
+
export type InsertSession = typeof sessions.$inferInsert;
|
|
174
|
+
export type Account = typeof accounts.$inferSelect;
|
|
175
|
+
export type InsertAccount = typeof accounts.$inferInsert;
|
|
176
|
+
export type Verification = typeof verifications.$inferSelect;
|
|
177
|
+
export type InsertVerification = typeof verifications.$inferInsert;
|
|
178
|
+
export type Organization = typeof organization.$inferSelect;
|
|
179
|
+
export type InsertOrganization = typeof organization.$inferInsert;
|
|
180
|
+
export type Member = typeof member.$inferSelect;
|
|
181
|
+
export type InsertMember = typeof member.$inferInsert;
|
|
182
|
+
export type Invitation = typeof invitation.$inferSelect;
|
|
183
|
+
export type InsertInvitation = typeof invitation.$inferInsert;
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plans, subscriptions, credit ledgers, purchases, local payments and
|
|
3
|
+
* Stripe events. Amounts in the credit ledgers are micros of their
|
|
4
|
+
* currency; amounts a buyer paid are minor units of theirs.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
pgTable,
|
|
9
|
+
text,
|
|
10
|
+
timestamp,
|
|
11
|
+
integer,
|
|
12
|
+
bigint,
|
|
13
|
+
boolean,
|
|
14
|
+
index,
|
|
15
|
+
unique,
|
|
16
|
+
} from "drizzle-orm/pg-core";
|
|
17
|
+
import { organization, users } from "./auth";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The registered plan catalogue, copied into rows so a subscription can
|
|
21
|
+
* reference its plan. The catalogue is the source: the rows are written
|
|
22
|
+
* from it at boot, and an edit made here is overwritten by the next one.
|
|
23
|
+
*/
|
|
24
|
+
export const plans = pgTable("plans", {
|
|
25
|
+
id: text("id").primaryKey(),
|
|
26
|
+
name: text("name").notNull(),
|
|
27
|
+
slug: text("slug").notNull().unique(),
|
|
28
|
+
description: text("description"),
|
|
29
|
+
/**
|
|
30
|
+
* Whole major units — 29 is twenty-nine of the currency, not cents —
|
|
31
|
+
* rounded from the catalogue's price. 0 for free. The row names no
|
|
32
|
+
* currency; readers take the deployment's billing currency.
|
|
33
|
+
*/
|
|
34
|
+
priceMonthly: integer("price_monthly").notNull(),
|
|
35
|
+
/** Whole major units, as `priceMonthly`. 0 when the plan has no yearly price. */
|
|
36
|
+
priceYearly: integer("price_yearly").notNull(),
|
|
37
|
+
stripePriceIdMonthly: text("stripe_price_id_monthly"),
|
|
38
|
+
stripePriceIdYearly: text("stripe_price_id_yearly"),
|
|
39
|
+
features: text("features").notNull(), // JSON string array
|
|
40
|
+
limits: text("limits").notNull(), // JSON string: { tokens, conversations, teamMembers, workspaces, documents }
|
|
41
|
+
isActive: boolean("is_active").notNull().default(true),
|
|
42
|
+
sortOrder: integer("sort_order").notNull().default(0),
|
|
43
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
44
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
/** One subscription per workspace (unique constraint). */
|
|
48
|
+
export const subscriptions = pgTable(
|
|
49
|
+
"subscriptions",
|
|
50
|
+
{
|
|
51
|
+
id: text("id").primaryKey(),
|
|
52
|
+
workspaceId: text("workspace_id")
|
|
53
|
+
.notNull()
|
|
54
|
+
.references(() => organization.id, { onDelete: "cascade" }),
|
|
55
|
+
planId: text("plan_id")
|
|
56
|
+
.notNull()
|
|
57
|
+
.references(() => plans.id, { onDelete: "restrict" }),
|
|
58
|
+
stripeCustomerId: text("stripe_customer_id"),
|
|
59
|
+
stripeSubscriptionId: text("stripe_subscription_id").unique(),
|
|
60
|
+
status: text("status").notNull().default("active"), // active|past_due|canceled|trialing|incomplete
|
|
61
|
+
billingMode: text("billing_mode").notNull().default("subscription"), // subscription|credit
|
|
62
|
+
currentPeriodStart: timestamp("current_period_start"),
|
|
63
|
+
currentPeriodEnd: timestamp("current_period_end"),
|
|
64
|
+
cancelAtPeriodEnd: boolean("cancel_at_period_end").notNull().default(false),
|
|
65
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
66
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
67
|
+
},
|
|
68
|
+
(table) => [
|
|
69
|
+
index("subscriptions_workspace_id_idx").on(table.workspaceId),
|
|
70
|
+
unique("subscriptions_workspace_id_unique").on(table.workspaceId),
|
|
71
|
+
]
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
/** One credit balance per workspace (unique constraint). */
|
|
75
|
+
export const creditBalances = pgTable("credit_balances", {
|
|
76
|
+
id: text("id").primaryKey(),
|
|
77
|
+
workspaceId: text("workspace_id")
|
|
78
|
+
.notNull()
|
|
79
|
+
.unique()
|
|
80
|
+
.references(() => organization.id, { onDelete: "cascade" }),
|
|
81
|
+
/** The balance, in micros of `currency`. */
|
|
82
|
+
balanceMicros: bigint("balance_micros", { mode: "number" })
|
|
83
|
+
.notNull()
|
|
84
|
+
.default(0),
|
|
85
|
+
totalPurchasedMicros: bigint("total_purchased_micros", { mode: "number" })
|
|
86
|
+
.notNull()
|
|
87
|
+
.default(0),
|
|
88
|
+
totalUsedMicros: bigint("total_used_micros", { mode: "number" })
|
|
89
|
+
.notNull()
|
|
90
|
+
.default(0),
|
|
91
|
+
/** What this ledger is denominated in; a write in another is refused. */
|
|
92
|
+
currency: text("currency").notNull().default("USD"),
|
|
93
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Singleton (id = "default") holding the FX rate and margin, so they change
|
|
98
|
+
* without a deploy. Read per request, cached 60s in-process.
|
|
99
|
+
*/
|
|
100
|
+
export const billingSettings = pgTable("billing_settings", {
|
|
101
|
+
id: text("id").primaryKey(),
|
|
102
|
+
/** The deployment's billing currency — every ledger row is in this. */
|
|
103
|
+
currency: text("currency").notNull().default("USD"),
|
|
104
|
+
/** What one USD costs in it, in micros: 1_000_000 is a USD deployment. */
|
|
105
|
+
usdRateMicros: bigint("usd_rate_micros", { mode: "number" })
|
|
106
|
+
.notNull()
|
|
107
|
+
.default(1_000_000),
|
|
108
|
+
/** Margin over provider cost, in basis points of a multiplier: 40_000 = 4×. */
|
|
109
|
+
marginBp: integer("margin_bp").notNull().default(40_000),
|
|
110
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
/** One-time credit purchases. */
|
|
114
|
+
export const creditPurchases = pgTable(
|
|
115
|
+
"credit_purchases",
|
|
116
|
+
{
|
|
117
|
+
id: text("id").primaryKey(),
|
|
118
|
+
workspaceId: text("workspace_id")
|
|
119
|
+
.notNull()
|
|
120
|
+
.references(() => organization.id, { onDelete: "cascade" }),
|
|
121
|
+
/** What the buyer paid, in minor units of `priceCurrency`. */
|
|
122
|
+
priceMinor: integer("price_minor"),
|
|
123
|
+
priceCurrency: text("price_currency"),
|
|
124
|
+
/**
|
|
125
|
+
* What the workspace was granted, in micros of `grantedCurrency`.
|
|
126
|
+
* Separate from the price on purpose: a pack sold for $5 grants an
|
|
127
|
+
* amount of the billing currency, which is a different unit.
|
|
128
|
+
*/
|
|
129
|
+
grantedMicros: bigint("granted_micros", { mode: "number" }),
|
|
130
|
+
grantedCurrency: text("granted_currency"),
|
|
131
|
+
stripePaymentIntentId: text("stripe_payment_intent_id"),
|
|
132
|
+
stripeCheckoutSessionId: text("stripe_checkout_session_id"),
|
|
133
|
+
status: text("status").notNull().default("pending"), // pending|completed|failed
|
|
134
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
135
|
+
},
|
|
136
|
+
(table) => [index("credit_purchases_workspace_id_idx").on(table.workspaceId)]
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Invoices issued through a registered payment provider (QR-and-poll
|
|
141
|
+
* methods such as QPay, PIX or UPI), one row per invoice. The row is
|
|
142
|
+
* written when the invoice is opened, so settlement knows who pays and
|
|
143
|
+
* what was priced without trusting the browser; `fulfilled_at` is set
|
|
144
|
+
* in the same transaction that grants what was bought, so a payment is
|
|
145
|
+
* granted once however many polls see it paid.
|
|
146
|
+
*/
|
|
147
|
+
export const payments = pgTable(
|
|
148
|
+
"payments",
|
|
149
|
+
{
|
|
150
|
+
id: text("id").primaryKey(),
|
|
151
|
+
/** The PAYMENT_MODE the invoice was opened under; settlement asks the same provider. */
|
|
152
|
+
provider: text("provider").notNull(),
|
|
153
|
+
invoiceId: text("invoice_id").notNull().unique(),
|
|
154
|
+
workspaceId: text("workspace_id")
|
|
155
|
+
.notNull()
|
|
156
|
+
.references(() => organization.id, { onDelete: "cascade" }),
|
|
157
|
+
userId: text("user_id").references(() => users.id, {
|
|
158
|
+
onDelete: "set null",
|
|
159
|
+
}),
|
|
160
|
+
/** What was bought, in the product's words: a plan slug, a bundle id. */
|
|
161
|
+
reference: text("reference").notNull(),
|
|
162
|
+
/** The price, in minor units of `currency`. */
|
|
163
|
+
amountMinor: integer("amount_minor").notNull(),
|
|
164
|
+
currency: text("currency").notNull(),
|
|
165
|
+
status: text("status").notNull().default("pending"), // pending|paid|failed
|
|
166
|
+
fulfilledAt: timestamp("fulfilled_at"),
|
|
167
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
168
|
+
},
|
|
169
|
+
(table) => [index("payments_workspace_id_idx").on(table.workspaceId)]
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
/** Every Stripe event, for idempotent webhook processing and audit. */
|
|
173
|
+
export const financeEvents = pgTable("finance_events", {
|
|
174
|
+
id: text("id").primaryKey(),
|
|
175
|
+
workspaceId: text("workspace_id").references(() => organization.id, {
|
|
176
|
+
onDelete: "set null",
|
|
177
|
+
}),
|
|
178
|
+
stripeEventId: text("stripe_event_id").notNull().unique(),
|
|
179
|
+
type: text("type").notNull(), // e.g., "checkout.session.completed", "invoice.paid"
|
|
180
|
+
/** Stripe's own amount, in the minor units of `currency`. */
|
|
181
|
+
amountMinor: integer("amount_minor"),
|
|
182
|
+
currency: text("currency").default("USD"),
|
|
183
|
+
metadata: text("metadata"), // JSON string
|
|
184
|
+
/**
|
|
185
|
+
* When a delivery took the event for processing. A lease: a claim
|
|
186
|
+
* older than the webhook's lease is taken as a delivery that died.
|
|
187
|
+
*/
|
|
188
|
+
claimedAt: timestamp("claimed_at"),
|
|
189
|
+
/** Set once the handlers finished; the event is never run again. */
|
|
190
|
+
processedAt: timestamp("processed_at"),
|
|
191
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Closes the admission → settlement race. Admission inserts a reservation
|
|
196
|
+
* for the worst-case estimate inside the same transaction that sums the
|
|
197
|
+
* other active reservations, so concurrent requests cannot all be admitted
|
|
198
|
+
* against the same balance. Settlement closes the reservation; abandoned
|
|
199
|
+
* ones expire via `expires_at`, are ignored by the sum, and are deleted by
|
|
200
|
+
* a cleanup job.
|
|
201
|
+
*/
|
|
202
|
+
export const creditReservations = pgTable(
|
|
203
|
+
"credit_reservations",
|
|
204
|
+
{
|
|
205
|
+
id: text("id").primaryKey(),
|
|
206
|
+
workspaceId: text("workspace_id")
|
|
207
|
+
.notNull()
|
|
208
|
+
.references(() => organization.id, { onDelete: "cascade" }),
|
|
209
|
+
/** Correlates admission with settlement. */
|
|
210
|
+
requestId: text("request_id").notNull().unique(),
|
|
211
|
+
/** The hold, in micros of `currency`. */
|
|
212
|
+
estimatedMicros: bigint("estimated_micros", { mode: "number" })
|
|
213
|
+
.notNull()
|
|
214
|
+
.default(0),
|
|
215
|
+
currency: text("currency").notNull().default("USD"),
|
|
216
|
+
status: text("status").notNull().default("active"), // active | settled
|
|
217
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
218
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
219
|
+
settledAt: timestamp("settled_at"),
|
|
220
|
+
},
|
|
221
|
+
(table) => [
|
|
222
|
+
index("credit_reservations_active_idx").on(
|
|
223
|
+
table.workspaceId,
|
|
224
|
+
table.status,
|
|
225
|
+
table.expiresAt
|
|
226
|
+
),
|
|
227
|
+
]
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
export type Plan = typeof plans.$inferSelect;
|
|
231
|
+
export type InsertPlan = typeof plans.$inferInsert;
|
|
232
|
+
export type Subscription = typeof subscriptions.$inferSelect;
|
|
233
|
+
export type InsertSubscription = typeof subscriptions.$inferInsert;
|
|
234
|
+
export type CreditBalance = typeof creditBalances.$inferSelect;
|
|
235
|
+
export type InsertCreditBalance = typeof creditBalances.$inferInsert;
|
|
236
|
+
export type CreditPurchase = typeof creditPurchases.$inferSelect;
|
|
237
|
+
export type InsertCreditPurchase = typeof creditPurchases.$inferInsert;
|
|
238
|
+
export type Payment = typeof payments.$inferSelect;
|
|
239
|
+
export type InsertPayment = typeof payments.$inferInsert;
|
|
240
|
+
export type FinanceEvent = typeof financeEvents.$inferSelect;
|
|
241
|
+
export type InsertFinanceEvent = typeof financeEvents.$inferInsert;
|
|
242
|
+
export type BillingSettings = typeof billingSettings.$inferSelect;
|
|
243
|
+
export type InsertBillingSettings = typeof billingSettings.$inferInsert;
|
|
244
|
+
export type CreditReservation = typeof creditReservations.$inferSelect;
|
|
245
|
+
export type InsertCreditReservation = typeof creditReservations.$inferInsert;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime overrides for feature gates: `@intelligo-dev/billing`'s feature
|
|
3
|
+
* check reads a flag by name here before it falls back to the plan's
|
|
4
|
+
* entitlements, so a feature can be switched without a deploy.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { pgTable, text, timestamp, boolean } from "drizzle-orm/pg-core";
|
|
8
|
+
|
|
9
|
+
export const featureFlags = pgTable("feature_flags", {
|
|
10
|
+
id: text("id").primaryKey(),
|
|
11
|
+
name: text("name").notNull().unique(),
|
|
12
|
+
description: text("description"),
|
|
13
|
+
enabledPlans: text("enabled_plans").notNull(), // JSON array string: e.g., '["free","pro","enterprise"]'
|
|
14
|
+
isActive: boolean("is_active").notNull().default(true),
|
|
15
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
16
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export type FeatureFlag = typeof featureFlags.$inferSelect;
|
|
20
|
+
export type InsertFeatureFlag = typeof featureFlags.$inferInsert;
|