1
1
import { Injectable } from '@nestjs/common' ;
2
2
import {
3
3
type ID ,
4
+ InputException ,
5
+ NotFoundException ,
4
6
type ObjectView ,
5
7
ServerException ,
6
8
type UnsecuredDto ,
7
9
} from '~/common' ;
8
10
import { HandleIdLookup } from '~/core' ;
11
+ import { IEventBus } from '~/core/events' ;
9
12
import { Privileges } from '../authorization' ;
13
+ import { UserService } from '../user' ;
10
14
import {
11
15
type CreateFieldRegion ,
12
16
FieldRegion ,
13
17
type FieldRegionListInput ,
14
18
type FieldRegionListOutput ,
15
19
type UpdateFieldRegion ,
16
20
} from './dto' ;
21
+ import { FieldRegionUpdatedEvent } from './events/field-region-updated.event' ;
17
22
import { FieldRegionRepository } from './field-region.repository' ;
18
23
19
24
@Injectable ( )
20
25
export class FieldRegionService {
21
26
constructor (
22
27
private readonly privileges : Privileges ,
28
+ private readonly events : IEventBus ,
29
+ private readonly users : UserService ,
23
30
private readonly repo : FieldRegionRepository ,
24
31
) { }
25
32
26
33
async create ( input : CreateFieldRegion ) : Promise < FieldRegion > {
27
34
this . privileges . for ( FieldRegion ) . verifyCan ( 'create' ) ;
35
+ await this . validateDirectorRole ( input . directorId ) ;
28
36
const dto = await this . repo . create ( input ) ;
29
37
return this . secure ( dto ) ;
30
38
}
@@ -50,10 +58,44 @@ export class FieldRegionService {
50
58
const changes = this . repo . getActualChanges ( fieldRegion , input ) ;
51
59
this . privileges . for ( FieldRegion , fieldRegion ) . verifyChanges ( changes ) ;
52
60
61
+ if ( changes . directorId ) {
62
+ await this . validateDirectorRole ( changes . directorId ) ;
63
+ }
64
+
65
+ if ( Object . keys ( changes ) . length === 0 ) {
66
+ return this . secure ( fieldRegion ) ;
67
+ }
68
+
53
69
const updated = await this . repo . update ( { id : input . id , ...changes } ) ;
70
+
71
+ const event = new FieldRegionUpdatedEvent ( fieldRegion , updated , {
72
+ id : input . id ,
73
+ ...changes ,
74
+ } ) ;
75
+ await this . events . publish ( event ) ;
76
+
54
77
return this . secure ( updated ) ;
55
78
}
56
79
80
+ private async validateDirectorRole ( directorId : ID < 'User' > ) {
81
+ let director ;
82
+ try {
83
+ director = await this . users . readOneUnsecured ( directorId ) ;
84
+ } catch ( e ) {
85
+ if ( e instanceof NotFoundException ) {
86
+ throw e . withField ( 'fieldRegion.directorId' ) ;
87
+ }
88
+ throw e ;
89
+ }
90
+ if ( ! director . roles . includes ( 'RegionalDirector' ) ) {
91
+ throw new InputException (
92
+ 'User does not have the Regional Director role' ,
93
+ 'fieldRegion.directorId' ,
94
+ ) ;
95
+ }
96
+ return director ;
97
+ }
98
+
57
99
async delete ( id : ID ) : Promise < void > {
58
100
const object = await this . readOne ( id ) ;
59
101
0 commit comments