Skip to content

Commit

Permalink
Add legal docs
Browse files Browse the repository at this point in the history
Create legal_docs migration

Handle legal files in api

Display legal docs in asset detail slider

Add legal files to asset form

Reset server/.env.local

Update README

Extract asset viewer files component

Merge duplicate postgres asset file mapping

Fix code quality issues

Replace string match with Regexp.exec

Use character class over explicit group in regex

Remove unused imports

Add missing `readonly` qualifiers

Fix name of relation from `file` to `legal_doc_item` table

Fix typo in README

Translate `legalDocItemCode` in selector

wip: Split file editor by type

Add unit tests for `FileRepo.determineUniqueFilename`

Update CHANGELOG.md
  • Loading branch information
daniel-va committed Oct 14, 2024
1 parent cb09734 commit 2d04dfe
Show file tree
Hide file tree
Showing 56 changed files with 1,361 additions and 739 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,6 @@ __pycache__

# NX cache
.nx/

# Asset sync progress file
asset-sync-progress.tmp.json
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@

- Anonymer Modus für view-assets
- Synchronisations-Service zwischen verschiedenen Instanzen prod, prod-extern, prod-view
- Dokumente für rechtliche Einwilligungen (_Legal Docs_) können nun separat von normalen Dateien
hochgeladen und angezeigt werden. Diese Einwilligungen können zusätzlich mit einem Typ versehen werden,
der die Art von Dokument wiederspiegelt.

### Changed

- Admins haben nun auf alle Arbeitsgruppen Leserechte anstatt Schreibrechte - für das Schreiben muss ein Admin sich der Arbeitsgruppe hinzufügen
- Der Button für Polygon-Filter ist nun links bei den restlichen Filtern
- Dependency Updates
- Existierende Dateien, welche mit `_LDoc.pdf` enden,
wurden als rechtliche Einwilligung mit Typ `permissionForm` markiert.

### Fixed

Expand Down
68 changes: 37 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SwissGeol Asset
# SwissGeol Assets

## Development

Expand All @@ -12,32 +12,30 @@ The following components must be installed on the development computer:

Follow these steps to set up the development environment on your local machine:

- [1. Configure Local Systems](#1-Configure-Local-Systems)
- [2. Install Dependencies](#2-Install-Dependencies)
- [3. Generate Database Types](#3-Generate-Database-Types)
- [4. Initialize MinIO](#4-Initialize-MinIO)
- [1. Install Dependencies](#2-Install-Dependencies)
- [2. Generate Database Types](#3-Generate-Database-Types)
- [3. Initialize MinIO](#4-Initialize-MinIO)

#### 1. Configure Local Systems

Configure `development/.env` according to the [local service configuration](#Local-Service-Configuration).

#### 2. Install Dependencies
#### 1. Install Dependencies

Install node modules:

```bash
npm install
```

#### 3. Generate Database Types
#### 2. Generate Database Types

Generate prisma-client for database-access:

```bash
npm run prisma -- generate
```

#### 4. Initialize MinIO
#### 3. Initialize MinIO

> Note that this step may be skipped if you do not need to interact with uploaded files,
> and don't want to upload files yourselves.
- [Start the development services](#Starting-the-Development-Environment).
- Open http://localhost:9001
Expand All @@ -46,7 +44,7 @@ npm run prisma -- generate
- Navigate to [the new bucket's browser](http://localhost:9001/browser/asset-sg) and create an empty folder with the name `asset-sg`.
- Navigate to [Configuration](http://localhost:9001/settings/configurations/region) and change the server region to `local`.
- Navigate to [Access Keys](http://localhost:9001/access-keys) and create a new access key.
- Open the file [`apps/server-asset-sg/.env.local`](apps/server-asset-sg/.env.local) and modify the following variables:
- Create the file [`apps/server-asset-sg/.env.local`](apps/server-asset-sg/.env.local) and add the following variables:
- Set `S3_ACCESS_KEY_ID` to your generated access key.
- Set `S3_SECRET_ACCESS_KEY` to your generated access key's secret.

Expand Down Expand Up @@ -150,10 +148,10 @@ nx run server-asset-sg:test -t 'AssetRepo create'

## Configuration

### Asset Server Configuration
### Server Configuration

The file `apps/server-asset-sg/.env.local` configures secrets for the SwissGeol Asset server.
An empty template for the file can be found in [`apps/server-asset-sg/.env.template`](apps/server-asset-sg/.env.template).
The file `apps/server-asset-sg/.env` configures the configuration for the SwissGeol Assets server.
By default, it is configured to work with the Docker services found in [`development/docker-compose.yml`](development/docker-compose.yml).

| Variable | Example | Description |
| ----------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------- |
Expand All @@ -174,25 +172,33 @@ An empty template for the file can be found in [`apps/server-asset-sg/.env.templ
| OCR_URL | | Leave empty. |
| OCR_CALLBACK_URL | | Leave empty. |

> The local docker configuration contains an OIDC container supporting OAuth.
> Use the example values to use it instead of an external issuer.
### Services Configuration

### Local Service Configuration
The file [`development/.env`](development/.env) configures secrets for the services used in local development.
By default, these secrets align with the server's configuration.

The file `development/.env` configures secrets for the services used in local development.
An empty template for the file can be found in [`development/.env.template`](development/.env.template).
| Variable | Beschreibung |
| ---------------- | -------------------------------------- |
| STORAGE_USER | Username for the MinIO container. |
| STORAGE_PASSWORD | Password for the MinIO container. |
| DB_USER | Username for the PostgreSQL container. |
| DB_PASSWORD | Password for the PostgreSQL container. |
| PGADMIN_EMAIL | Email for the PgAdmin container. |
| PGADMIN_PASSWORD | Password for the PgAdmin container. |

> Make sure that your passwords have a minimal length of 8 and contain at combination of
> upper, lower and special characters. Some of the passwords will be checked for validity during startup.
```bash
git update-index --no-skip-worktree development/.env
git update-index --no-skip-worktree apps/server-asset-sg/.env.local
```

Then, after having committed your changes, remove them again:

```bash
git update-index --skip-worktree development/.env
git update-index --skip-worktree apps/server-asset-sg/.env.local
```

| Variable | Wert | Beschreibung |
| ---------------- | -------- | -------------------------------------- |
| STORAGE_USER | _custom_ | Username for the MinIO container. |
| STORAGE_PASSWORD | _custom_ | Password for the MinIO container. |
| DB_USER | postgres | Username for the PostgreSQL container. |
| DB_PASSWORD | _custom_ | Password for the PostgreSQL container. |
| PGADMIN_EMAIL | _custom_ | Email for the PgAdmin container. |
| PGADMIN_PASSWORD | _custom_ | Password for the PgAdmin container. |
> Note that worktree modifications need to be committed, just like file changes.
## Database ORM

Expand Down
16 changes: 14 additions & 2 deletions apps/client-asset-sg/src/app/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const deAppTranslations = {
workgroup: 'Arbeitsgruppe',
resetSearch: 'Suche zurücksetzen',
file: 'Datei',
legalFile: 'Rechtliche Einwilligungen',
openFileInNewTab: '{{fileName}} in neuem Tab öffnen',
downloadFile: '{{fileName}} herunterladen',
assetsUnderMouseCursor: '{{ assetsCount }} Assets unter dem Mauszeiger gefunden. Bitte wählen Sie eines aus:',
Expand Down Expand Up @@ -117,9 +118,20 @@ export const deAppTranslations = {
alternativeId: 'Alternativ-ID',
alternativeIdDescription: 'Beschreibung Alternativ-ID',
addNewAlternativeId: 'Neue Alternativ-ID hinzufügen',
files: 'Dateien',
dragFileHere: 'Datei hierher ziehen',
},
files: {
tabName: 'Dateien',
Normal: {
one: 'Normale Datei',
many: 'Normale Dateien',
},
Legal: {
one: 'Rechtliche Einwilligung',
many: 'Rechtliche Einwilligungen',
},
legalDocItemCode: 'Typ',
or: 'oder',
dragFileHere: 'Datei hierher ziehen',
selectFile: 'Datei auswählen',
addNewFile: 'Neue Datei hinzufügen',
willBeDeleted: 'Wird gelöscht werden',
Expand Down
14 changes: 13 additions & 1 deletion apps/client-asset-sg/src/app/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export const enAppTranslations: AppTranslations = {
workgroup: 'Workgroup',
resetSearch: 'Reset search',
file: 'File',
legalFile: 'Legal consent',
openFileInNewTab: 'Open {{fileName}} in new tab',
downloadFile: 'Download {{fileName}}',
assetsUnderMouseCursor: '{{ assetsCount }} assets found under the mouse cursor. Please select one:',
Expand Down Expand Up @@ -118,7 +119,18 @@ export const enAppTranslations: AppTranslations = {
alternativeId: 'Alternative ID',
alternativeIdDescription: 'Alternative ID Description',
addNewAlternativeId: 'Add new alternative ID',
files: 'Files',
},
files: {
tabName: 'Files',
Normal: {
one: 'Normal File',
many: 'Normal Files',
},
Legal: {
one: 'Legal consent',
many: 'Legal consents',
},
legalDocItemCode: 'Type',
dragFileHere: 'Drag file here',
or: 'or',
selectFile: 'Select file',
Expand Down
14 changes: 13 additions & 1 deletion apps/client-asset-sg/src/app/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export const frAppTranslations: AppTranslations = {
workgroup: 'groupe de travail',
resetSearch: 'Réinitialiser la recherche',
file: 'Fichier',
legalFile: 'Consentements légaux',
openFileInNewTab: 'Ouvrir {{fileName}} dans un nouvel onglet',
downloadFile: 'Télécharger {{fileName}}',
assetsUnderMouseCursor:
Expand Down Expand Up @@ -119,7 +120,18 @@ export const frAppTranslations: AppTranslations = {
alternativeId: 'ID alternative',
alternativeIdDescription: "Description d'ID alternative",
addNewAlternativeId: 'Ajouter une nouvelle ID alternative',
files: 'Fichiers',
},
files: {
tabName: 'Fichiers',
Normal: {
one: 'Fichier normal',
many: 'Fichiers normaux',
},
Legal: {
one: 'Consentement Légal',
many: 'Consentements Légaux',
},
legalDocItemCode: 'Type',
dragFileHere: 'Glisser le fichier ici',
or: 'ou',
selectFile: 'Sélectionner un fichier',
Expand Down
16 changes: 14 additions & 2 deletions apps/client-asset-sg/src/app/i18n/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export const itAppTranslations: AppTranslations = {
workgroup: 'IT Arbeitsgruppe',
resetSearch: 'IT Suche zurücksetzen',
file: 'IT Datei',
legalFile: 'IT Rechtliche Einwilligungen',
openFileInNewTab: 'IT {{fileName}} in neuem Tab öffnen',
downloadFile: 'IT {{fileName}} herunterladen',
assetsUnderMouseCursor: 'IT {{ assetsCount }} Assets unter dem Mauszeiger gefunden. Bitte wählen Sie eines aus:',
Expand Down Expand Up @@ -118,14 +119,25 @@ export const itAppTranslations: AppTranslations = {
alternativeId: 'IT Alternativ-ID',
alternativeIdDescription: 'IT Beschreibung Alternativ-ID',
addNewAlternativeId: 'IT Neue Alternativ-ID hinzufügen',
files: 'IT Dateien',
},
files: {
tabName: 'IT Dateien',
Normal: {
one: 'IT Normale Datei',
many: 'IT Normale Dateien',
},
Legal: {
one: 'IT Rechtliche Einwilligung',
many: 'IT Rechtliche Einwilligungen',
},
legalDocItemCode: 'IT Typ',
dragFileHere: 'IT Datei hierher ziehen',
or: 'IT oder',
selectFile: 'IT Datei auswählen',
addNewFile: 'IT Neue Datei hinzufügen',
willBeDeleted: 'IT Wird gelöscht werden',
willBeUploaded: 'IT Wird hochgeladen werden',
fileSizeToLarge: 'IT Die Dateigrösse darf 250MB nicht überschreiten.',
fileSizeToLarge: 'IT Die Dateigrösse darf 250 MB nicht überschreiten.',
},
usage: {
tabName: 'IT Nutzung',
Expand Down
18 changes: 15 additions & 3 deletions apps/client-asset-sg/src/app/i18n/rm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export const rmAppTranslations: AppTranslations = {
workgroup: 'RM Arbeitsgruppe',
resetSearch: 'RM Suche zurücksetzen',
file: 'RM Datei',
legalFile: 'RM Rechtliche Einwilligungen',
openFileInNewTab: 'RM {{fileName}} in neuem Tab öffnen',
downloadFile: 'RM {{fileName}} herunterladen',
assetsUnderMouseCursor: 'RM {{ assetsCount }} Assets unter dem Mauszeiger gefunden. Bitte wählen Sie eines aus:',
Expand Down Expand Up @@ -118,14 +119,25 @@ export const rmAppTranslations: AppTranslations = {
alternativeId: 'RM Alternativ-ID',
alternativeIdDescription: 'RM Beschreibung Alternativ-ID',
addNewAlternativeId: 'RM Neue Alternativ-ID hinzufügen',
files: 'RM Dateien',
},
files: {
tabName: 'RM Dateien',
Normal: {
one: 'RM Normale Datei',
many: 'RM Normale Dateien',
},
Legal: {
one: 'RM Rechtliche Einwilligung',
many: 'RM Rechtliche Einwilligungen',
},
legalDocItemCode: 'RM Typ',
dragFileHere: 'RM Datei hierher ziehen',
or: 'FRM oder',
or: 'RM oder',
selectFile: 'RM Datei auswählen',
addNewFile: 'RM Neue Datei hinzufügen',
willBeDeleted: 'RM Wird gelöscht werden',
willBeUploaded: 'RM Wird hochgeladen werden',
fileSizeToLarge: 'RM Die Dateigrösse darf 250MB nicht überschreiten.',
fileSizeToLarge: 'RM Die Dateigrösse darf 250 MB nicht überschreiten.',
},
usage: {
tabName: 'RM Nutzung',
Expand Down
1 change: 1 addition & 0 deletions apps/server-asset-sg/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
http-client.env.json
.env.local
2 changes: 2 additions & 0 deletions apps/server-asset-sg/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ContactRepo } from '@/features/contacts/contact.repo';
import { ContactsController } from '@/features/contacts/contacts.controller';
import { FavoriteRepo } from '@/features/favorites/favorite.repo';
import { FavoritesController } from '@/features/favorites/favorites.controller';
import { FileRepo } from '@/features/files/file.repo';
import { FilesController } from '@/features/files/files.controller';
import { OcrController } from '@/features/ocr/ocr.controller';
import { StudiesController } from '@/features/studies/studies.controller';
Expand Down Expand Up @@ -58,6 +59,7 @@ import { WorkgroupsController } from '@/features/workgroups/workgroups.controlle
AssetSyncService,
ContactRepo,
FavoriteRepo,
FileRepo,
PrismaService,
StudyRepo,
UserRepo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const fakeContact = () =>

export const fakeAssetPatch = (): PatchAsset => ({
assetContacts: [],
assetFiles: [],
assetFormatItemCode: fakeAssetFormatItemCode(),
assetKindItemCode: fakeAssetKindItemCode(),
assetMainId: O.none,
Expand Down
28 changes: 16 additions & 12 deletions apps/server-asset-sg/src/features/asset-edit/asset-edit.repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,6 @@ export class AssetEditRepo implements Repo<AssetEditDetail, number, AssetEditDat
return this.loadDetail(asset);
}

async findByFile(fileId: number): Promise<AssetEditDetail | null> {
const asset = await this.prismaService.asset.findFirst({
where: { assetFiles: { some: { fileId } } },
select: selectPrismaAsset,
});
if (asset === null) {
return null;
}
return this.loadDetail(asset);
}

async list({ limit, offset, ids }: RepoListOptions<number> = {}): Promise<AssetEditDetail[]> {
const assets = await this.prismaService.asset.findMany({
select: selectPrismaAsset,
Expand Down Expand Up @@ -158,6 +147,18 @@ export class AssetEditRepo implements Repo<AssetEditDetail, number, AssetEditDat
deleteMany: {},
createMany: { data: data.patch.assetLanguages, skipDuplicates: true },
},
assetFiles: {
update: data.patch.assetFiles.map((it) => ({
data: {
file: {
update: {
...it,
},
},
},
where: { assetId_fileId: { assetId: id, fileId: it.id } },
})),
},
ids: {
deleteMany: {
idId: {
Expand Down Expand Up @@ -367,7 +368,10 @@ const selectPrismaAsset = selectOnAsset({
siblingXAssets: { select: { assetY: { select: { assetId: true, titlePublic: true } } } },
siblingYAssets: { select: { assetX: { select: { assetId: true, titlePublic: true } } } },
statusWorks: { select: { statusWorkItemCode: true, statusWorkDate: true } },
assetFiles: { select: { file: true } },
assetFiles: {
select: { file: { select: { id: true, name: true, size: true, type: true, legalDocItemCode: true } } },
orderBy: [{ file: { type: 'asc' } }, { file: { name: 'asc' } }],
},
workgroupId: true,
});

Expand Down
Loading

0 comments on commit 2d04dfe

Please sign in to comment.