Skip to content
This repository has been archived by the owner on May 11, 2021. It is now read-only.

Commit

Permalink
feat(typo): add merging typos
Browse files Browse the repository at this point in the history
  • Loading branch information
igorkamyshev committed Mar 29, 2019
1 parent fb42c01 commit 4443394
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 9 deletions.
67 changes: 67 additions & 0 deletions back/src/mind/application/TypoMerger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Injectable } from '@nestjs/common'

import { IncomeRepository } from '@back/money/domain/IncomeRepository'
import { OutcomeRepository } from '@back/money/domain/OutcomeRepository'
import { EntitySaver } from '@back/db/EntitySaver'

@Injectable()
export class TypoMerger {
public constructor(
private readonly incomeRepo: IncomeRepository,
private readonly outcomeRepo: OutcomeRepository,
private readonly entitySaver: EntitySaver,
) {}

public async merge(
primary: string,
secondary: string[],
userLogin: string,
): Promise<void> {
await Promise.all([
this.mergeInIncomes(primary, secondary, userLogin),
this.mergeInOutcomes(primary, secondary, userLogin),
])
}

private async mergeInIncomes(
primary: string,
secondary: string[],
userLogin: string,
): Promise<void> {
const [mainIncomes, incomes] = await Promise.all([
this.incomeRepo.findBySourcesForUser([primary], userLogin),
this.incomeRepo.findBySourcesForUser(secondary, userLogin),
])

if (mainIncomes.length === 0) {
return
}

incomes.forEach(income => {
income.source = primary
})

await this.entitySaver.save(...incomes)
}

private async mergeInOutcomes(
primary: string,
secondary: string[],
userLogin: string,
): Promise<void> {
const [mainOutcomes, outcomes] = await Promise.all([
this.outcomeRepo.findByCategoriesForUser([primary], userLogin),
this.outcomeRepo.findByCategoriesForUser(secondary, userLogin),
])

if (mainOutcomes.length === 0) {
return
}

outcomes.forEach(outcome => {
outcome.category = primary
})

await this.entitySaver.save(...outcomes)
}
}
5 changes: 4 additions & 1 deletion back/src/mind/mind.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { TipsFilter } from './application/TipsFilter'
import { DisabledTip } from './domain/DisabledTip.entity'
import { DisabledTipRepository } from './domain/DisabledTipRepository'
import { TipsDisabler } from './application/TipsDisabler'
import { TypoController } from './presentation/http/controller/TypoController'
import { TypoMerger } from './application/TypoMerger'

@Module({
imports: [
Expand All @@ -22,9 +24,10 @@ import { TipsDisabler } from './application/TipsDisabler'
MoneyModule,
TypeOrmModule.forFeature([DisabledTip]),
],
controllers: [TipController],
controllers: [TipController, TypoController],
providers: [
TypoFinder,
TypoMerger,
TypoAdviser,
AdviserUnity,
TipsFilter,
Expand Down
32 changes: 32 additions & 0 deletions back/src/mind/presentation/http/controller/TypoController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Controller, Get, Body, Post } from '@nestjs/common'
import {
ApiUseTags,
ApiBearerAuth,
ApiOperation,
ApiOkResponse,
} from '@nestjs/swagger'

import { OnlyForUsers } from '@back/user/presentation/http/security/OnlyForUsers'
import { TokenPayload } from '@back/user/application/dto/TokenPayload'
import { CurrentUser } from '@back/user/presentation/http/decorator/CurrentUser'

import { MergeTypoRequest } from '../request/MergeTypoRequest'
import { TypoMerger } from '@back/mind/application/TypoMerger'

@Controller('mind/typo')
@OnlyForUsers()
@ApiUseTags('mind')
@ApiBearerAuth()
export class TypoController {
public constructor(private readonly merger: TypoMerger) {}

@Post('merge')
@ApiOperation({ title: 'Merge typos' })
@ApiOkResponse({ description: 'Merges' })
public async showAll(
@CurrentUser() user: TokenPayload,
@Body() request: MergeTypoRequest,
): Promise<void> {
await this.merger.merge(request.primary, request.secondary, user.login)
}
}
11 changes: 11 additions & 0 deletions back/src/mind/presentation/http/request/MergeTypoRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ApiModelProperty } from '@nestjs/swagger'

import { MergeTypoModel } from '@shared/models/mind/MergeTypoModel'

export class MergeTypoRequest implements MergeTypoModel {
@ApiModelProperty({ example: 'Lunch' })
public readonly primary: string

@ApiModelProperty({ example: ['lunch', 'Lonch'] })
public readonly secondary: string[]
}
2 changes: 1 addition & 1 deletion back/src/money/domain/Income.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class Income implements AbstractTransaction {
public readonly date: Date

@Column()
public readonly source: string
public source: string

@ManyToOne(type => User)
public readonly author: User
Expand Down
13 changes: 13 additions & 0 deletions back/src/money/domain/IncomeRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ class IncomeRepo implements TransactionRepository {

return result.map(({ source }) => source)
}

public async findBySourcesForUser(
sources: string[],
userLogin: string,
): Promise<Income[]> {
return this.incomeRepo
.createQueryBuilder('income')
.where('income.source IN (:...sources)', { sources })
.innerJoin('income.author', 'author', 'author.login = :userLogin', {
userLogin,
})
.getMany()
}
}

export const IncomeRepository = IncomeRepo
Expand Down
2 changes: 1 addition & 1 deletion back/src/money/domain/Outcome.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class Outcome implements AbstractTransaction {
public readonly date: Date

@Column()
public readonly category: string
public category: string

@ManyToOne(type => User)
public readonly author: User
Expand Down
13 changes: 13 additions & 0 deletions back/src/money/domain/OutcomeRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ class OutomeRepo implements TransactionRepository {

return result.map(({ category }) => category)
}

public async findByCategoriesForUser(
categories: string[],
userLogin: string,
): Promise<Outcome[]> {
return this.outcomeRepo
.createQueryBuilder('outcome')
.where('outcome.category IN (:...categories)', { categories })
.innerJoin('outcome.author', 'author', 'author.login = :userLogin', {
userLogin,
})
.getMany()
}
}

export const OutcomeRepository = OutomeRepo
Expand Down
12 changes: 8 additions & 4 deletions front/src/domain/mind/actions/mergeTypos.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { MergeTypoModel } from '@shared/models/mind/MergeTypoModel'
import { refetchData } from '@front/domain/money/actions/refetchData'
import { fetchOrFail } from '@front/domain/store'

import { actions } from '../reducer/tips'
import { mergeTypoRequest } from '../api/mergeTypoRequest'

export const mergeTypos = (token: string, main: string, other: string[]) =>
fetchOrFail(actions.fetching, async dispatch => {
// TODO: real merging please =)
console.log(main, other)
export const mergeTypos = (token: string, merge: MergeTypoModel) =>
fetchOrFail(actions.fetching, async (dispatch, getApi) => {
await mergeTypoRequest(getApi())(merge)

dispatch(actions.data.removeTips([token]))

await dispatch(refetchData())
})
7 changes: 7 additions & 0 deletions front/src/domain/mind/api/mergeTypoRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Api } from '@front/domain/api'
import { MergeTypoModel } from '@shared/models/mind/MergeTypoModel'

export const mergeTypoRequest = (api: Api) => (
merge: MergeTypoModel,
): Promise<void> =>
api.client.post('/mind/typo/merge', merge).then(response => response.data)
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ export const Merge = ({ token, variants, target }: Props) => {

const createOnMerge = useCallback(
(mainVariant: string) => {
const otherVaraints = variants.filter(varinat => varinat !== mainVariant)
const merge = {
primary: mainVariant,
secondary: variants.filter(varinat => varinat !== mainVariant),
}

return () => dispatch(mergeTypos(token, mainVariant, otherVaraints))
return () => dispatch(mergeTypos(token, merge))
},
[variants, token],
)
Expand Down
4 changes: 4 additions & 0 deletions shared/models/mind/MergeTypoModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface MergeTypoModel {
primary: string
secondary: string[]
}

0 comments on commit 4443394

Please sign in to comment.