mirror of
https://github.com/lobehub/lobehub
synced 2026-04-21 09:37:28 +00:00
👷 build(database): add topic status and tasks automation mode (#13994)
This commit is contained in:
parent
93603ae83b
commit
3bcd581e7c
8 changed files with 14884 additions and 16 deletions
|
|
@ -516,8 +516,9 @@ table document_histories {
|
|||
saved_at "timestamp with time zone" [not null]
|
||||
|
||||
indexes {
|
||||
(document_id, saved_at) [name: 'document_histories_document_id_saved_at_idx']
|
||||
(user_id, saved_at) [name: 'document_histories_user_id_saved_at_idx']
|
||||
document_id [name: 'document_histories_document_id_idx']
|
||||
user_id [name: 'document_histories_user_id_idx']
|
||||
saved_at [name: 'document_histories_saved_at_idx']
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1523,7 +1524,8 @@ table tasks {
|
|||
status text [not null, default: 'backlog']
|
||||
priority integer [default: 0]
|
||||
sort_order integer [default: 0]
|
||||
heartbeat_interval integer [default: 300]
|
||||
automation_mode text
|
||||
heartbeat_interval integer
|
||||
heartbeat_timeout integer
|
||||
last_heartbeat_at "timestamp with time zone"
|
||||
schedule_pattern text
|
||||
|
|
@ -1550,6 +1552,7 @@ table tasks {
|
|||
parent_task_id [name: 'tasks_parent_task_id_idx']
|
||||
status [name: 'tasks_status_idx']
|
||||
priority [name: 'tasks_priority_idx']
|
||||
automation_mode [name: 'tasks_automation_mode_idx']
|
||||
(status, last_heartbeat_at) [name: 'tasks_heartbeat_idx']
|
||||
}
|
||||
}
|
||||
|
|
@ -1631,6 +1634,8 @@ table topics {
|
|||
metadata jsonb
|
||||
trigger text
|
||||
mode text
|
||||
status text
|
||||
completed_at "timestamp with time zone"
|
||||
accessed_at "timestamp with time zone" [not null, default: `now()`]
|
||||
created_at "timestamp with time zone" [not null, default: `now()`]
|
||||
updated_at "timestamp with time zone" [not null, default: `now()`]
|
||||
|
|
@ -1643,6 +1648,8 @@ table topics {
|
|||
group_id [name: 'topics_group_id_idx']
|
||||
agent_id [name: 'topics_agent_id_idx']
|
||||
trigger [name: 'topics_trigger_idx']
|
||||
status [name: 'topics_status_idx']
|
||||
(user_id, completed_at) [name: 'topics_user_id_completed_at_idx']
|
||||
() [name: 'topics_extract_status_gin_idx']
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
ALTER TABLE "tasks" ALTER COLUMN "heartbeat_interval" DROP DEFAULT;--> statement-breakpoint
|
||||
ALTER TABLE "tasks" ADD COLUMN IF NOT EXISTS "automation_mode" text;--> statement-breakpoint
|
||||
ALTER TABLE "topics" ADD COLUMN IF NOT EXISTS "status" text;--> statement-breakpoint
|
||||
ALTER TABLE "topics" ADD COLUMN IF NOT EXISTS "completed_at" timestamp with time zone;--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "tasks_automation_mode_idx" ON "tasks" USING btree ("automation_mode");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "topics_status_idx" ON "topics" USING btree ("status");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "topics_user_id_completed_at_idx" ON "topics" USING btree ("user_id","completed_at");
|
||||
14822
packages/database/migrations/meta/0099_snapshot.json
Normal file
14822
packages/database/migrations/meta/0099_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -693,6 +693,13 @@
|
|||
"when": 1776234919716,
|
||||
"tag": "0098_add_document_history",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 99,
|
||||
"version": "7",
|
||||
"when": 1776674965365,
|
||||
"tag": "0099_topic_status_tasks_automation_mode",
|
||||
"breakpoints": true
|
||||
}
|
||||
],
|
||||
"version": "6"
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ describe('TopicModel - Create', () => {
|
|||
editorData: null,
|
||||
trigger: null,
|
||||
mode: null,
|
||||
status: null,
|
||||
completedAt: null,
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: expect.any(Date),
|
||||
accessedAt: expect.any(Date),
|
||||
|
|
@ -109,6 +111,8 @@ describe('TopicModel - Create', () => {
|
|||
metadata: null,
|
||||
trigger: null,
|
||||
mode: null,
|
||||
status: null,
|
||||
completedAt: null,
|
||||
sessionId,
|
||||
userId,
|
||||
createdAt: expect.any(Date),
|
||||
|
|
|
|||
|
|
@ -58,8 +58,11 @@ export const tasks = pgTable(
|
|||
priority: integer('priority').default(0), // 'no' | 'urgent' | 'high' | 'normal' | 'low'
|
||||
sortOrder: integer('sort_order').default(0), // manual sort within parent, lower = higher
|
||||
|
||||
// Automation mode (mutually exclusive with each other; null = no automation)
|
||||
automationMode: text('automation_mode').$type<'heartbeat' | 'schedule'>(),
|
||||
|
||||
// Heartbeat
|
||||
heartbeatInterval: integer('heartbeat_interval').default(300), // seconds
|
||||
heartbeatInterval: integer('heartbeat_interval'), // seconds, null = no heartbeat configured
|
||||
heartbeatTimeout: integer('heartbeat_timeout'), // seconds, null = disabled (default off)
|
||||
lastHeartbeatAt: timestamptz('last_heartbeat_at'),
|
||||
|
||||
|
|
@ -97,6 +100,7 @@ export const tasks = pgTable(
|
|||
index('tasks_parent_task_id_idx').on(t.parentTaskId),
|
||||
index('tasks_status_idx').on(t.status),
|
||||
index('tasks_priority_idx').on(t.priority),
|
||||
index('tasks_automation_mode_idx').on(t.automationMode),
|
||||
index('tasks_heartbeat_idx').on(t.status, t.lastHeartbeatAt),
|
||||
],
|
||||
);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ export const topics = pgTable(
|
|||
metadata: jsonb('metadata').$type<ChatTopicMetadata | undefined>(),
|
||||
trigger: text('trigger'), // 'cron' | 'chat' | 'api' | 'eval' - topic creation trigger source
|
||||
mode: text('mode'), // 'temp' | 'test' | 'default' - topic usage scenario
|
||||
status: text('status', { enum: ['active', 'completed', 'archived'] }),
|
||||
completedAt: timestamptz('completed_at'),
|
||||
...timestamps,
|
||||
},
|
||||
(t) => [
|
||||
|
|
@ -52,6 +54,8 @@ export const topics = pgTable(
|
|||
index('topics_group_id_idx').on(t.groupId),
|
||||
index('topics_agent_id_idx').on(t.agentId),
|
||||
index('topics_trigger_idx').on(t.trigger),
|
||||
index('topics_status_idx').on(t.status),
|
||||
index('topics_user_id_completed_at_idx').on(t.userId, t.completedAt),
|
||||
index('topics_extract_status_gin_idx').using(
|
||||
'gin',
|
||||
sql`(metadata->'userMemoryExtractStatus') jsonb_path_ops`,
|
||||
|
|
|
|||
|
|
@ -44,22 +44,35 @@ afterEach(() => {
|
|||
vi.doUnmock('@/routes/onboarding/config');
|
||||
});
|
||||
|
||||
// Each test does vi.resetModules() + dynamic import of the component, which
|
||||
// re-parses antd + @lobehub/ui fresh. On cold CI runs this can blow past the
|
||||
// default 5s timeout even though the test is doing nothing slow itself.
|
||||
const TEST_TIMEOUT_MS = 15_000;
|
||||
|
||||
describe('ModeSwitch', () => {
|
||||
it('renders both onboarding variants when agent onboarding is enabled', async () => {
|
||||
it(
|
||||
'renders both onboarding variants when agent onboarding is enabled',
|
||||
async () => {
|
||||
await renderModeSwitch({ enabled: true, showLabel: true });
|
||||
|
||||
expect(screen.getByText('Choose your onboarding mode')).toBeInTheDocument();
|
||||
expect(screen.getByRole('radio', { name: 'Conversational' })).toBeChecked();
|
||||
expect(screen.getByRole('radio', { name: 'Classic' })).not.toBeChecked();
|
||||
});
|
||||
},
|
||||
TEST_TIMEOUT_MS,
|
||||
);
|
||||
|
||||
it('hides the onboarding switch entirely when agent onboarding is disabled', async () => {
|
||||
it(
|
||||
'hides the onboarding switch entirely when agent onboarding is disabled',
|
||||
async () => {
|
||||
await renderModeSwitch({ enabled: false });
|
||||
|
||||
expect(screen.queryByRole('radio', { name: 'Conversational' })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('radio', { name: 'Classic' })).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Choose your onboarding mode')).not.toBeInTheDocument();
|
||||
});
|
||||
},
|
||||
TEST_TIMEOUT_MS,
|
||||
);
|
||||
|
||||
it('keeps action buttons visible when agent onboarding is disabled', async () => {
|
||||
await renderModeSwitch({
|
||||
|
|
|
|||
Loading…
Reference in a new issue