dev: create rule
This commit is contained in:
parent
22e5c6ead2
commit
70cf100407
11 changed files with 128 additions and 9 deletions
|
@ -390,6 +390,16 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CreateRuleDto"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": ""
|
||||
|
@ -423,6 +433,14 @@
|
|||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ruleId",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -5436,6 +5454,21 @@
|
|||
],
|
||||
"type": "object"
|
||||
},
|
||||
"CreateRuleDto": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"$ref": "#/components/schemas/RuleKey"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"key",
|
||||
"value"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"CreateTagDto": {
|
||||
"properties": {
|
||||
"name": {
|
||||
|
@ -6169,6 +6202,14 @@
|
|||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RuleKey": {
|
||||
"enum": [
|
||||
"personId",
|
||||
"exifInfo.city",
|
||||
"asset.fileCreatedAt"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"SearchAlbumResponseDto": {
|
||||
"properties": {
|
||||
"count": {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { AlbumEntity, AssetEntity, UserEntity } from '@app/infra/entities';
|
||||
import { AlbumEntity, AssetEntity, RuleEntity, UserEntity } from '@app/infra/entities';
|
||||
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
||||
import { AccessCore, IAccessRepository, Permission } from '../access';
|
||||
import { BulkIdErrorReason, BulkIdResponseDto, BulkIdsDto, IAssetRepository, mapAsset } from '../asset';
|
||||
|
@ -7,7 +7,8 @@ import { IJobRepository, JobName } from '../job';
|
|||
import { IUserRepository } from '../user';
|
||||
import { AlbumCountResponseDto, AlbumResponseDto, mapAlbum } from './album-response.dto';
|
||||
import { IAlbumRepository } from './album.repository';
|
||||
import { AddUsersDto, CreateAlbumDto, GetAlbumsDto, UpdateAlbumDto } from './dto';
|
||||
import { AddUsersDto, CreateAlbumDto, CreateRuleDto, GetAlbumsDto, UpdateAlbumDto } from './dto';
|
||||
import { IRuleRepository } from './rule.repository';
|
||||
|
||||
@Injectable()
|
||||
export class AlbumService {
|
||||
|
@ -18,6 +19,7 @@ export class AlbumService {
|
|||
@Inject(IAssetRepository) private assetRepository: IAssetRepository,
|
||||
@Inject(IJobRepository) private jobRepository: IJobRepository,
|
||||
@Inject(IUserRepository) private userRepository: IUserRepository,
|
||||
@Inject(IRuleRepository) private ruleRepository: IRuleRepository,
|
||||
) {
|
||||
this.access = new AccessCore(accessRepository);
|
||||
}
|
||||
|
@ -98,6 +100,7 @@ export class AlbumService {
|
|||
sharedUsers: dto.sharedWithUserIds?.map((value) => ({ id: value } as UserEntity)) ?? [],
|
||||
assets: (dto.assetIds || []).map((id) => ({ id } as AssetEntity)),
|
||||
albumThumbnailAssetId: dto.assetIds?.[0] || null,
|
||||
rules: [],
|
||||
});
|
||||
|
||||
await this.jobRepository.queue({ name: JobName.SEARCH_INDEX_ALBUM, data: { ids: [album.id] } });
|
||||
|
@ -281,4 +284,29 @@ export class AlbumService {
|
|||
}
|
||||
return album;
|
||||
}
|
||||
|
||||
async addRule(authUser: AuthUserDto, id: string, dto: CreateRuleDto) {
|
||||
await this.access.requirePermission(authUser, Permission.ALBUM_READ, id);
|
||||
|
||||
const album = await this.findOrFail(id);
|
||||
const user = await this.userRepository.get(authUser.id);
|
||||
|
||||
if (!user) {
|
||||
throw new BadRequestException('User not found');
|
||||
}
|
||||
|
||||
const rule = new RuleEntity();
|
||||
rule.key = dto.key;
|
||||
rule.value = dto.value;
|
||||
rule.album = album;
|
||||
rule.albumId = album.id;
|
||||
rule.user = user;
|
||||
rule.ownerId = user.id;
|
||||
|
||||
await this.ruleRepository.create(rule);
|
||||
|
||||
return await this.findOrFail(id);
|
||||
}
|
||||
|
||||
async removeRule(authUser: AuthUserDto, ruleId: string) {}
|
||||
}
|
||||
|
|
|
@ -2,3 +2,4 @@ export * from './album-add-users.dto';
|
|||
export * from './album-create.dto';
|
||||
export * from './album-update.dto';
|
||||
export * from './get-albums.dto';
|
||||
export * from './rule.dto';
|
||||
|
|
12
server/src/domain/album/dto/rule.dto.ts
Normal file
12
server/src/domain/album/dto/rule.dto.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { RuleKey } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNotEmpty } from 'class-validator';
|
||||
|
||||
export class CreateRuleDto {
|
||||
@ApiProperty({ enumName: 'RuleKey', enum: RuleKey })
|
||||
@IsNotEmpty()
|
||||
key!: RuleKey;
|
||||
|
||||
@IsNotEmpty()
|
||||
value!: string;
|
||||
}
|
|
@ -2,3 +2,4 @@ export * from './album-response.dto';
|
|||
export * from './album.repository';
|
||||
export * from './album.service';
|
||||
export * from './dto';
|
||||
export * from './rule.repository';
|
||||
|
|
8
server/src/domain/album/rule.repository.ts
Normal file
8
server/src/domain/album/rule.repository.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { RuleEntity } from '@app/infra/entities';
|
||||
|
||||
export const IRuleRepository = 'IRuleRepository';
|
||||
|
||||
export interface IRuleRepository {
|
||||
create(rule: RuleEntity): Promise<RuleEntity>;
|
||||
delete(rule: RuleEntity): Promise<void>;
|
||||
}
|
|
@ -6,6 +6,7 @@ import {
|
|||
BulkIdResponseDto,
|
||||
BulkIdsDto,
|
||||
CreateAlbumDto as CreateDto,
|
||||
CreateRuleDto,
|
||||
UpdateAlbumDto as UpdateDto,
|
||||
} from '@app/domain';
|
||||
import { GetAlbumsDto } from '@app/domain/album/dto/get-albums.dto';
|
||||
|
@ -88,12 +89,16 @@ export class AlbumController {
|
|||
}
|
||||
|
||||
@Post(':id/rule')
|
||||
addRule(@AuthUser() authUser: AuthUserDto, @Param() { id }: UUIDParamDto) {
|
||||
throw new Error('Not implemented');
|
||||
addRule(@AuthUser() authUser: AuthUserDto, @Param() { id }: UUIDParamDto, @Body() dto: CreateRuleDto) {
|
||||
return this.service.addRule(authUser, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id/rule/:ruleId')
|
||||
removeRule(@AuthUser() authUser: AuthUserDto, @Param() { id }: UUIDParamDto) {
|
||||
removeRule(
|
||||
@AuthUser() authUser: AuthUserDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Param('ruleId', new ParseMeUUIDPipe({ version: '4' })) ruleId: string,
|
||||
) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
immichAppConfig,
|
||||
IPartnerRepository,
|
||||
IPersonRepository,
|
||||
IRuleRepository,
|
||||
ISearchRepository,
|
||||
ISharedLinkRepository,
|
||||
ISmartInfoRepository,
|
||||
|
@ -45,6 +46,7 @@ import {
|
|||
MediaRepository,
|
||||
PartnerRepository,
|
||||
PersonRepository,
|
||||
RuleRepository,
|
||||
SharedLinkRepository,
|
||||
SmartInfoRepository,
|
||||
SystemConfigRepository,
|
||||
|
@ -67,6 +69,7 @@ const providers: Provider[] = [
|
|||
{ provide: IMachineLearningRepository, useClass: MachineLearningRepository },
|
||||
{ provide: IPartnerRepository, useClass: PartnerRepository },
|
||||
{ provide: IPersonRepository, useClass: PersonRepository },
|
||||
{ provide: IRuleRepository, useClass: RuleRepository },
|
||||
{ provide: ISearchRepository, useClass: TypesenseRepository },
|
||||
{ provide: ISharedLinkRepository, useClass: SharedLinkRepository },
|
||||
{ provide: ISmartInfoRepository, useClass: SmartInfoRepository },
|
||||
|
|
|
@ -24,6 +24,7 @@ export class AlbumRepository implements IAlbumRepository {
|
|||
exifInfo: true,
|
||||
},
|
||||
sharedLinks: true,
|
||||
rules: true,
|
||||
},
|
||||
order: {
|
||||
assets: {
|
||||
|
@ -41,6 +42,7 @@ export class AlbumRepository implements IAlbumRepository {
|
|||
relations: {
|
||||
owner: true,
|
||||
sharedUsers: true,
|
||||
rules: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -48,7 +50,7 @@ export class AlbumRepository implements IAlbumRepository {
|
|||
getByAssetId(ownerId: string, assetId: string): Promise<AlbumEntity[]> {
|
||||
return this.repository.find({
|
||||
where: { ownerId, assets: { id: assetId } },
|
||||
relations: { owner: true, sharedUsers: true },
|
||||
relations: { owner: true, sharedUsers: true, rules: true },
|
||||
order: { createdAt: 'DESC' },
|
||||
});
|
||||
}
|
||||
|
@ -104,7 +106,7 @@ export class AlbumRepository implements IAlbumRepository {
|
|||
|
||||
getOwned(ownerId: string): Promise<AlbumEntity[]> {
|
||||
return this.repository.find({
|
||||
relations: { sharedUsers: true, sharedLinks: true, owner: true },
|
||||
relations: { sharedUsers: true, sharedLinks: true, owner: true, rules: true },
|
||||
where: { ownerId },
|
||||
order: { createdAt: 'DESC' },
|
||||
});
|
||||
|
@ -115,7 +117,7 @@ export class AlbumRepository implements IAlbumRepository {
|
|||
*/
|
||||
getShared(ownerId: string): Promise<AlbumEntity[]> {
|
||||
return this.repository.find({
|
||||
relations: { sharedUsers: true, sharedLinks: true, owner: true },
|
||||
relations: { sharedUsers: true, sharedLinks: true, owner: true, rules: true },
|
||||
where: [
|
||||
{ sharedUsers: { id: ownerId } },
|
||||
{ sharedLinks: { userId: ownerId } },
|
||||
|
@ -130,7 +132,7 @@ export class AlbumRepository implements IAlbumRepository {
|
|||
*/
|
||||
getNotShared(ownerId: string): Promise<AlbumEntity[]> {
|
||||
return this.repository.find({
|
||||
relations: { sharedUsers: true, sharedLinks: true, owner: true },
|
||||
relations: { sharedUsers: true, sharedLinks: true, owner: true, rules: true },
|
||||
where: { ownerId, sharedUsers: { id: IsNull() }, sharedLinks: { id: IsNull() } },
|
||||
order: { createdAt: 'DESC' },
|
||||
});
|
||||
|
@ -182,6 +184,7 @@ export class AlbumRepository implements IAlbumRepository {
|
|||
owner: true,
|
||||
sharedUsers: true,
|
||||
assets: true,
|
||||
rules: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ export * from './machine-learning.repository';
|
|||
export * from './media.repository';
|
||||
export * from './partner.repository';
|
||||
export * from './person.repository';
|
||||
export * from './rule.repository';
|
||||
export * from './shared-link.repository';
|
||||
export * from './smart-info.repository';
|
||||
export * from './system-config.repository';
|
||||
|
|
16
server/src/infra/repositories/rule.repository.ts
Normal file
16
server/src/infra/repositories/rule.repository.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { IRuleRepository } from '@app/domain';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { RuleEntity } from '../entities';
|
||||
|
||||
export class RuleRepository implements IRuleRepository {
|
||||
constructor(@InjectRepository(RuleEntity) private assetRepository: Repository<RuleEntity>) {}
|
||||
|
||||
create(rule: RuleEntity): Promise<RuleEntity> {
|
||||
return this.assetRepository.save(rule);
|
||||
}
|
||||
|
||||
delete(rule: RuleEntity): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue