Skip to content

Commit

Permalink
4081 - Rename Cycle (#4102)
Browse files Browse the repository at this point in the history
  • Loading branch information
minotogna authored Nov 11, 2024
1 parent 9d15ff9 commit 7f89aee
Show file tree
Hide file tree
Showing 13 changed files with 188 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/meta/assessment/activityLog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export enum ActivityLogMessage {
assessmentCreate = 'assessmentCreate',
assessmentCycleCreate = 'assessmentCycleCreate',
assessmentCycleDelete = 'assessmentCycleDelete',
assessmentCycleRename = 'assessmentCycleRename',
assessmentStatusUpdate = 'assessmentStatusUpdate',
assessmentUpdate = 'assessmentUpdate',
contactCreate = 'contactCreate',
Expand Down
2 changes: 2 additions & 0 deletions src/meta/assessment/cols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const cloneProps = (props: { cycleSource: Cycle; cycleTarget: Cycle; col: Col })
_props.labels[cycleTargetUuid] = Objects.cloneDeep(_props.labels[cycleSourceUuid])
if (!Objects.isNil(_props.linkedNodes?.[cycleSourceUuid]))
_props.linkedNodes[cycleTargetUuid] = Objects.cloneDeep(_props.linkedNodes[cycleSourceUuid])
if (!Objects.isNil(_props.select?.[cycleSourceUuid]))
_props.select[cycleTargetUuid] = Objects.cloneDeep(_props.select[cycleSourceUuid])
if (!Objects.isNil(_props.style?.[cycleSourceUuid]))
_props.style[cycleTargetUuid] = Objects.cloneDeep(_props.style[cycleSourceUuid])
if (!Objects.isNil(_props.validateFns?.[cycleSourceUuid]))
Expand Down
2 changes: 2 additions & 0 deletions src/server/controller/assessment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { generateMetadataCache } from './generateMetadataCache'
import { getOneWithCycle } from './getOne'
import { remove } from './remove'
import { removeCycle } from './removeCycle'
import { renameCycle } from './renameCycle'
import { updateDefaultCycle } from './update'

export const AssessmentController = {
Expand All @@ -24,6 +25,7 @@ export const AssessmentController = {
cloneCycle,
createCycle,
removeCycle,
renameCycle,

// data cache
generateDataCache,
Expand Down
1 change: 1 addition & 0 deletions src/server/controller/assessment/renameCycle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { renameCycle } from './renameCycle'
43 changes: 43 additions & 0 deletions src/server/controller/assessment/renameCycle/renameCycle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { ActivityLogMessage, Assessment, Cycle } from 'meta/assessment'
import { User } from 'meta/user'

import { generateMetaCache } from 'server/controller/assessment/generateMetaCache'
import { getOneWithCycle } from 'server/controller/assessment/getOne'
import { renameDataCache } from 'server/controller/assessment/renameCycle/renameDataCache'
import { renameMetadataCache } from 'server/controller/assessment/renameCycle/renameMetadataCache'
import { BaseProtocol, DB } from 'server/db'
import { CycleRepository } from 'server/repository/assessmentCycle/cycle'
import { ActivityLogRepository } from 'server/repository/public/activityLog'

type Props = {
assessment: Assessment
cycle: Cycle
name: string
user: User
}

type Returned = {
assessment: Assessment
cycle: Cycle
}

export const renameCycle = async (props: Props, client: BaseProtocol = DB): Promise<Returned> => {
const { assessment, cycle: cycleSource, name, user } = props
const { name: assessmentName } = assessment.props
const { uuid: cycleUuid } = cycleSource

return client.tx(async (t) => {
const cycleTarget = await CycleRepository.rename({ assessment, cycle: cycleSource, name }, t)

// update cache
await generateMetaCache(t)
await renameMetadataCache({ assessment, cycleSource, cycleTarget }, t)
await renameDataCache({ assessment, cycleSource, cycleTarget }, t)

const message = ActivityLogMessage.assessmentCycleRename
const activityLog = { target: cycleTarget, section: 'assessment', message, user }
await ActivityLogRepository.insertActivityLog({ activityLog, assessment }, t)

return getOneWithCycle({ assessmentName, cycleUuid }, t)
})
}
24 changes: 24 additions & 0 deletions src/server/controller/assessment/renameCycle/renameDataCache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Assessment, Cycle } from 'meta/assessment'

import { BaseProtocol, DB } from 'server/db'
import { CountryRepository } from 'server/repository/assessmentCycle/country'
import { DataRedisRepository } from 'server/repository/redis/data'
import { Logger } from 'server/utils/logger'

type Props = {
assessment: Assessment
cycleSource: Cycle
cycleTarget: Cycle
}

export const renameDataCache = async (props: Props, client: BaseProtocol = DB): Promise<void> => {
const { assessment, cycleSource, cycleTarget } = props
const { name: assessmentName } = assessment.props
const { name: cycleName } = cycleTarget

const countries = await CountryRepository.getMany({ assessment, cycle: cycleTarget }, client)
const countryISOs = countries.map((c) => c.countryIso)

await DataRedisRepository.renameCountriesData({ assessment, countryISOs, cycleSource, cycleTarget })
Logger.info(`${assessmentName}-${cycleName}: Data renamed from redis`)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Assessment, Cycle } from 'meta/assessment'

import { BaseProtocol, DB } from 'server/db'
import { RowRedisRepository } from 'server/repository/redis/row'
import { SectionRedisRepository } from 'server/repository/redis/section'
import { Logger } from 'server/utils/logger'

type Props = {
assessment: Assessment
cycleSource: Cycle
cycleTarget: Cycle
}

export const renameMetadataCache = async (props: Props, client: BaseProtocol = DB) => {
const { assessment, cycleSource, cycleTarget } = props
const { name: assessmentName } = assessment.props
const { name: cycleName } = cycleTarget

const rows = await RowRedisRepository.getRows({ assessment, force: true }, client)
Logger.debug(`${assessmentName}: "${Object.keys(rows).length} rows" generated`)

await SectionRedisRepository.renameCycleEntries({ assessment, cycleSource, cycleTarget })
Logger.debug(`${assessmentName}-${cycleName}: Metadata renamed from redis`)
}
2 changes: 2 additions & 0 deletions src/server/repository/assessmentCycle/cycle/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { create } from './create'
import { remove } from './remove'
import { removeSchema } from './removeSchema'
import { rename } from './rename'
import { update } from './update'

export const CycleRepository = {
create,
remove,
removeSchema,
rename,
update,
}
30 changes: 30 additions & 0 deletions src/server/repository/assessmentCycle/cycle/rename.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Objects } from 'utils/objects'

import { Assessment, Cycle } from 'meta/assessment'

import { BaseProtocol, DB, Schemas } from 'server/db'

type Props = {
assessment: Assessment
cycle: Cycle
name: string
}

export const rename = async (props: Props, client: BaseProtocol = DB): Promise<Cycle> => {
const { assessment, cycle, name } = props

const schemaCycleSource = Schemas.getNameCycle(assessment, cycle)
const schemaCycleTarget = Schemas.getNameCycle(assessment, { ...cycle, name })

await DB.query<void>(`alter schema ${schemaCycleSource} rename to ${schemaCycleTarget};`)

return client.one<Cycle>(
`
update public.assessment_cycle
set name = $2
where uuid = $1
returning *`,
[cycle.uuid, name],
Objects.camelize
)
}
2 changes: 2 additions & 0 deletions src/server/repository/redis/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getCountriesData } from './getCountriesData'
import { getODPYears } from './getODPYears'
import { removeCountriesData } from './removeCountriesData'
import { removeNodes } from './removeNodes'
import { renameCountriesData } from './renameCountriesData'
import { updateNode } from './updateNode'
import { updateNodes } from './updateNodes'

Expand All @@ -12,6 +13,7 @@ export const DataRedisRepository = {
getODPYears,
removeCountriesData,
removeNodes,
renameCountriesData,
updateNode,
updateNodes,
}
26 changes: 26 additions & 0 deletions src/server/repository/redis/data/renameCountriesData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { CountryIso } from 'meta/area'
import { Assessment, Cycle } from 'meta/assessment'

import { getKeyCountry, Keys } from 'server/repository/redis/keys'
import { RedisData } from 'server/repository/redis/redisData'

type PropsCache = {
assessment: Assessment
countryISOs: Array<CountryIso>
cycleSource: Cycle
cycleTarget: Cycle
}

export const renameCountriesData = async (props: PropsCache): Promise<void> => {
const { assessment, cycleSource, cycleTarget, countryISOs } = props

const redis = RedisData.getInstance()

await Promise.all(
countryISOs.map(async (countryIso) => {
const key = getKeyCountry({ assessment, cycle: cycleSource, countryIso, key: Keys.Data.data })
const keyNew = getKeyCountry({ assessment, cycle: cycleTarget, countryIso, key: Keys.Data.data })
await redis.rename(key, keyNew)
})
)
}
2 changes: 2 additions & 0 deletions src/server/repository/redis/section/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { getMany } from './getMany'
import { getManyMetadata } from './getManyMetadata'
import { getSubSection } from './getSubSection'
import { removeCycleEntries } from './removeCycleEntries'
import { renameCycleEntries } from './renameCycleEntries'

export const SectionRedisRepository = {
getMany,
getManyMetadata,
getSubSection,
removeCycleEntries,
renameCycleEntries,
}
29 changes: 29 additions & 0 deletions src/server/repository/redis/section/renameCycleEntries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Assessment, Cycle } from 'meta/assessment'

import { getKeyCycle, Keys } from 'server/repository/redis/keys'
import { RedisData } from 'server/repository/redis/redisData'

type Props = {
assessment: Assessment
cycleSource: Cycle
cycleTarget: Cycle
}

export const renameCycleEntries = async (props: Props): Promise<void> => {
const { assessment, cycleSource, cycleTarget } = props

const redis = RedisData.getInstance()
const sectionsKey = getKeyCycle({ assessment, cycle: cycleSource, key: Keys.Section.sections })
const sectionsKeyNew = getKeyCycle({ assessment, cycle: cycleTarget, key: Keys.Section.sections })
const sectionIndexKey = getKeyCycle({ assessment, cycle: cycleSource, key: Keys.Section.sectionsIndex })
const sectionIndexKeyNew = getKeyCycle({ assessment, cycle: cycleTarget, key: Keys.Section.sectionsIndex })
const subSectionIndexKey = getKeyCycle({ assessment, cycle: cycleSource, key: Keys.Section.subSectionsIndex })
const subSectionIndexKeyNew = getKeyCycle({ assessment, cycle: cycleTarget, key: Keys.Section.subSectionsIndex })
const sectionsMetadataKey = getKeyCycle({ assessment, cycle: cycleSource, key: Keys.Section.sectionsMetadata })
const sectionsMetadataKeyNew = getKeyCycle({ assessment, cycle: cycleTarget, key: Keys.Section.sectionsMetadata })

await redis.rename(sectionsKey, sectionsKeyNew)
await redis.rename(sectionIndexKey, sectionIndexKeyNew)
await redis.rename(subSectionIndexKey, subSectionIndexKeyNew)
await redis.rename(sectionsMetadataKey, sectionsMetadataKeyNew)
}

0 comments on commit 7f89aee

Please sign in to comment.