Skip to content

Commit 823bd9e

Browse files
brentkulwickiBrent Kulwicki
andauthored
[EdgeDB] - Ceremony queries (#3183)
Co-authored-by: Brent Kulwicki <[email protected]>
1 parent 26e5811 commit 823bd9e

9 files changed

+85
-51
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { NotImplementedException, PublicOf } from '~/common';
3+
import { castToEnum, RepoFor } from '~/core/edgedb';
4+
import { CeremonyRepository } from './ceremony.repository';
5+
import { Ceremony, CeremonyType } from './dto';
6+
7+
@Injectable()
8+
export class CeremonyEdgeDBRepository
9+
extends RepoFor(Ceremony, {
10+
hydrate: (ceremony) => ({
11+
...ceremony['*'],
12+
engagement: true,
13+
type: castToEnum(ceremony.__type__.name.slice(12, -8), CeremonyType),
14+
}),
15+
}).customize((cls, { defaults }) => {
16+
return class extends cls {
17+
static omit = [defaults.create];
18+
};
19+
})
20+
implements PublicOf<CeremonyRepository>
21+
{
22+
async create(): Promise<never> {
23+
throw new NotImplementedException();
24+
}
25+
}

src/components/ceremony/ceremony.module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { forwardRef, Module } from '@nestjs/common';
2+
import { splitDb } from '~/core';
23
import { AuthorizationModule } from '../authorization/authorization.module';
4+
import { CeremonyEdgeDBRepository } from './ceremony.edgedb.repository';
35
import { CeremonyLoader } from './ceremony.loader';
46
import { CeremonyRepository } from './ceremony.repository';
57
import { CeremonyResolver } from './ceremony.resolver';
@@ -11,7 +13,7 @@ import * as handlers from './handlers';
1113
providers: [
1214
CeremonyResolver,
1315
CeremonyService,
14-
CeremonyRepository,
16+
splitDb(CeremonyRepository, CeremonyEdgeDBRepository),
1517
CeremonyLoader,
1618
...Object.values(handlers),
1719
],

src/components/ceremony/ceremony.repository.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { Injectable } from '@nestjs/common';
22
import { node, Query, relation } from 'cypher-query-builder';
3-
import { ChangesOf } from '~/core/database/changes';
4-
import { ID, Session, UnsecuredDto } from '../../common';
5-
import { DtoRepository } from '../../core';
3+
import { ID, ServerException, Session, UnsecuredDto } from '~/common';
4+
import { DtoRepository } from '~/core';
65
import {
76
ACTIVE,
87
createNode,
@@ -11,7 +10,7 @@ import {
1110
paginate,
1211
requestingUser,
1312
sorting,
14-
} from '../../core/database/query';
13+
} from '~/core/database/query';
1514
import {
1615
Ceremony,
1716
CeremonyListInput,
@@ -32,18 +31,22 @@ export class CeremonyRepository extends DtoRepository<
3231
actualDate: input.actualDate,
3332
canDelete: true,
3433
};
35-
return await this.db
34+
const result = await this.db
3635
.query()
3736
.apply(await createNode(Ceremony, { initialProps }))
3837
.return<{ id: ID }>('node.id as id')
3938
.first();
39+
40+
if (!result) {
41+
throw new ServerException('failed to create a ceremony');
42+
}
43+
return result;
4044
}
4145

42-
async update(
43-
existing: Ceremony,
44-
changes: ChangesOf<Ceremony, UpdateCeremony>,
45-
) {
46-
return await this.updateProperties(existing, changes);
46+
async update(changes: UpdateCeremony, session: Session) {
47+
const { id, ...simpleChanges } = changes;
48+
await this.updateProperties({ id }, simpleChanges);
49+
return await this.readOne(id, session);
4750
}
4851

4952
protected hydrate(session: Session) {

src/components/ceremony/ceremony.resolver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
ListArg,
77
LoggedInSession,
88
Session,
9-
} from '../../common';
9+
} from '~/common';
1010
import { Loader, LoaderOf } from '../../core';
1111
import { CeremonyLoader, CeremonyService } from '../ceremony';
1212
import {

src/components/ceremony/ceremony.service.ts

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
UnsecuredDto,
99
} from '../../common';
1010
import { HandleIdLookup, ILogger, Logger } from '../../core';
11-
import { mapListResults } from '../../core/database/results';
1211
import { Privileges } from '../authorization';
1312
import { CeremonyRepository } from './ceremony.repository';
1413
import {
@@ -23,26 +22,14 @@ import {
2322
export class CeremonyService {
2423
constructor(
2524
private readonly privileges: Privileges,
26-
private readonly ceremonyRepo: CeremonyRepository,
25+
private readonly repo: CeremonyRepository,
2726
@Logger('ceremony:service') private readonly logger: ILogger,
2827
) {}
2928

3029
async create(input: CreateCeremony): Promise<ID> {
31-
try {
32-
const result = await this.ceremonyRepo.create(input);
33-
34-
if (!result) {
35-
throw new ServerException('failed to create a ceremony');
36-
}
30+
const { id } = await this.repo.create(input);
3731

38-
return result.id;
39-
} catch (exception) {
40-
this.logger.warning('Failed to create ceremony', {
41-
exception,
42-
});
43-
44-
throw exception;
45-
}
32+
return id;
4633
}
4734

4835
@HandleIdLookup(Ceremony)
@@ -56,36 +43,41 @@ export class CeremonyService {
5643
throw new InputException('No ceremony id to search for', 'ceremony.id');
5744
}
5845

59-
const dto = await this.ceremonyRepo.readOne(id, session);
60-
return await this.secure(dto, session);
46+
const dto = await this.repo.readOne(id, session);
47+
return this.secure(dto, session);
6148
}
6249

6350
async readMany(ids: readonly ID[], session: Session) {
64-
const ceremonies = await this.ceremonyRepo.readMany(ids, session);
65-
return await Promise.all(
66-
ceremonies.map((dto) => this.secure(dto, session)),
67-
);
51+
const ceremonies = await this.repo.readMany(ids, session);
52+
return ceremonies.map((dto) => this.secure(dto, session));
6853
}
6954

70-
async secure(dto: UnsecuredDto<Ceremony>, session: Session) {
55+
secure(dto: UnsecuredDto<Ceremony>, session: Session) {
7156
return this.privileges.for(session, Ceremony).secure(dto);
7257
}
7358

7459
async update(input: UpdateCeremony, session: Session): Promise<Ceremony> {
75-
const object = await this.readOne(input.id, session);
76-
const changes = this.ceremonyRepo.getActualChanges(object, input);
60+
const object = await this.repo.readOne(input.id, session);
61+
const changes = this.repo.getActualChanges(object, input);
7762
this.privileges.for(session, Ceremony, object).verifyChanges(changes);
78-
return await this.ceremonyRepo.update(object, changes);
63+
const updated = await this.repo.update(
64+
{
65+
id: input.id,
66+
...changes,
67+
},
68+
session,
69+
);
70+
return this.secure(updated, session);
7971
}
8072

8173
async delete(id: ID, session: Session): Promise<void> {
82-
const object = await this.readOne(id, session);
74+
const object = await this.repo.readOne(id, session);
8375

8476
// Only called internally, not exposed directly to users
8577
// this.privileges.for(session, Ceremony, object).verifyCan('delete');
8678

8779
try {
88-
await this.ceremonyRepo.deleteNode(object);
80+
await this.repo.deleteNode(object);
8981
} catch (exception) {
9082
this.logger.warning('Failed to delete Ceremony', {
9183
exception,
@@ -98,7 +90,10 @@ export class CeremonyService {
9890
input: CeremonyListInput,
9991
session: Session,
10092
): Promise<CeremonyListOutput> {
101-
const results = await this.ceremonyRepo.list(input, session);
102-
return await mapListResults(results, (dto) => this.secure(dto, session));
93+
const results = await this.repo.list(input, session);
94+
return {
95+
...results,
96+
items: results.items.map((dto) => this.secure(dto, session)),
97+
};
10398
}
10499
}

src/components/ceremony/dto/ceremony.dto.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import { Field, ObjectType } from '@nestjs/graphql';
22
import { keys as keysOf } from 'ts-transformer-keys';
3-
import { e } from '~/core/edgedb';
4-
import { RegisterResource } from '~/core/resources';
53
import {
64
Calculated,
75
Resource,
86
SecuredBoolean,
9-
SecuredDate,
7+
SecuredDateNullable,
108
SecuredProperty,
119
SecuredProps,
1210
Sensitivity,
1311
SensitivityField,
14-
} from '../../../common';
12+
} from '~/common';
13+
import { e } from '~/core/edgedb';
14+
import { RegisterResource } from '~/core/resources';
1515
import { CeremonyType } from './ceremony-type.enum';
1616

1717
@RegisterResource({ db: e.Engagement.Ceremony })
@@ -33,10 +33,10 @@ export class Ceremony extends Resource {
3333
readonly planned: SecuredBoolean;
3434

3535
@Field()
36-
readonly estimatedDate: SecuredDate;
36+
readonly estimatedDate: SecuredDateNullable;
3737

3838
@Field()
39-
readonly actualDate: SecuredDate;
39+
readonly actualDate: SecuredDateNullable;
4040

4141
@SensitivityField({
4242
description: "Based on the project's sensitivity",

src/components/ceremony/dto/create-ceremony.dto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Field, InputType } from '@nestjs/graphql';
2-
import { CalendarDate, DateField } from '../../../common';
2+
import { CalendarDate, DateField } from '~/common';
33
import { CeremonyType } from './ceremony-type.enum';
44

55
@InputType()

src/components/ceremony/dto/update-ceremony.dto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Field, InputType, ObjectType } from '@nestjs/graphql';
22
import { Type } from 'class-transformer';
33
import { ValidateNested } from 'class-validator';
4-
import { CalendarDate, DateField, ID, IdField } from '../../../common';
4+
import { CalendarDate, DateField, ID, IdField } from '~/common';
55
import { Ceremony } from './ceremony.dto';
66

77
@InputType()

src/components/ceremony/handlers/create-engagement-default-ceremony.handler.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { node, relation } from 'cypher-query-builder';
22
import { DateTime } from 'luxon';
3-
import { DatabaseService, EventsHandler, IEventHandler } from '../../../core';
3+
import {
4+
ConfigService,
5+
DatabaseService,
6+
EventsHandler,
7+
IEventHandler,
8+
} from '~/core';
49
import { EngagementCreatedEvent } from '../../engagement/events';
510
import { CeremonyService } from '../ceremony.service';
611
import { CeremonyType } from '../dto';
@@ -11,6 +16,7 @@ export class CreateEngagementDefaultCeremonyHandler
1116
{
1217
constructor(
1318
private readonly ceremonies: CeremonyService,
19+
private readonly config: ConfigService,
1420
private readonly db: DatabaseService,
1521
) {}
1622

@@ -22,6 +28,9 @@ export class CreateEngagementDefaultCeremonyHandler
2228
? CeremonyType.Dedication
2329
: CeremonyType.Certification,
2430
};
31+
if (this.config.databaseEngine === 'edgedb') {
32+
return;
33+
}
2534
const ceremonyId = await this.ceremonies.create(input);
2635

2736
// connect ceremonyId to engagement

0 commit comments

Comments
 (0)