mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Add cloud settings (#49)
These are meant to be organization settings about roo code cloud, rather than cloud managed non-cloud settings for the extension.
This commit is contained in:
parent
6a65576136
commit
cdb9734b29
12 changed files with 738 additions and 14 deletions
|
|
@ -11,6 +11,7 @@ import {
|
|||
type OrganizationSettings,
|
||||
organizationAllowListSchema,
|
||||
organizationDefaultSettingsSchema,
|
||||
organizationCloudSettingsSchema,
|
||||
} from '@/types';
|
||||
import { AuditLogTargetType, client as db, orgSettings } from '@/db/server';
|
||||
import { handleError, isAuthSuccess } from '@/lib/server';
|
||||
|
|
@ -18,9 +19,7 @@ import { handleError, isAuthSuccess } from '@/lib/server';
|
|||
import { validateAuth } from './auth';
|
||||
import { insertAuditLog } from './auditLogs';
|
||||
|
||||
export async function getOrganizationSettings(): Promise<
|
||||
OrganizationSettings | undefined
|
||||
> {
|
||||
export async function getOrganizationSettings(): Promise<OrganizationSettings> {
|
||||
const { userId, orgId } = await auth();
|
||||
|
||||
if (!userId) {
|
||||
|
|
@ -37,7 +36,7 @@ export async function getOrganizationSettings(): Promise<
|
|||
.where(eq(orgSettings.orgId, orgId))
|
||||
.limit(1);
|
||||
|
||||
return settings.length === 0 ? ORGANIZATION_DEFAULT : settings[0];
|
||||
return settings[0] || ORGANIZATION_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -47,12 +46,16 @@ const updateOrganizationSchema = z
|
|||
.object({
|
||||
defaultSettings: organizationDefaultSettingsSchema.optional(),
|
||||
allowList: organizationAllowListSchema.optional(),
|
||||
cloudSettings: organizationCloudSettingsSchema.optional(),
|
||||
})
|
||||
.refine(
|
||||
(data) =>
|
||||
data.defaultSettings !== undefined || data.allowList !== undefined,
|
||||
data.defaultSettings !== undefined ||
|
||||
data.allowList !== undefined ||
|
||||
data.cloudSettings !== undefined,
|
||||
{
|
||||
message: 'At least one of defaultSettings or allowList must be provided',
|
||||
message:
|
||||
'At least one of defaultSettings, allowList, or cloudSettings must be provided',
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -96,12 +99,17 @@ export async function updateOrganization(
|
|||
updateData.allowList = validatedData.allowList;
|
||||
}
|
||||
|
||||
if (validatedData.cloudSettings) {
|
||||
updateData.cloudSettings = validatedData.cloudSettings;
|
||||
}
|
||||
|
||||
if (isNewRecord) {
|
||||
await tx.insert(orgSettings).values({
|
||||
orgId,
|
||||
version: 1,
|
||||
defaultSettings: validatedData.defaultSettings || {},
|
||||
allowList: validatedData.allowList || ORGANIZATION_ALLOW_ALL,
|
||||
cloudSettings: validatedData.cloudSettings || {},
|
||||
});
|
||||
} else {
|
||||
await tx
|
||||
|
|
@ -135,6 +143,17 @@ export async function updateOrganization(
|
|||
description: 'Updated organization allow list',
|
||||
});
|
||||
}
|
||||
|
||||
if (validatedData.cloudSettings) {
|
||||
await insertAuditLog(tx, {
|
||||
userId,
|
||||
orgId,
|
||||
targetType: AuditLogTargetType.CLOUD_SETTINGS,
|
||||
targetId: 'organization-cloud-settings',
|
||||
newValue: validatedData.cloudSettings,
|
||||
description: 'Updated organization cloud settings',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
'use client';
|
||||
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { toast } from 'sonner';
|
||||
import { Cloud } from 'lucide-react';
|
||||
|
||||
import {
|
||||
type OrganizationSettings,
|
||||
type OrganizationCloudSettings,
|
||||
} from '@/types';
|
||||
import {
|
||||
getOrganizationSettings,
|
||||
updateOrganization,
|
||||
} from '@/actions/organizationSettings';
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
} from '@/components/ui';
|
||||
|
||||
type CloudSettingsFormValues = {
|
||||
recordTaskMessages: boolean;
|
||||
};
|
||||
|
||||
type CloudSettingsFormProps = {
|
||||
orgSettings: OrganizationSettings;
|
||||
queryClient: ReturnType<typeof useQueryClient>;
|
||||
};
|
||||
|
||||
const CloudSettingsForm = ({
|
||||
orgSettings,
|
||||
queryClient,
|
||||
}: CloudSettingsFormProps) => {
|
||||
const t = useTranslations('CloudSettings');
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
|
||||
const form = useForm<CloudSettingsFormValues>({
|
||||
defaultValues: {
|
||||
recordTaskMessages:
|
||||
orgSettings.cloudSettings?.recordTaskMessages ?? false,
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = async (data: CloudSettingsFormValues) => {
|
||||
setIsSaving(true);
|
||||
|
||||
try {
|
||||
const cloudSettings: OrganizationCloudSettings = {
|
||||
recordTaskMessages: data.recordTaskMessages,
|
||||
};
|
||||
|
||||
const result = await updateOrganization({ cloudSettings });
|
||||
|
||||
if (result.success) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['getOrganizationSettings'],
|
||||
});
|
||||
toast.success('Cloud settings saved successfully');
|
||||
} else {
|
||||
throw new Error(result.error || 'An unexpected error occurred.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update cloud settings:', error);
|
||||
toast.error('Failed to save cloud settings. Please try again.');
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="cl-header 🔒️ cl-internal-qo3qk7">
|
||||
<div className="cl-internal-1pr5xvn">
|
||||
<h1 className="cl-headerTitle 🔒️ cl-internal-190cjq9">
|
||||
{t('cloud_section_title')}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mb-6 text-sm text-muted-foreground">
|
||||
{t('cloud_section_description')}
|
||||
</p>
|
||||
<div className="space-y-8">
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||
<div className="space-y-4 rounded-lg p-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Cloud className="size-5" />
|
||||
<h2 className="text-lg font-medium">Task Recording</h2>
|
||||
</div>
|
||||
<div className="mt-4 space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="recordTaskMessages"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-start space-x-3 space-y-0 rounded-md border p-4">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
disabled={isSaving}
|
||||
/>
|
||||
</FormControl>
|
||||
<div className="space-y-1 leading-none">
|
||||
<FormLabel>{t('record_task_messages')}</FormLabel>
|
||||
<FormDescription>
|
||||
{t('record_task_messages_description')}
|
||||
</FormDescription>
|
||||
</div>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end space-x-4 border-t pt-4">
|
||||
<Button type="submit" disabled={isSaving}>
|
||||
{isSaving ? (
|
||||
<>
|
||||
<span className="mr-2">Saving...</span>
|
||||
<span className="animate-spin">⟳</span>
|
||||
</>
|
||||
) : (
|
||||
'Save Changes'
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const CloudSettings = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { data: orgSettings } = useQuery({
|
||||
queryKey: ['getOrganizationSettings'],
|
||||
queryFn: getOrganizationSettings,
|
||||
});
|
||||
|
||||
if (!orgSettings) {
|
||||
return (
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<div className="animate-spin text-2xl">⟳</div>
|
||||
<span className="ml-2">Loading settings...</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<CloudSettingsForm orgSettings={orgSettings} queryClient={queryClient} />
|
||||
);
|
||||
};
|
||||
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { OrganizationProfile } from '@clerk/nextjs';
|
||||
import { ListTodo, SlidersHorizontal } from 'lucide-react';
|
||||
import { ListTodo, SlidersHorizontal, Cloud } from 'lucide-react';
|
||||
|
||||
import { DefaultParameters } from './DefaultParameters';
|
||||
import { ProviderWhitelist } from './ProviderWhitelist';
|
||||
import { CloudSettings } from './CloudSettings';
|
||||
|
||||
export const Org = () => {
|
||||
const t = useTranslations('OrganizationProfile');
|
||||
|
|
@ -24,6 +25,13 @@ export const Org = () => {
|
|||
>
|
||||
<ProviderWhitelist />
|
||||
</OrganizationProfile.Page>
|
||||
<OrganizationProfile.Page
|
||||
label={t('cloud_settings')}
|
||||
url="cloud-settings"
|
||||
labelIcon={<Cloud className="size-4" />}
|
||||
>
|
||||
<CloudSettings />
|
||||
</OrganizationProfile.Page>
|
||||
<OrganizationProfile.Page
|
||||
label={t('default_parameters')}
|
||||
url="default-parameters"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import { auth } from '@clerk/nextjs/server';
|
||||
|
||||
import { type OrganizationSettings, ORGANIZATION_ALLOW_ALL } from '@/types';
|
||||
import { getOrganizationSettings } from '@/actions/organizationSettings';
|
||||
|
||||
export async function GET() {
|
||||
|
|
@ -22,12 +21,7 @@ export async function GET() {
|
|||
);
|
||||
}
|
||||
|
||||
const settings: OrganizationSettings =
|
||||
(await getOrganizationSettings()) || {
|
||||
defaultSettings: {},
|
||||
allowList: ORGANIZATION_ALLOW_ALL,
|
||||
version: 0,
|
||||
};
|
||||
const settings = await getOrganizationSettings();
|
||||
|
||||
return NextResponse.json(settings);
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@ export enum AuditLogTargetType {
|
|||
PROVIDER_WHITELIST = 1,
|
||||
DEFAULT_PARAMETERS = 2,
|
||||
MEMBER_CHANGE = 3, // TODO: Currently no logs of this type are collected.
|
||||
CLOUD_SETTINGS = 4,
|
||||
}
|
||||
|
|
|
|||
1
src/db/migrations/0004_overjoyed_bucky.sql
Normal file
1
src/db/migrations/0004_overjoyed_bucky.sql
Normal file
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE "organization_settings" ADD COLUMN "cloud_settings" jsonb DEFAULT '{}'::jsonb NOT NULL;
|
||||
503
src/db/migrations/meta/0004_snapshot.json
Normal file
503
src/db/migrations/meta/0004_snapshot.json
Normal file
|
|
@ -0,0 +1,503 @@
|
|||
{
|
||||
"id": "5c95f3bf-5048-4ba1-9f71-2110879fc161",
|
||||
"prevId": "bef500d1-5175-4068-af51-1f565355f1ac",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.audit_logs": {
|
||||
"name": "audit_logs",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"organization_id": {
|
||||
"name": "organization_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"target_type": {
|
||||
"name": "target_type",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"target_id": {
|
||||
"name": "target_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"new_value": {
|
||||
"name": "new_value",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"audit_logs_user_id_idx": {
|
||||
"name": "audit_logs_user_id_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "user_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"audit_logs_organization_id_idx": {
|
||||
"name": "audit_logs_organization_id_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "organization_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"audit_logs_target_idx": {
|
||||
"name": "audit_logs_target_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "target_type",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
},
|
||||
{
|
||||
"expression": "target_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"audit_logs_created_at_idx": {
|
||||
"name": "audit_logs_created_at_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "created_at",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"audit_logs_user_id_users_id_fk": {
|
||||
"name": "audit_logs_user_id_users_id_fk",
|
||||
"tableFrom": "audit_logs",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": ["user_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"audit_logs_organization_id_organizations_id_fk": {
|
||||
"name": "audit_logs_organization_id_organizations_id_fk",
|
||||
"tableFrom": "audit_logs",
|
||||
"tableTo": "organizations",
|
||||
"columnsFrom": ["organization_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.organization_settings": {
|
||||
"name": "organization_settings",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"organization_id": {
|
||||
"name": "organization_id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"version": {
|
||||
"name": "version",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 1
|
||||
},
|
||||
"cloud_settings": {
|
||||
"name": "cloud_settings",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'{}'::jsonb"
|
||||
},
|
||||
"default_settings": {
|
||||
"name": "default_settings",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'{}'::jsonb"
|
||||
},
|
||||
"allow_list": {
|
||||
"name": "allow_list",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'{\"allowAll\":true,\"providers\":{}}'::jsonb"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"organization_settings_created_at_idx": {
|
||||
"name": "organization_settings_created_at_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "created_at",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"organization_settings_organization_id_organizations_id_fk": {
|
||||
"name": "organization_settings_organization_id_organizations_id_fk",
|
||||
"tableFrom": "organization_settings",
|
||||
"tableTo": "organizations",
|
||||
"columnsFrom": ["organization_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.organizations": {
|
||||
"name": "organizations",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"image_url": {
|
||||
"name": "image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"entity": {
|
||||
"name": "entity",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"last_sync_at": {
|
||||
"name": "last_sync_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"organizations_slug_idx": {
|
||||
"name": "organizations_slug_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "slug",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"organizations_created_at_idx": {
|
||||
"name": "organizations_created_at_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "created_at",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"organization_id": {
|
||||
"name": "organization_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"organization_role": {
|
||||
"name": "organization_role",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"image_url": {
|
||||
"name": "image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"entity": {
|
||||
"name": "entity",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"last_sync_at": {
|
||||
"name": "last_sync_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"users_organization_id_idx": {
|
||||
"name": "users_organization_id_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "organization_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"users_organization_role_idx": {
|
||||
"name": "users_organization_role_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "organization_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
},
|
||||
{
|
||||
"expression": "organization_role",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"users_email_idx": {
|
||||
"name": "users_email_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "email",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"users_created_at_idx": {
|
||||
"name": "users_created_at_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "created_at",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"users_organization_id_organizations_id_fk": {
|
||||
"name": "users_organization_id_organizations_id_fk",
|
||||
"tableFrom": "users",
|
||||
"tableTo": "organizations",
|
||||
"columnsFrom": ["organization_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
}
|
||||
},
|
||||
"enums": {},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"roles": {},
|
||||
"policies": {},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,13 @@
|
|||
"when": 1747551227749,
|
||||
"tag": "0003_strange_wild_pack",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1748555520729,
|
||||
"tag": "0004_overjoyed_bucky",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
type OrganizationDefaultSettings,
|
||||
type OrganizationAllowList,
|
||||
ORGANIZATION_ALLOW_ALL,
|
||||
type OrganizationCloudSettings,
|
||||
} from '@/types';
|
||||
|
||||
import { AuditLogTargetType } from './enums';
|
||||
|
|
@ -93,6 +94,10 @@ export const orgSettings = pgTable(
|
|||
.primaryKey()
|
||||
.references(() => orgs.id), // Assigned by Clerk.
|
||||
version: integer('version').notNull().default(1),
|
||||
cloudSettings: jsonb('cloud_settings')
|
||||
.notNull()
|
||||
.$type<OrganizationCloudSettings>()
|
||||
.default({}),
|
||||
defaultSettings: jsonb('default_settings')
|
||||
.notNull()
|
||||
.$type<OrganizationDefaultSettings>()
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
},
|
||||
"OrganizationProfile": {
|
||||
"provider_whitelist": "Provider Whitelist",
|
||||
"cloud_settings": "Cloud Settings",
|
||||
"default_parameters": "Default Parameters"
|
||||
},
|
||||
"ProviderWhitelist": {
|
||||
|
|
@ -27,6 +28,12 @@
|
|||
"parameters_section_title": "Default Parameters",
|
||||
"parameters_section_description": "Set global default parameters for AI model calls"
|
||||
},
|
||||
"CloudSettings": {
|
||||
"cloud_section_title": "Cloud Settings",
|
||||
"cloud_section_description": "Configure how your organization's data is handled in the cloud.",
|
||||
"record_task_messages": "Record task messages",
|
||||
"record_task_messages_description": "When enabled task messages and interactions will be recorded."
|
||||
},
|
||||
"Analytics": {
|
||||
"view_mode_title": "View By",
|
||||
"view_mode_developers": "Developers",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
},
|
||||
"OrganizationProfile": {
|
||||
"provider_whitelist": "Liste blanche des fournisseurs",
|
||||
"cloud_settings": "Paramètres Cloud",
|
||||
"default_parameters": "Paramètres par défaut"
|
||||
},
|
||||
"ProviderWhitelist": {
|
||||
|
|
@ -27,6 +28,12 @@
|
|||
"parameters_section_title": "Paramètres par défaut",
|
||||
"parameters_section_description": "Définissez les paramètres par défaut globaux pour les appels aux modèles d'IA"
|
||||
},
|
||||
"CloudSettings": {
|
||||
"cloud_section_title": "Paramètres Cloud",
|
||||
"cloud_section_description": "Configurez la manière dont les données de votre organisation sont gérées dans le cloud.",
|
||||
"record_task_messages": "Enregistrer les messages de tâche",
|
||||
"record_task_messages_description": "Lorsque cette option est activée, les messages et interactions de tâche seront enregistrés."
|
||||
},
|
||||
"Analytics": {
|
||||
"view_mode_title": "Afficher Par",
|
||||
"view_mode_developers": "Développeurs",
|
||||
|
|
|
|||
|
|
@ -40,8 +40,17 @@ export type OrganizationDefaultSettings = z.infer<
|
|||
typeof organizationDefaultSettingsSchema
|
||||
>;
|
||||
|
||||
export const organizationCloudSettingsSchema = z.object({
|
||||
recordTaskMessages: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export type OrganizationCloudSettings = z.infer<
|
||||
typeof organizationCloudSettingsSchema
|
||||
>;
|
||||
|
||||
export const organizationSettingsSchema = z.object({
|
||||
version: z.number(),
|
||||
cloudSettings: organizationCloudSettingsSchema.optional(),
|
||||
defaultSettings: organizationDefaultSettingsSchema,
|
||||
allowList: organizationAllowListSchema,
|
||||
});
|
||||
|
|
@ -50,6 +59,7 @@ export type OrganizationSettings = z.infer<typeof organizationSettingsSchema>;
|
|||
|
||||
export const ORGANIZATION_DEFAULT: OrganizationSettings = {
|
||||
version: 0,
|
||||
cloudSettings: {},
|
||||
defaultSettings: {},
|
||||
allowList: ORGANIZATION_ALLOW_ALL,
|
||||
} as const;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue