Skip to content

Commit 1120725

Browse files
committed
Finish ToolUsage module
1 parent 447966a commit 1120725

13 files changed

+198
-179
lines changed

dbschema/resource.gel

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
module default {
2-
abstract type Resource extending Mixin::Audited;
2+
abstract type Resource extending Mixin::Audited {
3+
tools := .<container[is Tool::Usage];
4+
}
35
}

src/components/authorization/policies/by-role/consultant.policy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export const projectTransitions = () =>
2626
r.ProgressReportTeamNews,
2727
r.ProgressReportMedia,
2828
r.ProgressReportVarianceExplanation,
29+
r.ToolUsage,
2930
r.StepProgress,
3031
].map((it) => it.when(member).read),
3132

src/components/authorization/policies/by-role/field-operations-director.policy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { Policy, Role } from '../util';
2121
'Field Ops Rejects Proposal',
2222
).execute,
2323
r.PeriodicReport.edit,
24+
r.ToolUsage.edit.create.delete,
2425
r.StepProgress.edit,
2526
])
2627
export class FieldOperationsDirectorPolicy {}

src/components/authorization/policies/by-role/project-manager.policy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ export const momentumProjectsTransitions = () =>
163163
])
164164
.children((c) => c.posts.read.create),
165165
r.ProjectMember.read.when(member).edit.create.delete,
166+
r.ToolUsage.read.when(member).edit.create.delete,
166167
[r.StepProgress].flatMap((it) => [
167168
it.whenAll(member, variant('partner')).read,
168169
it.whenAll(member, variant('official')).edit,

src/components/tools/tool-usage/dto/create-tool-usage.dto.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Field, InputType, ObjectType } from '@nestjs/graphql';
2-
import { CalendarDate, DateField, type ID, IdField } from '~/common';
2+
import { type CalendarDate, DateField, type ID, IdField } from '~/common';
33
import { ToolUsage } from './tool-usage.dto';
44

55
@InputType()
@@ -15,7 +15,7 @@ export abstract class CreateToolUsage {
1515
readonly tool: ID<'Tool'>;
1616

1717
@DateField({ nullable: true })
18-
readonly startDate?: CalendarDate;
18+
readonly startDate?: CalendarDate | null;
1919
}
2020

2121
@ObjectType()

src/components/tools/tool-usage/dto/tool-usage.dto.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
Resource,
44
type Secured,
55
SecuredDateNullable,
6-
SecuredProperty,
76
type SetUnsecuredType,
87
type UnsecuredDto,
98
} from '~/common';
@@ -27,12 +26,9 @@ export class ToolUsage extends Resource {
2726
@Field()
2827
readonly startDate: SecuredDateNullable;
2928

30-
readonly creator: LinkTo<'User'>;
29+
readonly creator: LinkTo<'Actor'>;
3130
}
3231

33-
@ObjectType()
34-
export class SecuredToolUsage extends SecuredProperty(ToolUsage) {}
35-
3632
declare module '~/core/resources/map' {
3733
interface ResourceMap {
3834
ToolUsage: typeof ToolUsage;

src/components/tools/tool-usage/dto/update-tool-usage.dto.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,12 @@ import { ToolUsage } from './tool-usage.dto';
55
@InputType()
66
export abstract class UpdateToolUsage {
77
@IdField()
8-
readonly id: ID;
8+
readonly id: ID<ToolUsage>;
99

1010
@DateField({ nullable: true })
1111
readonly startDate?: CalendarDate | null;
1212
}
1313

14-
@InputType()
15-
export abstract class UpdateToolUsageInput {
16-
@Field()
17-
readonly usage: UpdateToolUsage;
18-
}
19-
2014
@ObjectType()
2115
export abstract class UpdateToolUsageOutput {
2216
@Field()

src/components/tools/tool-usage/resource-tools.resolver.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,14 @@ import { Resource } from '~/common';
33
import { ToolUsage } from './dto';
44
import { ToolUsageService } from './tool-usage.service';
55

6-
@Resolver(() => Resource, { isAbstract: true })
6+
@Resolver(() => Resource)
77
export class ResourceToolsResolver {
88
constructor(private readonly toolUsageService: ToolUsageService) {}
99

1010
@ResolveField(() => [ToolUsage], {
11-
description: 'Tool usages for this resource',
11+
description: 'Tools used in this resource',
1212
})
13-
async tools(@Parent() resource: Resource): Promise<ToolUsage[]> {
14-
if (resource.__typename === 'ToolUsage' || resource.__typename === 'Tool') {
15-
return [];
16-
}
17-
return await this.toolUsageService.findByContainerId(resource.id);
13+
async tools(@Parent() resource: Resource): Promise<readonly ToolUsage[]> {
14+
return await this.toolUsageService.readByContainer(resource);
1815
}
1916
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { type ID, type PublicOf } from '~/common';
3+
import { e, RepoFor } from '~/core/gel';
4+
import { ToolUsage } from './dto';
5+
import { type ToolUsageRepository as Neo4jRepository } from './tool-usage.neo4j.repository';
6+
7+
const resAsBaseNode = e.shape(e.Resource, (res) => ({
8+
identity: res.id,
9+
labels: e.array_agg(e.set(res.__type__.name)),
10+
properties: e.select({
11+
id: res.id,
12+
createdAt: res.createdAt,
13+
}),
14+
}));
15+
16+
@Injectable()
17+
export class ToolUsageRepository
18+
extends RepoFor(ToolUsage, {
19+
hydrate: (usage) => ({
20+
...usage['*'],
21+
container: resAsBaseNode(usage.container),
22+
tool: usage.tool['*'],
23+
creator: usage.createdBy,
24+
}),
25+
})
26+
implements PublicOf<Neo4jRepository>
27+
{
28+
async listForContainer(container: ID) {
29+
return await this.db.run(this.listForContainerQuery, { container });
30+
}
31+
private readonly listForContainerQuery = e.params(
32+
{ container: e.uuid },
33+
($) => {
34+
const container = e.cast(e.Resource, $.container);
35+
return e.select(container.tools, this.hydrate);
36+
},
37+
);
38+
}
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
import { Module } from '@nestjs/common';
2+
import { splitDb } from '~/core/database';
23
import { ToolCoreModule } from '../tool/tool.module';
34
import { ResourceToolsResolver } from './resource-tools.resolver';
5+
import { ToolUsageRepository as GelRepository } from './tool-usage.gel.repository';
46
import { ToolUsageLoader } from './tool-usage.loader';
5-
import { ToolUsageRepository } from './tool-usage.repository';
7+
import { ToolUsageRepository as Neo4jRepository } from './tool-usage.neo4j.repository';
68
import { ToolUsageResolver } from './tool-usage.resolver';
79
import { ToolUsageService } from './tool-usage.service';
810

911
@Module({
1012
imports: [ToolCoreModule],
1113
providers: [
12-
ToolUsageService,
13-
ToolUsageRepository,
1414
ToolUsageResolver,
15-
ToolUsageLoader,
1615
ResourceToolsResolver,
16+
ToolUsageLoader,
17+
ToolUsageService,
18+
splitDb(Neo4jRepository, GelRepository),
1719
],
18-
exports: [ToolUsageService, ResourceToolsResolver],
20+
exports: [ToolUsageService],
1921
})
2022
export class ToolUsageModule {}

0 commit comments

Comments
 (0)