diff --git a/.editorconfig b/.editorconfig
index 71cd14e9..aa5b9729 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -7,6 +7,7 @@ indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
+end_of_line = lf
[*.md]
max_line_length = off
diff --git a/.github/ISSUE_TEMPLATE/1-issue.md b/.github/ISSUE_TEMPLATE/1-issue.md
new file mode 100644
index 00000000..b22f1e61
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/1-issue.md
@@ -0,0 +1,23 @@
+---
+name: Issue
+about: Beschreibe eine neue Aufgabe
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Beschreibung**
+
+Eine klare und präzise Beschreibung der Ausgangssituation, der Problematik sowie bereits bekannter Lösungsansätze.
+
+
+
+**Abgrenzung**
+
+Nicht beachtet in dieser Aufgabe wird die Suche nach der Frage.
+
+**Acceptance Criteria**
+
+ - [ ] Die Antwort muss 42 sein.
+ - [ ] ...
diff --git a/.github/ISSUE_TEMPLATE/2-bug.md b/.github/ISSUE_TEMPLATE/2-bug.md
new file mode 100644
index 00000000..21936a17
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/2-bug.md
@@ -0,0 +1,33 @@
+---
+name: Bug
+about: Melde einen neuen Bug
+title: 'Bug: '
+labels: bug
+assignees: ''
+
+---
+
+**Beschreibung**
+Eine klare und präzise Beschreibung des Problems.
+
+**Schritte zum Reproduzieren**
+1. Gehe zur Seite '....'
+2. Klicke auf '....'
+3. Scrolle zu '....'
+4. Ein Fehler erscheint
+
+**Beobachtetes Verhalten**
+Eine Beschreibung des Fehlverhaltens.
+
+**Erwartetes Verhalten**
+Eine Beschreibung des eigentlich erwarteten Verhaltens
+
+**Screenshots**
+Zeige Screenshots, wenn vorhanden und hilfreich.
+
+**Plattform**
+Falls relevant:
+ - Device: [e.g. Desktop, iPhone6]
+ - OS: [e.g. Windows, iOS8.1]
+ - Browser [e.g. firefox, edge]
+ - Mobile Version [e.g. 22]
diff --git a/.github/actions/create-image/action.yaml b/.github/actions/create-image/action.yaml
new file mode 100644
index 00000000..62955900
--- /dev/null
+++ b/.github/actions/create-image/action.yaml
@@ -0,0 +1,57 @@
+name: 'create docker image'
+description: 'Builds a docker image and tags it'
+inputs:
+ IMAGE_NAME:
+ description: 'The image name'
+ required: true
+ TAG:
+ description: 'The version of the image'
+ required: true
+ DOCKERFILE:
+ description: 'The path to the Dockerfile'
+ required: true
+ GITHUB_TOKEN:
+ description: 'The github token'
+ required: true
+
+runs:
+ using: 'composite'
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set environment variables
+ shell: bash
+ run: |
+ echo COMMITED_AT=$(git show -s --format=%cI ${{ github.sha }}) >> $GITHUB_ENV
+ echo REVISION=$(git rev-parse --short HEAD) >> $GITHUB_ENV
+
+ - name: Collect docker image metadata
+ id: meta-data
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ inputs.IMAGE_NAME }}
+ labels: |
+ org.opencontainers.image.created=${{ env.COMMITED_AT }}
+ org.opencontainers.image.maintainer=EBP Schweiz AG
+ flavor: |
+ latest=false
+ tags: |
+ ${{ inputs.TAG }}
+
+ - name: Log in to the GitHub container registry
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.repository_owner }}
+ password: ${{ inputs.GITHUB_TOKEN }}
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v5
+ with:
+ context: ./
+ file: ${{ inputs.DOCKERFILE }}
+ push: true
+ tags: ${{ steps.meta-data.outputs.tags }}
+ labels: ${{ steps.meta-data.outputs.labels }}
+ no-cache: true
diff --git a/.github/actions/deploy/action.yaml b/.github/actions/deploy/action.yaml
deleted file mode 100644
index 30d4f921..00000000
--- a/.github/actions/deploy/action.yaml
+++ /dev/null
@@ -1,84 +0,0 @@
-name: "Pulumi deployment to cluster"
-description: "Starts a pulumi deployment to the cluster"
-inputs:
- # secrets for login etc
- pulumiConfigSecret:
- description: "Pulumi config secret"
- required: true
- npmPkgToken:
- description: "token for npm pkg access"
- required: true
- awsAccessKeyId:
- description: "AWS access key id"
- required: true
- awsSecretAccessKey:
- description: "AWS secret access key"
- required: true
- eksClusterName:
- description: "AWS EKS cluster name"
- required: true
- eksRoleArn:
- description: "AWS EKS Role ARN"
- required: true
- # variables for pulumi setup
- pulumiConfigPassphrase:
- description: "Pulumi config passphrase"
- required: true
- stack:
- description: "Pulumi stack name"
- required: true
- command:
- description: "Pulumi command to run"
- required: false
- default: "preview"
- region:
- description: "AWS region"
- required: false
- default: "eu-central-1"
- s3Bucket:
- description: "S3 bucket for pulumi state"
- required: false
- default: "swissgeol-assets-swisstopo"
- version:
- description: "App version for assets"
- required: false
- default: "dev"
-runs:
- using: "composite"
- steps:
- # https://github.com/marketplace/actions/configure-aws-credentials-for-github-actions
- - name: configure aws credentials
- uses: aws-actions/configure-aws-credentials@v2
- with:
- aws-access-key-id: ${{ inputs.awsAccessKeyId }}
- aws-secret-access-key: ${{ inputs.awsSecretAccessKey }}
- aws-region: ${{ inputs.region }}
-
- - name: Create kubeconfig
- shell: bash
- working-directory: ./deployment
- run: |
- aws --region ${{ inputs.region }} eks update-kubeconfig --name ${{ inputs.eksClusterName }} --alias swissgeol-${{ inputs.eksClusterName }} --role-arn ${{ inputs.eksRoleArn }}
- kubectl get namespaces
-
- - name: install pulumi deps
- shell: bash
- working-directory: ./deployment
- run: |
- echo "//npm.pkg.github.com/:_authToken=${{ inputs.npmPkgToken }}" >> .npmrc
- npm ci
-
- # https://github.com/marketplace/actions/pulumi-cli-action
- - name: execute pulumi
- uses: pulumi/actions@v4
- with:
- command: ${{ inputs.command }}
- stack-name: ${{ inputs.stack }}
- cloud-url: "s3://${{ inputs.s3Bucket }}?region=${{ inputs.region }}&awssdk=v2"
- work-dir: ./deployment
- config-map: "{ geoadmin-swissgeol-asset:version: {value: ${{ inputs.version }}, secret: false }}"
- env:
- AWS_ACCESS_KEY_ID: ${{ inputs.awsAccessKeyId }}
- AWS_SECRET_ACCESS_KEY: ${{ inputs.awsSecretAccessKey }}
- AWS_REGION: ${{ inputs.region }}
- PULUMI_CONFIG_PASSPHRASE: ${{ inputs.pulumiConfigPassphrase }}
diff --git a/.github/actions/generate-version/action.yaml b/.github/actions/generate-version/action.yaml
deleted file mode 100644
index 952f52dc..00000000
--- a/.github/actions/generate-version/action.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: "Generate Version for Asset"
-description: "Generates a new version from git sha"
-inputs:
- path:
- description: "path for version.json"
- required: true
-runs:
- using: "composite"
- steps:
- - name: generate version.json
- shell: bash
- run: |
- VERSION="{\"tag\": \"generated_by_build\",\"build\": \"${{github.run_number}}\",\"commit\": \"${{github.sha}}\"}"
- echo $VERSION > ${{ inputs.path }}/version.json
- cat ${{ inputs.path }}/version.json
diff --git a/.github/actions/registry-push/action.yaml b/.github/actions/registry-push/action.yaml
deleted file mode 100644
index 4ea0ab86..00000000
--- a/.github/actions/registry-push/action.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: "Container regsistry login & push"
-description: "Logins to the registry and pushes the given images"
-inputs:
- image:
- description: "Container image name"
- required: true
- username:
- description: "Username for the registry"
- required: true
- password:
- description: "Password for the registry"
- required: true
-runs:
- using: "composite"
- steps:
- # https://github.com/marketplace/actions/docker-login
- - name: Login to container registry
- uses: docker/login-action@v2
- with:
- registry: ghcr.io
- username: ${{ inputs.username }}
- password: ${{ inputs.password }}
-
- - name: Push container image
- shell: bash
- run: docker push ${{ inputs.image }}
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..8d1d36af
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,231 @@
+name: build
+
+on:
+ push:
+ branches:
+ - '**'
+ workflow_dispatch:
+
+env:
+ NODE_VERSION: '20.x'
+
+jobs:
+ install:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Setup node
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ - name: Cache node modules
+ uses: actions/cache@v4
+ with:
+ path: ./node_modules
+ key: "${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}"
+ restore-keys: |
+ ${{ runner.os }}-npm-
+ - name: Install node dependencies
+ run: npm ci
+ - name: Run postinstall
+ run: npm run postinstall
+ - name: Generate prisma types
+ run: |
+ cd apps/server-asset-sg/
+ npx ng gen-prisma-client
+
+ test:
+ runs-on: ubuntu-latest
+ needs: install
+ env:
+ DB_USERNAME: postgres-test
+ DB_PASSWORD: postgres-test
+ DB_DATABASE: postgres-test
+ DATABASE_URL: postgres://postgres-test:postgres-test@localhost:5432/postgres-test?schema=public
+ services:
+ db:
+ image: postgis/postgis
+ ports:
+ - '5432:5432'
+ env:
+ POSTGRES_USER: ${{ env.DB_USERNAME }}
+ POSTGRES_PASSWORD: ${{ env.DB_PASSWORD }}
+ POSTGRES_DB: ${{ env.DB_DATABASE }}
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
+ elasticsearch:
+ image: docker.elastic.co/elasticsearch/elasticsearch:8.12.1
+ ports:
+ - '9200:9200'
+ env:
+ ES_JAVA_OPTS: -Xms512m -Xmx512m
+ xpack.security.enabled: false
+ discovery.type: single-node
+ cluster.routing.allocation.disk.threshold_enabled: false
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Setup node
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ - name: Restore cached node modules
+ uses: actions/cache@v4
+ with:
+ path: ./node_modules
+ key: "${{ runner.os }}-npm-${{ steps.cache-node-modules.outputs.cache-key }}"
+ - name: Migrate database
+ run: |
+ cd apps/server-asset-sg/
+ npx prisma migrate deploy --schema src/app/prisma/schema.prisma
+ - name: Run tests
+ run: npm run test
+
+ lint:
+ runs-on: ubuntu-latest
+ needs: install
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Setup node
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ - name: Restore cached node modules
+ uses: actions/cache@v4
+ with:
+ path: ./node_modules
+ key: "${{ runner.os }}-npm-${{ steps.cache-node-modules.outputs.cache-key }}"
+ - name: Run lint
+ run: npm run lint
+
+ # It would be cleaner and probably more performant to replace this build step
+ # with either a non-emitting build or a simple type check.
+ # We only have `build` available for now,
+ # since the project is currently split across a multitude of small packages,
+ # all of which have to specify their own commands.
+ # (Daniel von Atzigen, 2024-04-12)
+ build:
+ runs-on: ubuntu-latest
+ needs:
+ - test
+ - lint
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Setup node
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ - name: Restore cached node modules
+ uses: actions/cache@v4
+ with:
+ path: ./node_modules
+ key: "${{ runner.os }}-npm-${{ steps.cache-node-modules.outputs.cache-key }}"
+ - name: Reset nx
+ run: npx nx reset
+ - name: Run build
+ run: npm run build
+
+ build_and_push_app:
+ name: 'build and push app'
+ if: github.event_name == 'push' && github.ref == 'refs/heads/develop'
+ needs:
+ - build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Create image
+ uses: ./.github/actions/create-image
+ with:
+ IMAGE_NAME: ${{ vars.BASE_IMAGE_NAME }}-app
+ TAG: edge
+ DOCKERFILE: ./apps/client-asset-sg/docker/Dockerfile
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ build_and_push_api:
+ name: 'build and push api'
+ if: github.event_name == 'push' && github.ref == 'refs/heads/develop'
+ needs:
+ - build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Create image
+ uses: ./.github/actions/create-image
+ with:
+ IMAGE_NAME: ${{ vars.BASE_IMAGE_NAME }}-api
+ TAG: edge
+ DOCKERFILE: ./apps/server-asset-sg/docker/Dockerfile
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ tag_edge_commit:
+ name: 'tag edge commit'
+ needs:
+ - build_and_push_app
+ - build_and_push_api
+ runs-on: ubuntu-latest
+ steps:
+ - name: Create/update tag
+ uses: actions/github-script@v7
+ with:
+ script: |
+ github.rest.git.createRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: 'refs/tags/edge',
+ sha: context.sha
+ }).catch(err => {
+ if (err.status !== 422) throw err;
+ github.rest.git.updateRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: 'tags/edge',
+ sha: context.sha
+ });
+ })
+
+ tag_rc_image:
+ name: tag rc image
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
+ needs:
+ - build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Login to GitHub Packages
+ run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
+
+ - name: Pull docker image
+ run: docker pull ${{ vars.BASE_IMAGE_NAME }}-app:edge
+
+ - name: Tag docker image
+ run: docker tag ${{ vars.BASE_IMAGE_NAME }}-app:edge ${{ vars.BASE_IMAGE_NAME }}-app:release-candidate
+
+ - name: Push docker image
+ run: docker push ${{ vars.BASE_IMAGE_NAME }}-app:release-candidate
+
+ tag_rc_commit:
+ name: 'tag rc commit'
+ needs: tag_rc_image
+ runs-on: ubuntu-latest
+ steps:
+ - name: Create/update tag
+ uses: actions/github-script@v7
+ with:
+ script: |
+ github.rest.git.createRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: 'refs/tags/release-candidate',
+ sha: context.sha
+ }).catch(err => {
+ if (err.status !== 422) throw err;
+ github.rest.git.updateRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: 'tags/release-candidate',
+ sha: context.sha
+ });
+ })
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 00000000..6440b54c
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,38 @@
+name: code-ql
+
+on:
+ push:
+ branches:
+ - develop
+ workflow_dispatch:
+ schedule:
+ - cron: '35 4 * * 5'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'javascript' ]
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v3
+ with:
+ languages: ${{ matrix.language }}
+
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v3
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v3
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..1667602b
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,115 @@
+name: release
+
+on:
+ workflow_dispatch:
+ inputs:
+ version:
+ description: "Version number (e.g. 1.12)"
+ required: true
+jobs:
+ release_app:
+ name: release app
+ needs:
+ - read_version
+ runs-on: ubuntu-latest
+ steps:
+ - name: Login to GitHub Packages
+ run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
+
+ - name: Pull docker image
+ run: docker pull ${{ vars.BASE_IMAGE_NAME }}-app:release-candidate
+
+ - name: Tag docker image
+ run: |
+ docker tag ${{ vars.BASE_IMAGE_NAME }}-app:release-candidate ${{ vars.BASE_IMAGE_NAME }}-app:${{ inputs.VERSION }}
+ docker tag ${{ vars.BASE_IMAGE_NAME }}-app:release-candidate ${{ vars.BASE_IMAGE_NAME }}-app:latest
+
+ - name: Push docker image
+ run: |
+ docker push ${{ vars.BASE_IMAGE_NAME }}-app:${{ inputs.VERSION }}
+ docker push ${{ vars.BASE_IMAGE_NAME }}-app:latest
+
+ release_api:
+ name: release api
+ needs:
+ - read_version
+ runs-on: ubuntu-latest
+ steps:
+ - name: Login to GitHub Packages
+ run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
+
+ - name: Pull docker image
+ run: docker pull ${{ vars.BASE_IMAGE_NAME }}-api:release-candidate
+
+ - name: Tag docker image
+ run: |
+ docker tag ${{ vars.BASE_IMAGE_NAME }}-api:release-candidate ${{ vars.BASE_IMAGE_NAME }}-api:${{ inputs.VERSION }}
+ docker tag ${{ vars.BASE_IMAGE_NAME }}-api:release-candidate ${{ vars.BASE_IMAGE_NAME }}-api:latest
+
+ - name: Push docker image
+ run: |
+ docker push ${{ vars.BASE_IMAGE_NAME }}-api:${{ inputs.VERSION }}
+ docker push ${{ vars.BASE_IMAGE_NAME }}-api:latest
+
+
+ tag_commit:
+ name: 'tag commit'
+ needs:
+ - release_app
+ - release_api
+ runs-on: ubuntu-latest
+ steps:
+ - name: Create/update latest tag
+ uses: actions/github-script@v7
+ with:
+ script: |
+ github.rest.git.createRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: 'refs/tags/latest',
+ sha: context.sha
+ }).catch(err => {
+ if (err.status !== 422) throw err;
+ github.rest.git.updateRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: 'tags/latest',
+ sha: context.sha
+ });
+ })
+
+ - name: Create/update version tag
+ uses: actions/github-script@v7
+ with:
+ script: |
+ github.rest.git.createRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: 'refs/tags/${{ inputs.VERSION }}',
+ sha: context.sha
+ }).catch(err => {
+ if (err.status !== 422) throw err;
+ github.rest.git.updateRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: 'tags/${{ inputs.VERSION }}',
+ sha: context.sha
+ });
+ })
+
+ create_release:
+ name: 'create release'
+ needs:
+ - release_app
+ - release_api
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Create release
+ uses: softprops/action-gh-release@v2
+ with:
+ tag_name: '${{ inputs.VERSION }}'
+ name: 'swissgeol-assets v${{ inputs.VERSION }}'
+ generate_release_notes: true
+ make_latest: true
diff --git a/.github/workflows/swissgeol-dev.yml b/.github/workflows/swissgeol-dev.yml
deleted file mode 100644
index 6133b3b0..00000000
--- a/.github/workflows/swissgeol-dev.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: Swissgeol Asset Dev Deploy
-
-on:
- push:
- branches: ["main"]
- workflow_dispatch:
-env:
- APP_IMAGE: ghcr.io/geoadmin/swissgeol-asset-app:dev
- API_IMAGE: ghcr.io/geoadmin/swissgeol-asset-api:dev
-
-jobs:
- # ------------------
- build-web-app:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-node@v3
- with:
- node-version: 18
-
- - name: generate version.json
- id: generate-version
- uses: ./.github/actions/generate-version
- with:
- path: ./apps/client-asset-sg/src/assets
-
- - name: Build app Docker image
- run: docker build . -f ./apps/client-asset-sg/docker/Dockerfile -t ${{ env.APP_IMAGE }}
-
- - name: Push container image
- id: registry-push
- uses: ./.github/actions/registry-push
- with:
- image: ${{ env.APP_IMAGE }}
- username: ${{ vars.SWISSGEOL_BUILD_USERNAME }}
- password: ${{ secrets.SWISSGEOL_BUILD_PAT }}
-
- # ------------------
- build-web-api:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-node@v3
- with:
- node-version: 18
-
- - name: generate version.json
- id: generate-version
- uses: ./.github/actions/generate-version
- with:
- path: ./apps/server-asset-sg/src/assets
-
- - name: Run NPM build
- run: |
- npm ci
- npm run build -- server-asset-sg
- - name: Retag Image
- working-directory: ./apps/server-asset-sg/docker
- run: docker tag registry.lambda-it.ch/asset-swissgeol/api:latest ${{ env.API_IMAGE }}
-
- - name: Push container image
- id: registry-push
- uses: ./.github/actions/registry-push
- with:
- image: ${{ env.API_IMAGE }}
- username: ${{ vars.SWISSGEOL_BUILD_USERNAME }}
- password: ${{ secrets.SWISSGEOL_BUILD_PAT }}
diff --git a/.github/workflows/swissgeol-int.yml b/.github/workflows/swissgeol-int.yml
deleted file mode 100644
index 4294496b..00000000
--- a/.github/workflows/swissgeol-int.yml
+++ /dev/null
@@ -1,100 +0,0 @@
-name: Swissgeol Asset Int Deploy
-
-on:
- release:
- types: [published]
- workflow_dispatch:
- inputs:
- tag:
- description: "Container Tag"
-env:
- APP_IMAGE: ghcr.io/geoadmin/swissgeol-asset-app:${{ github.event.inputs.tag || github.event.release.tag_name }}
- API_IMAGE: ghcr.io/geoadmin/swissgeol-asset-api:${{ github.event.inputs.tag || github.event.release.tag_name }}
-
-jobs:
- # ------------------
- build-web-app:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- with:
- ref: ${{ github.event.release.tag_name }}
- - uses: actions/setup-node@v3
- with:
- node-version: 18
-
- - name: generate version.json
- id: generate-version
- uses: ./.github/actions/generate-version
- with:
- path: ./apps/client-asset-sg/src/assets
-
- - name: Build app Docker image
- run: docker build . -f ./apps/client-asset-sg/docker/Dockerfile -t ${{ env.APP_IMAGE }}
-
- - name: Push container image
- id: registry-push
- uses: ./.github/actions/registry-push
- with:
- image: ${{ env.APP_IMAGE }}
- username: ${{ vars.SWISSGEOL_BUILD_USERNAME }}
- password: ${{ secrets.SWISSGEOL_BUILD_PAT }}
-
- # ------------------
- build-web-api:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- with:
- ref: ${{ github.event.release.tag_name }}
- - uses: actions/setup-node@v3
- with:
- node-version: 18
-
- - name: generate version.json
- id: generate-version
- uses: ./.github/actions/generate-version
- with:
- path: ./apps/client-asset-sg/src/assets
-
- - name: Run NPM build
- run: |
- npm ci
- npm run build -- server-asset-sg
- - name: Retag Image
- working-directory: ./apps/server-asset-sg/docker
- run: docker tag registry.lambda-it.ch/asset-swissgeol/api:latest ${{ env.API_IMAGE }}
-
- - name: Push container image
- id: registry-push
- uses: ./.github/actions/registry-push
- with:
- image: ${{ env.API_IMAGE }}
- username: ${{ vars.SWISSGEOL_BUILD_USERNAME }}
- password: ${{ secrets.SWISSGEOL_BUILD_PAT }}
-
- # ------------------
- deployment:
- runs-on: ubuntu-latest
- needs: [build-web-app, build-web-api]
- steps:
- - uses: actions/checkout@v3
- with:
- ref: ${{ github.event.release.tag_name }}
- - uses: actions/setup-node@v3
- with:
- node-version: 18
-
- - name: Pulumi deployment to cluster
- uses: ./.github/actions/deploy
- with:
- pulumiConfigSecret: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
- awsAccessKeyId: ${{ secrets.AWS_ACCESS_KEY_ID }}
- awsSecretAccessKey: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- eksClusterName: int
- eksRoleArn: arn:aws:iam::779726271945:role/kubernetes-admins-int
- pulumiConfigPassphrase: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
- stack: swissgeol-asset-int
- npmPkgToken: ${{ secrets.SWISSGEOL_BUILD_PAT }}
- command: up
- version: ${{ github.event.release.tag_name }}
diff --git a/.github/workflows/swissgeol-prod.yml b/.github/workflows/swissgeol-prod.yml
deleted file mode 100644
index 4528d5fc..00000000
--- a/.github/workflows/swissgeol-prod.yml
+++ /dev/null
@@ -1,100 +0,0 @@
-name: Swissgeol Asset Prod Deploy
-
-on:
- release:
- types: [published]
- workflow_dispatch:
- inputs:
- tag:
- description: "Container Tag"
-env:
- APP_IMAGE: ghcr.io/geoadmin/swissgeol-asset-app:${{ github.event.inputs.tag || github.event.release.tag_name }}
- API_IMAGE: ghcr.io/geoadmin/swissgeol-asset-api:${{ github.event.inputs.tag || github.event.release.tag_name }}
-
-jobs:
- # ------------------
- build-web-app:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- with:
- ref: ${{ github.event.release.tag_name }}
- - uses: actions/setup-node@v3
- with:
- node-version: 18
-
- - name: generate version.json
- id: generate-version
- uses: ./.github/actions/generate-version
- with:
- path: ./apps/client-asset-sg/src/assets
-
- - name: Build app Docker image
- run: docker build . -f ./apps/client-asset-sg/docker/Dockerfile -t ${{ env.APP_IMAGE }}
-
- - name: Push container image
- id: registry-push
- uses: ./.github/actions/registry-push
- with:
- image: ${{ env.APP_IMAGE }}
- username: ${{ vars.SWISSGEOL_BUILD_USERNAME }}
- password: ${{ secrets.SWISSGEOL_BUILD_PAT }}
-
- # ------------------
- build-web-api:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- with:
- ref: ${{ github.event.release.tag_name }}
- - uses: actions/setup-node@v3
- with:
- node-version: 18
-
- - name: generate version.json
- id: generate-version
- uses: ./.github/actions/generate-version
- with:
- path: ./apps/client-asset-sg/src/assets
-
- - name: Run NPM build
- run: |
- npm ci
- npm run build -- server-asset-sg
- - name: Retag Image
- working-directory: ./apps/server-asset-sg/docker
- run: docker tag registry.lambda-it.ch/asset-swissgeol/api:latest ${{ env.API_IMAGE }}
-
- - name: Push container image
- id: registry-push
- uses: ./.github/actions/registry-push
- with:
- image: ${{ env.API_IMAGE }}
- username: ${{ vars.SWISSGEOL_BUILD_USERNAME }}
- password: ${{ secrets.SWISSGEOL_BUILD_PAT }}
-
- # ------------------
- deployment:
- runs-on: ubuntu-latest
- needs: [build-web-app, build-web-api]
- steps:
- - uses: actions/checkout@v3
- with:
- ref: ${{ github.event.release.tag_name }}
- - uses: actions/setup-node@v3
- with:
- node-version: 18
-
- - name: Pulumi deployment to cluster
- uses: ./.github/actions/deploy
- with:
- pulumiConfigSecret: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
- awsAccessKeyId: ${{ secrets.AWS_ACCESS_KEY_ID }}
- awsSecretAccessKey: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- eksClusterName: prod
- eksRoleArn: arn:aws:iam::779726271945:role/kubernetes-admins-prod
- pulumiConfigPassphrase: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
- stack: swissgeol-asset-prod
- npmPkgToken: ${{ secrets.SWISSGEOL_BUILD_PAT }}
- command: up
- version: ${{ github.event.release.tag_name }}
diff --git a/.gitignore b/.gitignore
index c04fa8be..1c03120f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,6 +49,7 @@ Thumbs.db
__pycache__
+.env.local
.env.staging
.env.prod
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 34d8f2e1..db0ada5d 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,7 +1,7 @@
{
"editor.codeActionsOnSave": {
- "source.organizeImports": false,
- "source.fixAll.eslint": true
+ "source.organizeImports": "never",
+ "source.fixAll.eslint": "explicit"
},
"peacock.color": "#0b7285",
"peacock.remoteColor": "#000",
diff --git a/README.md b/README.md
index 7582a80f..17303b39 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,185 @@
-# asset-swissgeol-ch
+# SwissGeol Asset
-More docs for asset-swissgeol-ch: https://github.com/Lambda-IT/asset-swissgeol-ch/wiki
+## Development
+The following components must be installed on the development computer:
-## Instances
+✔️ Git
+✔️ Docker
+✔️ Node.js 20 LTS
-- assets.swissgeol.ch
- - assets.swissgeol.ch/kibana
-- int-assets.swissgeol.ch
- - int-assets.swissgeol.ch/kibana
+### Setting Up the Development Environment
+Follow these steps to set up the development environment on your local machine:
+* [1. Configure Local Systems](#1-Configure-Local-Systems)
+* [2. Configure the Asset Server](#2-Configure-the-Asset-Server)
+* [3. Install Dependencies](#3-Install-Dependencies)
+* [4. Build Local Systems](#4-Build-Local-Systems)
+* [5. Initialize MinIO](#5-Initialize-MinIO)
+
+#### 1. Configure Local Systems
+Configure `development/.env` according to the [development services configuration](#Development-Services-Configuration).
+
+#### 2. Configure the Asset Server
+Create an empty copy of the [web server configuration](#Asset-Server-Configuration) as [`apps/server-asset-sg/.env.local`](apps/server-asset-sg/.env.local).
+Configure the following variables:
+* Set `AUTH_URL=http://localhost:8866`.
+* Set `FRONTEND_URL=http://localhost:4200`.
+* Set `DATABASE_URL=postgres://asset-swissgeol:asset-swissgeol@localhost:5432/postgres?schema=public`.
+* Set `GOTRUE_JWT_SECRET` to the same value as in [`development/.env`](development/.env).
+* Leave `OCR_URL` empty.
+* Leave `OCR_CALLBACK_URL` empty.
+
+#### 3. Install Dependencies
+Install node modules:
+```bash
+npm run install
+```
+
+Decorate the Angular CLI with the Nx CLI:
+```bash
+npm run postinstall
+```
+
+#### 4. Build Local Services
+Generate prisma-client for database-access:
+```bash
+cd apps/server-asset-sg/
+ng gen-prisma-client
+```
+
+Build postgis-gotrue docker image:
+```bash
+cd development/images/db
+docker build -t postgis-gotrue .
+```
+
+#### 5. Initialize MinIO
+* [Start the development services](#Starting-the-Development-Environment).
+* Open http://localhost:9001
+* Sign in using the `STORAGE_USER` and `STORAGE_PASSWORD` of your development environment.
+* Navigate to [Buckets](http://localhost:9001/buckets) and create a new bucket with the name `asset-sg`.
+* 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 your Asset Server Configuration at [`apps/server-asset-sg/.env.local`](apps/server-asset-sg/.env.local) and make the following changes:
+ * `S3_REGION=local`
+ * `S3_ENDPOINT=http://localhost:9000`
+ * `S3_BUCKET_NAME=asset-sg`
+ * `S3_ASSET_FOLDER=asset-sg`
+ * `S3_ACCESS_KEY_ID` as your newly generated access key.
+ * `S3_SECRET_ACCESS_KEY` as your newly generated access key's secret.
+
+### Starting the Development Environment
+Start development services:
+```bash
+cd development
+docker compose up
+```
+Start the application:
+```bash
+npm run start
+```
+
+### Local Services and Applications
+| 🔖App/Service | 🔗Link | 🧞User | 🔐Password |
+|:-------------------------|:-------------------------------------------------|:-------------------------|:-------------------------|
+| Assets (client) | [localhost:4200](http://localhost:4200/) | `admin@swissgeol.assets` | `swissgeol_assets` |
+| Assets REST API (server) | [localhost:3333/api/](http://localhost:3333/api) | n/a | n/a |
+| postgreSQL (docker) | localhost:5432 | .env `$DB_USER` | .env `$DB_PASSWORD` |
+| Elasticsearch (docker) | [localhost:9200](http://localhost:9200) | n/a | n/a |
+| Kibana (docker) | [localhost:5601](http://localhost:5601) | n/a | n/a |
+| pgAdmin (docker) | [localhost:5051](http://localhost:5051/) | .env `$PGADMIN_EMAIL` | .env `$PGADMIN_PASSWORD` |
+| MinIO (docker) | [localhost:9001](http://localhost:9001/) | .env `$STORAGE_USER` | .env `$STORAGE_PASSWORD` |
+| smtp4dev (docker) | [localhost:5000](http://localhost:5000/) | n/a | n/a |
+| oidc-server (docker) | [localhost:4011](http://localhost:4011/) | n/a | n/a |
+
+### Importing Example Data
+You can dump data from a remote environment into a local file so you can initialize your development database with it.
+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'
+```
+> The export will output warnings related to circular foreign-key constraints.
+> These can be safely ignored.
+
+> The export will only contain the database's data, not its structure.
+> Data related to the authentication process is also excluded,
+> so we don't run into conflicts when using a different eIAM provider.
+
+To import the dumped data, run the following commands.
+Ensure to start your database service beforehand.
+```bash
+# Reset the database:
+npm run prisma -- migrate reset -f
+npm run prisma -- migrate deploy
+
+# Import example data:
+cd development
+docker compose exec db sh -c 'psql --dbname=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB} -f /dump.sql'
+```
+> You will need to manually sync the data to Elasticsearch via the admin panel in the web UI.
+
+## Testing
+> Tests execute automatically on every push to the Git repository.
+
+The local tests require a running instance of both _postgreSQL_ and _Elasticsearch_.
+Make sure that your local development environment is fully shutdown and then run the test services:
+```bash
+cd development
+docker compose down
+docker compose -f docker-compose.test.yml up
+```
+Then run all tests:
+```bash
+npm run test
+```
+It is also possible to run only specific tests:
+```bash
+# Run only the server tests:
+nx run server-asset-sg:test
+
+# Run only a specific test suite:
+nx run server-asset-sg:test -t 'AssetRepo'
+
+# Run only a specific, nested test suite:
+nx run server-asset-sg:test -t 'AssetRepo create'
+```
+
+## Configuration
+### Asset 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).
+
+| Variable | Example | Description |
+|----------------------|--------------------------------------------------------------------------------------------|------------------------------------------------------------|
+| AUTH_URL | http://my.gotrue.example:8866 | URL of the GoTrue auth service. |
+| FRONTEND_URL | http://assets.geo.admin.ch | Public URL of the SwissGeol Asset web client. |
+| S3_REGION | euw-3 | Region of the S3 instance. |
+| S3_ENDPOINT | http://compute-1.amazonaws.com | URL to the S3 instance. |
+| S3_ACCESS_KEY_ID | AP6wpeXraSc0IH4d42IN | Access Key for the S3 instance. |
+| S3_SECRET_ACCESS_KEY | fSx5Bfib0OeAyG1mwtslKA04Qj6oPStLcpnkACmF | Secret Key for the S3 instance. |
+| S3_BUCKET_NAME | asset-sg | S3 bucket name. |
+| S3_ASSET_FOLDER | asset-sg | Folder within the S3 bucket into which objects are stored. |
+| DATABASE_URL | postgres://asset-swissgeol:asset-swissgeol@my.postgres.example:5432/postgres?schema=public | PostgreSQL access URL. |
+| GOTRUE_JWT_SECRET | 18af41574b30be7539d8c3e45ccdeea9431cff6419cdce5cabc5f28cfb73e15c | JWT secret key for the GoTrue server. |
+| OCR_URL | | Leave empty. |
+| OCR_CALLBACK_URL | | Leave empty. |
+
+
+### Development Services 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).
+
+> 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.
+
+| 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. |
+| GOTRUE_JWT_SECRET | _custom_ | JWT Secret Key for the GoTrue container. |
diff --git a/apps/client-asset-sg-e2e/cypress.config.ts b/apps/client-asset-sg-e2e/cypress.config.ts
index ec4ed885..39337d99 100644
--- a/apps/client-asset-sg-e2e/cypress.config.ts
+++ b/apps/client-asset-sg-e2e/cypress.config.ts
@@ -1,5 +1,5 @@
-import { defineConfig } from 'cypress';
import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset';
+import { defineConfig } from 'cypress';
export default defineConfig({
e2e: nxE2EPreset(__dirname),
diff --git a/apps/client-asset-sg-e2e/src/support/commands.ts b/apps/client-asset-sg-e2e/src/support/commands.ts
index 4200179b..384d6715 100644
--- a/apps/client-asset-sg-e2e/src/support/commands.ts
+++ b/apps/client-asset-sg-e2e/src/support/commands.ts
@@ -18,7 +18,7 @@ declare namespace Cypress {
//
// -- This is a parent command --
Cypress.Commands.add('login', (email, password) => {
- console.log('Custom command example: Login', email, password);
+ console.log('Custom command example: Login');
});
//
// -- This is a child command --
diff --git a/apps/client-asset-sg/docker/Dockerfile b/apps/client-asset-sg/docker/Dockerfile
index ae87bd02..5842e09c 100644
--- a/apps/client-asset-sg/docker/Dockerfile
+++ b/apps/client-asset-sg/docker/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:16-alpine as ui-builder
+FROM node:20-alpine as app-builder
WORKDIR /app
COPY . .
@@ -11,10 +11,9 @@ RUN npx nx build client-asset-sg
# final image build
FROM nginx:mainline-alpine
-LABEL maintainer=support@lambda-it.ch
WORKDIR /usr/share/nginx/html
-COPY --from=ui-builder /app/dist/apps/client-asset-sg .
+COPY --from=app-builder /app/dist/apps/client-asset-sg .
# this nginx base image will parse the template and will move it to
# /etc/nginx/conf.d/default.conf before it starts nginx process
diff --git a/apps/client-asset-sg/project.json b/apps/client-asset-sg/project.json
index dceecf5a..b99fba3a 100644
--- a/apps/client-asset-sg/project.json
+++ b/apps/client-asset-sg/project.json
@@ -1,93 +1,120 @@
{
- "name": "client-asset-sg",
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
- "projectType": "application",
- "sourceRoot": "apps/client-asset-sg/src",
- "prefix": "asset-sg",
- "targets": {
- "build": {
- "executor": "@angular-devkit/build-angular:browser",
- "outputs": ["{options.outputPath}"],
- "options": {
- "outputPath": "dist/apps/client-asset-sg",
- "index": "apps/client-asset-sg/src/index.html",
- "main": "apps/client-asset-sg/src/main.ts",
- "polyfills": ["zone.js"],
- "tsConfig": "apps/client-asset-sg/tsconfig.app.json",
- "inlineStyleLanguage": "scss",
- "assets": ["apps/client-asset-sg/src/favicon.ico", "apps/client-asset-sg/src/assets"],
- "styles": ["apps/client-asset-sg/src/styles.scss"],
- "scripts": []
+ "name": "client-asset-sg",
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
+ "projectType": "application",
+ "sourceRoot": "apps/client-asset-sg/src",
+ "prefix": "asset-sg",
+ "targets": {
+ "build": {
+ "executor": "@angular-devkit/build-angular:browser",
+ "outputs": [
+ "{options.outputPath}"
+ ],
+ "options": {
+ "outputPath": "dist/apps/client-asset-sg",
+ "index": "apps/client-asset-sg/src/index.html",
+ "main": "apps/client-asset-sg/src/main.ts",
+ "polyfills": [
+ "zone.js"
+ ],
+ "tsConfig": "apps/client-asset-sg/tsconfig.app.json",
+ "inlineStyleLanguage": "scss",
+ "assets": [
+ "apps/client-asset-sg/src/favicon.ico",
+ "apps/client-asset-sg/src/assets"
+ ],
+ "styles": [
+ "apps/client-asset-sg/src/styles.scss"
+ ],
+ "scripts": []
+ },
+ "configurations": {
+ "production": {
+ "budgets": [
+ {
+ "type": "initial",
+ "maximumWarning": "1.2mb",
+ "maximumError": "1.3mb"
},
- "configurations": {
- "production": {
- "budgets": [
- {
- "type": "initial",
- "maximumWarning": "1.2mb",
- "maximumError": "1.3mb"
- },
- {
- "type": "anyComponentStyle",
- "maximumWarning": "2kb",
- "maximumError": "4kb"
- }
- ],
- "outputHashing": "all",
- "fileReplacements": [
- {
- "replace": "apps/client-asset-sg/src/environments/environment.ts",
- "with": "apps/client-asset-sg/src/environments/environment.prod.ts"
- }
- ]
- },
- "development": {
- "buildOptimizer": false,
- "optimization": false,
- "vendorChunk": true,
- "extractLicenses": false,
- "sourceMap": true,
- "namedChunks": true
- }
- },
- "defaultConfiguration": "production"
- },
- "serve": {
- "executor": "@angular-devkit/build-angular:dev-server",
- "configurations": {
- "production": {
- "browserTarget": "client-asset-sg:build:production"
- },
- "development": {
- "browserTarget": "client-asset-sg:build:development"
- }
- },
- "defaultConfiguration": "development",
- "options": {
- "proxyConfig": "apps/client-asset-sg/proxy.conf.json"
+ {
+ "type": "anyComponentStyle",
+ "maximumWarning": "2kb",
+ "maximumError": "4kb"
}
- },
- "extract-i18n": {
- "executor": "@angular-devkit/build-angular:extract-i18n",
- "options": {
- "browserTarget": "client-asset-sg:build"
+ ],
+ "outputHashing": "all",
+ "fileReplacements": [
+ {
+ "replace": "apps/client-asset-sg/src/environments/environment.ts",
+ "with": "apps/client-asset-sg/src/environments/environment.prod.ts"
}
+ ]
},
- "lint": {
- "executor": "@nrwl/linter:eslint",
- "outputs": ["{options.outputFile}"],
- "options": {
- "lintFilePatterns": ["apps/client-asset-sg/**/*.ts", "apps/client-asset-sg/**/*.html"]
+ "int": {
+ "fileReplacements": [
+ {
+ "replace": "apps/client-asset-sg/src/environments/environment.ts",
+ "with": "apps/client-asset-sg/src/environments/environment.int.ts"
}
+ ]
},
- "test": {
- "executor": "@nrwl/jest:jest",
- "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
- "options": {
- "jestConfig": "apps/client-asset-sg/jest.config.ts",
- "passWithNoTests": true
- }
+ "development": {
+ "buildOptimizer": false,
+ "optimization": false,
+ "vendorChunk": true,
+ "extractLicenses": false,
+ "sourceMap": true,
+ "namedChunks": true
}
+ },
+ "defaultConfiguration": "production"
+ },
+ "serve": {
+ "executor": "@angular-devkit/build-angular:dev-server",
+ "configurations": {
+ "production": {
+ "browserTarget": "client-asset-sg:build:production"
+ },
+ "int": {
+ "browserTarget": "client-asset-sg:build:int"
+ },
+ "development": {
+ "browserTarget": "client-asset-sg:build:development"
+ }
+ },
+ "defaultConfiguration": "development",
+ "options": {
+ "proxyConfig": "apps/client-asset-sg/proxy.conf.json"
+ }
+ },
+ "extract-i18n": {
+ "executor": "@angular-devkit/build-angular:extract-i18n",
+ "options": {
+ "browserTarget": "client-asset-sg:build"
+ }
+ },
+ "lint": {
+ "executor": "@nrwl/linter:eslint",
+ "outputs": [
+ "{options.outputFile}"
+ ],
+ "options": {
+ "lintFilePatterns": [
+ "apps/client-asset-sg/**/*.ts",
+ "apps/client-asset-sg/**/*.html"
+ ]
+ }
},
- "tags": []
+ "test": {
+ "executor": "@nrwl/jest:jest",
+ "outputs": [
+ "{workspaceRoot}/coverage/{projectRoot}"
+ ],
+ "options": {
+ "jestConfig": "apps/client-asset-sg/jest.config.ts",
+ "passWithNoTests": true
+ }
+ }
+ },
+ "tags": []
}
diff --git a/apps/client-asset-sg/src/app/app.component.html b/apps/client-asset-sg/src/app/app.component.html
index 51447d42..52c102ab 100644
--- a/apps/client-asset-sg/src/app/app.component.html
+++ b/apps/client-asset-sg/src/app/app.component.html
@@ -1,10 +1,10 @@
Guten Tag
-
- Es wurde für Sie ein Login erstellt für den Zugang bei asset.swissgeol.ch. Bitte aktivieren Sie den Benutzer über
- den folgenden Link:
- {{ .ConfirmationURL }}&lang=de
-
- Freundliche Grüsse
- Ihr Swisstopo Team
-
Hello
-
- A login has been created for you to access assset.swissgeol.ch. Please activate the account via the following
- link:
- {{ .ConfirmationURL }}&lang=en
-
- Best regards
- Your Swisstopo Team
-
- Folgen Sie diesem Link, um das Passwort für Ihren Benutzer zurückzusetzen:
- {{ .ConfirmationURL }}&lang=de
-
- Freundliche Grüsse
- Ihr Swisstopo Team
-
- Follow this link to reset the password for your user:
- {{ .ConfirmationURL }}&lang=en
-
- Best regards
- Your Swisstopo Team
-