Skip to content
Snippets Groups Projects
migration.data.ts 11 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { Migration } from './migration.type'
    
    import {
      PROFILE_DOCTYPE,
      PROFILETYPE_DOCTYPE,
      USERCHALLENGE_DOCTYPE,
    
      ENEDIS_DAY_DOCTYPE,
      GRDF_DAY_DOCTYPE,
    
    } from 'doctypes'
    
    import { DataloadEntity, Profile, ProfileType, UserChallenge } from 'models'
    
    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,
    
        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.',
    
        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
          })
        },
      },
    
      {
        baseSchemaVersion: 11,
        targetSchemaVersion: 12,
        appVersion: '1.6.1',
        description: 'Corrects daily Enedis data.',
        releaseNotes: null,
        docTypes: ENEDIS_DAY_DOCTYPE,
        queryOptions: {
          scope: 'conso',
          tag: 'day',
          limit: 730,
        },
        run: async (_client: Client, docs: any[]): Promise<DataloadEntity[]> => {
          let prevData: DataloadEntity = {
            id: '',
            day: 0,
            hour: 0,
            load: 0,
            minute: 0,
            month: 0,
            year: 0,
          }
          return docs.map(doc => {
            if (
              prevData.day === doc.day &&
              prevData.month === doc.month &&
              prevData.year === doc.year
            ) {
              doc.deleteAction = true
            }
            if (doc.price) {
              delete doc.price
            }
            prevData = doc
            return doc
          })
        },
      },
      {
        baseSchemaVersion: 12,
        targetSchemaVersion: 13,
        appVersion: '1.6.1',
        description: 'Corrects daily GRDF data.',
        releaseNotes: null,
        docTypes: GRDF_DAY_DOCTYPE,
        queryOptions: {
          scope: 'conso',
          tag: 'day',
          limit: 730,
        },
        run: async (_client: Client, docs: any[]): Promise<DataloadEntity[]> => {
          let prevData: DataloadEntity = {
            id: '',
            day: 0,
            hour: 0,
            load: 0,
            minute: 0,
            month: 0,
            year: 0,
          }
          return docs.map(doc => {
            if (
              prevData.day === doc.day &&
              prevData.month === doc.month &&
              prevData.year === doc.year
            ) {
              doc.deleteAction = true
            }
            if (doc.price) {
              delete doc.price
            }
            prevData = doc
            return doc
          })
        },
      },