Skip to content

Commit 80a9c87

Browse files
committed
Add the 3 system agents to seeds & create repositories
1 parent 9327005 commit 80a9c87

File tree

6 files changed

+134
-10
lines changed

6 files changed

+134
-10
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { SeedFn } from '~/core/edgedb/seeds.run';
2+
3+
const agents = [
4+
{ name: 'Ghost' },
5+
{ name: 'Anonymous' },
6+
{ name: 'External Mailing Group', roles: ['Leadership'] },
7+
];
8+
9+
export default (async function ({ runAndPrint }) {
10+
await runAndPrint(
11+
`
12+
with
13+
agentsJson := json_array_unpack(<json>$agentsJson),
14+
newAgents := (select agentsJson filter <str>agentsJson['name'] not in SystemAgent.name),
15+
added := (
16+
for entry in newAgents union (
17+
insert SystemAgent {
18+
name := <str>entry['name'],
19+
roles := <str>json_array_unpack(json_get(entry, 'roles'))
20+
})
21+
)
22+
select { \`Added System Agents\` := added.name }
23+
filter count(added) > 0;
24+
`,
25+
{ agentsJson: agents },
26+
);
27+
} satisfies SeedFn);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { Role } from '~/common';
3+
import { disableAccessPolicies, EdgeDB, edgeql } from '~/core/edgedb';
4+
import { ActorRepository } from './actor.repository';
5+
6+
@Injectable()
7+
export class ActorEdgeDBRepository extends ActorRepository {
8+
private readonly db: EdgeDB;
9+
constructor(edgedb: EdgeDB) {
10+
super();
11+
this.db = edgedb.withOptions(disableAccessPolicies);
12+
}
13+
14+
protected async upsertAgent(name: string, roles?: readonly Role[]) {
15+
const query = edgeql(`
16+
select (
17+
(select SystemAgent filter .name = <str>$name) ??
18+
(insert SystemAgent {
19+
name := <str>$name,
20+
roles := array_unpack(<optional array<Role>>$roles)
21+
})
22+
) {*}
23+
`);
24+
return await this.db.run(query, { name, roles });
25+
}
26+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { node } from 'cypher-query-builder';
3+
import { ID, Role } from '~/common';
4+
import { DatabaseService } from '~/core';
5+
import { ActorRepository } from './actor.repository';
6+
7+
@Injectable()
8+
export class ActorNeo4jRepository extends ActorRepository {
9+
constructor(private readonly db: DatabaseService) {
10+
super();
11+
}
12+
13+
protected async upsertAgent(name: string, roles?: readonly Role[]) {
14+
const res = await this.db
15+
.query()
16+
.merge(node('agent', 'SystemAgent', { name }))
17+
.onCreate.set({
18+
variables: {
19+
'agent.id': 'apoc.create.uuid()',
20+
},
21+
values: {
22+
'agent.roles': roles ?? [],
23+
},
24+
})
25+
.return<{ agent: { id: ID; name: string; roles: readonly Role[] } }>(
26+
'apoc.convert.toMap(agent) AS agent',
27+
)
28+
.first();
29+
return res!.agent;
30+
}
31+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { CachedByArg } from '@seedcompany/common';
3+
import { ID, Role } from '~/common';
4+
5+
@Injectable()
6+
export abstract class ActorRepository {
7+
@CachedByArg()
8+
async getAnonymous() {
9+
return await this.upsertAgent('Anonymous');
10+
}
11+
12+
@CachedByArg()
13+
async getGhost() {
14+
return await this.upsertAgent('Ghost');
15+
}
16+
17+
@CachedByArg()
18+
async getExternalMailingGroup() {
19+
return await this.upsertAgent('External Mailing Group', ['Leadership']);
20+
}
21+
22+
protected abstract upsertAgent(
23+
name: string,
24+
roles?: readonly Role[],
25+
): Promise<{ id: ID; name: string; roles: readonly Role[] }>;
26+
}

src/components/user/user.module.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { LocationModule } from '../location/location.module';
77
import { OrganizationModule } from '../organization/organization.module';
88
import { PartnerModule } from '../partner/partner.module';
99
import { TimeZoneModule } from '../timezone';
10+
import { ActorEdgeDBRepository } from './actor.edgedb.repository';
11+
import { ActorNeo4jRepository } from './actor.neo4j.repository';
12+
import { ActorRepository } from './actor.repository';
1013
import { AssignableRolesResolver } from './assignable-roles.resolver';
1114
import { EducationModule } from './education/education.module';
1215
import { KnownLanguageRepository } from './known-language.repository';
@@ -38,7 +41,17 @@ import { UserService } from './user.service';
3841
UserService,
3942
splitDb(UserRepository, UserEdgeDBRepository),
4043
KnownLanguageRepository,
44+
{
45+
...splitDb(ActorNeo4jRepository, ActorEdgeDBRepository),
46+
provide: ActorRepository,
47+
},
48+
],
49+
exports: [
50+
UserService,
51+
UserRepository,
52+
ActorRepository,
53+
EducationModule,
54+
UnavailabilityModule,
4155
],
42-
exports: [UserService, UserRepository, EducationModule, UnavailabilityModule],
4356
})
4457
export class UserModule {}

src/core/database/split-db.provider.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ import { ConfigService } from '../config/config.service';
66
export const splitDb = <T>(
77
neo4jRepository: Type<T>,
88
edgeDbRepository: Type<PublicOf<T>>,
9-
): Provider => ({
10-
provide: neo4jRepository,
11-
inject: [ModuleRef, ConfigService],
12-
useFactory: async (moduleRef: ModuleRef, config: ConfigService) => {
13-
const cls =
14-
config.databaseEngine === 'edgedb' ? edgeDbRepository : neo4jRepository;
15-
return await moduleRef.create<T>(cls);
16-
},
17-
});
9+
) =>
10+
({
11+
provide: neo4jRepository,
12+
inject: [ModuleRef, ConfigService],
13+
useFactory: async (moduleRef: ModuleRef, config: ConfigService) => {
14+
const cls =
15+
config.databaseEngine === 'edgedb' ? edgeDbRepository : neo4jRepository;
16+
return await moduleRef.create<T>(cls);
17+
},
18+
} satisfies Provider);

0 commit comments

Comments
 (0)