@opentrust/db 7.1.0

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.
Files changed (83) hide show
  1. package/dist/client.d.ts +3 -0
  2. package/dist/client.d.ts.map +1 -0
  3. package/dist/client.js +51 -0
  4. package/dist/dialect.d.ts +3 -0
  5. package/dist/dialect.d.ts.map +1 -0
  6. package/dist/dialect.js +12 -0
  7. package/dist/generate.d.ts +2 -0
  8. package/dist/generate.d.ts.map +1 -0
  9. package/dist/generate.js +20 -0
  10. package/dist/helpers.d.ts +11 -0
  11. package/dist/helpers.d.ts.map +1 -0
  12. package/dist/helpers.js +32 -0
  13. package/dist/index.d.ts +13 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +12 -0
  16. package/dist/migrate.d.ts +2 -0
  17. package/dist/migrate.d.ts.map +1 -0
  18. package/dist/migrate.js +61 -0
  19. package/dist/queries/agents.d.ts +25 -0
  20. package/dist/queries/agents.d.ts.map +1 -0
  21. package/dist/queries/agents.js +46 -0
  22. package/dist/queries/auth.d.ts +18 -0
  23. package/dist/queries/auth.d.ts.map +1 -0
  24. package/dist/queries/auth.js +77 -0
  25. package/dist/queries/detection-results.d.ts +24 -0
  26. package/dist/queries/detection-results.d.ts.map +1 -0
  27. package/dist/queries/detection-results.js +43 -0
  28. package/dist/queries/observations.d.ts +58 -0
  29. package/dist/queries/observations.d.ts.map +1 -0
  30. package/dist/queries/observations.js +212 -0
  31. package/dist/queries/policies.d.ts +25 -0
  32. package/dist/queries/policies.d.ts.map +1 -0
  33. package/dist/queries/policies.js +38 -0
  34. package/dist/queries/scanners.d.ts +25 -0
  35. package/dist/queries/scanners.d.ts.map +1 -0
  36. package/dist/queries/scanners.js +56 -0
  37. package/dist/queries/settings.d.ts +8 -0
  38. package/dist/queries/settings.d.ts.map +1 -0
  39. package/dist/queries/settings.js +30 -0
  40. package/dist/queries/usage.d.ts +18 -0
  41. package/dist/queries/usage.d.ts.map +1 -0
  42. package/dist/queries/usage.js +54 -0
  43. package/dist/schema/index.d.ts +4415 -0
  44. package/dist/schema/index.d.ts.map +1 -0
  45. package/dist/schema/index.js +19 -0
  46. package/dist/schema/mysql.d.ts +1479 -0
  47. package/dist/schema/mysql.d.ts.map +1 -0
  48. package/dist/schema/mysql.js +151 -0
  49. package/dist/schema/pg.d.ts +1479 -0
  50. package/dist/schema/pg.d.ts.map +1 -0
  51. package/dist/schema/pg.js +151 -0
  52. package/dist/schema/sqlite.d.ts +1479 -0
  53. package/dist/schema/sqlite.d.ts.map +1 -0
  54. package/dist/schema/sqlite.js +153 -0
  55. package/dist/seed.d.ts +2 -0
  56. package/dist/seed.d.ts.map +1 -0
  57. package/dist/seed.js +49 -0
  58. package/drizzle/sqlite/0000_serious_martin_li.sql +143 -0
  59. package/drizzle/sqlite/meta/0000_snapshot.json +945 -0
  60. package/drizzle/sqlite/meta/_journal.json +13 -0
  61. package/drizzle.config.mysql.ts +10 -0
  62. package/drizzle.config.pg.ts +10 -0
  63. package/drizzle.config.sqlite.ts +10 -0
  64. package/package.json +55 -0
  65. package/src/client.ts +66 -0
  66. package/src/dialect.ts +13 -0
  67. package/src/generate.ts +26 -0
  68. package/src/helpers.ts +47 -0
  69. package/src/index.ts +12 -0
  70. package/src/migrate.ts +74 -0
  71. package/src/queries/agents.ts +68 -0
  72. package/src/queries/auth.ts +94 -0
  73. package/src/queries/detection-results.ts +58 -0
  74. package/src/queries/observations.ts +275 -0
  75. package/src/queries/policies.ts +59 -0
  76. package/src/queries/scanners.ts +74 -0
  77. package/src/queries/settings.ts +34 -0
  78. package/src/queries/usage.ts +69 -0
  79. package/src/schema/index.ts +22 -0
  80. package/src/schema/mysql.ts +207 -0
  81. package/src/schema/pg.ts +208 -0
  82. package/src/schema/sqlite.ts +199 -0
  83. package/src/seed.ts +56 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/schema/sqlite.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAInB,CAAC;AAGH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBlB,CAAC;AAGF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgB9B,CAAC;AAGF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBpB,CAAC;AAGF,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBrB,CAAC;AAGF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB5B,CAAC;AAGF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBhC,CAAC;AAIF,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EActB,CAAC;AAIF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAaxB,CAAC;AAGF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqB5B,CAAC"}
@@ -0,0 +1,153 @@
1
+ import { sqliteTable, text, integer, real, index } from "drizzle-orm/sqlite-core";
2
+ // ─── Settings ─────────────────────────────────────────────────
3
+ export const settings = sqliteTable("settings", {
4
+ key: text("key").primaryKey(),
5
+ value: text("value").notNull(),
6
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString()),
7
+ });
8
+ // ─── Agents ─────────────────────────────────────────────────────
9
+ export const agents = sqliteTable("agents", {
10
+ id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
11
+ tenantId: text("tenant_id").notNull().default("default"),
12
+ name: text("name").notNull(),
13
+ description: text("description"),
14
+ provider: text("provider").notNull().default("custom"),
15
+ status: text("status").notNull().default("inactive"),
16
+ lastSeenAt: text("last_seen_at"),
17
+ metadata: text("metadata", { mode: "json" }).notNull().default({}),
18
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
19
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString()),
20
+ }, (table) => ({
21
+ statusIdx: index("idx_agents_status").on(table.status),
22
+ tenantIdIdx: index("idx_agents_tenant_id").on(table.tenantId),
23
+ }));
24
+ // ─── Scanner Definitions ────────────────────────────────────────
25
+ export const scannerDefinitions = sqliteTable("scanner_definitions", {
26
+ id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
27
+ tenantId: text("tenant_id").notNull().default("default"),
28
+ scannerId: text("scanner_id").notNull(),
29
+ name: text("name").notNull(),
30
+ description: text("description").notNull(),
31
+ config: text("config", { mode: "json" }).notNull().default({}),
32
+ isEnabled: integer("is_enabled", { mode: "boolean" }).notNull().default(true),
33
+ isDefault: integer("is_default", { mode: "boolean" }).notNull().default(false),
34
+ }, (table) => ({
35
+ scannerIdIdx: index("idx_scanner_defs_scanner_id").on(table.scannerId),
36
+ tenantIdIdx: index("idx_scanner_defs_tenant_id").on(table.tenantId),
37
+ }));
38
+ // ─── Policies ───────────────────────────────────────────────────
39
+ export const policies = sqliteTable("policies", {
40
+ id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
41
+ tenantId: text("tenant_id").notNull().default("default"),
42
+ name: text("name").notNull(),
43
+ description: text("description"),
44
+ scannerIds: text("scanner_ids", { mode: "json" }).notNull().default([]),
45
+ action: text("action").notNull().default("log"),
46
+ sensitivityThreshold: real("sensitivity_threshold").notNull().default(0.5),
47
+ isEnabled: integer("is_enabled", { mode: "boolean" }).notNull().default(true),
48
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
49
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString()),
50
+ }, (table) => ({
51
+ tenantIdIdx: index("idx_policies_tenant_id").on(table.tenantId),
52
+ }));
53
+ // ─── Usage Logs ─────────────────────────────────────────────────
54
+ export const usageLogs = sqliteTable("usage_logs", {
55
+ id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
56
+ tenantId: text("tenant_id").notNull().default("default"),
57
+ agentId: text("agent_id"),
58
+ endpoint: text("endpoint").notNull(),
59
+ statusCode: integer("status_code").notNull(),
60
+ responseSafe: integer("response_safe", { mode: "boolean" }),
61
+ categories: text("categories", { mode: "json" }).notNull().default([]),
62
+ latencyMs: integer("latency_ms").notNull(),
63
+ requestId: text("request_id").notNull(),
64
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
65
+ }, (table) => ({
66
+ agentIdIdx: index("idx_usage_logs_agent_id").on(table.agentId),
67
+ createdAtIdx: index("idx_usage_logs_created_at").on(table.createdAt),
68
+ tenantIdIdx: index("idx_usage_logs_tenant_id").on(table.tenantId),
69
+ }));
70
+ // ─── Detection Results ──────────────────────────────────────────
71
+ export const detectionResults = sqliteTable("detection_results", {
72
+ id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
73
+ tenantId: text("tenant_id").notNull().default("default"),
74
+ agentId: text("agent_id"),
75
+ safe: integer("safe", { mode: "boolean" }).notNull(),
76
+ categories: text("categories", { mode: "json" }).notNull().default([]),
77
+ sensitivityScore: real("sensitivity_score").notNull().default(0),
78
+ findings: text("findings", { mode: "json" }).notNull().default([]),
79
+ latencyMs: integer("latency_ms").notNull(),
80
+ requestId: text("request_id").notNull(),
81
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
82
+ }, (table) => ({
83
+ agentIdIdx: index("idx_detection_results_agent_id").on(table.agentId),
84
+ createdAtIdx: index("idx_detection_results_created_at").on(table.createdAt),
85
+ tenantIdIdx: index("idx_detection_results_tenant_id").on(table.tenantId),
86
+ }));
87
+ // ─── Tool Call Observations ─────────────────────────────────────
88
+ export const toolCallObservations = sqliteTable("tool_call_observations", {
89
+ id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
90
+ tenantId: text("tenant_id").notNull().default("default"),
91
+ agentId: text("agent_id").notNull(),
92
+ sessionKey: text("session_key"),
93
+ toolName: text("tool_name").notNull(),
94
+ category: text("category"),
95
+ accessPattern: text("access_pattern"),
96
+ paramsJson: text("params_json", { mode: "json" }),
97
+ phase: text("phase").notNull(),
98
+ resultJson: text("result_json", { mode: "json" }),
99
+ error: text("error"),
100
+ durationMs: integer("duration_ms"),
101
+ blocked: integer("blocked", { mode: "boolean" }).notNull().default(false),
102
+ blockReason: text("block_reason"),
103
+ timestamp: text("timestamp").notNull().$defaultFn(() => new Date().toISOString()),
104
+ }, (table) => ({
105
+ agentIdIdx: index("idx_tool_obs_agent_id").on(table.agentId),
106
+ toolNameIdx: index("idx_tool_obs_tool_name").on(table.toolName),
107
+ timestampIdx: index("idx_tool_obs_timestamp").on(table.timestamp),
108
+ tenantIdIdx: index("idx_tool_obs_tenant_id").on(table.tenantId),
109
+ }));
110
+ // ─── Magic Links ─────────────────────────────────────────────
111
+ // One-time login tokens sent via email (15-min TTL)
112
+ export const magicLinks = sqliteTable("magic_links", {
113
+ id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
114
+ email: text("email").notNull(),
115
+ token: text("token").notNull().unique(),
116
+ expiresAt: text("expires_at").notNull(),
117
+ usedAt: text("used_at"),
118
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
119
+ }, (table) => ({
120
+ tokenIdx: index("idx_magic_links_token").on(table.token),
121
+ emailIdx: index("idx_magic_links_email").on(table.email),
122
+ }));
123
+ // ─── User Sessions ────────────────────────────────────────────
124
+ // Persistent sessions created after magic link verification (30-day TTL)
125
+ export const userSessions = sqliteTable("user_sessions", {
126
+ id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
127
+ email: text("email").notNull(),
128
+ token: text("token").notNull().unique(),
129
+ expiresAt: text("expires_at").notNull(),
130
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
131
+ }, (table) => ({
132
+ tokenIdx: index("idx_user_sessions_token").on(table.token),
133
+ emailIdx: index("idx_user_sessions_email").on(table.email),
134
+ }));
135
+ // ─── Agent Permissions ────────────────────────────────────────
136
+ export const agentPermissions = sqliteTable("agent_permissions", {
137
+ id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
138
+ tenantId: text("tenant_id").notNull().default("default"),
139
+ agentId: text("agent_id").notNull(),
140
+ toolName: text("tool_name").notNull(),
141
+ category: text("category"),
142
+ accessPattern: text("access_pattern"),
143
+ targetsJson: text("targets_json", { mode: "json" }).notNull().default([]),
144
+ callCount: integer("call_count").notNull().default(0),
145
+ errorCount: integer("error_count").notNull().default(0),
146
+ firstSeen: text("first_seen").notNull().$defaultFn(() => new Date().toISOString()),
147
+ lastSeen: text("last_seen").notNull().$defaultFn(() => new Date().toISOString()),
148
+ }, (table) => ({
149
+ agentIdIdx: index("idx_agent_perms_agent_id").on(table.agentId),
150
+ toolNameIdx: index("idx_agent_perms_tool_name").on(table.toolName),
151
+ tenantIdIdx: index("idx_agent_perms_tenant_id").on(table.tenantId),
152
+ uniqueAgentTool: index("idx_agent_perms_unique").on(table.tenantId, table.agentId, table.toolName),
153
+ }));
package/dist/seed.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=seed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../src/seed.ts"],"names":[],"mappings":""}
package/dist/seed.js ADDED
@@ -0,0 +1,49 @@
1
+ import { config } from "dotenv";
2
+ import { resolve, dirname } from "path";
3
+ import { fileURLToPath } from "url";
4
+ const __filename = fileURLToPath(import.meta.url);
5
+ const __dirname = dirname(__filename);
6
+ config({ path: resolve(__dirname, "../../../.env") });
7
+ async function seed() {
8
+ const { db } = await import("./client.js");
9
+ const { scannerDefinitions } = await import("./schema/index.js");
10
+ const { DEFAULT_SCANNERS, DEFAULT_TENANT_ID } = await import("@opentrust/shared");
11
+ const { getDialect } = await import("./dialect.js");
12
+ const { eq } = await import("drizzle-orm");
13
+ console.log(`Seeding default scanners (dialect: ${getDialect()})...`);
14
+ for (const scanner of DEFAULT_SCANNERS) {
15
+ const id = crypto.randomUUID();
16
+ const values = {
17
+ id,
18
+ scannerId: scanner.scannerId,
19
+ name: scanner.name,
20
+ description: scanner.description,
21
+ isEnabled: true,
22
+ isDefault: true,
23
+ tenantId: DEFAULT_TENANT_ID,
24
+ };
25
+ try {
26
+ const existing = await db
27
+ .select()
28
+ .from(scannerDefinitions)
29
+ .where(eq(scannerDefinitions.scannerId, scanner.scannerId))
30
+ .limit(1);
31
+ if (existing.length === 0) {
32
+ await db.insert(scannerDefinitions).values(values);
33
+ console.log(` Seeded ${scanner.scannerId}: ${scanner.name}`);
34
+ }
35
+ else {
36
+ console.log(` Skipped ${scanner.scannerId}: already exists`);
37
+ }
38
+ }
39
+ catch (err) {
40
+ console.warn(` Warning: ${scanner.scannerId} seed failed:`, err);
41
+ }
42
+ }
43
+ console.log("Seeding complete.");
44
+ process.exit(0);
45
+ }
46
+ seed().catch((err) => {
47
+ console.error("Seed failed:", err);
48
+ process.exit(1);
49
+ });
@@ -0,0 +1,143 @@
1
+ CREATE TABLE `agent_permissions` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `tenant_id` text DEFAULT 'default' NOT NULL,
4
+ `agent_id` text NOT NULL,
5
+ `tool_name` text NOT NULL,
6
+ `category` text,
7
+ `access_pattern` text,
8
+ `targets_json` text DEFAULT '[]' NOT NULL,
9
+ `call_count` integer DEFAULT 0 NOT NULL,
10
+ `error_count` integer DEFAULT 0 NOT NULL,
11
+ `first_seen` text NOT NULL,
12
+ `last_seen` text NOT NULL
13
+ );
14
+ --> statement-breakpoint
15
+ CREATE INDEX `idx_agent_perms_agent_id` ON `agent_permissions` (`agent_id`);--> statement-breakpoint
16
+ CREATE INDEX `idx_agent_perms_tool_name` ON `agent_permissions` (`tool_name`);--> statement-breakpoint
17
+ CREATE INDEX `idx_agent_perms_tenant_id` ON `agent_permissions` (`tenant_id`);--> statement-breakpoint
18
+ CREATE INDEX `idx_agent_perms_unique` ON `agent_permissions` (`tenant_id`,`agent_id`,`tool_name`);--> statement-breakpoint
19
+ CREATE TABLE `agents` (
20
+ `id` text PRIMARY KEY NOT NULL,
21
+ `tenant_id` text DEFAULT 'default' NOT NULL,
22
+ `name` text NOT NULL,
23
+ `description` text,
24
+ `provider` text DEFAULT 'custom' NOT NULL,
25
+ `status` text DEFAULT 'inactive' NOT NULL,
26
+ `last_seen_at` text,
27
+ `metadata` text DEFAULT '{}' NOT NULL,
28
+ `created_at` text NOT NULL,
29
+ `updated_at` text NOT NULL
30
+ );
31
+ --> statement-breakpoint
32
+ CREATE INDEX `idx_agents_status` ON `agents` (`status`);--> statement-breakpoint
33
+ CREATE INDEX `idx_agents_tenant_id` ON `agents` (`tenant_id`);--> statement-breakpoint
34
+ CREATE TABLE `detection_results` (
35
+ `id` text PRIMARY KEY NOT NULL,
36
+ `tenant_id` text DEFAULT 'default' NOT NULL,
37
+ `agent_id` text,
38
+ `safe` integer NOT NULL,
39
+ `categories` text DEFAULT '[]' NOT NULL,
40
+ `sensitivity_score` real DEFAULT 0 NOT NULL,
41
+ `findings` text DEFAULT '[]' NOT NULL,
42
+ `latency_ms` integer NOT NULL,
43
+ `request_id` text NOT NULL,
44
+ `created_at` text NOT NULL
45
+ );
46
+ --> statement-breakpoint
47
+ CREATE INDEX `idx_detection_results_agent_id` ON `detection_results` (`agent_id`);--> statement-breakpoint
48
+ CREATE INDEX `idx_detection_results_created_at` ON `detection_results` (`created_at`);--> statement-breakpoint
49
+ CREATE INDEX `idx_detection_results_tenant_id` ON `detection_results` (`tenant_id`);--> statement-breakpoint
50
+ CREATE TABLE `magic_links` (
51
+ `id` text PRIMARY KEY NOT NULL,
52
+ `email` text NOT NULL,
53
+ `token` text NOT NULL,
54
+ `expires_at` text NOT NULL,
55
+ `used_at` text,
56
+ `created_at` text NOT NULL
57
+ );
58
+ --> statement-breakpoint
59
+ CREATE UNIQUE INDEX `magic_links_token_unique` ON `magic_links` (`token`);--> statement-breakpoint
60
+ CREATE INDEX `idx_magic_links_token` ON `magic_links` (`token`);--> statement-breakpoint
61
+ CREATE INDEX `idx_magic_links_email` ON `magic_links` (`email`);--> statement-breakpoint
62
+ CREATE TABLE `policies` (
63
+ `id` text PRIMARY KEY NOT NULL,
64
+ `tenant_id` text DEFAULT 'default' NOT NULL,
65
+ `name` text NOT NULL,
66
+ `description` text,
67
+ `scanner_ids` text DEFAULT '[]' NOT NULL,
68
+ `action` text DEFAULT 'log' NOT NULL,
69
+ `sensitivity_threshold` real DEFAULT 0.5 NOT NULL,
70
+ `is_enabled` integer DEFAULT true NOT NULL,
71
+ `created_at` text NOT NULL,
72
+ `updated_at` text NOT NULL
73
+ );
74
+ --> statement-breakpoint
75
+ CREATE INDEX `idx_policies_tenant_id` ON `policies` (`tenant_id`);--> statement-breakpoint
76
+ CREATE TABLE `scanner_definitions` (
77
+ `id` text PRIMARY KEY NOT NULL,
78
+ `tenant_id` text DEFAULT 'default' NOT NULL,
79
+ `scanner_id` text NOT NULL,
80
+ `name` text NOT NULL,
81
+ `description` text NOT NULL,
82
+ `config` text DEFAULT '{}' NOT NULL,
83
+ `is_enabled` integer DEFAULT true NOT NULL,
84
+ `is_default` integer DEFAULT false NOT NULL
85
+ );
86
+ --> statement-breakpoint
87
+ CREATE INDEX `idx_scanner_defs_scanner_id` ON `scanner_definitions` (`scanner_id`);--> statement-breakpoint
88
+ CREATE INDEX `idx_scanner_defs_tenant_id` ON `scanner_definitions` (`tenant_id`);--> statement-breakpoint
89
+ CREATE TABLE `settings` (
90
+ `key` text PRIMARY KEY NOT NULL,
91
+ `value` text NOT NULL,
92
+ `updated_at` text NOT NULL
93
+ );
94
+ --> statement-breakpoint
95
+ CREATE TABLE `tool_call_observations` (
96
+ `id` text PRIMARY KEY NOT NULL,
97
+ `tenant_id` text DEFAULT 'default' NOT NULL,
98
+ `agent_id` text NOT NULL,
99
+ `session_key` text,
100
+ `tool_name` text NOT NULL,
101
+ `category` text,
102
+ `access_pattern` text,
103
+ `params_json` text,
104
+ `phase` text NOT NULL,
105
+ `result_json` text,
106
+ `error` text,
107
+ `duration_ms` integer,
108
+ `blocked` integer DEFAULT false NOT NULL,
109
+ `block_reason` text,
110
+ `timestamp` text NOT NULL
111
+ );
112
+ --> statement-breakpoint
113
+ CREATE INDEX `idx_tool_obs_agent_id` ON `tool_call_observations` (`agent_id`);--> statement-breakpoint
114
+ CREATE INDEX `idx_tool_obs_tool_name` ON `tool_call_observations` (`tool_name`);--> statement-breakpoint
115
+ CREATE INDEX `idx_tool_obs_timestamp` ON `tool_call_observations` (`timestamp`);--> statement-breakpoint
116
+ CREATE INDEX `idx_tool_obs_tenant_id` ON `tool_call_observations` (`tenant_id`);--> statement-breakpoint
117
+ CREATE TABLE `usage_logs` (
118
+ `id` text PRIMARY KEY NOT NULL,
119
+ `tenant_id` text DEFAULT 'default' NOT NULL,
120
+ `agent_id` text,
121
+ `endpoint` text NOT NULL,
122
+ `status_code` integer NOT NULL,
123
+ `response_safe` integer,
124
+ `categories` text DEFAULT '[]' NOT NULL,
125
+ `latency_ms` integer NOT NULL,
126
+ `request_id` text NOT NULL,
127
+ `created_at` text NOT NULL
128
+ );
129
+ --> statement-breakpoint
130
+ CREATE INDEX `idx_usage_logs_agent_id` ON `usage_logs` (`agent_id`);--> statement-breakpoint
131
+ CREATE INDEX `idx_usage_logs_created_at` ON `usage_logs` (`created_at`);--> statement-breakpoint
132
+ CREATE INDEX `idx_usage_logs_tenant_id` ON `usage_logs` (`tenant_id`);--> statement-breakpoint
133
+ CREATE TABLE `user_sessions` (
134
+ `id` text PRIMARY KEY NOT NULL,
135
+ `email` text NOT NULL,
136
+ `token` text NOT NULL,
137
+ `expires_at` text NOT NULL,
138
+ `created_at` text NOT NULL
139
+ );
140
+ --> statement-breakpoint
141
+ CREATE UNIQUE INDEX `user_sessions_token_unique` ON `user_sessions` (`token`);--> statement-breakpoint
142
+ CREATE INDEX `idx_user_sessions_token` ON `user_sessions` (`token`);--> statement-breakpoint
143
+ CREATE INDEX `idx_user_sessions_email` ON `user_sessions` (`email`);