migration.data.ts 9.31 KiB
import { Migration } from './migration.type'
import {
PROFILE_DOCTYPE,
PROFILETYPE_DOCTYPE,
USERCHALLENGE_DOCTYPE,
EGL_DAY_DOCTYPE,
EGL_MONTH_DOCTYPE,
EGL_YEAR_DOCTYPE,
FLUIDPRICES_DOCTYPE,
} from 'doctypes'
import { Profile, ProfileType, UserChallenge } from 'models'
import { Client } from 'cozy-client'
import { DateTime } from 'luxon'
import { UserQuizState } from 'enum/userQuiz.enum'
import fluidsPricesData from 'db/fluidPrices.json'
export const SCHEMA_INITIAL_VERSION = 0
export const MIGRATION_RESULT_NOOP = 'MigrationNoop'
export const MIGRATION_RESULT_COMPLETE = 'MigrationComplete'
export const MIGRATION_RESULT_FAILED = 'MigrationFailed'
export const migrations: Migration[] = [
{
baseSchemaVersion: SCHEMA_INITIAL_VERSION,
targetSchemaVersion: 1,
appVersion: '1.3.0',
description:
'Removes old profileType artifacts from users database : \n - Oldest profileType is deleted \n - Removes insulation work form fields that were prone to errors \n - Changes area and outsideFacingWalls form field to strings \n - Changes updateDate values of all existing profileType to match "created_at" entry (former updateDate values got corrupted and hold no meanings).',
releaseNotes: null,
docTypes: PROFILETYPE_DOCTYPE,
run: async (_client: Client, docs: any[]): Promise<ProfileType[]> => {
docs.sort(function(a, b) {
const c = DateTime.fromISO(a.cozyMetadata.createdAt, {
zone: 'utc',
})
const d = DateTime.fromISO(b.cozyMetadata.createdAt, {
zone: 'utc',
})
return d.millisecond - c.millisecond
})
if (docs[0].area === 100) {
docs[0].deleteAction = true
}
return docs.map(doc => {
if (
doc.individualInsulationWork.includes(
'window_replacement_and_wall_insulation'
)
) {
doc.individualInsulationWork = [
'window_replacement',
'wall_insulation',
]
}
if (
doc.individualInsulationWork.includes(
'window_replacement_and_roof_insulation'
)
) {
doc.individualInsulationWork = [
'window_replacement',
'roof_insulation',
]
}
if (
doc.individualInsulationWork.includes(
'window_replacement_and_roof_and_wall_insulation'
)
) {
doc.individualInsulationWork = [
'window_replacement',
'roof_insulation',
'wall_insulation',
]
}
doc.outsideFacingWalls = doc.outsideFacingWalls.toString()
doc.area = doc.area.toString()
doc.updateDate = doc.cozyMetadata.createdAt
return doc
})
},
},
{
baseSchemaVersion: 1,
targetSchemaVersion: 2,
appVersion: '1.3.0',
description: 'Removes old profileType and GCUApprovalDate from profile.',
docTypes: PROFILE_DOCTYPE,
releaseNotes: null,
run: async (_client: Client, docs: any[]): Promise<Profile[]> => {
return docs.map(doc => {
if (doc.GCUApprovalDate) {
delete doc.GCUApprovalDate
}
if (doc.profileType) {
delete doc.profileType
}
return doc
})
},
},
{
baseSchemaVersion: 2,
targetSchemaVersion: 3,
appVersion: '1.3.0',
description:
'Updates userChallenges to make sure no quiz results are overflowing.',
releaseNotes: null,
docTypes: USERCHALLENGE_DOCTYPE,
run: async (_client: Client, docs: any[]): Promise<UserChallenge[]> => {
return docs.map(doc => {
if (doc.quiz.result > 5) {
doc.quiz.result = 5
doc.progress = {
actionProgress: 5,
explorationProgress: 5,
quizProgress: 5,
}
doc.quiz.state = UserQuizState.DONE
}
return doc
})
},
},
{
baseSchemaVersion: 3,
targetSchemaVersion: 4,
appVersion: '1.4.3',
description: 'Corrects daily EGL data.',
releaseNotes: {
title:
"Des corrections sur la connexion aux données de consommation d'eau ont été apportées.",
description:
'Merci de mettre à jour votre connecteur après avoir fermé cette fenêtre. Pour mettre à jour votre connecteur, rendez-vous maintenant du côté de la page Conso, dans la page du fluide concerné.',
},
docTypes: EGL_DAY_DOCTYPE,
queryOptions: {
scope: 'conso',
tag: 'day',
limit: 120,
},
run: async (_client: Client, docs: any[]): Promise<any[]> => {
return docs.map(doc => {
doc.deleteAction = true
return doc
})
},
},
{
baseSchemaVersion: 4,
targetSchemaVersion: 5,
appVersion: '1.4.3',
description: 'Corrects monthly EGL data.',
releaseNotes: null,
docTypes: EGL_MONTH_DOCTYPE,
queryOptions: {
scope: 'conso',
tag: 'month',
limit: 4,
},
run: async (_client: Client, docs: any[]): Promise<any[]> => {
return docs.map(doc => {
doc.deleteAction = true
return doc
})
},
},
{
baseSchemaVersion: 5,
targetSchemaVersion: 6,
appVersion: '1.4.3',
description: 'Corrects yearly EGL data.',
releaseNotes: null,
docTypes: EGL_YEAR_DOCTYPE,
queryOptions: {
scope: 'conso',
tag: 'year',
limit: 1,
},
run: async (_client: Client, docs: any[]): Promise<any[]> => {
return docs.map(doc => {
doc.deleteAction = true
return doc
})
},
},
{
baseSchemaVersion: 6,
targetSchemaVersion: 7,
appVersion: '1.4.4',
description: 'Corrects individual insulation work field on profileType.',
releaseNotes: null,
docTypes: PROFILETYPE_DOCTYPE,
run: async (_client: Client, docs: any[]): Promise<ProfileType[]> => {
return docs.map(doc => {
if (!Array.isArray(doc.individualInsulationWork)) {
doc.individualInsulationWork = [doc.individualInsulationWork]
}
if (
doc.individualInsulationWork.includes(
'window_replacement_and_wall_insulation'
)
) {
doc.individualInsulationWork = [
'window_replacement',
'wall_insulation',
]
}
if (
doc.individualInsulationWork.includes(
'window_replacement_and_roof_insulation'
)
) {
doc.individualInsulationWork = [
'window_replacement',
'roof_insulation',
]
}
if (
doc.individualInsulationWork.includes(
'window_replacement_and_roof_and_wall_insulation'
)
) {
doc.individualInsulationWork = [
'window_replacement',
'roof_insulation',
'wall_insulation',
]
}
return doc
})
},
},
{
baseSchemaVersion: 7,
targetSchemaVersion: 8,
appVersion: '1.5.0',
description:
'ProfileTypes start now at the begining of the month, no duplications can exist over the same month.',
releaseNotes: null,
docTypes: PROFILETYPE_DOCTYPE,
run: async (_client: Client, docs: any[]): Promise<any[]> => {
function checkDate(d1, d2) {
const dtd1: DateTime = DateTime.fromISO(d1)
const dtd2: DateTime = DateTime.fromISO(d2)
return dtd1.year === dtd2.year && dtd1.month === dtd2.month
}
for (let i = 0; i < docs.length; i++) {
const dtStartOfMonth: DateTime = DateTime.fromISO(docs[i].updateDate)
docs[i].updateDate = dtStartOfMonth
.setZone('utc', {
keepLocalTime: true,
})
.startOf('month')
if (
docs[i + 1] &&
checkDate(docs[i].updateDate, docs[i + 1].updateDate)
) {
docs[i].deleteAction = true
}
}
return docs
},
},
{
baseSchemaVersion: 8,
targetSchemaVersion: 9,
appVersion: '1.6.0',
description: 'Init new doctype fluidPrices',
releaseNotes: null,
docTypes: FLUIDPRICES_DOCTYPE,
isCreate: true,
run: async (_client: Client, docs: any[]): Promise<any> => {
for (const fluidPrice of fluidsPricesData) {
await _client.create(FLUIDPRICES_DOCTYPE, fluidPrice)
}
},
},
{
baseSchemaVersion: 9,
targetSchemaVersion: 10,
appVersion: '1.6.0',
description:
"Profil now contains partnersIssueDate in order to handle partners' issue display",
releaseNotes: null,
docTypes: PROFILE_DOCTYPE,
run: async (_client: Client, docs: any[]): Promise<Profile[]> => {
return docs.map((doc: Profile) => {
doc.partnersIssueDate = DateTime.local()
.minus({ day: 1 })
.startOf('day')
console.log(doc)
return doc
})
},
},
{
baseSchemaVersion: 10,
targetSchemaVersion: 11,
appVersion: '1.6.0',
description:
'Rename tutorial to onboaring in ecolyo profile, remove isLastTermAccepted',
releaseNotes: null,
docTypes: PROFILE_DOCTYPE,
run: async (_client: Client, docs: any[]): Promise<ProfileType[]> => {
return docs.map(doc => {
if (doc.tutorial) {
doc.onboarding = { ...doc.tutorial }
delete doc.tutorial
}
if (typeof doc.isLastTermAccepted != 'undefined') {
delete doc.isLastTermAccepted
}
return doc
})
},
},
]