diff --git a/apps/devmx/public/portal-devpr-mx.svg b/apps/devmx/public/portal-devpr-mx.svg new file mode 100644 index 00000000..9e4dea29 --- /dev/null +++ b/apps/devmx/public/portal-devpr-mx.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + diff --git a/apps/server/src/assets/templates/user-code.html b/apps/server/src/assets/templates/user-code.html index 04c180b9..214a1c13 100644 --- a/apps/server/src/assets/templates/user-code.html +++ b/apps/server/src/assets/templates/user-code.html @@ -1,3 +1,4 @@
-

{{value}}

+

{{value}}

+ diff --git a/apps/server/src/assets/templates/user-tag.html b/apps/server/src/assets/templates/user-tag.html new file mode 100644 index 00000000..911a017c --- /dev/null +++ b/apps/server/src/assets/templates/user-tag.html @@ -0,0 +1,12 @@ +
+

Olá {{displayName}}, tudo beleza?

+ +

+ Você foi marcado(a) em uma foto da comunidade, acesse o album + {{title}} para ver +

+
+ + diff --git a/packages/album/data-access/src/lib/application/photo.facade.ts b/packages/album/data-access/src/lib/application/photo.facade.ts index 40515f67..70e51714 100644 --- a/packages/album/data-access/src/lib/application/photo.facade.ts +++ b/packages/album/data-access/src/lib/application/photo.facade.ts @@ -1,5 +1,10 @@ import { createClientProvider, EntityFacade } from '@devmx/shared-data-access'; -import { Photo, EditablePhoto } from '@devmx/shared-api-interfaces'; +import { take } from 'rxjs'; +import { + Photo, + EditablePhoto, + UpdatePhotoTags, +} from '@devmx/shared-api-interfaces'; import { CreatePhotoUseCase, DeletePhotoUseCase, @@ -10,7 +15,7 @@ import { UploadPhoto, UploadPhotoUseCase, } from '@devmx/album-domain/client'; -import { take } from 'rxjs'; + export class PhotoFacade extends EntityFacade { constructor( @@ -59,7 +64,7 @@ export class PhotoFacade extends EntityFacade { return request$.pipe(take(1)); } - updateTags(data: EditablePhoto) { + updateTags(data: UpdatePhotoTags) { this.onUpdate(this.updatePhotoTagsUseCase.execute(data)); } diff --git a/packages/album/data-source/src/lib/album.providers.ts b/packages/album/data-source/src/lib/album.providers.ts index 474c7808..d6f55508 100644 --- a/packages/album/data-source/src/lib/album.providers.ts +++ b/packages/album/data-source/src/lib/album.providers.ts @@ -1,5 +1,5 @@ -import { provideFacades, provideServices, provideUseCases } from './providers'; +import { provideAlbum, providePhoto } from './providers'; export function provideAlbums() { - return [...provideServices(), ...provideUseCases(), ...provideFacades()]; + return [...provideAlbum(), ...providePhoto()]; } diff --git a/packages/album/data-source/src/lib/application/photos.facade.ts b/packages/album/data-source/src/lib/application/photos.facade.ts index b5a6605b..35da6395 100644 --- a/packages/album/data-source/src/lib/application/photos.facade.ts +++ b/packages/album/data-source/src/lib/application/photos.facade.ts @@ -1,4 +1,4 @@ -import { PhotoDto, CreatePhotoDto, UpdatePhotoDto } from '../dtos'; +import { PhotoDto, CreatePhotoDto, UpdatePhotoDto, UpdatePhotoTagsDto } from '../dtos'; import { Photo } from '@devmx/shared-api-interfaces'; import { plainToInstance } from 'class-transformer'; import { @@ -6,6 +6,7 @@ import { DeletePhotoUseCase, FindPhotoByIDUseCase, FindPhotosUseCase, + UpdatePhotoTagsUseCase, UpdatePhotoUseCase, } from '@devmx/album-domain/server'; import { @@ -20,7 +21,8 @@ export class PhotosFacade { private findPhotosUseCase: FindPhotosUseCase, private findPhotoByIDUseCase: FindPhotoByIDUseCase, private updatePhotoUseCase: UpdatePhotoUseCase, - private deletePhotoUseCase: DeletePhotoUseCase + private deletePhotoUseCase: DeletePhotoUseCase, + private updatePhotoTagsUseCase: UpdatePhotoTagsUseCase ) {} async create(data: CreatePhotoDto) { @@ -30,23 +32,28 @@ export class PhotosFacade { async find(params: QueryParamsDto) { const { data, items, pages } = await this.findPhotosUseCase.execute(params); - const albums = plainToInstance(PhotoDto, data); - return new PageDto(albums, items, pages); + const photos = plainToInstance(PhotoDto, data); + return new PageDto(photos, items, pages); } async findOne(id: string) { - const album = await this.findPhotoByIDUseCase.execute(id); - return plainToInstance(PhotoDto, album); + const photo = await this.findPhotoByIDUseCase.execute(id); + return plainToInstance(PhotoDto, photo); } async update(id: string, data: UpdatePhotoDto) { - const album = await this.updatePhotoUseCase.execute({ ...data, id }); - return plainToInstance(PhotoDto, album); + const photo = await this.updatePhotoUseCase.execute({ ...data, id }); + return plainToInstance(PhotoDto, photo); + } + + async updateTags(id: string, data: UpdatePhotoTagsDto) { + const photo = await this.updatePhotoTagsUseCase.execute({ ...data, id }); + return plainToInstance(PhotoDto, photo); } async delete(id: string) { - const album = this.deletePhotoUseCase.execute(id); - return plainToInstance(PhotoDto, album); + const photo = this.deletePhotoUseCase.execute(id); + return plainToInstance(PhotoDto, photo); } } @@ -57,5 +64,6 @@ export function providePhotosFacade() { FindPhotoByIDUseCase, UpdatePhotoUseCase, DeletePhotoUseCase, + UpdatePhotoTagsUseCase ]); } diff --git a/packages/album/data-source/src/lib/dtos/index.ts b/packages/album/data-source/src/lib/dtos/index.ts index f5e14a9c..979eb8ef 100644 --- a/packages/album/data-source/src/lib/dtos/index.ts +++ b/packages/album/data-source/src/lib/dtos/index.ts @@ -1,6 +1,7 @@ -export * from './album'; -export * from './create-album'; -export * from './create-photo'; -export * from './photo'; -export * from './update-album'; -export * from './update-photo'; +export * from './album'; +export * from './create-album'; +export * from './create-photo'; +export * from './photo'; +export * from './update-album'; +export * from './update-photo-tags'; +export * from './update-photo'; diff --git a/packages/album/data-source/src/lib/dtos/update-photo-tags.ts b/packages/album/data-source/src/lib/dtos/update-photo-tags.ts new file mode 100644 index 00000000..d7aca943 --- /dev/null +++ b/packages/album/data-source/src/lib/dtos/update-photo-tags.ts @@ -0,0 +1,42 @@ +import { IsNotEmpty, IsNumber, IsOptional } from 'class-validator'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { UserTagDto } from '@devmx/shared-data-source'; +import { Exclude, Type } from 'class-transformer'; +import { + UserTag, + ImageMimeType, + UpdatePhotoTags, +} from '@devmx/shared-api-interfaces'; + +export class UpdatePhotoTagsDto implements UpdatePhotoTags { + id: string; + + @Exclude() + data: string; + + @IsNumber() + @ApiProperty() + @Type(() => Number) + width: number; + + @IsNumber() + @ApiProperty() + @Type(() => Number) + height: number; + + @IsNotEmpty() + album: string; + + @IsOptional() + @ApiPropertyOptional() + type: ImageMimeType; + + @IsOptional() + @ApiPropertyOptional() + caption?: string; + + @Type(() => UserTagDto) + tags: UserTag[] = []; + + owner: string; +} diff --git a/packages/album/data-source/src/lib/providers/album.ts b/packages/album/data-source/src/lib/providers/album.ts new file mode 100644 index 00000000..e76b6177 --- /dev/null +++ b/packages/album/data-source/src/lib/providers/album.ts @@ -0,0 +1,23 @@ +import { provideAlbumsMongoService } from '../infrastructure'; +import { provideAlbumsFacade } from '../application'; +import { + provideCreateAlbumUseCase, + provideDeleteAlbumUseCase, + provideFindAlbumByIDUseCase, + provideFindAlbumsUseCase, + provideUpdateAlbumUseCase, +} from '@devmx/album-domain/server'; + +export function provideAlbum() { + return [ + provideAlbumsMongoService(), + + provideCreateAlbumUseCase(), + provideFindAlbumsUseCase(), + provideFindAlbumByIDUseCase(), + provideUpdateAlbumUseCase(), + provideDeleteAlbumUseCase(), + + provideAlbumsFacade() + ]; +} diff --git a/packages/album/data-source/src/lib/providers/facades.ts b/packages/album/data-source/src/lib/providers/facades.ts deleted file mode 100644 index bd7d84b0..00000000 --- a/packages/album/data-source/src/lib/providers/facades.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { provideAlbumsFacade, providePhotosFacade } from '../application'; - -export function provideFacades() { - return [provideAlbumsFacade(), providePhotosFacade()]; -} diff --git a/packages/album/data-source/src/lib/providers/index.ts b/packages/album/data-source/src/lib/providers/index.ts index 7134c954..8a0c44ba 100644 --- a/packages/album/data-source/src/lib/providers/index.ts +++ b/packages/album/data-source/src/lib/providers/index.ts @@ -1,3 +1,2 @@ -export * from './facades'; -export * from './services'; -export * from './use-cases'; +export * from './album'; +export * from './photo'; diff --git a/packages/album/data-source/src/lib/providers/photo.ts b/packages/album/data-source/src/lib/providers/photo.ts new file mode 100644 index 00000000..36763760 --- /dev/null +++ b/packages/album/data-source/src/lib/providers/photo.ts @@ -0,0 +1,27 @@ +import { providePhotosMongoService } from '../infrastructure'; +import { providePhotosFacade } from '../application'; +import { + provideAddPhotoUseCase, + provideCreatePhotoUseCase, + provideDeletePhotoUseCase, + provideFindPhotoByIDUseCase, + provideFindPhotosUseCase, + provideUpdatePhotoTagsUseCase, + provideUpdatePhotoUseCase, +} from '@devmx/album-domain/server'; + +export function providePhoto() { + return [ + providePhotosMongoService(), + + provideAddPhotoUseCase(), + provideCreatePhotoUseCase(), + provideFindPhotosUseCase(), + provideFindPhotoByIDUseCase(), + provideUpdatePhotoUseCase(), + provideUpdatePhotoTagsUseCase(), + provideDeletePhotoUseCase(), + + providePhotosFacade(), + ]; +} diff --git a/packages/album/data-source/src/lib/providers/services.ts b/packages/album/data-source/src/lib/providers/services.ts deleted file mode 100644 index 59e97dc4..00000000 --- a/packages/album/data-source/src/lib/providers/services.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { - provideAlbumsMongoService, - providePhotosMongoService, -} from '../infrastructure'; - -export function provideServices() { - return [provideAlbumsMongoService(), providePhotosMongoService()]; -} diff --git a/packages/album/data-source/src/lib/providers/use-cases.ts b/packages/album/data-source/src/lib/providers/use-cases.ts deleted file mode 100644 index deb4e6d7..00000000 --- a/packages/album/data-source/src/lib/providers/use-cases.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { createUseCaseProvider } from '@devmx/shared-data-source'; -import { - AddPhotoUseCase, - AlbumsService, - CreateAlbumUseCase, - CreatePhotoUseCase, - DeleteAlbumUseCase, - DeletePhotoUseCase, - FindAlbumByIDUseCase, - FindAlbumsUseCase, - FindPhotoByIDUseCase, - FindPhotosUseCase, - PhotosService, - UpdateAlbumUseCase, - UpdatePhotoUseCase, -} from '@devmx/album-domain/server'; - -export function provideCreateAlbumUseCase() { - return createUseCaseProvider(CreateAlbumUseCase, [AlbumsService]); -} - -export function provideFindAlbumsUseCase() { - return createUseCaseProvider(FindAlbumsUseCase, [AlbumsService]); -} - -export function provideFindAlbumByIDUseCase() { - return createUseCaseProvider(FindAlbumByIDUseCase, [AlbumsService]); -} - -export function provideUpdateAlbumUseCase() { - return createUseCaseProvider(UpdateAlbumUseCase, [AlbumsService]); -} - -export function provideDeleteAlbumUseCase() { - return createUseCaseProvider(DeleteAlbumUseCase, [AlbumsService]); -} - -export function provideAddPhotoUseCase() { - return createUseCaseProvider(AddPhotoUseCase, [AlbumsService]); -} - -export function provideCreatePhotoUseCase() { - return createUseCaseProvider(CreatePhotoUseCase, [PhotosService]); -} - -export function provideFindPhotosUseCase() { - return createUseCaseProvider(FindPhotosUseCase, [PhotosService]); -} - -export function provideFindPhotoByIDUseCase() { - return createUseCaseProvider(FindPhotoByIDUseCase, [PhotosService]); -} - -export function provideUpdatePhotoUseCase() { - return createUseCaseProvider(UpdatePhotoUseCase, [PhotosService]); -} - -export function provideDeletePhotoUseCase() { - return createUseCaseProvider(DeletePhotoUseCase, [PhotosService]); -} - -export function provideUseCases() { - return [ - provideCreateAlbumUseCase(), - provideFindAlbumsUseCase(), - provideFindAlbumByIDUseCase(), - provideUpdateAlbumUseCase(), - provideDeleteAlbumUseCase(), - provideAddPhotoUseCase(), - - provideCreatePhotoUseCase(), - provideFindPhotosUseCase(), - provideFindPhotoByIDUseCase(), - provideUpdatePhotoUseCase(), - provideDeletePhotoUseCase(), - ]; -} diff --git a/packages/album/domain/package.json b/packages/album/domain/package.json index d9d20cb6..906c9aac 100644 --- a/packages/album/domain/package.json +++ b/packages/album/domain/package.json @@ -6,7 +6,8 @@ "@devmx/shared-api-interfaces": "0.0.1", "rxjs": "^7.8.0", "@devmx/shared-util-errors": "0.0.1", - "@devmx/shared-util-data": "0.0.1" + "@devmx/shared-util-data": "0.0.1", + "@devmx/account-domain": "0.0.1" }, "type": "commonjs", "main": "./src/index.js", diff --git a/packages/album/domain/src/server/use-cases/add-photo.ts b/packages/album/domain/src/server/use-cases/add-photo.ts index a58a9ab0..909db435 100644 --- a/packages/album/domain/src/server/use-cases/add-photo.ts +++ b/packages/album/domain/src/server/use-cases/add-photo.ts @@ -2,6 +2,7 @@ import { Album, UseCase } from '@devmx/shared-api-interfaces'; import { NotFoundError } from '@devmx/shared-util-errors'; import { AlbumsService } from '../services'; import { AddPhoto } from '../dtos'; +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; export class AddPhotoUseCase implements UseCase { constructor(private albumsService: AlbumsService) {} @@ -18,3 +19,7 @@ export class AddPhotoUseCase implements UseCase { return await this.albumsService.update(id, album); } } + +export function provideAddPhotoUseCase() { + return createUseCaseProvider(AddPhotoUseCase, [AlbumsService]); +} diff --git a/packages/album/domain/src/server/use-cases/create-album.ts b/packages/album/domain/src/server/use-cases/create-album.ts index 08e2e028..a8e74b54 100644 --- a/packages/album/domain/src/server/use-cases/create-album.ts +++ b/packages/album/domain/src/server/use-cases/create-album.ts @@ -1,4 +1,5 @@ import { Album, EditableAlbum, UseCase } from '@devmx/shared-api-interfaces'; +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; import { AlbumsService } from '../services'; export class CreateAlbumUseCase implements UseCase { @@ -8,3 +9,7 @@ export class CreateAlbumUseCase implements UseCase { return this.albumsService.create(data); } } + +export function provideCreateAlbumUseCase() { + return createUseCaseProvider(CreateAlbumUseCase, [AlbumsService]); +} diff --git a/packages/album/domain/src/server/use-cases/create-photo.ts b/packages/album/domain/src/server/use-cases/create-photo.ts index f0a4514f..4acc06b8 100644 --- a/packages/album/domain/src/server/use-cases/create-photo.ts +++ b/packages/album/domain/src/server/use-cases/create-photo.ts @@ -1,4 +1,5 @@ import { Photo, EditablePhoto, UseCase } from '@devmx/shared-api-interfaces'; +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; import { PhotosService } from '../services'; export class CreatePhotoUseCase implements UseCase { @@ -8,3 +9,7 @@ export class CreatePhotoUseCase implements UseCase { return this.photosService.create(data); } } + +export function provideCreatePhotoUseCase() { + return createUseCaseProvider(CreatePhotoUseCase, [PhotosService]); +} diff --git a/packages/album/domain/src/server/use-cases/delete-album.ts b/packages/album/domain/src/server/use-cases/delete-album.ts index 0fcdea2e..087acdc9 100644 --- a/packages/album/domain/src/server/use-cases/delete-album.ts +++ b/packages/album/domain/src/server/use-cases/delete-album.ts @@ -1,3 +1,4 @@ +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; import { Album, UseCase } from '@devmx/shared-api-interfaces'; import { AlbumsService } from '../services'; @@ -8,3 +9,7 @@ export class DeleteAlbumUseCase implements UseCase { return this.albumsService.delete(id); } } + +export function provideDeleteAlbumUseCase() { + return createUseCaseProvider(DeleteAlbumUseCase, [AlbumsService]); +} diff --git a/packages/album/domain/src/server/use-cases/delete-photo.ts b/packages/album/domain/src/server/use-cases/delete-photo.ts index e1d2c91b..0341e825 100644 --- a/packages/album/domain/src/server/use-cases/delete-photo.ts +++ b/packages/album/domain/src/server/use-cases/delete-photo.ts @@ -1,5 +1,6 @@ import { Photo, UseCase } from '@devmx/shared-api-interfaces'; import { PhotosService } from '../services'; +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; export class DeletePhotoUseCase implements UseCase { constructor(private photosService: PhotosService) {} @@ -8,3 +9,7 @@ export class DeletePhotoUseCase implements UseCase { return this.photosService.delete(id); } } + +export function provideDeletePhotoUseCase() { + return createUseCaseProvider(DeletePhotoUseCase, [PhotosService]); +} diff --git a/packages/album/domain/src/server/use-cases/find-abums.ts b/packages/album/domain/src/server/use-cases/find-abums.ts index b6719c90..7850e933 100644 --- a/packages/album/domain/src/server/use-cases/find-abums.ts +++ b/packages/album/domain/src/server/use-cases/find-abums.ts @@ -1,3 +1,4 @@ +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; import { AlbumsService } from '../services'; import { Page, @@ -15,3 +16,7 @@ export class FindAlbumsUseCase return this.albumsService.find(params); } } + +export function provideFindAlbumsUseCase() { + return createUseCaseProvider(FindAlbumsUseCase, [AlbumsService]); +} diff --git a/packages/album/domain/src/server/use-cases/find-album-by-id.ts b/packages/album/domain/src/server/use-cases/find-album-by-id.ts index c9742d4f..fa9224b4 100644 --- a/packages/album/domain/src/server/use-cases/find-album-by-id.ts +++ b/packages/album/domain/src/server/use-cases/find-album-by-id.ts @@ -1,3 +1,4 @@ +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; import { Album, UseCase } from '@devmx/shared-api-interfaces'; import { AlbumsService } from '../services'; @@ -8,3 +9,7 @@ export class FindAlbumByIDUseCase implements UseCase { return this.albumsService.findOne(id); } } + +export function provideFindAlbumByIDUseCase() { + return createUseCaseProvider(FindAlbumByIDUseCase, [AlbumsService]); +} diff --git a/packages/album/domain/src/server/use-cases/find-photo-by-id.ts b/packages/album/domain/src/server/use-cases/find-photo-by-id.ts index 93317d76..b356af8e 100644 --- a/packages/album/domain/src/server/use-cases/find-photo-by-id.ts +++ b/packages/album/domain/src/server/use-cases/find-photo-by-id.ts @@ -1,3 +1,4 @@ +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; import { Photo, UseCase } from '@devmx/shared-api-interfaces'; import { PhotosService } from '../services'; @@ -8,3 +9,7 @@ export class FindPhotoByIDUseCase implements UseCase { return this.photosService.findOne(id); } } + +export function provideFindPhotoByIDUseCase() { + return createUseCaseProvider(FindPhotoByIDUseCase, [PhotosService]); +} diff --git a/packages/album/domain/src/server/use-cases/find-photos.ts b/packages/album/domain/src/server/use-cases/find-photos.ts index a3897571..5b5ac9c2 100644 --- a/packages/album/domain/src/server/use-cases/find-photos.ts +++ b/packages/album/domain/src/server/use-cases/find-photos.ts @@ -1,3 +1,4 @@ +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; import { PhotosService } from '../services'; import { Page, @@ -15,3 +16,7 @@ export class FindPhotosUseCase return this.photosService.find(params); } } + +export function provideFindPhotosUseCase() { + return createUseCaseProvider(FindPhotosUseCase, [PhotosService]); +} diff --git a/packages/album/domain/src/server/use-cases/index.ts b/packages/album/domain/src/server/use-cases/index.ts index 88790264..21764042 100644 --- a/packages/album/domain/src/server/use-cases/index.ts +++ b/packages/album/domain/src/server/use-cases/index.ts @@ -1,11 +1,12 @@ -export * from './add-photo'; -export * from './create-album'; -export * from './create-photo'; -export * from './delete-album'; -export * from './delete-photo'; -export * from './find-abums'; -export * from './find-album-by-id'; -export * from './find-photo-by-id'; -export * from './find-photos'; -export * from './update-album'; -export * from './update-photo'; +export * from './add-photo'; +export * from './create-album'; +export * from './create-photo'; +export * from './delete-album'; +export * from './delete-photo'; +export * from './find-abums'; +export * from './find-album-by-id'; +export * from './find-photo-by-id'; +export * from './find-photos'; +export * from './update-album'; +export * from './update-photo-tags'; +export * from './update-photo'; diff --git a/packages/album/domain/src/server/use-cases/update-album.ts b/packages/album/domain/src/server/use-cases/update-album.ts index 0805c605..ed2bde1f 100644 --- a/packages/album/domain/src/server/use-cases/update-album.ts +++ b/packages/album/domain/src/server/use-cases/update-album.ts @@ -1,4 +1,5 @@ import { Album, EditableAlbum, UseCase } from '@devmx/shared-api-interfaces'; +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; import { AlbumsService } from '../services'; export class UpdateAlbumUseCase implements UseCase { @@ -8,3 +9,7 @@ export class UpdateAlbumUseCase implements UseCase { return this.albumsService.update(data.id, data); } } + +export function provideUpdateAlbumUseCase() { + return createUseCaseProvider(UpdateAlbumUseCase, [AlbumsService]); +} diff --git a/packages/album/domain/src/server/use-cases/update-photo-tags.ts b/packages/album/domain/src/server/use-cases/update-photo-tags.ts new file mode 100644 index 00000000..91436a12 --- /dev/null +++ b/packages/album/domain/src/server/use-cases/update-photo-tags.ts @@ -0,0 +1,76 @@ +import { createUseCaseProvider, render } from '@devmx/shared-util-data/server'; +import { MailerService } from '@devmx/shared-api-interfaces/server'; +import { UsersService } from '@devmx/account-domain/server'; +import { AlbumsService, PhotosService } from '../services'; +import { NotFoundError } from '@devmx/shared-util-errors'; +import { createMail } from '@devmx/shared-util-data'; +import { + Photo, + UseCase, + EditablePhoto, + UpdatePhotoTags, +} from '@devmx/shared-api-interfaces'; + +export class UpdatePhotoTagsUseCase implements UseCase { + constructor( + private photosService: PhotosService, + private albumsService: AlbumsService, + private mailerService: MailerService, + private usersService: UsersService + ) {} + + async execute(data: UpdatePhotoTags) { + const photo = await this.photosService.findOne(data.id); + + if (!photo) { + throw new NotFoundError(`Photo ${data.id} não encontrada`); + } + + const album = await this.albumsService.findOne(data.album); + + if (!album) { + throw new NotFoundError(`Album ${data.album} não encontrado`); + } + + const tagUserIds = new Set(photo.tags?.map((tag) => tag.user.id) ?? []); + + const newTags = (data.tags ?? []).filter( + (tag) => !tagUserIds.has(tag.user.id) + ); + + if (newTags.length > 0) { + for (const tag of newTags) { + const user = await this.usersService.findOne(tag.user.id); + if (!user) { + throw new NotFoundError( + `Usuário ${tag.user.displayName} não encontrado` + ); + } + + const title = album.title; + const displayName = user.displayName; + const url = `https://devparana.mx/#/albuns/${data.album}`; + + const mail = createMail( + user.contact.email, + render('user-tag.html', { displayName, url, title }), + `Você foi marcado em uma foto da comunidade`, + 'portal@devparana.mx' + ); + + await this.mailerService.send(mail); + } + } + + return this.photosService.update(data.id, data); + } +} + +export function provideUpdatePhotoTagsUseCase() { + return createUseCaseProvider(UpdatePhotoTagsUseCase, [ + PhotosService, + AlbumsService, + MailerService, + UsersService, + ]); +} diff --git a/packages/album/domain/src/server/use-cases/update-photo.ts b/packages/album/domain/src/server/use-cases/update-photo.ts index 3c0c23fa..6d12b816 100644 --- a/packages/album/domain/src/server/use-cases/update-photo.ts +++ b/packages/album/domain/src/server/use-cases/update-photo.ts @@ -1,4 +1,5 @@ import { Photo, EditablePhoto, UseCase } from '@devmx/shared-api-interfaces'; +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; import { PhotosService } from '../services'; export class UpdatePhotoUseCase implements UseCase { @@ -8,3 +9,7 @@ export class UpdatePhotoUseCase implements UseCase { return this.albumsService.update(data.id, data); } } + +export function provideUpdatePhotoUseCase() { + return createUseCaseProvider(UpdatePhotoUseCase, [PhotosService]); +} diff --git a/packages/album/feature-shell/src/lib/containers/album/album.container.html b/packages/album/feature-shell/src/lib/containers/album/album.container.html index c245f988..f991bf6c 100644 --- a/packages/album/feature-shell/src/lib/containers/album/album.container.html +++ b/packages/album/feature-shell/src/lib/containers/album/album.container.html @@ -4,7 +4,11 @@
@for (photo of album.photos; track photo.id) { - + }
} diff --git a/packages/album/feature-shell/src/lib/containers/album/album.container.ts b/packages/album/feature-shell/src/lib/containers/album/album.container.ts index 9975e766..7e934873 100644 --- a/packages/album/feature-shell/src/lib/containers/album/album.container.ts +++ b/packages/album/feature-shell/src/lib/containers/album/album.container.ts @@ -34,14 +34,17 @@ export class AlbumContainer { map((data) => data['album'] as Album) ); - open(photo: Photo, auth: Authentication) { + open(photo: Photo, auth: Authentication, album: string) { this.photoViewer .open({ photo, auth }) .closed.pipe(take(1)) - .subscribe(this.updateTags); + .subscribe(this.updateTags(album)); } - updateTags = (photo?: Photo) => { - if (photo) this.photoFacade.updateTags(photo); + updateTags = (album: string) => (photo?: Photo) => { + if (photo && photo.tags) { + const tags = photo.tags ?? []; + this.photoFacade.updateTags({ ...photo, tags, album }); + } }; } diff --git a/packages/album/resource/src/lib/controllers/photos.ts b/packages/album/resource/src/lib/controllers/photos.ts index 483a2c19..4e587229 100644 --- a/packages/album/resource/src/lib/controllers/photos.ts +++ b/packages/album/resource/src/lib/controllers/photos.ts @@ -34,6 +34,7 @@ import { PhotosFacade, CreatePhotoDto, UpdatePhotoDto, + UpdatePhotoTagsDto, } from '@devmx/album-data-source'; import 'multer'; import { plainToClass } from 'class-transformer'; @@ -83,7 +84,7 @@ export class PhotosController { @ApiOkResponse({ type: PhotoDto }) async photoTags( @Param('id') id: string, - @Body() updatePhotoDto: UpdatePhotoDto + @Body() updatePhotoDto: UpdatePhotoTagsDto ) { const photo = await this.photosFacade.findOne(id); @@ -93,8 +94,8 @@ export class PhotosController { try { const data = { ...photo, ...updatePhotoDto }; - const value = plainToClass(UpdatePhotoDto, data); - return await this.photosFacade.update(id, value); + const value = plainToClass(UpdatePhotoTagsDto, data); + return await this.photosFacade.updateTags(id, value); } catch (err) { throw new BadRequestException(err); } diff --git a/packages/shared/api-interfaces/src/lib/dtos/index.ts b/packages/shared/api-interfaces/src/lib/dtos/index.ts index 56afcc3e..62d34511 100644 --- a/packages/shared/api-interfaces/src/lib/dtos/index.ts +++ b/packages/shared/api-interfaces/src/lib/dtos/index.ts @@ -35,5 +35,6 @@ export * from './query'; export * from './sign-in'; export * from './sign-up'; export * from './update-event'; +export * from './update-photo-tags'; export * from './update-roles'; export * from './user-ref'; diff --git a/packages/shared/api-interfaces/src/lib/dtos/update-photo-tags.ts b/packages/shared/api-interfaces/src/lib/dtos/update-photo-tags.ts new file mode 100644 index 00000000..1a1fb2d8 --- /dev/null +++ b/packages/shared/api-interfaces/src/lib/dtos/update-photo-tags.ts @@ -0,0 +1,6 @@ +import { Photo, UserTag } from '../entities'; + +export interface UpdatePhotoTags extends Photo { + tags: UserTag[]; + album: string; +} diff --git a/packages/shared/api-interfaces/src/lib/entities/photo.ts b/packages/shared/api-interfaces/src/lib/entities/photo.ts index dcfdfdc2..b1114b64 100644 --- a/packages/shared/api-interfaces/src/lib/entities/photo.ts +++ b/packages/shared/api-interfaces/src/lib/entities/photo.ts @@ -1,6 +1,5 @@ import { ImageMimeType } from '../types'; import { UserTag } from './user-tag'; -import { UserRef } from '../dtos'; export interface Photo { id: string; diff --git a/packages/shared/ui-global/icon/src/lib/icon-registry.ts b/packages/shared/ui-global/icon/src/lib/icon-registry.ts index daef3e63..aece19e0 100644 --- a/packages/shared/ui-global/icon/src/lib/icon-registry.ts +++ b/packages/shared/ui-global/icon/src/lib/icon-registry.ts @@ -21,10 +21,3 @@ export class IconRegistry { this.#cache[name] = icon; }; } - -export function provideIconRegistry() { - return { - provide: IconRegistry, - deps: [HttpClient], - }; -}