diff --git a/apiserver/dora/store/__init__.py b/apiserver/dora/store/__init__.py index 2f959d93a..0ec5170c5 100644 --- a/apiserver/dora/store/__init__.py +++ b/apiserver/dora/store/__init__.py @@ -20,7 +20,7 @@ def configure_db_with_app(app): app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False app.config["SQLALCHEMY_DATABASE_URI"] = connection_uri - app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {"pool_size": 20, "max_overflow": 5} + app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {"pool_size": 10, "max_overflow": 5} db.init_app(app) diff --git a/web-server/libdefs/ambient.d.ts b/web-server/libdefs/ambient.d.ts index 560951f3f..df608b3ba 100644 --- a/web-server/libdefs/ambient.d.ts +++ b/web-server/libdefs/ambient.d.ts @@ -14,7 +14,7 @@ declare type Org = { created_at: Date; name: string; domain: string; - onboarding_steps: OnboardingStep[]; + onboarding_state: OnboardingStep[]; integrations: Partial; }; @@ -48,7 +48,7 @@ declare type IdentityMap = Record< { username: string; meta?: { avatar_url?: string } } >; -declare type IntegrationsMap = Record<'github', true>; +declare type IntegrationsMap = Record<'github' | 'gitlab' | 'bitbucket', true>; declare type User = { id: string; diff --git a/web-server/pages/api/auth/session.ts b/web-server/pages/api/auth/session.ts index ca846c79c..705087f50 100644 --- a/web-server/pages/api/auth/session.ts +++ b/web-server/pages/api/auth/session.ts @@ -1,5 +1,6 @@ import { NextApiResponse } from 'next/types'; +import { getOnBoardingState } from '@/api/resources/orgs/[org_id]/onboarding'; import { Endpoint, nullSchema } from '@/api-helpers/global'; import { Table } from '@/constants/db'; import { db, getFirstRow } from '@/utils/db'; @@ -33,8 +34,10 @@ endpoint.handle.GET(nullSchema, async (_req, res) => { getOrgDetails(), getOrgIntegrations() ]); + + const onboardingState = await getOnBoardingState(orgDetails.id); res.send({ - org: { ...orgDetails, org_onboarding_steps: [], integrations } || {} + org: { ...orgDetails, ...onboardingState, integrations } || {} }); }); diff --git a/web-server/pages/api/resources/orgs/[org_id]/onboarding.ts b/web-server/pages/api/resources/orgs/[org_id]/onboarding.ts index 36378f54c..f35e2931e 100644 --- a/web-server/pages/api/resources/orgs/[org_id]/onboarding.ts +++ b/web-server/pages/api/resources/orgs/[org_id]/onboarding.ts @@ -20,15 +20,32 @@ const endpoint = new Endpoint(pathSchema); endpoint.handle.GET(nullSchema, async (req, res) => { const { org_id } = req.payload; - const results = await db(Table.UIPreferences) - .select(Columns[Table.UIPreferences].data) - .where(Columns[Table.UIPreferences].entity_id, org_id); - return res.send(results[0]?.data ?? { onboarding_state: [] }); + return res.send(await getOnBoardingState(org_id)); }); endpoint.handle.PUT(putSchema, async (req, res) => { const { org_id, onboarding_state } = req.payload; + return res.send( + await updateOnBoardingState(org_id, onboarding_state as OnboardingSteps[]) + ); +}); + +export default endpoint.serve(); + +export const getOnBoardingState = async ( + org_id: string +): Promise<{ onboarding_state: OnboardingSteps[] }> => { + const results = await db(Table.UIPreferences) + .select(Columns[Table.UIPreferences].data) + .where(Columns[Table.UIPreferences].entity_id, org_id); + return results[0]?.data ?? { onboarding_state: [] }; +}; + +export const updateOnBoardingState = async ( + org_id: ID, + onboarding_state: OnboardingSteps[] +): Promise<{ onboarding_state: OnboardingSteps[] }> => { const results = await db(Table.UIPreferences) .insert({ entity_type: 'ORG', @@ -46,8 +63,5 @@ endpoint.handle.PUT(putSchema, async (req, res) => { ]) .merge() .returning('*'); - - return res.send(results[0]?.data ?? { onboarding_state: [] }); -}); - -export default endpoint.serve(); + return results[0]?.data ?? { onboarding_state: [] }; +}; diff --git a/web-server/pages/api/resources/orgs/[org_id]/teams/v2.ts b/web-server/pages/api/resources/orgs/[org_id]/teams/v2.ts index 1634bc737..9721faa89 100644 --- a/web-server/pages/api/resources/orgs/[org_id]/teams/v2.ts +++ b/web-server/pages/api/resources/orgs/[org_id]/teams/v2.ts @@ -1,4 +1,4 @@ -import { groupBy, prop, uniq, mapObjIndexed, forEachObjIndexed } from 'ramda'; +import { groupBy, prop, mapObjIndexed, forEachObjIndexed } from 'ramda'; import * as yup from 'yup'; import { enableOrgReposIfNotEnabled } from '@/api/integrations/orgs'; @@ -7,14 +7,17 @@ import { getProviderOrgs, getRepos } from '@/api/internal/[org_id]/git_provider_org'; +import { + getOnBoardingState, + updateOnBoardingState +} from '@/api/resources/orgs/[org_id]/onboarding'; import { getTeamRepos } from '@/api/resources/team_repos'; -import { handleRequest } from '@/api-helpers/axios'; import { Endpoint } from '@/api-helpers/global'; import { Columns, Table } from '@/constants/db'; import { Integration } from '@/constants/integrations'; import { getTeamV2Mock } from '@/mocks/teams'; import { BaseTeam } from '@/types/api/teams'; -import { ReqOrgRepo } from '@/types/resources'; +import { OnboardingSteps, ReqOrgRepo } from '@/types/resources'; import { db, getFirstRow } from '@/utils/db'; const getSchema = yup.object().shape({ @@ -113,14 +116,21 @@ endpoint.handle.POST(postSchema, async (req, res) => { org_repos ); - const [team, repos] = await Promise.all([ + const [team, repos, onboardingState] = await Promise.all([ createTeam(org_id, name, []), - enableOrgReposIfNotEnabled(org_id, provider as Integration, orgReposList) + enableOrgReposIfNotEnabled(org_id, provider as Integration, orgReposList), + getOnBoardingState(org_id) ]); - const teamRepos = await addReposToTeam( - team.id, - repos.map((r) => r.id) + const updatedOnboardingState = Array.from( + new Set(onboardingState.onboarding_state).add(OnboardingSteps.TEAM_CREATED) ); + const [teamRepos] = await Promise.all([ + addReposToTeam( + team.id, + repos.map((r) => r.id) + ), + updateOnBoardingState(org_id, updatedOnboardingState) + ]); res.send({ team, teamReposMap: groupBy(prop('team_id'), teamRepos), repos }); }); @@ -182,27 +192,34 @@ const updateTeam = async ( team_name: string, member_ids: string[] ): Promise => { - return handleRequest(`/team/${team_id}`, { - method: 'PATCH', - data: { + return db('Team') + .insert({ + id: team_id, name: team_name, - member_ids: uniq(member_ids) - } - }); + member_ids: member_ids, + is_deleted: false, + updated_at: new Date() + }) + .onConflict('id') + .merge() + .returning('*') + .then(getFirstRow); }; const createTeam = async ( org_id: ID, team_name: string, - member_ids: string[] = [] + member_ids: string[] ): Promise => { - return handleRequest(`/org/${org_id}/team`, { - method: 'POST', - data: { + return db(Table.Team) + .insert({ + org_id, name: team_name, - member_ids: uniq(member_ids) - } - }); + member_ids: member_ids, + is_deleted: false + }) + .returning('*') + .then(getFirstRow); }; const addReposToTeam = async (team_id: ID, repo_ids: ID[]) => {