Skip to content

Commit

Permalink
refactor: merge bot list query requests (#596)
Browse files Browse the repository at this point in the history
* 重构 bots 查询接口,将空间机器人需要的多张表信息一次返回,减少空间页面额外的循环请求
  • Loading branch information
ch-liuzhide authored Dec 18, 2024
2 parents feadeda + 320fa71 commit f8206b7
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 43 deletions.
17 changes: 9 additions & 8 deletions client/app/factory/list/components/BotCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@ import {
Tooltip,
} from '@nextui-org/react';
import { useRouter } from 'next/navigation';
import {
useBotDelete,
useGetBotBoundRepos,
useGetBotRagTask,
} from '@/app/hooks/useBot';
import { useBotDelete, useGetBotRagTask } from '@/app/hooks/useBot';
import { TaskStatus } from '@/types/task';
import ErrorBadgeIcon from '@/public/icons/ErrorBadgeIcon';
import KnowledgeTaskCompleteIcon from '@/public/icons/CheckBadgeIcon';
Expand All @@ -33,12 +29,17 @@ import CardCartIcon from '@/public/icons/CardCartIcon';

declare type Bot = Tables<'bots'>;

const BotInfoIconList = (props: { bot: Bot }) => {
interface BotInfo extends Bot {
github_installed?: boolean;
picture?: string;
nickname?: string;
}

const BotInfoIconList = (props: { bot: BotInfo }) => {
const { bot } = props;
const { data } = useGetBotBoundRepos(bot.id);
const showHomeIcon = bot.domain_whitelist && bot.domain_whitelist.length > 0;
const showCartIcon = bot.public;
const showGithubIcon = data && Array.isArray(data) && data.length > 0;
const showGithubIcon = bot.github_installed;
const texts = [
showGithubIcon ? I18N.components.BotCard.gITHU : '',
showHomeIcon ? I18N.components.BotCard.guanWang : undefined,
Expand Down
70 changes: 70 additions & 0 deletions migrations/supabase/migrations/20241218093541_remote_schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
alter table "public"."profiles" drop constraint "profile_pkey";

drop index if exists "public"."profile_pkey";

alter table "public"."profiles" alter column "sub" set not null;

CREATE INDEX idx_file_sha ON public.rag_docs USING btree (file_sha);

CREATE UNIQUE INDEX profiles_pkey ON public.profiles USING btree (id);

alter table "public"."profiles" add constraint "profiles_pkey" PRIMARY KEY using index "profiles_pkey";

set check_function_bodies = off;

create or replace view "public"."bots_with_profiles_and_github" as SELECT bots.id,
bots.created_at,
bots.updated_at,
bots.avatar,
bots.description,
bots.name,
bots.public,
bots.starters,
bots.uid,
bots.repo_name,
profiles.picture,
profiles.nickname,
CASE
WHEN (github_repo_config.robot_id IS NOT NULL) THEN true
ELSE false
END AS github_installed
FROM ((bots
LEFT JOIN profiles ON (((bots.uid)::text = (profiles.sub)::text)))
LEFT JOIN github_repo_config ON ((bots.id = (github_repo_config.robot_id)::uuid)));


CREATE OR REPLACE FUNCTION public.get_bots_with_profiles_and_github()
RETURNS TABLE(id uuid, created_at timestamp without time zone, updated_at timestamp without time zone, avatar text, description text, name text, public boolean, starters text, uid text, domain_whitelist text[], repo_name text, picture text, nickname text, github_installed boolean)
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN QUERY
SELECT
b.id::uuid,
b.created_at::timestamp,
b.updated_at::timestamp,
b.avatar::text,
b.description::text,
b.name::text,
b.public::boolean,
b.starters::text,
b.uid::text,
b.domain_whitelist::text[],
b.repo_name::text,
p.picture::text,
p.nickname::text,
CASE
WHEN grc.robot_id IS NOT NULL THEN TRUE
ELSE FALSE
END AS github_installed
FROM
bots b
LEFT JOIN
profiles p ON b.uid = p.sub
LEFT JOIN
github_repo_config grc ON b.id::varchar = grc.robot_id;
END;
$function$
;


61 changes: 61 additions & 0 deletions server/bot/list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from typing import Optional

from github import Github
from core.dao.repositoryConfigDAO import RepositoryConfigDAO
from petercat_utils import get_client
from github import Github, Auth


def query_list(
name: Optional[str] = None,
user_id: Optional[str] = None,
access_token: Optional[str] = None,
personal: Optional[str] = None,
):
try:
supabase = get_client()
query = (
supabase.rpc("get_bots_with_profiles_and_github")
if personal == "true"
else supabase.table("bots").select(
"id, created_at, updated_at, avatar, description, name, public, starters, uid, repo_name"
)
)
if name:
query = query.filter("name", "like", f"%{name}%")

if personal == "true":
if not access_token or not user_id:
return {"data": [], "personal": personal}

auth = Auth.Token(token=access_token)
github_user = Github(auth=auth).get_user()
orgs_ids = [org.id for org in github_user.get_orgs()]
bot_ids = []

repository_config_dao = RepositoryConfigDAO()
bots = repository_config_dao.query_bot_id_by_owners(
orgs_ids + [github_user.id]
)

if bots:
bot_ids = [bot["robot_id"] for bot in bots if bot["robot_id"]]

or_clause = f"uid.eq.{user_id}" + (
f",id.in.({','.join(map(str, bot_ids))})" if bot_ids else ""
)
query = query.or_(or_clause)
else:
query = query.eq("public", True)

query = query.order("updated_at", desc=True)
data = query.execute()
if data.data:
unique_data = {}
for item in data.data:
unique_data[item["id"]] = item
deduplicated_list = list(unique_data.values())
return deduplicated_list
return data.data
except Exception as e:
print(f"query list error: {e}")
38 changes: 3 additions & 35 deletions server/bot/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from fastapi.responses import JSONResponse
from github import Github, Auth
from auth.get_user_info import get_user, get_user_id
from bot.list import query_list
from core.dao.botApprovalDAO import BotApprovalDAO
from core.dao.botDAO import BotDAO
from core.dao.repositoryConfigDAO import RepositoryConfigDAO
Expand Down Expand Up @@ -32,42 +33,9 @@ def get_bot_list(
user: Annotated[User | None, Depends(get_user)] = None,
):
try:
supabase = get_client()
query = supabase.table("bots").select(
"id, created_at, updated_at, avatar, description, name, public, starters, uid, repo_name"
)

if personal == "true":
if not user or not user.access_token:
return {"data": [], "personal": personal}

auth = Auth.Token(token=user.access_token)
github_user = Github(auth=auth).get_user()
orgs_ids = [org.id for org in github_user.get_orgs()]
bot_ids = []

repository_config_dao = RepositoryConfigDAO()
bots = repository_config_dao.query_bot_id_by_owners(
orgs_ids + [github_user.id]
)

if bots:
bot_ids = [bot["robot_id"] for bot in bots if bot["robot_id"]]

or_clause = f"uid.eq.{user.id}" + (
f",id.in.({','.join(map(str, bot_ids))})" if bot_ids else ""
)
query = query.or_(or_clause)
else:
query = query.eq("public", True)

if name:
query = query.filter("name", "like", f"%{name}%")

query = query.order("updated_at", desc=True)
data = query.execute()
data = query_list(name, user.id, user.access_token, personal)

return {"data": data.data if data and data.data else [], "personal": personal}
return {"data": data if data else [], "personal": personal}

except Exception as e:
return JSONResponse(
Expand Down

0 comments on commit f8206b7

Please sign in to comment.