@useatlas/types 0.0.1 → 0.0.2

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/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/auth.ts
2
2
  var AUTH_MODES = ["none", "simple-key", "managed", "byot"];
3
- var ATLAS_ROLES = ["viewer", "analyst", "admin"];
3
+ var ATLAS_ROLES = ["member", "admin", "owner", "platform_admin"];
4
4
  // src/connection.ts
5
5
  var DB_TYPES = [
6
6
  { value: "postgres", label: "PostgreSQL" },
@@ -24,12 +24,43 @@ var ALL_STATUSES = [
24
24
  "timed_out"
25
25
  ];
26
26
  var RESOLVED_STATUSES = new Set(ALL_STATUSES.filter((s) => s !== "pending_approval"));
27
+ var ACTION_STATUSES = [
28
+ "pending",
29
+ "approved",
30
+ "denied",
31
+ "executed",
32
+ "failed",
33
+ "timed_out",
34
+ "auto_approved",
35
+ "rolled_back"
36
+ ];
27
37
  var VALID_STATUSES = new Set(ALL_STATUSES);
28
38
  function isActionToolResult(result) {
29
39
  if (result == null || typeof result !== "object")
30
40
  return false;
31
41
  const r = result;
32
- return typeof r.actionId === "string" && typeof r.status === "string" && VALID_STATUSES.has(r.status);
42
+ if (typeof r.actionId !== "string" || r.actionId.length === 0)
43
+ return false;
44
+ if (typeof r.status !== "string")
45
+ return false;
46
+ if (!VALID_STATUSES.has(r.status))
47
+ return false;
48
+ switch (r.status) {
49
+ case "pending_approval":
50
+ return typeof r.summary === "string";
51
+ case "approved":
52
+ case "executed":
53
+ case "auto_approved":
54
+ return "result" in r;
55
+ case "failed":
56
+ return typeof r.error === "string";
57
+ case "denied":
58
+ case "rolled_back":
59
+ case "timed_out":
60
+ return true;
61
+ default:
62
+ return false;
63
+ }
33
64
  }
34
65
 
35
66
  // src/scheduled-task.ts
@@ -55,6 +86,7 @@ function isRecipient(value) {
55
86
  // src/errors.ts
56
87
  var CHAT_ERROR_CODES = [
57
88
  "auth_error",
89
+ "session_expired",
58
90
  "rate_limited",
59
91
  "configuration_error",
60
92
  "no_datasource",
@@ -65,8 +97,118 @@ var CHAT_ERROR_CODES = [
65
97
  "provider_timeout",
66
98
  "provider_unreachable",
67
99
  "provider_error",
68
- "internal_error"
100
+ "internal_error",
101
+ "validation_error",
102
+ "not_found",
103
+ "forbidden",
104
+ "forbidden_role",
105
+ "org_not_found",
106
+ "plan_limit_exceeded",
107
+ "trial_expired",
108
+ "billing_check_failed",
109
+ "workspace_check_failed",
110
+ "workspace_suspended",
111
+ "workspace_throttled",
112
+ "workspace_deleted"
69
113
  ];
114
+ function isChatErrorCode(value) {
115
+ return CHAT_ERROR_CODES.includes(value);
116
+ }
117
+ var RETRYABLE_MAP = {
118
+ rate_limited: true,
119
+ provider_timeout: true,
120
+ provider_unreachable: true,
121
+ provider_error: true,
122
+ provider_rate_limit: true,
123
+ internal_error: true,
124
+ auth_error: false,
125
+ session_expired: false,
126
+ configuration_error: false,
127
+ no_datasource: false,
128
+ invalid_request: false,
129
+ provider_model_not_found: false,
130
+ provider_auth_error: false,
131
+ validation_error: false,
132
+ not_found: false,
133
+ forbidden: false,
134
+ forbidden_role: false,
135
+ org_not_found: false,
136
+ plan_limit_exceeded: false,
137
+ trial_expired: false,
138
+ billing_check_failed: true,
139
+ workspace_check_failed: true,
140
+ workspace_suspended: false,
141
+ workspace_throttled: true,
142
+ workspace_deleted: false
143
+ };
144
+ function isRetryableError(code) {
145
+ return RETRYABLE_MAP[code];
146
+ }
147
+ var CLIENT_ERROR_CODES = [
148
+ "api_unreachable",
149
+ "auth_failure",
150
+ "rate_limited_http",
151
+ "server_error",
152
+ "offline"
153
+ ];
154
+ function extractHostFromError(msg) {
155
+ const refusedMatch = msg.match(/ECONNREFUSED\s+(\S+)/i);
156
+ if (refusedMatch)
157
+ return refusedMatch[1];
158
+ const notFoundMatch = msg.match(/ENOTFOUND\s+(\S+)/i);
159
+ if (notFoundMatch)
160
+ return notFoundMatch[1];
161
+ return "(unknown host)";
162
+ }
163
+ function matchError(error, opts) {
164
+ const msg = error instanceof Error ? error.message : String(error);
165
+ if (/too many (clients already|connections)|connection pool exhausted|remaining connection slots are reserved/i.test(msg)) {
166
+ return {
167
+ code: "rate_limited",
168
+ message: "Database connection pool exhausted — try again in a few seconds, or reduce concurrent queries"
169
+ };
170
+ }
171
+ if (/ECONNREFUSED/i.test(msg)) {
172
+ const host = extractHostFromError(msg);
173
+ return {
174
+ code: "internal_error",
175
+ message: `Database unreachable at ${host} — check that the database is running and accessible`
176
+ };
177
+ }
178
+ if (/ENOTFOUND/i.test(msg)) {
179
+ const host = extractHostFromError(msg);
180
+ return {
181
+ code: "internal_error",
182
+ message: `Could not resolve hostname "${host}" — check your connection URL`
183
+ };
184
+ }
185
+ if (/SELF_SIGNED_CERT|UNABLE_TO_VERIFY_LEAF_SIGNATURE|ssl\s+connection|tls\s+handshake|certificate\s+(has expired|verify|error|rejected)/i.test(msg)) {
186
+ return {
187
+ code: "internal_error",
188
+ message: "SSL connection failed — check sslmode in your connection string"
189
+ };
190
+ }
191
+ if (/timeout|timed out|AbortError/i.test(msg)) {
192
+ const seconds = Math.max(1, opts?.timeoutSeconds ?? 30);
193
+ return {
194
+ code: "provider_timeout",
195
+ message: `Query exceeded the ${seconds}-second timeout — try a simpler query or increase ATLAS_QUERY_TIMEOUT`
196
+ };
197
+ }
198
+ if (/\b502\s+Bad Gateway\b|\b503\s+Service Unavailable\b/i.test(msg)) {
199
+ return {
200
+ code: "provider_unreachable",
201
+ message: "AI provider API unavailable — this is usually temporary, retry in a few seconds"
202
+ };
203
+ }
204
+ if (/fetch failed/i.test(msg)) {
205
+ return {
206
+ code: "provider_unreachable",
207
+ message: "Network request failed — the remote service may be down or unreachable"
208
+ };
209
+ }
210
+ return null;
211
+ }
70
212
  function authErrorMessage(authMode) {
71
213
  switch (authMode) {
72
214
  case "simple-key":
@@ -83,65 +225,302 @@ function authErrorMessage(authMode) {
83
225
  }
84
226
  }
85
227
  }
228
+ function classifyClientError(error) {
229
+ const msg = error.message;
230
+ if (msg.startsWith("{") || msg.startsWith("[")) {
231
+ return null;
232
+ }
233
+ if (typeof window !== "undefined" && typeof navigator !== "undefined" && navigator.onLine === false) {
234
+ return "offline";
235
+ }
236
+ if (error.name === "TypeError" || /fetch failed|failed to fetch|networkerror|network\s+request\s+failed|ECONNREFUSED|ENOTFOUND|ERR_CONNECTION_REFUSED/i.test(msg)) {
237
+ return "api_unreachable";
238
+ }
239
+ if (/\b401\b|Unauthorized/i.test(msg) && !/\bretry/i.test(msg)) {
240
+ return "auth_failure";
241
+ }
242
+ if (/\b429\b|Too Many Requests/i.test(msg)) {
243
+ return "rate_limited_http";
244
+ }
245
+ if (/\b50[0-9]\b|Internal Server Error|Bad Gateway|Service Unavailable/i.test(msg)) {
246
+ return "server_error";
247
+ }
248
+ return null;
249
+ }
250
+ function clientErrorInfo(clientCode, authMode) {
251
+ switch (clientCode) {
252
+ case "offline":
253
+ return {
254
+ title: "You appear to be offline.",
255
+ detail: "Reconnecting when your network is restored...",
256
+ clientCode,
257
+ retryable: true
258
+ };
259
+ case "api_unreachable":
260
+ return {
261
+ title: "Unable to connect to Atlas.",
262
+ detail: "Check your API URL configuration and ensure the server is running.",
263
+ clientCode,
264
+ retryable: true
265
+ };
266
+ case "auth_failure":
267
+ return {
268
+ title: authErrorMessage(authMode),
269
+ clientCode,
270
+ retryable: false
271
+ };
272
+ case "rate_limited_http":
273
+ return {
274
+ title: "Too many requests.",
275
+ detail: "Please try again in a moment.",
276
+ retryAfterSeconds: 30,
277
+ clientCode,
278
+ retryable: true
279
+ };
280
+ case "server_error":
281
+ return {
282
+ title: "Something went wrong on our end.",
283
+ detail: "Please try again.",
284
+ clientCode,
285
+ retryable: true
286
+ };
287
+ default: {
288
+ const _exhaustive = clientCode;
289
+ return { title: `Unknown error (${_exhaustive}).` };
290
+ }
291
+ }
292
+ }
86
293
  function parseChatError(error, authMode) {
294
+ const clientCode = classifyClientError(error);
87
295
  let parsed;
88
296
  try {
89
297
  parsed = JSON.parse(error.message);
90
298
  } catch {
91
- return { title: "Something went wrong. Please try again." };
299
+ if (clientCode) {
300
+ return clientErrorInfo(clientCode, authMode);
301
+ }
302
+ const raw = error.message.length > 200 ? error.message.slice(0, 200) + "..." : error.message;
303
+ return { title: "Something went wrong. Please try again.", detail: raw };
92
304
  }
93
- const code = typeof parsed.error === "string" ? parsed.error : undefined;
305
+ const rawCode = typeof parsed.error === "string" ? parsed.error : undefined;
94
306
  const serverMessage = typeof parsed.message === "string" ? parsed.message : undefined;
95
- switch (code) {
307
+ const requestId = typeof parsed.requestId === "string" ? parsed.requestId : undefined;
308
+ if (rawCode === undefined || !isChatErrorCode(rawCode)) {
309
+ return { title: serverMessage ?? "Something went wrong. Please try again.", requestId };
310
+ }
311
+ const retryable = isRetryableError(rawCode);
312
+ switch (rawCode) {
96
313
  case "auth_error":
97
- return { title: authErrorMessage(authMode), code };
314
+ return { title: authErrorMessage(authMode), code: rawCode, retryable, requestId };
98
315
  case "rate_limited": {
99
316
  const raw = typeof parsed.retryAfterSeconds === "number" ? parsed.retryAfterSeconds : undefined;
100
317
  const clamped = raw !== undefined ? Math.max(0, Math.min(raw, 300)) : undefined;
101
318
  return {
102
319
  title: "Too many requests.",
103
- detail: clamped !== undefined ? `Try again in ${clamped} seconds.` : "Please wait before trying again.",
320
+ detail: clamped !== undefined ? `Try again in ${clamped} seconds.` : serverMessage ?? "Please wait before trying again.",
104
321
  retryAfterSeconds: clamped,
105
- code
322
+ code: rawCode,
323
+ retryable,
324
+ requestId
106
325
  };
107
326
  }
108
327
  case "configuration_error":
109
- return { title: "Atlas is not fully configured.", detail: serverMessage, code };
328
+ return { title: "Atlas is not fully configured.", detail: serverMessage, code: rawCode, retryable, requestId };
110
329
  case "no_datasource":
111
- return { title: "No data source configured.", detail: serverMessage, code };
330
+ return { title: "No data source configured.", detail: serverMessage, code: rawCode, retryable, requestId };
112
331
  case "invalid_request":
113
- return { title: "Invalid request.", detail: serverMessage, code };
332
+ return { title: "Invalid request.", detail: serverMessage, code: rawCode, retryable, requestId };
114
333
  case "provider_model_not_found":
115
- return { title: "The configured AI model was not found.", detail: serverMessage, code };
334
+ return { title: "The configured AI model was not found.", detail: serverMessage, code: rawCode, retryable, requestId };
116
335
  case "provider_auth_error":
117
- return { title: "The AI provider could not authenticate.", detail: serverMessage, code };
336
+ return { title: "The AI provider could not authenticate.", detail: serverMessage, code: rawCode, retryable, requestId };
118
337
  case "provider_rate_limit":
119
- return { title: "The AI provider is rate limiting requests.", detail: serverMessage, code };
338
+ return { title: "The AI provider is rate limiting requests.", detail: serverMessage, code: rawCode, retryable, requestId };
120
339
  case "provider_timeout":
121
- return { title: "The AI provider timed out.", detail: serverMessage, code };
340
+ return { title: "The AI provider timed out.", detail: serverMessage, code: rawCode, retryable, requestId };
122
341
  case "provider_unreachable":
123
- return { title: "Could not reach the AI provider.", detail: serverMessage, code };
342
+ return { title: "Could not reach the AI provider.", detail: serverMessage, code: rawCode, retryable, requestId };
124
343
  case "provider_error":
125
- return { title: "The AI provider returned an error.", detail: serverMessage, code };
344
+ return { title: "The AI provider returned an error.", detail: serverMessage, code: rawCode, retryable, requestId };
126
345
  case "internal_error":
127
- return { title: serverMessage ?? "An unexpected error occurred.", code };
128
- default:
129
- return { title: serverMessage ?? "Something went wrong. Please try again." };
346
+ return { title: serverMessage ?? "An unexpected error occurred.", code: rawCode, retryable, requestId };
347
+ case "validation_error":
348
+ return { title: "Validation error.", detail: serverMessage, code: rawCode, retryable, requestId };
349
+ case "not_found":
350
+ return { title: "Not found.", detail: serverMessage, code: rawCode, retryable, requestId };
351
+ case "forbidden":
352
+ return { title: "Access denied.", detail: serverMessage, code: rawCode, retryable, requestId };
353
+ case "session_expired":
354
+ return { title: "Your session has expired.", detail: serverMessage ?? "Please sign in again.", code: rawCode, retryable, requestId };
355
+ case "forbidden_role":
356
+ return { title: "Admin role required.", detail: serverMessage, code: rawCode, retryable, requestId };
357
+ case "org_not_found":
358
+ return { title: "No active organization.", detail: serverMessage ?? "Select an organization and try again.", code: rawCode, retryable, requestId };
359
+ case "plan_limit_exceeded":
360
+ return { title: "Plan limit exceeded.", detail: serverMessage ?? "Upgrade your plan or wait until the next billing period.", code: rawCode, retryable, requestId };
361
+ case "trial_expired":
362
+ return { title: "Trial expired.", detail: serverMessage ?? "Upgrade to a paid plan to continue using Atlas.", code: rawCode, retryable, requestId };
363
+ case "billing_check_failed":
364
+ return { title: "Billing check failed.", detail: serverMessage ?? "Unable to verify billing status. Please try again.", code: rawCode, retryable, requestId };
365
+ case "workspace_check_failed":
366
+ return { title: "Workspace check failed.", detail: serverMessage ?? "Unable to verify workspace status. Please try again.", code: rawCode, retryable, requestId };
367
+ case "workspace_suspended":
368
+ return { title: "Workspace suspended.", detail: serverMessage ?? "Contact your workspace administrator to reactivate it.", code: rawCode, retryable, requestId };
369
+ case "workspace_throttled":
370
+ return { title: "Workspace throttled.", detail: serverMessage ?? "Your workspace has been temporarily throttled due to unusual activity. Requests will be delayed.", code: rawCode, retryable, requestId };
371
+ case "workspace_deleted":
372
+ return { title: "Workspace deleted.", detail: serverMessage ?? "This workspace has been permanently deleted. Create a new workspace to continue.", code: rawCode, retryable, requestId };
373
+ default: {
374
+ const _exhaustive = rawCode;
375
+ return { title: serverMessage ?? `Something went wrong (${_exhaustive}).`, requestId };
376
+ }
130
377
  }
131
378
  }
379
+ // src/share.ts
380
+ var SHARE_MODES = ["public", "org"];
381
+ var SHARE_EXPIRY_OPTIONS = {
382
+ "1h": 3600,
383
+ "24h": 86400,
384
+ "7d": 604800,
385
+ "30d": 2592000,
386
+ never: null
387
+ };
388
+ // src/compliance.ts
389
+ var PII_CATEGORIES = [
390
+ "email",
391
+ "phone",
392
+ "ssn",
393
+ "credit_card",
394
+ "name",
395
+ "ip_address",
396
+ "date_of_birth",
397
+ "address",
398
+ "passport",
399
+ "driver_license",
400
+ "other"
401
+ ];
402
+ var PII_CONFIDENCE_LEVELS = ["high", "medium", "low"];
403
+ var MASKING_STRATEGIES = ["full", "partial", "hash", "redact"];
404
+ var PII_DETECTION_METHODS = ["regex", "column_name", "type_heuristic"];
405
+ var MASKING_ROLES = ["admin", "owner", "analyst", "viewer", "member"];
406
+ var COMPLIANCE_REPORT_TYPES = ["data-access", "user-activity"];
407
+ var COMPLIANCE_EXPORT_FORMATS = ["json", "csv"];
408
+ // src/organization.ts
409
+ var ORG_ROLES = [...ATLAS_ROLES].reverse();
410
+ // src/learned-pattern.ts
411
+ var LEARNED_PATTERN_STATUSES = ["pending", "approved", "rejected"];
412
+ var LEARNED_PATTERN_SOURCES = ["agent", "atlas-learn"];
413
+ // src/prompt.ts
414
+ var PROMPT_INDUSTRIES = ["saas", "ecommerce", "cybersecurity"];
415
+ // src/sso.ts
416
+ var SSO_PROVIDER_TYPES = ["saml", "oidc"];
417
+ // src/profiler.ts
418
+ var OBJECT_TYPES = ["table", "view", "materialized_view"];
419
+ var FK_SOURCES = ["constraint", "inferred"];
420
+ var PARTITION_STRATEGIES = ["range", "list", "hash"];
421
+ // src/model-config.ts
422
+ var MODEL_CONFIG_PROVIDERS = ["anthropic", "openai", "azure-openai", "custom"];
423
+ // src/approval.ts
424
+ var APPROVAL_RULE_TYPES = ["table", "column", "cost"];
425
+ var APPROVAL_STATUSES = ["pending", "approved", "denied", "expired"];
426
+ // src/platform.ts
427
+ var WORKSPACE_STATUSES = ["active", "suspended", "deleted"];
428
+ var PLAN_TIERS = ["free", "trial", "team", "enterprise"];
429
+ var NOISY_NEIGHBOR_METRICS = ["queries", "tokens", "storage"];
430
+ // src/onboarding-email.ts
431
+ var ONBOARDING_EMAIL_STEPS = [
432
+ "welcome",
433
+ "connect_database",
434
+ "first_query",
435
+ "invite_team",
436
+ "explore_features"
437
+ ];
438
+ var ONBOARDING_MILESTONES = [
439
+ "signup_completed",
440
+ "database_connected",
441
+ "first_query_executed",
442
+ "team_member_invited",
443
+ "feature_explored"
444
+ ];
445
+ // src/abuse.ts
446
+ var ABUSE_LEVELS = ["none", "warning", "throttled", "suspended"];
447
+ var ABUSE_TRIGGERS = [
448
+ "query_rate",
449
+ "error_rate",
450
+ "unique_tables",
451
+ "manual"
452
+ ];
453
+ // src/sla.ts
454
+ var SLA_ALERT_STATUSES = ["firing", "resolved", "acknowledged"];
455
+ var SLA_ALERT_TYPES = ["latency_p99", "error_rate"];
456
+ // src/backups.ts
457
+ var BACKUP_STATUSES = ["in_progress", "completed", "failed", "verified"];
458
+ // src/residency.ts
459
+ var WELL_KNOWN_REGIONS = [
460
+ "us-east",
461
+ "us-west",
462
+ "eu-west",
463
+ "eu-central",
464
+ "ap-southeast",
465
+ "ap-northeast"
466
+ ];
467
+ var MIGRATION_STATUSES = ["pending", "in_progress", "completed", "failed"];
468
+ // src/domain.ts
469
+ var DOMAIN_STATUSES = ["pending", "verified", "failed"];
470
+ var CERTIFICATE_STATUSES = ["PENDING", "ISSUED", "FAILED"];
132
471
  export {
133
472
  parseChatError,
473
+ matchError,
474
+ isRetryableError,
134
475
  isRecipient,
476
+ isChatErrorCode,
135
477
  isActionToolResult,
478
+ classifyClientError,
136
479
  authErrorMessage,
480
+ WORKSPACE_STATUSES,
481
+ WELL_KNOWN_REGIONS,
482
+ SSO_PROVIDER_TYPES,
483
+ SLA_ALERT_TYPES,
484
+ SLA_ALERT_STATUSES,
485
+ SHARE_MODES,
486
+ SHARE_EXPIRY_OPTIONS,
137
487
  RUN_STATUSES,
138
488
  RESOLVED_STATUSES,
489
+ PROMPT_INDUSTRIES,
490
+ PLAN_TIERS,
491
+ PII_DETECTION_METHODS,
492
+ PII_CONFIDENCE_LEVELS,
493
+ PII_CATEGORIES,
494
+ PARTITION_STRATEGIES,
495
+ ORG_ROLES,
496
+ ONBOARDING_MILESTONES,
497
+ ONBOARDING_EMAIL_STEPS,
498
+ OBJECT_TYPES,
499
+ NOISY_NEIGHBOR_METRICS,
500
+ MODEL_CONFIG_PROVIDERS,
501
+ MIGRATION_STATUSES,
502
+ MASKING_STRATEGIES,
503
+ MASKING_ROLES,
504
+ LEARNED_PATTERN_STATUSES,
505
+ LEARNED_PATTERN_SOURCES,
506
+ FK_SOURCES,
507
+ DOMAIN_STATUSES,
139
508
  DELIVERY_STATUSES,
140
509
  DELIVERY_CHANNELS,
141
510
  DB_TYPES,
511
+ COMPLIANCE_REPORT_TYPES,
512
+ COMPLIANCE_EXPORT_FORMATS,
513
+ CLIENT_ERROR_CODES,
142
514
  CHAT_ERROR_CODES,
515
+ CERTIFICATE_STATUSES,
516
+ BACKUP_STATUSES,
143
517
  AUTH_MODES,
144
518
  ATLAS_ROLES,
519
+ APPROVAL_STATUSES,
520
+ APPROVAL_RULE_TYPES,
145
521
  ALL_STATUSES,
146
- ACTION_APPROVAL_MODES
522
+ ACTION_STATUSES,
523
+ ACTION_APPROVAL_MODES,
524
+ ABUSE_TRIGGERS,
525
+ ABUSE_LEVELS
147
526
  };
@@ -0,0 +1,27 @@
1
+ /** Learned query pattern types — wire format for the learned_patterns table. */
2
+ /** All valid learned pattern statuses. */
3
+ export declare const LEARNED_PATTERN_STATUSES: readonly ["pending", "approved", "rejected"];
4
+ /** Status lifecycle for learned query patterns. */
5
+ export type LearnedPatternStatus = (typeof LEARNED_PATTERN_STATUSES)[number];
6
+ /** All valid learned pattern sources. */
7
+ export declare const LEARNED_PATTERN_SOURCES: readonly ["agent", "atlas-learn"];
8
+ /** Who proposed the pattern. */
9
+ export type LearnedPatternSource = (typeof LEARNED_PATTERN_SOURCES)[number];
10
+ /** Wire format for the learned_patterns table. */
11
+ export interface LearnedPattern {
12
+ id: string;
13
+ orgId: string | null;
14
+ patternSql: string;
15
+ description: string | null;
16
+ sourceEntity: string | null;
17
+ sourceQueries: string[] | null;
18
+ /** Score between 0.0 (no confidence) and 1.0 (full confidence). */
19
+ confidence: number;
20
+ repetitionCount: number;
21
+ status: LearnedPatternStatus;
22
+ proposedBy: LearnedPatternSource | null;
23
+ reviewedBy: string | null;
24
+ createdAt: string;
25
+ updatedAt: string;
26
+ reviewedAt: string | null;
27
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Workspace-level model configuration types shared across API, frontend, and SDK.
3
+ *
4
+ * Enterprise customers can configure their own LLM provider and API key per
5
+ * workspace, overriding the platform default. Supported providers: Anthropic,
6
+ * OpenAI, Azure OpenAI, and custom OpenAI-compatible endpoints.
7
+ */
8
+ export declare const MODEL_CONFIG_PROVIDERS: readonly ["anthropic", "openai", "azure-openai", "custom"];
9
+ export type ModelConfigProvider = (typeof MODEL_CONFIG_PROVIDERS)[number];
10
+ export interface WorkspaceModelConfig {
11
+ id: string;
12
+ orgId: string;
13
+ provider: ModelConfigProvider;
14
+ model: string;
15
+ /** Base URL — required for azure-openai and custom providers. */
16
+ baseUrl: string | null;
17
+ /** API key masked to last 4 characters (never sent in full). */
18
+ apiKeyMasked: string;
19
+ createdAt: string;
20
+ updatedAt: string;
21
+ }
22
+ export interface SetWorkspaceModelConfigRequest {
23
+ provider: ModelConfigProvider;
24
+ model: string;
25
+ /** Omit to keep the existing key on update. Required on initial creation. */
26
+ apiKey?: string;
27
+ /** Required for azure-openai and custom providers. */
28
+ baseUrl?: string;
29
+ }
30
+ export interface TestModelConfigRequest {
31
+ provider: ModelConfigProvider;
32
+ model: string;
33
+ apiKey: string;
34
+ baseUrl?: string;
35
+ }
36
+ export interface TestModelConfigResponse {
37
+ success: boolean;
38
+ message: string;
39
+ /** Model name returned by the provider, if available. */
40
+ modelName?: string;
41
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Onboarding email sequence types shared across API and frontend.
3
+ *
4
+ * Defines the email steps, milestone triggers, and tracking state for
5
+ * the automated drip campaign sent to new users.
6
+ */
7
+ export declare const ONBOARDING_EMAIL_STEPS: readonly ["welcome", "connect_database", "first_query", "invite_team", "explore_features"];
8
+ export type OnboardingEmailStep = (typeof ONBOARDING_EMAIL_STEPS)[number];
9
+ export declare const ONBOARDING_MILESTONES: readonly ["signup_completed", "database_connected", "first_query_executed", "team_member_invited", "feature_explored"];
10
+ export type OnboardingMilestone = (typeof ONBOARDING_MILESTONES)[number];
11
+ /** Trigger source for an onboarding email — either a milestone or a time-based fallback. */
12
+ export type OnboardingEmailTrigger = OnboardingMilestone | "time_based";
13
+ export interface OnboardingEmailRecord {
14
+ id: string;
15
+ userId: string;
16
+ orgId: string;
17
+ step: OnboardingEmailStep;
18
+ sentAt: string;
19
+ /** The milestone that triggered this email, or "time_based" for fallback nudges. */
20
+ triggeredBy: OnboardingEmailTrigger;
21
+ }
22
+ export interface OnboardingEmailStatus {
23
+ userId: string;
24
+ email: string;
25
+ orgId: string;
26
+ /** Steps that have been sent. Together with pendingSteps, partitions all OnboardingEmailStep values. */
27
+ sentSteps: OnboardingEmailStep[];
28
+ /** Steps remaining. Complement of sentSteps against the full sequence. */
29
+ pendingSteps: OnboardingEmailStep[];
30
+ /** Whether the user has unsubscribed from onboarding emails. */
31
+ unsubscribed: boolean;
32
+ createdAt: string;
33
+ }
34
+ export interface OnboardingEmailPreferences {
35
+ userId: string;
36
+ onboardingEmails: boolean;
37
+ updatedAt: string;
38
+ }
39
+ /** @deprecated Use OnboardingEmailPreferences instead. */
40
+ export type EmailPreferences = OnboardingEmailPreferences;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Organization types shared across API, frontend, and SDK.
3
+ *
4
+ * These align with Better Auth's organization plugin schema.
5
+ * Atlas uses organizations as the tenant boundary — all data
6
+ * (conversations, audit logs, connections, etc.) is scoped to an org.
7
+ */
8
+ import type { AtlasRole } from "./auth";
9
+ export interface Organization {
10
+ id: string;
11
+ name: string;
12
+ slug: string;
13
+ logo?: string | null;
14
+ metadata?: Record<string, unknown> | null;
15
+ createdAt: string;
16
+ }
17
+ export interface OrgMember {
18
+ id: string;
19
+ organizationId: string;
20
+ userId: string;
21
+ role: OrgRole;
22
+ createdAt: string;
23
+ user?: {
24
+ id: string;
25
+ name: string;
26
+ email: string;
27
+ image?: string | null;
28
+ };
29
+ }
30
+ export interface OrgInvitation {
31
+ id: string;
32
+ organizationId: string;
33
+ email: string;
34
+ role: OrgRole;
35
+ status: "pending" | "accepted" | "rejected" | "canceled";
36
+ inviterId: string;
37
+ expiresAt: string;
38
+ createdAt: string;
39
+ organization?: {
40
+ id: string;
41
+ name: string;
42
+ slug: string;
43
+ };
44
+ }
45
+ /**
46
+ * Org roles in descending privilege order. Same values as AtlasRole,
47
+ * listed high-to-low for display. Single source of truth is ATLAS_ROLES
48
+ * in auth.ts — this is a reversed view for convenience.
49
+ */
50
+ export declare const ORG_ROLES: readonly AtlasRole[];
51
+ export type OrgRole = AtlasRole;