Skip to content

Commit

Permalink
Implement EdgeDB Product Repo
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanjnelson committed Dec 5, 2024
1 parent 23d2333 commit 5aa5778
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/components/product/dto/product.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ declare module '../dto/producible.dto' {
}
}

export const ProductConcretes = {
DirectScriptureProduct,
DerivativeScriptureProduct,
OtherProduct,
};

declare module '~/core/resources/map' {
interface ResourceMap {
Product: typeof Product;
Expand Down
217 changes: 217 additions & 0 deletions src/components/product/product.edgedb.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import { Injectable, Type } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { LazyGetter } from 'lazy-get-decorator';
import { ID, PublicOf, Session } from '../../common';
import { grabInstances } from '../../common/instance-maps';
import { e, RepoFor } from '../../core/edgedb';
import {
ProductConcretes as ConcreteTypes,
CreateDerivativeScriptureProduct,
CreateDirectScriptureProduct,
CreateOtherProduct,
Product,
} from './dto';
import { ProductRepository } from './product.repository';

// scriptureReferencesOverride, scriptureReferences

const baseHydrate = e.shape(e.Product, (product) => ({
...product['*'],
__typename: product.__type__.name,
project: {
id: true,
status: true,
type: true,
},
engagement: {
id: true,
status: true,
},
parent: e.tuple({
identity: product.engagement.id,
labels: e.array_agg(e.set(product.engagement.__type__.name.slice(9, null))),
properties: e.tuple({
id: product.engagement.id,
createdAt: product.engagement.createdAt,
}),
}),
pnpIndex: true,
scriptureReferences: product.scripture,
}));

const directScriptureExtraHydrate = {
totalVerses: true,
totalVerseEquivalents: true,
} as const;

const derivativeScriptureExtraHydrate = {
scripture: true,
composite: true,
totalVerses: true,
totalVerseEquivalents: true,
} as const;

const otherExtraHydrate = {
title: true,
description: true,
} as const;

const directScriptureProductHydrate = e.shape(
e.DirectScriptureProduct,
(dsp) => ({
...baseHydrate(dsp),
__typename: dsp.__type__.name,
unspecifiedScripture: {
book: true,
totalVerses: true,
},
//TODO - remove after migration
unspecifiedScripturePortion: {
book: true,
totalVerses: true,
},
...directScriptureExtraHydrate,
}),
);

const derivativeScriptureProductHydrate = e.shape(
e.DerivativeScriptureProduct,
(dsp) => ({
...baseHydrate(dsp),
__typename: dsp.__type__.name,
scriptureReferencesOverride: dsp.scriptureOverride,
produces: {
scriptureReferences: e.tuple([dsp.produces.scripture]),
createdAt: dsp.produces.createdAt,
id: dsp.produces.id,
},
...derivativeScriptureExtraHydrate,
}),
);

const otherProductHydrate = e.shape(e.OtherProduct, (op) => ({
...baseHydrate(op),
__typename: op.__type__.name,
scriptureReferencesOverride: false, //TODO - remove after migration
...otherExtraHydrate,
}));

const hydrate = e.shape(e.Product, (product) => ({
...baseHydrate(product),
...e.is(e.DirectScriptureProduct, directScriptureExtraHydrate),
...e.is(e.DerivativeScriptureProduct, derivativeScriptureExtraHydrate),
...e.is(e.OtherProduct, otherExtraHydrate),
}));

export const ConcreteRepos = {
DirectScriptureProduct: class DirectScriptureProductRepository extends RepoFor(
ConcreteTypes.DirectScriptureProduct,
{
hydrate: directScriptureProductHydrate,
omit: ['create'],
},
) {
async create(input: CreateDirectScriptureProduct) {
const engagement = e.cast(
e.LanguageEngagement,
e.uuid(input.engagementId),
);
return await this.defaults.create({
...input,
projectContext: engagement.projectContext,
});
}
},

DerivativeScriptureProduct: class DerivativeScriptureProductRepository extends RepoFor(
ConcreteTypes.DerivativeScriptureProduct,
{
hydrate: derivativeScriptureProductHydrate,
omit: ['create'],
},
) {
async create(input: CreateDerivativeScriptureProduct) {
const engagement = e.cast(
e.LanguageEngagement,
e.uuid(input.engagementId),
);
return await this.defaults.create({
...input,
projectContext: engagement.projectContext,
});
}
},

OtherProduct: class OtherProductRepository extends RepoFor(
ConcreteTypes.OtherProduct,
{
hydrate: otherProductHydrate,
omit: ['create'],
},
) {
async create(input: CreateOtherProduct) {
const engagement = e.cast(
e.LanguageEngagement,
e.uuid(input.engagementId),
);
return await this.defaults.create({
...input,
projectContext: engagement.projectContext,
});
}
},
} satisfies Record<keyof typeof ConcreteTypes, Type>;

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

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

async createDerivative(

Check failure on line 181 in src/components/product/product.edgedb.repository.ts

View workflow job for this annotation

GitHub Actions / lint

Property 'createDerivative' in type 'ProductEdgedbRepository' is not assignable to the same property in base type 'PublicOf<ProductRepository>'.
input: CreateDerivativeScriptureProduct & {
totalVerses: number;
totalVerseEquivalents: number;
},
_session: Session,
) {
return await this.concretes.DerivativeScriptureProduct.create(input);
}

async createDirect(

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

View workflow job for this annotation

GitHub Actions / lint

Property 'createDirect' in type 'ProductEdgedbRepository' is not assignable to the same property in base type 'PublicOf<ProductRepository>'.
input: CreateDirectScriptureProduct & {
totalVerses: number;
totalVerseEquivalents: number;
},
_session: Session,
) {
return await this.concretes.DirectScriptureProduct.create(input);
}

async createOther(input: CreateOtherProduct, _session: Session) {

Check failure on line 201 in src/components/product/product.edgedb.repository.ts

View workflow job for this annotation

GitHub Actions / lint

Property 'createOther' in type 'ProductEdgedbRepository' is not assignable to the same property in base type 'PublicOf<ProductRepository>'.
return await this.concretes.OtherProduct.create(input);
}

async listIdsAndScriptureRefs(engagementId: ID) {

Check failure on line 205 in src/components/product/product.edgedb.repository.ts

View workflow job for this annotation

GitHub Actions / lint

Property 'listIdsAndScriptureRefs' in type 'ProductEdgedbRepository' is not assignable to the same property in base type 'PublicOf<ProductRepository>'.
const engagement = e.cast(e.LanguageEngagement, e.uuid(engagementId));
const query = e.select(e.DirectScriptureProduct, (dsp) => ({
id: true,
pnpIndex: true,
scriptureRanges: dsp.scripture,
unspecifiedScripture: dsp.unspecifiedScripture,
filter: e.op(dsp.engagement, '=', engagement),
}));

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

0 comments on commit 5aa5778

Please sign in to comment.