Skip to content

Commit

Permalink
Work on engagement queries. LanguageEngagements pass types now.
Browse files Browse the repository at this point in the history
  • Loading branch information
CarsonF committed Jun 6, 2024
1 parent b825320 commit cadc5ea
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 76 deletions.
23 changes: 14 additions & 9 deletions src/components/engagement/dto/engagement.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import {
Secured,
SecuredBoolean,
SecuredDateNullable,
SecuredDateTime,
SecuredDateTimeNullable,
SecuredProps,
SecuredRichTextNullable,
SecuredString,
SecuredStringNullable,
Sensitivity,
SensitivityField,
UnsecuredDto,
Expand Down Expand Up @@ -118,17 +118,17 @@ class Engagement extends ChangesetAwareResource {

@Field()
// Convert from date to datetime at migration
readonly lastSuspendedAt: SecuredDateTime;
readonly lastSuspendedAt: SecuredDateTimeNullable;

@Field()
// Convert from date to datetime at migration
readonly lastReactivatedAt: SecuredDateTime;
readonly lastReactivatedAt: SecuredDateTimeNullable;

@Field({
description: 'The last time the engagement status was modified',
})
// Convert from last terminated/completed at migration
readonly statusModifiedAt: SecuredDateTime;
readonly statusModifiedAt: SecuredDateTimeNullable;

@DateTimeField()
readonly modifiedAt: DateTime;
Expand Down Expand Up @@ -178,12 +178,12 @@ export class LanguageEngagement extends Engagement {
readonly sentPrintingDate: SecuredDateNullable;

@Field()
readonly paratextRegistryId: SecuredString;
readonly paratextRegistryId: SecuredStringNullable;

readonly pnp: Secured<LinkTo<'File'>>;
readonly pnp: Secured<LinkTo<'File'> | null>;

@Field()
readonly historicGoal: SecuredString;
readonly historicGoal: SecuredStringNullable;
}

@RegisterResource({ db: e.InternshipEngagement })
Expand Down Expand Up @@ -216,12 +216,17 @@ export class InternshipEngagement extends Engagement {
@DbLabel('ProductMethodology')
readonly methodologies: SecuredMethodologies;

readonly growthPlan: Secured<LinkTo<'File'>>;
readonly growthPlan: Secured<LinkTo<'File'> | null>;
}

export const engagementRange = (engagement: UnsecuredDto<Engagement>) =>
DateInterval.tryFrom(engagement.startDate, engagement.endDate);

export const EngagementConcretes = {
LanguageEngagement: LanguageEngagement,
InternshipEngagement: InternshipEngagement,
} as const satisfies Record<Engagement['__typename'], typeof Engagement>;

declare module '~/core/resources/map' {
interface ResourceMap {
Engagement: typeof Engagement;
Expand Down
151 changes: 88 additions & 63 deletions src/components/engagement/engagement.edgedb.repository.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,119 @@
import { Injectable } from '@nestjs/common';
import { Injectable, Type } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { LazyGetter } from 'lazy-get-decorator';
import { difference } from 'lodash';
import { ID, PublicOf, Session } from '~/common';
import { grabInstances } from '~/common/instance-maps';
import { castToEnum, e, RepoFor } from '~/core/edgedb';
import { ProjectType } from '../project/dto';
import {
EngagementConcretes as ConcreteTypes,
CreateInternshipEngagement,
CreateLanguageEngagement,
EngagementListInput,
EngagementStatus,
IEngagement,
UpdateInternshipEngagement,
UpdateLanguageEngagement,
} from './dto';
import { EngagementRepository } from './engagement.repository';

const hydrate = e.shape(e.Engagement, (engagement) => ({
const baseHydrate = e.shape(e.Engagement, (engagement) => ({
...engagement['*'],
ceremony: true,
__typename: castToEnum(engagement.__type__.name.slice(9, null), [
'LanguageEngagement',
'InternshipEngagement',
]),
project: e.select(engagement.project, (project) => ({
id: true,
status: true,
type: castToEnum(project.__type__.name.slice(9, -7), ProjectType),
})),
parent: e.tuple({
identity: engagement.project.id,
labels: e.array_agg(e.set(engagement.project.__type__.name.slice(9, null))),
properties: e.tuple({
id: engagement.project.id,
createdAt: engagement.project.createdAt,
}),
}),
ceremony: true,
completeDate: engagement.completedDate, // TODO fix in schema
}));

const languageHydrate = e.shape(e.LanguageEngagement, (le) => ({
...le['*'],
...baseHydrate(le),
__typename: castToEnum(le.__type__.name.slice(9, null), [
'LanguageEngagement',
]),
language: true,
pnp: true,
}));

const languageHydrate = e.shape(e.LanguageEngagement, (engagement) => ({
...hydrate,
project: engagement.project,
language: engagement.language,
pnp: engagement.pnp,
const internshipHydrate = e.shape(e.InternshipEngagement, (ie) => ({
...ie['*'],
...baseHydrate(ie),
__typename: castToEnum(ie.__type__.name.slice(9, null), [
'InternshipEngagement',
]),
intern: true,
mentor: true,
countryOfOrigin: true,
growthPlan: true,
}));

const internshipHydrate = e.shape(e.InternshipEngagement, (engagement) => ({
...hydrate,
project: engagement.project,
intern: engagement.intern,
mentor: engagement.mentor,
countryOfOrigin: engagement.countryOfOrigin,
growthPlan: engagement.growthPlan,
const hydrate = e.shape(e.Engagement, (engagement) => ({
...languageHydrate(engagement),
...internshipHydrate(engagement),
__typename: castToEnum(engagement.__type__.name.slice(9, null), [
'LanguageEngagement',
'InternshipEngagement',
]),
}));

export const ConcreteRepos = {
LanguageEngagement: class LanguageEngagementRepository extends RepoFor(
ConcreteTypes.LanguageEngagement,
{ hydrate: languageHydrate, omit: ['create', 'update'] },
) {
async create(input: CreateLanguageEngagement) {
const project = e.cast(e.TranslationProject, e.uuid(input.projectId));
return await this.defaults.create({
...input,
projectContext: project.projectContext,
});
}

async update({ id, ...changes }: UpdateLanguageEngagement) {
return await this.defaults.update({ id, ...changes });
}
},

InternshipEngagement: class InternshipEngagementRepository extends RepoFor(
ConcreteTypes.InternshipEngagement,
{ hydrate: internshipHydrate },
) {},
} satisfies Record<keyof typeof ConcreteTypes, Type>;

@Injectable()
export class EngagementEdgeDBRepository
extends RepoFor(IEngagement, { hydrate, omit: ['create', 'update'] })
implements PublicOf<EngagementRepository>
{
constructor(private readonly moduleRef: ModuleRef) {
super();
}

@LazyGetter() protected get concretes() {
return grabInstances(this.moduleRef, ConcreteRepos);
}

async createLanguageEngagement(
input: CreateLanguageEngagement,
_session: Session,
_changeset?: ID,
) {
const { projectId, languageId, pnp, ...props } = input;

const project = e.cast(e.TranslationProject, e.uuid(projectId));
const language = e.cast(e.Language, e.uuid(languageId));

const createdLanguageEngagement = e.insert(e.LanguageEngagement, {
project: project as any,
language: language,
projectContext: project.projectContext,
pnp: undefined, //TODO
...props,
});

const query = e.select(createdLanguageEngagement, languageHydrate);

return await this.db.run(query);
return await this.concretes.LanguageEngagement.create(input);
}

async createInternshipEngagement(

Check failure on line 119 in src/components/engagement/engagement.edgedb.repository.ts

View workflow job for this annotation

GitHub Actions / lint

Property 'createInternshipEngagement' in type 'EngagementEdgeDBRepository' is not assignable to the same property in base type 'PublicOf<EngagementRepository>'.
Expand Down Expand Up @@ -100,33 +146,17 @@ export class EngagementEdgeDBRepository
return await this.db.run(query);
}

getActualLanguageChanges = this.getActualChanges(LanguageEngagement);

async updateLanguage(
changes: UpdateLanguageEngagement,
_session: Session,
_changeset?: ID,
) {
const { id, pnp, ...simpleChanges } = changes;

const languageEngagement = e.cast(e.LanguageEngagement, e.uuid(id));

if (pnp) {
//TODO
}

const updated = e.update(languageEngagement, () => ({
set: {
...simpleChanges,
},
}));

const query = e.select(updated, languageHydrate);
get getActualLanguageChanges() {
return this.concretes.LanguageEngagement.getActualChanges;
}

return await this.db.run(query);
async updateLanguage(input: UpdateLanguageEngagement) {
return await this.concretes.LanguageEngagement.update(input);
}

getActualInternshipChanges = this.getActualChanges(InternshipEngagement);
get getActualInternshipChanges() {
return this.concretes.InternshipEngagement.getActualChanges;
}

async updateInternship(

Check failure on line 161 in src/components/engagement/engagement.edgedb.repository.ts

View workflow job for this annotation

GitHub Actions / lint

Property 'updateInternship' in type 'EngagementEdgeDBRepository' is not assignable to the same property in base type 'PublicOf<EngagementRepository>'.
changes: UpdateInternshipEngagement,
Expand Down Expand Up @@ -158,11 +188,6 @@ export class EngagementEdgeDBRepository

return await this.db.run(query);
}

async list(input: EngagementListInput, _session: Session, _changeset?: ID) {
return await this.defaults.list(input);
}

async listAllByProjectId(projectId: ID, _session: Session) {

Check failure on line 191 in src/components/engagement/engagement.edgedb.repository.ts

View workflow job for this annotation

GitHub Actions / lint

Property 'listAllByProjectId' in type 'EngagementEdgeDBRepository' is not assignable to the same property in base type 'PublicOf<EngagementRepository>'.
const project = e.cast(e.Project, e.uuid(projectId));
const query = e.select(project, hydrate);
Expand All @@ -181,10 +206,10 @@ export class EngagementEdgeDBRepository
e.set(...difference([...EngagementStatus.Ongoing], excludes)),
);

const query = e.select(project.engagements, (eng) => ({
const engagements = e.select(project.engagements, (eng) => ({

Check failure on line 209 in src/components/engagement/engagement.edgedb.repository.ts

View workflow job for this annotation

GitHub Actions / lint

Property 'engagements' does not exist on type '$expr_Cast<$Project, Cardinality.One>'.
filter: e.op(eng.status, 'in', ongoingExceptExclusions),
}));

return await this.db.run(query);
return await this.db.run(engagements.id);
}
}
12 changes: 9 additions & 3 deletions src/components/engagement/engagement.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ export class EngagementRepository extends CommonRepository {
relation('out', '', 'status', ACTIVE),
node('status'),
])
.return<{ dto: UnsecuredDto<Engagement> }>(
.return<{
dto: UnsecuredDto<LanguageEngagement | InternshipEngagement>;
}>(
merge('props', 'changedProps', {
__typename: typenameForView(
['LanguageEngagement', 'InternshipEngagement'],
Expand Down Expand Up @@ -252,7 +254,11 @@ export class EngagementRepository extends CommonRepository {
'engagement.pnp',
);

return await this.readOne(result.id, session, viewOfChangeset(changeset));
return (await this.readOne(
result.id,
session,
viewOfChangeset(changeset),
)) as UnsecuredDto<LanguageEngagement>;
}

async createInternshipEngagement(
Expand Down Expand Up @@ -510,7 +516,7 @@ export class EngagementRepository extends CommonRepository {
async getOngoingEngagementIds(
projectId: ID,
excludes: EngagementStatus[] = [],
) {
): Promise<readonly ID[]> {
const rows = await this.db
.query()
.match([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export class UpdateProjectStatusHandler

private async updateEngagements(
status: EngagementStatus,
engagementIds: ID[],
engagementIds: readonly ID[],
type: ProjectType,
session: Session,
) {
Expand Down

0 comments on commit cadc5ea

Please sign in to comment.