Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature 29: Enable assigning multiple languages to a single asset #113

Merged
merged 6 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ To do so, use the following commands.
Be aware that you need to manually insert the `{DB_*}` values beforehand.
```bash
cd development
docker compose exec db sh -c 'pg_dump --dbname=postgresql://{DB_USERNAME}:{DB_PASSWORD}@{DB_HOST}:5432/{DB_DATABASE} --data-only --exclude-table asset_user -n public > /dump.sql'
docker compose exec db sh -c 'pg_dump --dbname=postgresql://{DB_USERNAME}:{DB_PASSWORD}@{DB_HOST}:5432/{DB_DATABASE} --data-only --exclude-table asset_user _prisma_migrations -n public > /dump.sql'
```
> The export will output warnings related to circular foreign-key constraints.
> These can be safely ignored.
Expand Down
6 changes: 5 additions & 1 deletion apps/server-asset-sg/src/app/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,11 @@ export class AppService {
lastProcessedDate: true,
assetKindItemCode: true,
assetFormatItemCode: true,
languageItemCode: true,
assetLanguages: {
select: {
languageItem: true,
}
},
internalUse: { select: { isAvailable: true } },
publicUse: { select: { isAvailable: true } },
ids: { select: { id: true, description: true } },
Expand Down
4 changes: 2 additions & 2 deletions apps/server-asset-sg/src/app/asset-edit/asset-edit.fake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const fakeAssetPatch = (): PatchAsset => ({
internalUse: fakeAssetUsage(),
publicUse: fakeAssetUsage(),
isNatRel: false,
languageItemCode: fakeLanguageItemCode(),
assetLanguages: [],
manCatLabelRefs: [],
newStatusWorkItemCode: O.none,
newStudies: [],
Expand Down Expand Up @@ -83,7 +83,7 @@ export const fakeAssetEditDetail = (): AssetEditDetail => ({
internalUse: fakeAssetUsage(),
publicUse: fakeAssetUsage(),
isNatRel: false,
languageItemCode: fakeLanguageItemCode(),
assetLanguages: [],
lastProcessedDate: new Date(),
manCatLabelRefs: [],
municipality: '',
Expand Down
6 changes: 5 additions & 1 deletion apps/server-asset-sg/src/app/jwt/jwt-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import * as jwt from 'jsonwebtoken';
import { Jwt, JwtPayload } from 'jsonwebtoken';
import jwkToPem from 'jwk-to-pem';

import { environment } from '../../environments/environment';
import { AuthenticatedRequest } from '../models/request';
import { PrismaService } from '../prisma/prisma.service';

Expand Down Expand Up @@ -116,9 +117,12 @@ export class JwtMiddleware implements NestMiddleware {
}

private getJwkTE(): TE.TaskEither<Error, JwksKey[]> {
const jwksPath = environment.production
? '/.well-known/jwks.json'
: '/.well-known/openid-configuration/jwks';
return pipe(
TE.tryCatch(
() => axios.get(`${process.env.OAUTH_ISSUER}/.well-known/jwks.json`),
() => axios.get(`${process.env.OAUTH_ISSUER}${jwksPath}`),
reason => new Error(`${reason}`),
),
TE.map(response => response.data.keys),
Expand Down
22 changes: 21 additions & 1 deletion apps/server-asset-sg/src/app/models/AssetDetailFromPostgres.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { pipe } from 'fp-ts/function';
import * as C from 'io-ts/Codec';
import * as D from 'io-ts/Decoder';

import { DT } from '@asset-sg/core';
Expand All @@ -23,13 +24,32 @@ export const AssetDetailFromPostgres = pipe(
),
assetKindItemCode: D.string,
assetFormatItemCode: D.string,
languageItemCode: D.string,
ids: D.array(
D.struct({
id: D.string,
description: D.string,
}),
),
assetLanguages: D.array(
D.struct({
languageItem: D.struct({
languageItemCode: C.string,
geolCode: C.string,
name: C.string,
nameDe: C.string,
nameFr: C.string,
nameRm: C.string,
nameIt: C.string,
nameEn: C.string,
description: C.string,
descriptionDe: C.string,
descriptionFr: C.string,
descriptionRm: C.string,
descriptionIt: C.string,
descriptionEn: C.string,
}),
})
),
assetContacts: D.array(
D.struct({
role: AssetContactRole,
Expand Down
4 changes: 2 additions & 2 deletions apps/server-asset-sg/src/app/models/asset-edit-detail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { pipe } from 'fp-ts/function';
import * as D from 'io-ts/Decoder';

import { DT } from '@asset-sg/core';
import { AssetContactEdit, DateIdFromDate, LinkedAsset, StatusAssetUseCode } from '@asset-sg/shared';
import { AssetContactEdit, AssetLanguageEdit, DateIdFromDate, LinkedAsset, StatusAssetUseCode } from '@asset-sg/shared';

import { PostgresAllStudies } from '../postgres-studies/postgres-studies';

Expand All @@ -27,7 +27,6 @@ export const AssetEditDetailFromPostgres = pipe(
}),
assetKindItemCode: D.string,
assetFormatItemCode: D.string,
languageItemCode: D.string,
isNatRel: D.boolean,
sgsId: D.nullable(D.number),
geolDataInfo: D.nullable(D.string),
Expand All @@ -41,6 +40,7 @@ export const AssetEditDetailFromPostgres = pipe(
description: D.string,
}),
),
assetLanguages: D.array(AssetLanguageEdit),
assetContacts: D.array(AssetContactEdit),
manCatLabelRefs: D.array(
pipe(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Warnings:

- You are about to drop the column `language_item_code` on the `asset` table. All the data in the column will be lost.

*/

-- CreateTable
CREATE TABLE "public"."asset_language" (
"asset_id" INTEGER NOT NULL,
"language_item_code" TEXT NOT NULL,

CONSTRAINT "asset_language_pkey" PRIMARY KEY ("asset_id","language_item_code")
);

-- AddForeignKey
ALTER TABLE "public"."asset_language" ADD CONSTRAINT "asset_language_asset_id_fkey" FOREIGN KEY ("asset_id") REFERENCES "public"."asset"("asset_id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "public"."asset_language" ADD CONSTRAINT "asset_language_language_item_code_fkey" FOREIGN KEY ("language_item_code") REFERENCES "public"."language_item"("language_item_code") ON DELETE RESTRICT ON UPDATE CASCADE;

-- MigrateLanguages
INSERT INTO "public"."asset_language" ("asset_id", "language_item_code")
SELECT a.asset_id, a.language_item_code FROM "public"."asset" a;

-- DropForeignKey
ALTER TABLE "public"."asset" DROP CONSTRAINT "asset_language_item_code_fkey";

-- AlterTable
ALTER TABLE "public"."asset" DROP COLUMN "language_item_code";
16 changes: 13 additions & 3 deletions apps/server-asset-sg/src/app/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,6 @@ model Asset {
assetKindItemCode String @map("asset_kind_item_code")
assetKindItem AssetKindItem @relation(fields: [assetKindItemCode], references: [assetKindItemCode])
createDate DateTime @map("create_date")
languageItemCode String @map("language_item_code")
languageItem LanguageItem @relation(fields: [languageItemCode], references: [languageItemCode])
assetFormatItemCode String @map("asset_format_item_code")
assetFormatItem AssetFormatItem @relation(fields: [assetFormatItemCode], references: [assetFormatItemCode])
authorBiblio String? @map("author_biblio_id")
Expand All @@ -155,6 +153,7 @@ model Asset {
assetFormatCompositions AssetFormatComposition[]
assetKindCompositions AssetKindComposition[]
assetPublications AssetPublication[]
assetLanguages AssetLanguage[]
autoCats AutoCat[]
ids Id[]
legalDocs LegalDoc[]
Expand Down Expand Up @@ -630,12 +629,23 @@ model LanguageItem {
descriptionIt String @map("description_it")
descriptionEn String @map("description_en")

assets Asset[]
assets AssetLanguage[]

@@map("language_item")
@@schema("public")
}

model AssetLanguage {
assetId Int @map("asset_id")
asset Asset @relation(fields: [assetId], references: [assetId])
languageItemCode String @map("language_item_code")
languageItem LanguageItem @relation(fields: [languageItemCode], references: [languageItemCode])

@@id([assetId, languageItemCode])
@@map("asset_language")
@@schema("public")
}

model ManCatLabelItem {
manCatLabelItemCode String @id @map("man_cat_label_item_code")
geolCode String @map("geol_code")
Expand Down
8 changes: 4 additions & 4 deletions apps/server-asset-sg/src/app/repos/asset.repo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ describe(AssetRepo, () => {
const user = fakeUser();
const patch = fakeAssetPatch();
const expected = await repo.create({ patch, user });

// When
const actual = await repo.find(expected.assetId);

// Then
expect(actual).not.toBeNull();
expect(actual).toEqual(expected);
Expand Down Expand Up @@ -122,7 +122,6 @@ describe(AssetRepo, () => {
expect(record.internalUse).toEqual(patch.internalUse);
expect(record.assetKindItemCode).toEqual(patch.assetKindItemCode);
expect(record.assetFormatItemCode).toEqual(patch.assetFormatItemCode);
expect(record.languageItemCode).toEqual(patch.languageItemCode);
expect(record.isNatRel).toEqual(patch.isNatRel);
expect(record.sgsId).toBeNull();
expect(record.geolDataInfo).toEqual(null);
Expand All @@ -131,6 +130,7 @@ describe(AssetRepo, () => {
expect(record.municipality).toBeNull();
expect(record.ids).toEqual(patch.ids);
expect(record.assetContacts).toEqual(patch.assetContacts);
expect(record.assetLanguages).toEqual(patch.assetLanguages);
expect(record.manCatLabelRefs).toEqual(patch.manCatLabelRefs);
expect(record.assetFormatCompositions).toEqual([]);
expect(record.typeNatRels).toEqual(patch.typeNatRels);
Expand Down Expand Up @@ -179,7 +179,6 @@ describe(AssetRepo, () => {
expect(updated.internalUse).toEqual(patch.internalUse);
expect(updated.assetKindItemCode).toEqual(patch.assetKindItemCode);
expect(updated.assetFormatItemCode).toEqual(patch.assetFormatItemCode);
expect(updated.languageItemCode).toEqual(patch.languageItemCode);
expect(updated.isNatRel).toEqual(patch.isNatRel);
expect(updated.sgsId).toBeNull();
expect(updated.geolDataInfo).toEqual(null);
Expand All @@ -188,6 +187,7 @@ describe(AssetRepo, () => {
expect(updated.municipality).toBeNull();
expect(updated.ids).toEqual(patch.ids);
expect(updated.assetContacts).toEqual(patch.assetContacts);
expect(updated.assetLanguages).toEqual(patch.assetLanguages);
expect(updated.manCatLabelRefs).toEqual(patch.manCatLabelRefs);
expect(updated.assetFormatCompositions).toEqual([]);
expect(updated.typeNatRels).toEqual(patch.typeNatRels);
Expand Down
16 changes: 13 additions & 3 deletions apps/server-asset-sg/src/app/repos/asset.repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ export class AssetRepo implements Repo<AssetEditDetail, number, AssetData> {
receiptDate: DateIdFromDate.encode(data.patch.receiptDate),
assetKindItem: { connect: { assetKindItemCode: data.patch.assetKindItemCode } },
assetFormatItem: { connect: { assetFormatItemCode: data.patch.assetFormatItemCode } },
languageItem: { connect: { languageItemCode: data.patch.languageItemCode } },
isExtract: false,
isNatRel: data.patch.isNatRel,
lastProcessedDate: new Date(),
Expand All @@ -73,6 +72,9 @@ export class AssetRepo implements Repo<AssetEditDetail, number, AssetData> {
assetContacts: {
createMany: { data: data.patch.assetContacts, skipDuplicates: true },
},
assetLanguages: {
createMany: { data: data.patch.assetLanguages, skipDuplicates: true },
},
ids: {
createMany: {
data: data.patch.ids.map(({ id, description }) => ({ id, description })),
Expand Down Expand Up @@ -122,7 +124,6 @@ export class AssetRepo implements Repo<AssetEditDetail, number, AssetData> {
receiptDate: DateIdFromDate.encode(data.patch.receiptDate),
assetKindItemCode: data.patch.assetKindItemCode,
assetFormatItemCode: data.patch.assetFormatItemCode,
languageItemCode: data.patch.languageItemCode,
isNatRel: data.patch.isNatRel,
assetMainId: O.toUndefined(data.patch.assetMainId),
lastProcessedDate: new Date(),
Expand All @@ -140,6 +141,10 @@ export class AssetRepo implements Repo<AssetEditDetail, number, AssetData> {
deleteMany: {},
createMany: { data: data.patch.assetContacts, skipDuplicates: true },
},
assetLanguages: {
deleteMany: {},
createMany: { data: data.patch.assetLanguages, skipDuplicates: true },
},
ids: {
deleteMany: {
idId: {
Expand Down Expand Up @@ -245,6 +250,11 @@ export class AssetRepo implements Repo<AssetEditDetail, number, AssetData> {
where: { assetId: id },
});

// Delete the record's `assetLanguage` records.
await this.prismaService.assetLanguage.deleteMany({
where: { assetId: id },
});

// Delete the record's `id` records.
await this.prismaService.id.deleteMany({
where: { assetId: id },
Expand Down Expand Up @@ -322,7 +332,6 @@ const selectPrismaAsset = selectOnAsset({
processor: true,
assetKindItemCode: true,
assetFormatItemCode: true,
languageItemCode: true,
internalUse: true,
publicUse: true,
isNatRel: true,
Expand All @@ -333,6 +342,7 @@ const selectPrismaAsset = selectOnAsset({
municipality: true,
ids: true,
assetContacts: { select: { role: true, contactId: true } },
assetLanguages: { select: { languageItemCode: true } },
manCatLabelRefs: { select: { manCatLabelItemCode: true } },
assetFormatCompositions: { select: { assetFormatItemCode: true } },
typeNatRels: { select: { natRelItemCode: true } },
Expand Down
Loading
Loading