diff --git a/alfa-client/.prettierignore b/alfa-client/.prettierignore
index ee7824bd9c6d18d685c77479a451c9554c111e9d..0eb1899d00dd4018fa9605a6b746a08a07174333 100644
--- a/alfa-client/.prettierignore
+++ b/alfa-client/.prettierignore
@@ -6,4 +6,5 @@ packages/workspace/src/generators/**/files/**/*.json
 /.nx/cache
 .angular
 
-/.nx/workspace-data
\ No newline at end of file
+/.nx/workspace-data
+*.md
\ No newline at end of file
diff --git a/alfa-client/apps/admin/src/main.ts b/alfa-client/apps/admin/src/main.ts
index 7f198e2f5459037b727eb464f2259321948eeaed..de7bed8ea66ac6e222311d9d8c185b4cad477b85 100644
--- a/alfa-client/apps/admin/src/main.ts
+++ b/alfa-client/apps/admin/src/main.ts
@@ -21,15 +21,14 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { EnvironmentModule, loadEnvironment } from '@alfa-client/environment-shared';
-import { enableProdMode, importProvidersFrom, Injectable } from '@angular/core';
-import { isNil } from 'lodash-es';
-
+import { AggregationMappingProvider } from '@admin-client/reporting-shared';
 import { ApiRootModule } from '@alfa-client/api-root-shared';
+import { EnvironmentModule, loadEnvironment } from '@alfa-client/environment-shared';
 import { NavigationSharedModule } from '@alfa-client/navigation-shared';
 import { registerLocaleData } from '@angular/common';
 import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
 import localeDe from '@angular/common/locales/de';
+import { enableProdMode, importProvidersFrom, Injectable } from '@angular/core';
 import { bootstrapApplication, BrowserModule } from '@angular/platform-browser';
 import { provideAnimations } from '@angular/platform-browser/animations';
 import {
@@ -49,6 +48,7 @@ import { ConfigurationsProviders } from 'libs/admin/configuration-shared/src/lib
 import { PostfachProviders } from 'libs/admin/postfach-shared/src/lib/postfach.providers';
 import { SettingsProviders } from 'libs/admin/settings-shared/src/lib/settings.providers';
 import { UserProviders } from 'libs/admin/user/src/lib/user.providers';
+import { isNil } from 'lodash-es';
 import { HttpBinaryFileInterceptor } from '../../../libs/tech-shared/src/lib/interceptor/http-binary-file.interceptor';
 import { HttpXsrfInterceptor } from '../../../libs/tech-shared/src/lib/interceptor/http-xsrf.interceptor';
 import { XhrInterceptor } from '../../../libs/tech-shared/src/lib/interceptor/xhr.interceptor';
@@ -97,6 +97,7 @@ loadEnvironment(environment.environmentUrl).then((env) => {
       PostfachProviders,
       SettingsProviders,
       UserProviders,
+      AggregationMappingProvider,
       importProvidersFrom(
         NavigationSharedModule,
         BrowserModule,
diff --git a/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.spec.ts b/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.spec.ts
index a861afd0728827a45330d8d5d2d78f63e6dfc5d1..938cc1b0061d2194105629ca70c1e5f8619d881c 100644
--- a/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.spec.ts
+++ b/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.spec.ts
@@ -1,7 +1,7 @@
+import { AdminStatistikFieldsFormComponent } from '@admin-client/statistik';
 import { existsAsHtmlElement } from '@alfa-client/test-utils';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { MockComponent } from 'ng-mocks';
-import { AdminStatistikFieldsFormComponent } from '../../../../../../libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component';
 import { getDataTestIdOf } from '../../../../../../libs/tech-shared/test/data-test';
 import { StatistikFieldsFormPageComponent } from './statistik-fields-form-page.component';
 
diff --git a/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.ts b/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.ts
index e249c034417fc7133d8cc2c5db690ddcb94ea50f..c4122b72d148865b4219d5446a3c2060574b23e7 100644
--- a/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.ts
+++ b/alfa-client/apps/admin/src/pages/statistik/statistik-fields-form-page/statistik-fields-form-page.component.ts
@@ -1,6 +1,6 @@
+import { AdminStatistikFieldsFormComponent } from '@admin-client/statistik';
 import { CommonModule } from '@angular/common';
 import { Component } from '@angular/core';
-import { AdminStatistikFieldsFormComponent } from '../../../../../../libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component';
 
 @Component({
   selector: 'statistik-fields-form-page',
diff --git a/alfa-client/libs/admin/postfach-shared/project.json b/alfa-client/libs/admin/postfach-shared/project.json
index 6489dc23d02f10a0660d03ccd39ccebae8dadc5d..e02554623fc02a4f2929efea43c8669d24ecdf3a 100644
--- a/alfa-client/libs/admin/postfach-shared/project.json
+++ b/alfa-client/libs/admin/postfach-shared/project.json
@@ -10,7 +10,7 @@
       "executor": "@nx/jest:jest",
       "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
       "options": {
-        "tsConfig": "libs/admin//postfach-shared/tsconfig.spec.json",
+        "tsConfig": "libs/admin/postfach-shared/tsconfig.spec.json",
         "jestConfig": "libs/admin/postfach-shared/jest.config.ts"
       }
     },
diff --git a/alfa-client/libs/admin/postfach-shared/src/lib/postfach-resource.service.ts b/alfa-client/libs/admin/postfach-shared/src/lib/postfach-resource.service.ts
index 48043163dea114eba85fa881d9047ec90f8ef24a..a617ed3abf3f31d102889877f0d10a8117bb23b2 100644
--- a/alfa-client/libs/admin/postfach-shared/src/lib/postfach-resource.service.ts
+++ b/alfa-client/libs/admin/postfach-shared/src/lib/postfach-resource.service.ts
@@ -21,7 +21,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { SettingsService } from '@admin-client/settings-shared';
+import { SettingName, SettingsService } from '@admin-client/settings-shared';
 import { ApiResourceService, ResourceRepository, ResourceServiceConfig } from '@alfa-client/tech-shared';
 import { PostfachLinkRel } from './postfach.linkrel';
 import { PostfachResource } from './postfach.model';
@@ -34,7 +34,7 @@ export function createPostfachResourceService(repository: ResourceRepository, se
 
 function buildConfig(settingService: SettingsService): ResourceServiceConfig<PostfachResource> {
   return {
-    resource: settingService.getPostfach(),
+    resource: settingService.get(SettingName.POSTFACH),
     getLinkRel: PostfachLinkRel.SELF,
     edit: { linkRel: PostfachLinkRel.SELF },
   };
diff --git a/alfa-client/libs/admin/postfach-shared/src/lib/postfach.model.ts b/alfa-client/libs/admin/postfach-shared/src/lib/postfach.model.ts
index c592dec3e6621543ca69e9ee23abdeea1ec6f4ec..e3ce2fb8bd6153796bea9bf82422718d2324721e 100644
--- a/alfa-client/libs/admin/postfach-shared/src/lib/postfach.model.ts
+++ b/alfa-client/libs/admin/postfach-shared/src/lib/postfach.model.ts
@@ -21,8 +21,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { Resource } from '@ngxp/rest';
-import { SettingName } from 'libs/admin/settings-shared/src/lib/settings.model';
+import { SettingItemResource } from 'libs/admin/settings-shared/src/lib/settings.model';
 
 export interface Absender {
   name: string;
@@ -37,9 +36,4 @@ export interface Postfach {
   signatur: string;
 }
 
-export declare type PostfachSettingsItem = {
-  name: SettingName.POSTFACH;
-  settingBody: Postfach;
-};
-
-export declare type PostfachResource = Resource & PostfachSettingsItem;
+export declare type PostfachResource = SettingItemResource<Postfach>;
diff --git a/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.spec.ts b/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.spec.ts
index d779cb50dc2173e7dee4dc929a7e11f5d259724d..2441dc06db2b787fe3f33389d1fb2daae412e3bf 100644
--- a/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.spec.ts
+++ b/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.spec.ts
@@ -21,6 +21,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
+import { SettingItem } from '@admin-client/settings-shared';
 import { createEmptyStateResource, createStateResource, StateResource } from '@alfa-client/tech-shared';
 import { Mock, mock } from '@alfa-client/test-utils';
 import { SnackBarService } from '@alfa-client/ui';
@@ -31,7 +32,7 @@ import { singleCold, singleHot } from 'libs/tech-shared/test/marbles';
 import { Observable, of } from 'rxjs';
 import { createPostfachResource, createPostfachSettingItem } from '../test/postfach';
 import { PostfachResourceService } from './postfach-resource.service';
-import { PostfachResource, PostfachSettingsItem } from './postfach.model';
+import { Postfach, PostfachResource } from './postfach.model';
 import { PostfachService } from './postfach.service';
 
 describe('PostfachService', () => {
@@ -78,7 +79,7 @@ describe('PostfachService', () => {
   });
 
   describe('save', () => {
-    const postfachSettingsItem: PostfachSettingsItem = createPostfachSettingItem();
+    const postfachSettingsItem: SettingItem<Postfach> = createPostfachSettingItem();
     const postfachResource: PostfachResource = createPostfachResource();
     const postfachStateResource: StateResource<PostfachResource> = createStateResource(postfachResource);
 
diff --git a/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.ts b/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.ts
index 19cf4ef6cf561586b44f3afee70e4c716ec54052..3321cfc1690bd504a1e0f94ac6eda627170a29c9 100644
--- a/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.ts
+++ b/alfa-client/libs/admin/postfach-shared/src/lib/postfach.service.ts
@@ -21,13 +21,13 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { SettingName } from '@admin-client/settings-shared';
+import { SettingItem, SettingName } from '@admin-client/settings-shared';
 import { createEmptyStateResource, StateResource } from '@alfa-client/tech-shared';
 import { SnackBarService } from '@alfa-client/ui';
 import { inject, Injectable } from '@angular/core';
 import { Observable, startWith, tap } from 'rxjs';
 import { PostfachResourceService } from './postfach-resource.service';
-import { Postfach, PostfachResource, PostfachSettingsItem } from './postfach.model';
+import { Postfach, PostfachResource } from './postfach.model';
 
 @Injectable()
 export class PostfachService {
@@ -51,7 +51,7 @@ export class PostfachService {
     }
   }
 
-  private buildPostfachSettingItem(postfach: Postfach): PostfachSettingsItem {
+  private buildPostfachSettingItem(postfach: Postfach): SettingItem<Postfach> {
     return {
       name: SettingName.POSTFACH,
       settingBody: postfach,
diff --git a/alfa-client/libs/admin/postfach-shared/src/test/postfach.ts b/alfa-client/libs/admin/postfach-shared/src/test/postfach.ts
index 93d7492c32b0e0b595a447757952ee358b0e1345..88132bc3d88c73d130f50caed0da9aa15ae68d5b 100644
--- a/alfa-client/libs/admin/postfach-shared/src/test/postfach.ts
+++ b/alfa-client/libs/admin/postfach-shared/src/test/postfach.ts
@@ -22,9 +22,9 @@
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
 import { faker } from '@faker-js/faker';
-import { SettingItemResource, SettingName } from 'libs/admin/settings-shared/src/lib/settings.model';
+import { SettingItem, SettingName } from 'libs/admin/settings-shared/src/lib/settings.model';
 import { toResource } from 'libs/tech-shared/test/resource';
-import { Postfach, PostfachResource, PostfachSettingsItem } from '../lib/postfach.model';
+import { Postfach, PostfachResource } from '../lib/postfach.model';
 
 export function createPostfach(): Postfach {
   return {
@@ -39,7 +39,7 @@ export function createPostfach(): Postfach {
   };
 }
 
-export function createPostfachSettingItem(): PostfachSettingsItem {
+export function createPostfachSettingItem(): SettingItem<Postfach> {
   return {
     name: SettingName.POSTFACH,
     settingBody: createPostfach(),
@@ -49,10 +49,3 @@ export function createPostfachSettingItem(): PostfachSettingsItem {
 export function createPostfachResource(): PostfachResource {
   return toResource(createPostfachSettingItem());
 }
-
-export function createSettingItemResource(): SettingItemResource {
-  return toResource({
-    name: faker.word.sample(),
-    settingBody: {},
-  });
-}
diff --git a/alfa-client/libs/admin/reporting-shared/.eslintrc.json b/alfa-client/libs/admin/reporting-shared/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..7474579d583c598ae092a906b3e6cf1ad3c08a50
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/.eslintrc.json
@@ -0,0 +1,33 @@
+{
+  "extends": ["../../../.eslintrc.json"],
+  "ignorePatterns": ["!**/*"],
+  "overrides": [
+    {
+      "files": ["*.ts"],
+      "extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
+      "rules": {
+        "@angular-eslint/directive-selector": [
+          "error",
+          {
+            "type": "attribute",
+            "prefix": "admin",
+            "style": "camelCase"
+          }
+        ],
+        "@angular-eslint/component-selector": [
+          "error",
+          {
+            "type": "element",
+            "prefix": "admin",
+            "style": "kebab-case"
+          }
+        ]
+      }
+    },
+    {
+      "files": ["*.html"],
+      "extends": ["plugin:@nx/angular-template"],
+      "rules": {}
+    }
+  ]
+}
diff --git a/alfa-client/libs/admin/reporting-shared/README.md b/alfa-client/libs/admin/reporting-shared/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..be5bb22469ec116a5b8b3d498db669555c92da4e
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/README.md
@@ -0,0 +1,7 @@
+# admin-reporting-shared
+
+This library was generated with [Nx](https://nx.dev).
+
+## Running unit tests
+
+Run `nx test admin-reporting-shared` to execute the unit tests.
diff --git a/alfa-client/libs/admin/reporting-shared/jest.config.ts b/alfa-client/libs/admin/reporting-shared/jest.config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b4f392a061baff74cb98d86a02f0100960384315
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/jest.config.ts
@@ -0,0 +1,21 @@
+export default {
+  displayName: 'admin-reporting-shared',
+  preset: '../../../jest.preset.js',
+  setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
+  coverageDirectory: '../../../coverage/libs/admin/reporting-shared',
+  transform: {
+    '^.+\\.(ts|mjs|js|html)$': [
+      'jest-preset-angular',
+      {
+        tsconfig: '<rootDir>/tsconfig.spec.json',
+        stringifyContentPathRegex: '\\.(html|svg)$',
+      },
+    ],
+  },
+  transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
+  snapshotSerializers: [
+    'jest-preset-angular/build/serializers/no-ng-attributes',
+    'jest-preset-angular/build/serializers/ng-snapshot',
+    'jest-preset-angular/build/serializers/html-comment',
+  ],
+};
diff --git a/alfa-client/libs/admin/reporting-shared/project.json b/alfa-client/libs/admin/reporting-shared/project.json
new file mode 100644
index 0000000000000000000000000000000000000000..f7a760900530aff273dc117494292f1e2b028824
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/project.json
@@ -0,0 +1,22 @@
+{
+  "name": "admin-reporting-shared",
+  "$schema": "../../../node_modules/nx/schemas/project-schema.json",
+  "sourceRoot": "libs/admin/reporting-shared/src",
+  "prefix": "admin",
+  "projectType": "library",
+  "tags": [],
+  "targets": {
+    "test": {
+      "executor": "@nx/jest:jest",
+      "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
+      "options": {
+        "tsConfig": "libs/admin/reporting-shared/tsconfig.spec.json",
+        "jestConfig": "libs/admin/reporting-shared/jest.config.ts"
+      }
+    },
+    "lint": {
+      "executor": "@nx/eslint:lint",
+      "outputs": ["{options.outputFile}"]
+    }
+  }
+}
diff --git a/alfa-client/libs/admin/reporting-shared/src/index.ts b/alfa-client/libs/admin/reporting-shared/src/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..44ab78233d97deaf497e327e28f71c431ae6960e
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/src/index.ts
@@ -0,0 +1,4 @@
+export * from './lib/aggregation-mapping-resource.service';
+export * from './lib/aggregation-mapping.model';
+export * from './lib/aggregation-mapping.provider';
+export * from './lib/aggregation-mapping.service';
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..65eb7a8e1680b97f12cdba2556ae8d9d9041883c
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts
@@ -0,0 +1,26 @@
+import { ConfigurationLinkRel, ConfigurationResource, ConfigurationService } from '@admin-client/configuration-shared';
+import { ListResourceServiceConfig, ResourceListService, ResourceRepository } from '@alfa-client/tech-shared';
+import { AggregationMappingListLinkRel } from './aggregation-mapping.linkrel';
+import { AggregationMappingListResource, AggregationMappingResource } from './aggregation-mapping.model';
+
+export class AggregationMappingListResourceService extends ResourceListService<
+  ConfigurationResource,
+  AggregationMappingListResource,
+  AggregationMappingResource
+> {}
+
+export function createAggregationMappingResourceService(
+  repository: ResourceRepository,
+  configurationService: ConfigurationService,
+) {
+  return new ResourceListService(buildConfig(configurationService), repository);
+}
+
+function buildConfig(configurationService: ConfigurationService): ListResourceServiceConfig<ConfigurationResource> {
+  return {
+    baseResource: configurationService.get(),
+    listLinkRel: ConfigurationLinkRel.AGGREGATION_MAPPINGS,
+    listResourceListLinkRel: AggregationMappingListLinkRel.LIST,
+    createLinkRel: AggregationMappingListLinkRel.SELF,
+  };
+}
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.linkrel.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.linkrel.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a4a02bfd7087b105a9d0d2dd816aa2b180a4db9c
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.linkrel.ts
@@ -0,0 +1,4 @@
+export enum AggregationMappingListLinkRel {
+  LIST = 'aggregationMappings',
+  SELF = 'self',
+}
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.model.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0db6cb4e397768b10781b3c34c9379fc866cec2b
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.model.ts
@@ -0,0 +1,20 @@
+import { ListResource } from '@alfa-client/tech-shared';
+import { Resource } from '@ngxp/rest';
+
+export interface AggregationMapping {
+  formIdentifier: FormIdentifier;
+  mappings: FieldMapping[];
+}
+
+export interface FormIdentifier {
+  formEngineName: string;
+  formId: string;
+}
+
+export interface FieldMapping {
+  sourcePath: string;
+  targetPath: string;
+}
+
+export interface AggregationMappingResource extends AggregationMapping, Resource {}
+export interface AggregationMappingListResource extends ListResource {}
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.provider.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.provider.ts
new file mode 100644
index 0000000000000000000000000000000000000000..888d7154e81dbfe53fb7476e4de8835463de6d25
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.provider.ts
@@ -0,0 +1,17 @@
+import { ResourceRepository } from '@alfa-client/tech-shared';
+import { Provider } from '@angular/core';
+import { ConfigurationService } from 'libs/admin/configuration-shared/src/lib/configuration.service';
+import {
+  AggregationMappingListResourceService,
+  createAggregationMappingResourceService,
+} from './aggregation-mapping-resource.service';
+import { AggregationMappingService } from './aggregation-mapping.service';
+
+export const AggregationMappingProvider: Provider[] = [
+  {
+    provide: AggregationMappingListResourceService,
+    useFactory: createAggregationMappingResourceService,
+    deps: [ResourceRepository, ConfigurationService],
+  },
+  AggregationMappingService,
+];
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ecf4387ceee6a3dbdd6775f8ef4fa3a306144002
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts
@@ -0,0 +1,79 @@
+import { StateResource, createStateResource } from '@alfa-client/tech-shared';
+import { Mock, mock } from '@alfa-client/test-utils';
+import { TestBed } from '@angular/core/testing';
+import { singleCold } from 'libs/tech-shared/test/marbles';
+import { Observable } from 'rxjs';
+import {
+  createAggregationMapping,
+  createAggregationMappingListResource,
+  createAggregationMappingResource,
+} from '../../test/aggregation-mapping';
+import { AggregationMappingListResourceService } from './aggregation-mapping-resource.service';
+import { AggregationMapping, AggregationMappingListResource, AggregationMappingResource } from './aggregation-mapping.model';
+import { AggregationMappingService } from './aggregation-mapping.service';
+
+describe('AggregationMappingService', () => {
+  let service: AggregationMappingService;
+  let listResourceService: Mock<AggregationMappingListResourceService>;
+
+  beforeEach(() => {
+    listResourceService = mock(AggregationMappingListResourceService);
+
+    TestBed.configureTestingModule({
+      providers: [AggregationMappingService, { provide: AggregationMappingListResourceService, useValue: listResourceService }],
+    });
+
+    service = TestBed.inject(AggregationMappingService);
+  });
+
+  it('should create', () => {
+    expect(service).toBeTruthy();
+  });
+
+  describe('get list', () => {
+    const aggregationMappingListResource: AggregationMappingListResource = createAggregationMappingListResource();
+    const aggregationMappingListStateResource: StateResource<AggregationMappingListResource> =
+      createStateResource(aggregationMappingListResource);
+
+    beforeEach(() => {
+      listResourceService.getList = jest.fn().mockReturnValue(singleCold(aggregationMappingListStateResource));
+    });
+
+    it('should call listResourceService', () => {
+      service.getList();
+
+      expect(listResourceService.getList).toHaveBeenCalled();
+    });
+
+    it('should return value', () => {
+      const loadedAggregationMappingListResource: Observable<StateResource<AggregationMappingListResource>> = service.getList();
+
+      expect(loadedAggregationMappingListResource).toBeObservable(singleCold(aggregationMappingListStateResource));
+    });
+  });
+
+  describe('create', () => {
+    const aggregationMappingResource: AggregationMappingResource = createAggregationMappingResource();
+    const aggregationMappingStateResource: StateResource<AggregationMappingResource> =
+      createStateResource(aggregationMappingResource);
+
+    const aggregationMapping: AggregationMapping = createAggregationMapping();
+
+    beforeEach(() => {
+      listResourceService.create = jest.fn().mockReturnValue(singleCold(aggregationMappingStateResource));
+    });
+
+    it('should call resourceService', () => {
+      service.create(aggregationMapping);
+
+      expect(listResourceService.create).toHaveBeenCalledWith(aggregationMapping);
+    });
+
+    it('should return value', () => {
+      const loadedAggregationMappingResource: Observable<StateResource<AggregationMappingResource>> =
+        service.create(aggregationMapping);
+
+      expect(loadedAggregationMappingResource).toBeObservable(singleCold(aggregationMappingStateResource));
+    });
+  });
+});
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..20a8ce6c1ccda133323bac99a671d887e77afb8e
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts
@@ -0,0 +1,18 @@
+import { StateResource } from '@alfa-client/tech-shared';
+import { Injectable, inject } from '@angular/core';
+import { Observable } from 'rxjs';
+import { AggregationMappingListResourceService } from './aggregation-mapping-resource.service';
+import { AggregationMapping, AggregationMappingListResource, AggregationMappingResource } from './aggregation-mapping.model';
+
+@Injectable()
+export class AggregationMappingService {
+  readonly listService = inject(AggregationMappingListResourceService);
+
+  public getList(): Observable<StateResource<AggregationMappingListResource>> {
+    return this.listService.getList();
+  }
+
+  public create(toCreate: AggregationMapping): Observable<StateResource<AggregationMappingResource>> {
+    return this.listService.create(toCreate);
+  }
+}
diff --git a/alfa-client/libs/admin/reporting-shared/src/test-setup.ts b/alfa-client/libs/admin/reporting-shared/src/test-setup.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c408668266d2fec3a9803c0ec044bc163fb987fe
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/src/test-setup.ts
@@ -0,0 +1,12 @@
+import '@testing-library/jest-dom';
+import 'jest-preset-angular/setup-jest';
+
+import { getTestBed } from '@angular/core/testing';
+import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
+
+getTestBed().resetTestEnvironment();
+getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
+  teardown: { destroyAfterEach: false },
+  errorOnUnknownProperties: true,
+  errorOnUnknownElements: true,
+});
diff --git a/alfa-client/libs/admin/reporting-shared/test/aggregation-mapping.ts b/alfa-client/libs/admin/reporting-shared/test/aggregation-mapping.ts
new file mode 100644
index 0000000000000000000000000000000000000000..acbcc9fa75722396e4a410ea77e9157a2a8ce8fc
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/test/aggregation-mapping.ts
@@ -0,0 +1,35 @@
+import { faker } from '@faker-js/faker';
+import { times } from 'lodash-es';
+import { LinkRelationName } from '../../../tech-shared/src';
+import { toResource } from '../../../tech-shared/test/resource';
+import { AggregationMapping, AggregationMappingListResource, AggregationMappingResource } from '../src';
+import { AggregationMappingListLinkRel } from '../src/lib/aggregation-mapping.linkrel';
+
+export function createAggregationMapping(): AggregationMapping {
+  return {
+    formIdentifier: {
+      formEngineName: faker.lorem.word(),
+      formId: faker.string.uuid(),
+    },
+    mappings: [
+      {
+        sourcePath: faker.lorem.word(),
+        targetPath: faker.lorem.word(),
+      },
+    ],
+  };
+}
+
+export function createAggregationMappingResource(linkRelations: LinkRelationName[] = []): AggregationMappingResource {
+  return toResource(createAggregationMapping(), linkRelations);
+}
+
+export function createAggregationMappingResources(linkRelations: LinkRelationName[] = []): AggregationMappingResource[] {
+  return times(10, () => createAggregationMappingResource(linkRelations));
+}
+
+export function createAggregationMappingListResource(linkRelations: LinkRelationName[] = []): AggregationMappingListResource {
+  return toResource({}, linkRelations, {
+    [AggregationMappingListLinkRel.LIST]: createAggregationMappingResources(),
+  });
+}
diff --git a/alfa-client/libs/admin/reporting-shared/tsconfig.json b/alfa-client/libs/admin/reporting-shared/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..8ca9ad312c2bd4dc364383853ddd91a2ed8f86fd
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/tsconfig.json
@@ -0,0 +1,16 @@
+{
+  "extends": "../../../tsconfig.base.json",
+  "files": [],
+  "include": [],
+  "references": [
+    {
+      "path": "./tsconfig.lib.json"
+    },
+    {
+      "path": "./tsconfig.spec.json"
+    }
+  ],
+  "compilerOptions": {
+    "target": "es2022"
+  }
+}
diff --git a/alfa-client/libs/admin/reporting-shared/tsconfig.lib.json b/alfa-client/libs/admin/reporting-shared/tsconfig.lib.json
new file mode 100644
index 0000000000000000000000000000000000000000..8441346f6e5858b2ef4235cb3c3160eda256f94a
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/tsconfig.lib.json
@@ -0,0 +1,12 @@
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "outDir": "../../../dist/out-tsc",
+    "declaration": true,
+    "declarationMap": true,
+    "inlineSources": true,
+    "types": []
+  },
+  "exclude": ["src/**/*.spec.ts", "src/test-setup.ts", "jest.config.ts", "src/**/*.test.ts"],
+  "include": ["src/**/*.ts"]
+}
diff --git a/alfa-client/libs/admin/reporting-shared/tsconfig.spec.json b/alfa-client/libs/admin/reporting-shared/tsconfig.spec.json
new file mode 100644
index 0000000000000000000000000000000000000000..723782fbd367969806c5992aea882773ab65af8b
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/tsconfig.spec.json
@@ -0,0 +1,12 @@
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "outDir": "../../../dist/out-tsc",
+    "module": "commonjs",
+    "types": ["jest", "node"],
+    "target": "ES2022",
+    "useDefineForClassFields": false
+  },
+  "files": ["src/test-setup.ts"],
+  "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts", "jest.config.ts"]
+}
diff --git a/alfa-client/libs/admin/settings-shared/jest.config.ts b/alfa-client/libs/admin/settings-shared/jest.config.ts
index e9e4c0e81848959b2203b3551b8a0e999c127500..9c940034939a689a0f138e47d5c3a5c34d2bb92e 100644
--- a/alfa-client/libs/admin/settings-shared/jest.config.ts
+++ b/alfa-client/libs/admin/settings-shared/jest.config.ts
@@ -1,9 +1,8 @@
 export default {
-  displayName: 'admin-settings',
+  displayName: 'admin-settings-shared',
   preset: '../../../jest.preset.js',
   setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
-  globals: {},
-  coverageDirectory: '../../coverage/libs/admin/settings-shared',
+  coverageDirectory: '../../../coverage/libs/admin/settings-shared',
   transform: {
     '^.+\\.(ts|mjs|js|html)$': [
       'jest-preset-angular',
@@ -13,7 +12,7 @@ export default {
       },
     ],
   },
-  transformIgnorePatterns: ['node_modules/(?!.pnpm|.*\\.mjs$)'],
+  transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
   snapshotSerializers: [
     'jest-preset-angular/build/serializers/no-ng-attributes',
     'jest-preset-angular/build/serializers/ng-snapshot',
diff --git a/alfa-client/libs/admin/settings-shared/project.json b/alfa-client/libs/admin/settings-shared/project.json
index 702a27446f83db42dc97ec9409c8f3d323dcbb65..02e461c6816868190ac3b45dea543a934a1d6d1d 100644
--- a/alfa-client/libs/admin/settings-shared/project.json
+++ b/alfa-client/libs/admin/settings-shared/project.json
@@ -1,15 +1,11 @@
 {
-  "name": "admin-settings",
+  "name": "admin-settings-shared",
   "$schema": "../../../node_modules/nx/schemas/project-schema.json",
   "sourceRoot": "libs/admin/settings-shared/src",
-  "projectType": "library",
   "prefix": "admin",
+  "projectType": "library",
   "tags": [],
   "targets": {
-    "lint": {
-      "executor": "@nx/eslint:lint",
-      "outputs": ["{options.outputFile}"]
-    },
     "test": {
       "executor": "@nx/jest:jest",
       "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
@@ -17,6 +13,10 @@
         "tsConfig": "libs/admin/settings-shared/tsconfig.spec.json",
         "jestConfig": "libs/admin/settings-shared/jest.config.ts"
       }
+    },
+    "lint": {
+      "executor": "@nx/eslint:lint",
+      "outputs": ["{options.outputFile}"]
     }
   }
 }
diff --git a/alfa-client/libs/admin/settings-shared/src/lib/settings-resource.service.ts b/alfa-client/libs/admin/settings-shared/src/lib/settings-resource.service.ts
index a75f91afec901a8c969c00ede9a8631766421f1f..7e9df14e6ec13929f720978ada7ebcb3e74c5ef9 100644
--- a/alfa-client/libs/admin/settings-shared/src/lib/settings-resource.service.ts
+++ b/alfa-client/libs/admin/settings-shared/src/lib/settings-resource.service.ts
@@ -4,7 +4,11 @@ import { Resource } from '@ngxp/rest';
 import { SettingListLinkRel } from './settings.linkrel';
 import { SettingItemResource, SettingListResource } from './settings.model';
 
-export class SettingListResourceService extends ResourceListService<Resource, SettingListResource, SettingItemResource> {}
+export class SettingListResourceService extends ResourceListService<
+  Resource,
+  SettingListResource,
+  SettingItemResource<unknown>
+> {}
 
 export function createSettingListResourceService(repository: ResourceRepository, configurationService: ConfigurationService) {
   return new ResourceListService(buildConfig(configurationService), repository);
diff --git a/alfa-client/libs/admin/settings-shared/src/lib/settings.model.ts b/alfa-client/libs/admin/settings-shared/src/lib/settings.model.ts
index 263fca126d53eb889e1701e931a8b32a38899145..2e97584b7934ea105c828cbb2523c0d16ce431a1 100644
--- a/alfa-client/libs/admin/settings-shared/src/lib/settings.model.ts
+++ b/alfa-client/libs/admin/settings-shared/src/lib/settings.model.ts
@@ -25,16 +25,16 @@ import { ListResource } from '@alfa-client/tech-shared';
 import { Resource } from '@ngxp/rest';
 
 export interface SettingListResource extends ListResource {
-  _embedded: { settings: SettingItemResource[] };
+  _embedded: { settings: SettingItemResource<unknown>[] };
 }
 
 export enum SettingName {
   POSTFACH = 'Postfach',
 }
 
-export interface SettingItem {
+export interface SettingItem<T> {
   name: SettingName;
-  settingBody: unknown;
+  settingBody: T;
 }
 
-export declare type SettingItemResource = Resource & SettingItem;
+export interface SettingItemResource<T> extends SettingItem<T>, Resource {}
diff --git a/alfa-client/libs/admin/settings-shared/src/lib/settings.service.spec.ts b/alfa-client/libs/admin/settings-shared/src/lib/settings.service.spec.ts
index 9b24d56767a9f5de93f738638d976333cfa93af7..1cf23c357186c0480ce12a349497c2c1f66139e5 100644
--- a/alfa-client/libs/admin/settings-shared/src/lib/settings.service.spec.ts
+++ b/alfa-client/libs/admin/settings-shared/src/lib/settings.service.spec.ts
@@ -21,16 +21,14 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { PostfachResource } from '@admin-client/postfach-shared';
 import { StateResource, createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared';
 import { Mock, mock } from '@alfa-client/test-utils';
 import { TestBed } from '@angular/core/testing';
 import { singleCold } from 'libs/tech-shared/test/marbles';
 import { Observable, of } from 'rxjs';
-import { createPostfachResource, createSettingItemResource } from '../../../postfach-shared/src/test/postfach';
-import { createSettingsListResource } from '../../test/settings';
+import { createSettingItemResource, createSettingsListResource } from '../../test/settings';
 import { SettingListResourceService } from './settings-resource.service';
-import { SettingListResource } from './settings.model';
+import { SettingItemResource, SettingListResource, SettingName } from './settings.model';
 import { SettingsService } from './settings.service';
 
 describe('SettingsService', () => {
@@ -51,11 +49,12 @@ describe('SettingsService', () => {
     expect(service).toBeTruthy();
   });
 
-  describe('get Postfach', () => {
-    const postfachResource = createPostfachResource();
-    const postfachStateResource: StateResource<PostfachResource> = createStateResource(postfachResource);
+  describe('get by setting name', () => {
+    const settingItemName: SettingName = <SettingName>'DUMMY';
+    const settingItemResource: SettingItemResource<unknown> = { ...createSettingItemResource(), name: settingItemName };
+    const settingItemStateResource: StateResource<SettingItemResource<unknown>> = createStateResource(settingItemResource);
     const settingsListResource: StateResource<SettingListResource> = createStateResource(
-      createSettingsListResource([postfachResource]),
+      createSettingsListResource([settingItemResource]),
     );
 
     beforeEach(() => {
@@ -63,28 +62,28 @@ describe('SettingsService', () => {
     });
 
     it('should call resource service', () => {
-      service.getPostfach();
+      service.get(settingItemName);
 
       expect(settingListResourceService.getList).toHaveBeenCalled();
     });
 
-    it('should return null for non postfach resource', () => {
+    it('should return null for non existing setting item resource', () => {
       const emptySettingsListResource: StateResource<SettingListResource> = createStateResource(
         createSettingsListResource([createSettingItemResource()]),
       );
-
       settingListResourceService.getList = jest.fn().mockReturnValue(singleCold(emptySettingsListResource));
 
-      const postfach: Observable<StateResource<PostfachResource>> = service.getPostfach();
-      expect(postfach).toBeObservable(singleCold(createEmptyStateResource()));
+      const settingItemStateResource$: Observable<StateResource<SettingItemResource<unknown>>> = service.get(settingItemName);
+
+      expect(settingItemStateResource$).toBeObservable(singleCold(createEmptyStateResource()));
     });
 
-    it('should return item resource as postfach resource', () => {
+    it('should return item resource as setting item resource', () => {
       settingListResourceService.getList = jest.fn().mockReturnValue(singleCold(settingsListResource));
 
-      const postfach: Observable<StateResource<PostfachResource>> = service.getPostfach();
+      const settingItemStateResource$: Observable<StateResource<SettingItemResource<unknown>>> = service.get(settingItemName);
 
-      expect(postfach).toBeObservable(singleCold(postfachStateResource));
+      expect(settingItemStateResource$).toBeObservable(singleCold(settingItemStateResource));
     });
   });
 });
diff --git a/alfa-client/libs/admin/settings-shared/src/lib/settings.service.ts b/alfa-client/libs/admin/settings-shared/src/lib/settings.service.ts
index 51faa2be7ea9aa2a9f878de233ad56d32ec0f81c..770c9d7da6230f67e7d92c553e97e062277b5994 100644
--- a/alfa-client/libs/admin/settings-shared/src/lib/settings.service.ts
+++ b/alfa-client/libs/admin/settings-shared/src/lib/settings.service.ts
@@ -1,15 +1,17 @@
-import { PostfachResource } from '@admin-client/postfach-shared';
 import { StateResource } from '@alfa-client/tech-shared';
 import { inject, Injectable } from '@angular/core';
 import { map, Observable } from 'rxjs';
 import { SettingListResourceService } from './settings-resource.service';
-import { getPostfachResource } from './settings.util';
+import { SettingItemResource, SettingListResource, SettingName } from './settings.model';
+import { getSettingItemResource } from './settings.util';
 
 @Injectable()
 export class SettingsService {
   private settingListResourceService = inject(SettingListResourceService);
 
-  public getPostfach(): Observable<StateResource<PostfachResource>> {
-    return this.settingListResourceService.getList().pipe(map(getPostfachResource));
+  public get<T>(name: SettingName): Observable<StateResource<SettingItemResource<T>>> {
+    return this.settingListResourceService
+      .getList()
+      .pipe(map((list: StateResource<SettingListResource>) => getSettingItemResource<T>(list, name)));
   }
 }
diff --git a/alfa-client/libs/admin/settings-shared/src/lib/settings.util.spec.ts b/alfa-client/libs/admin/settings-shared/src/lib/settings.util.spec.ts
index 5b78df34aa506c8180878416054cd11bb4164d14..fe8480f147ba265070096e70d6fe54f817324397 100644
--- a/alfa-client/libs/admin/settings-shared/src/lib/settings.util.spec.ts
+++ b/alfa-client/libs/admin/settings-shared/src/lib/settings.util.spec.ts
@@ -21,30 +21,31 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { PostfachResource } from '@admin-client/postfach-shared';
-import { SettingListResource } from '@admin-client/settings-shared';
 import { createEmptyStateResource, createStateResource, StateResource } from '@alfa-client/tech-shared';
-import { createPostfachResource } from 'libs/admin/postfach-shared/src/test/postfach';
-import { createFilledSettingsListResource } from '../../test/settings';
-import { getPostfachResource } from './settings.util';
+import { Resource } from '@ngxp/rest';
+import { createFilledSettingsListResource, createSettingItemResource } from '../../test/settings';
+import { SettingItemResource, SettingListResource, SettingName } from './settings.model';
+import { getSettingItemResource } from './settings.util';
 
-describe('get postfach resource', () => {
-  it('should return state resource with postfach resource if exists', () => {
-    const postfachResource: PostfachResource = createPostfachResource();
+describe('get setting item resource', () => {
+  const settingName: SettingName = <SettingName>'DUMMY';
+
+  it('should return matching setting resource as state resource if exists', () => {
+    const settingItemResource: SettingItemResource<unknown> = { ...createSettingItemResource(), name: settingName };
     const settingsListResource: StateResource<SettingListResource> = createStateResource(
-      createFilledSettingsListResource([postfachResource]),
+      createFilledSettingsListResource([settingItemResource]),
     );
 
-    const postfachStateResource: StateResource<PostfachResource> = getPostfachResource(settingsListResource);
+    const stateResource: StateResource<Resource> = getSettingItemResource(settingsListResource, settingName);
 
-    expect(postfachStateResource.resource).toEqual(postfachResource);
+    expect(stateResource.resource).toEqual(settingItemResource);
   });
 
-  it('should return empty state resource if postfach resource NOT exists', () => {
+  it('should return empty state resource if no matching resource exists', () => {
     const settingsListResource: StateResource<SettingListResource> = createStateResource(createFilledSettingsListResource([]));
 
-    const postfachStateResource: StateResource<PostfachResource> = getPostfachResource(settingsListResource);
+    const stateResource: StateResource<Resource> = getSettingItemResource(settingsListResource, settingName);
 
-    expect(postfachStateResource).toEqual(createEmptyStateResource());
+    expect(stateResource).toEqual(createEmptyStateResource());
   });
 });
diff --git a/alfa-client/libs/admin/settings-shared/src/lib/settings.util.ts b/alfa-client/libs/admin/settings-shared/src/lib/settings.util.ts
index d5cf7605cada028e253a26d1e3641eee5856e2c7..2a00f86b2a84fef05b45ccfde06c3ff8a6321745 100644
--- a/alfa-client/libs/admin/settings-shared/src/lib/settings.util.ts
+++ b/alfa-client/libs/admin/settings-shared/src/lib/settings.util.ts
@@ -21,7 +21,6 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { PostfachResource } from '@admin-client/postfach-shared';
 import {
   createEmptyStateResource,
   createStateResource,
@@ -32,14 +31,11 @@ import {
 import { SettingListLinkRel } from './settings.linkrel';
 import { SettingItemResource, SettingListResource, SettingName } from './settings.model';
 
-export function getPostfachResource(settingsListResource: StateResource<SettingListResource>): StateResource<PostfachResource> {
-  const entries: SettingItemResource[] = getEmbeddedResources(settingsListResource, SettingListLinkRel.LIST);
-  const postfachSettingItemResource: SettingItemResource = entries.find(isPostfachSettingItem);
-  return isNotNil(postfachSettingItemResource) ?
-      createStateResource(postfachSettingItemResource as PostfachResource)
-    : createEmptyStateResource();
-}
-
-function isPostfachSettingItem(item: SettingItemResource): boolean {
-  return item.name === SettingName.POSTFACH;
+export function getSettingItemResource<T>(
+  settingsListResource: StateResource<SettingListResource>,
+  itemName: SettingName,
+): StateResource<SettingItemResource<T>> {
+  const entries: SettingItemResource<T>[] = getEmbeddedResources(settingsListResource, SettingListLinkRel.LIST);
+  const entry: SettingItemResource<T> = entries.find((item: SettingItemResource<T>) => item.name === itemName);
+  return isNotNil(entry) ? createStateResource(entry) : createEmptyStateResource<SettingItemResource<T>>();
 }
diff --git a/alfa-client/libs/admin/settings-shared/test/settings.ts b/alfa-client/libs/admin/settings-shared/test/settings.ts
index c3b9478ea57d373b18ad6315c0e5161fd7d9b008..a7bf1ded5bac477efcce579bd74f1646d8664a2d 100644
--- a/alfa-client/libs/admin/settings-shared/test/settings.ts
+++ b/alfa-client/libs/admin/settings-shared/test/settings.ts
@@ -1,9 +1,10 @@
+import { faker } from '@faker-js/faker/.';
 import { Resource } from '@ngxp/rest';
 import { toResource } from 'libs/tech-shared/test/resource';
 import { SettingListLinkRel } from '../src/lib/settings.linkrel';
 import { SettingItemResource, SettingListResource } from '../src/lib/settings.model';
 
-export function createSettingsListResource(settingsItems: SettingItemResource[]): SettingListResource {
+export function createSettingsListResource(settingsItems: SettingItemResource<unknown>[]): SettingListResource {
   return toResource({}, [], {
     settings: settingsItems,
   });
@@ -14,3 +15,10 @@ export function createFilledSettingsListResource(resources: Resource[], linkRela
     [SettingListLinkRel.LIST]: resources,
   });
 }
+
+export function createSettingItemResource(): SettingItemResource<unknown> {
+  return toResource({
+    name: faker.word.sample(),
+    settingBody: {},
+  });
+}
diff --git a/alfa-client/libs/admin/shared/src/index.ts b/alfa-client/libs/admin/shared/src/index.ts
index ece2c025dc3e05d4b26ad131fc7e419331e301d2..8f0992f8376dfb02cbd0096e33f516ac819f3d97 100644
--- a/alfa-client/libs/admin/shared/src/index.ts
+++ b/alfa-client/libs/admin/shared/src/index.ts
@@ -1 +1,4 @@
+export * from './lib/admin-cancel-button/admin-cancel-button.component';
+export * from './lib/admin-save-button/admin-save-button.component';
 export * from './lib/routes';
+export * from './lib/token';
diff --git a/alfa-client/libs/admin/shared/src/lib/admin-cancel-button/admin-cancel-button.component.html b/alfa-client/libs/admin/shared/src/lib/admin-cancel-button/admin-cancel-button.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..3125fbdfd9242e48e3a30a5891e445bb6d8b8498
--- /dev/null
+++ b/alfa-client/libs/admin/shared/src/lib/admin-cancel-button/admin-cancel-button.component.html
@@ -0,0 +1,3 @@
+<ods-routing-button [linkPath]="linkPath" text="Abbrechen" variant="outline" dataTestId="cancel-button">
+  <ods-close-icon icon class="fill-primary" />
+</ods-routing-button>
diff --git a/alfa-client/libs/admin/shared/src/lib/admin-cancel-button/admin-cancel-button.component.spec.ts b/alfa-client/libs/admin/shared/src/lib/admin-cancel-button/admin-cancel-button.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..253650b230fb8be30ddb854fe3ad62351b058e5b
--- /dev/null
+++ b/alfa-client/libs/admin/shared/src/lib/admin-cancel-button/admin-cancel-button.component.spec.ts
@@ -0,0 +1,36 @@
+import { AdminCancelButtonComponent } from '@admin-client/shared';
+import { getMockComponent } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RoutingButtonComponent } from '@ods/component';
+import { CloseIconComponent } from '@ods/system';
+import { MockComponent } from 'ng-mocks';
+
+describe('AdminCancelButtonComponent', () => {
+  let component: AdminCancelButtonComponent;
+  let fixture: ComponentFixture<AdminCancelButtonComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [AdminCancelButtonComponent],
+      declarations: [MockComponent(RoutingButtonComponent), MockComponent(CloseIconComponent)],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(AdminCancelButtonComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('button', () => {
+    it('should be called with linkPath', () => {
+      component.linkPath = 'dummyLinkPath';
+
+      fixture.detectChanges();
+
+      expect(getMockComponent(fixture, RoutingButtonComponent).linkPath).toBe('dummyLinkPath');
+    });
+  });
+});
diff --git a/alfa-client/libs/admin/shared/src/lib/admin-cancel-button/admin-cancel-button.component.ts b/alfa-client/libs/admin/shared/src/lib/admin-cancel-button/admin-cancel-button.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8c284f05c61e3d545025c8447d4d302a0fc3db85
--- /dev/null
+++ b/alfa-client/libs/admin/shared/src/lib/admin-cancel-button/admin-cancel-button.component.ts
@@ -0,0 +1,14 @@
+import { CommonModule } from '@angular/common';
+import { Component, Input } from '@angular/core';
+import { RoutingButtonComponent } from '@ods/component';
+import { CloseIconComponent } from '@ods/system';
+
+@Component({
+  selector: 'admin-cancel-button',
+  templateUrl: './admin-cancel-button.component.html',
+  standalone: true,
+  imports: [CommonModule, RoutingButtonComponent, CloseIconComponent],
+})
+export class AdminCancelButtonComponent {
+  @Input() linkPath: string;
+}
diff --git a/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.html b/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..8bd6a5f92932e22006b3b8e2cb353a9c3fa93eb1
--- /dev/null
+++ b/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.html
@@ -0,0 +1,6 @@
+<ods-button-with-spinner
+  (clickEmitter)="submit()"
+  text="Speichern"
+  dataTestId="save-button"
+  [stateResource]="stateResource$ | async"
+/>
diff --git a/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.spec.ts b/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..52a303f378e824677dd6518126ae838ebd416e3a
--- /dev/null
+++ b/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.spec.ts
@@ -0,0 +1,71 @@
+import { ADMIN_FORMSERVICE } from '@admin-client/shared';
+import { AbstractFormService, createStateResource, StateResource } from '@alfa-client/tech-shared';
+import { dispatchEventFromFixture, getMockComponent, Mock, MockEvent } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { Resource } from '@ngxp/rest';
+import { ButtonWithSpinnerComponent } from '@ods/component';
+import { getDataTestIdAttributeOf } from 'libs/tech-shared/test/data-test';
+import { singleCold } from 'libs/tech-shared/test/marbles';
+import { createDummyResource } from 'libs/tech-shared/test/resource';
+import { MockComponent } from 'ng-mocks';
+import { of } from 'rxjs';
+import { AdminSaveButtonComponent } from './admin-save-button.component';
+
+describe('AdminSaveButtonComponent', () => {
+  let component: AdminSaveButtonComponent;
+  let fixture: ComponentFixture<AdminSaveButtonComponent>;
+
+  let formService: Mock<AbstractFormService<Resource>>;
+
+  const saveButton: string = getDataTestIdAttributeOf('save-button');
+
+  const stateResource: StateResource<Resource> = createStateResource(createDummyResource());
+
+  beforeEach(async () => {
+    formService = <any>{ submit: jest.fn().mockReturnValue(singleCold(stateResource)) };
+
+    await TestBed.configureTestingModule({
+      imports: [AdminSaveButtonComponent],
+      declarations: [MockComponent(ButtonWithSpinnerComponent)],
+      providers: [
+        {
+          provide: ADMIN_FORMSERVICE,
+          useValue: formService,
+        },
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(AdminSaveButtonComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('on submit', () => {
+    it('should call formService', () => {
+      dispatchEventFromFixture(fixture, saveButton, MockEvent.CLICK);
+
+      expect(formService.submit).toHaveBeenCalled();
+    });
+
+    it('should assign state resource', () => {
+      dispatchEventFromFixture(fixture, saveButton, MockEvent.CLICK);
+
+      expect(component.stateResource$).toBeObservable(singleCold(stateResource));
+    });
+  });
+
+  describe('button', () => {
+    it('should call with stateResource', () => {
+      component.stateResource$ = of(stateResource);
+
+      fixture.detectChanges();
+
+      const comp: ButtonWithSpinnerComponent = getMockComponent(fixture, ButtonWithSpinnerComponent);
+      expect(comp.stateResource).toBe(stateResource);
+    });
+  });
+});
diff --git a/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.ts b/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..60abd08c7f311ecabe6d56ecc47fbfcd16412877
--- /dev/null
+++ b/alfa-client/libs/admin/shared/src/lib/admin-save-button/admin-save-button.component.ts
@@ -0,0 +1,23 @@
+import { ADMIN_FORMSERVICE } from '@admin-client/shared';
+import { AbstractFormService, createEmptyStateResource, StateResource } from '@alfa-client/tech-shared';
+import { CommonModule } from '@angular/common';
+import { Component, inject } from '@angular/core';
+import { Resource } from '@ngxp/rest';
+import { ButtonWithSpinnerComponent } from '@ods/component';
+import { Observable, of } from 'rxjs';
+
+@Component({
+  selector: 'admin-save-button',
+  standalone: true,
+  imports: [CommonModule, ButtonWithSpinnerComponent],
+  templateUrl: './admin-save-button.component.html',
+})
+export class AdminSaveButtonComponent {
+  private formService: AbstractFormService<Resource> = inject(ADMIN_FORMSERVICE);
+
+  public stateResource$: Observable<StateResource<Resource>> = of(createEmptyStateResource<Resource>());
+
+  public submit(): void {
+    this.stateResource$ = this.formService.submit();
+  }
+}
diff --git a/alfa-client/libs/admin/shared/src/lib/token.ts b/alfa-client/libs/admin/shared/src/lib/token.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f19e2c875946591ba08470c654f91c80664176aa
--- /dev/null
+++ b/alfa-client/libs/admin/shared/src/lib/token.ts
@@ -0,0 +1,5 @@
+import { AbstractFormService } from '@alfa-client/tech-shared';
+import { InjectionToken } from '@angular/core';
+import { Resource } from '@ngxp/rest';
+
+export const ADMIN_FORMSERVICE = new InjectionToken<AbstractFormService<Resource>>('adminFormService');
diff --git a/alfa-client/libs/admin/statistik/src/index.ts b/alfa-client/libs/admin/statistik/src/index.ts
index cdc5d7b64f24d50920b721f3ab01c5b69cb41b99..157271feb3bf8625864f12faec9623307c3b7690 100644
--- a/alfa-client/libs/admin/statistik/src/index.ts
+++ b/alfa-client/libs/admin/statistik/src/index.ts
@@ -1 +1,2 @@
 export * from './lib/statistik-container/statistik-container.component';
+export * from './lib/statistik-fields-form/admin-statistik-fields-form.component';
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html
index 77c10ae229f5d8c6430d82349d6f2d213fa72054..1fd0441a39d71372d0c65fd84d0ce5386ac52fd2 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html
@@ -24,10 +24,12 @@
 
 -->
 <h1 class="heading-1" data-test-id="statistik-header-text">Statistik</h1>
-<div class="mt-4">
-  <ods-button
+<div class="mt-4 w-fit">
+  <ods-routing-button
+    [linkPath]="ROUTES.STATISTIK_NEU"
     text="Weitere Felder auswerten"
-    (clickEmitter)="navigateToStatistikFieldsForm()"
     dataTestId="weitere-felder-auswerten-button"
-  ></ods-button>
+  ></ods-routing-button>
 </div>
+
+<ng-container *ngIf="listStateResource$ | async"></ng-container>
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts
index b4390c03face2557262e05f6964e02dc40e4cd7a..a2bc7e4bfe5efdec1af21b9ad1da7deaccf1a21f 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.spec.ts
@@ -21,11 +21,15 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { ROUTES } from '@admin-client/shared';
-import { NavigationService } from '@alfa-client/navigation-shared';
-import { existsAsHtmlElement, mock, Mock, triggerEvent } from '@alfa-client/test-utils';
+import { AggregationMappingListResource, AggregationMappingService } from '@admin-client/reporting-shared';
+import { createStateResource, StateResource } from '@alfa-client/tech-shared';
+import { existsAsHtmlElement, mock, Mock } from '@alfa-client/test-utils';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RoutingButtonComponent } from '@ods/component';
+import { singleCold } from 'libs/tech-shared/test/marbles';
+import { MockComponent } from 'ng-mocks';
 import { getDataTestIdAttributeOf } from '../../../../../tech-shared/test/data-test';
+import { createAggregationMappingListResource } from '../../../../reporting-shared/test/aggregation-mapping';
 import { StatistikContainerComponent } from './statistik-container.component';
 
 describe('StatistikContainerComponent', () => {
@@ -34,43 +38,34 @@ describe('StatistikContainerComponent', () => {
 
   const evaluateAdditionalFieldsTestId: string = getDataTestIdAttributeOf('weitere-felder-auswerten-button');
 
-  let navigationService: Mock<NavigationService>;
-
-  beforeEach(() => {
-    navigationService = mock(NavigationService);
-  });
+  let aggregationMappingService: Mock<AggregationMappingService>;
 
   beforeEach(async () => {
+    aggregationMappingService = mock(AggregationMappingService);
+
     await TestBed.configureTestingModule({
       imports: [StatistikContainerComponent],
-      providers: [
-        {
-          provide: NavigationService,
-          useValue: navigationService,
+      declarations: [MockComponent(RoutingButtonComponent)],
+    })
+      .overrideComponent(StatistikContainerComponent, {
+        set: {
+          providers: [
+            {
+              provide: AggregationMappingService,
+              useValue: aggregationMappingService,
+            },
+          ],
         },
-      ],
-    });
-  });
+      })
+      .compileComponents();
 
-  beforeEach(() => {
     fixture = TestBed.createComponent(StatistikContainerComponent);
     component = fixture.componentInstance;
-
     fixture.detectChanges();
   });
 
-  describe('component', () => {
-    it('should create', () => {
-      expect(component).toBeTruthy();
-    });
-
-    describe('navigateToStatistikFieldsForm', () => {
-      it('should call navigation service', () => {
-        component.navigateToStatistikFieldsForm();
-
-        expect(navigationService.navigate).toHaveBeenCalledWith(ROUTES.STATISTIK_NEU);
-      });
-    });
+  it('should create', () => {
+    expect(component).toBeTruthy();
   });
 
   describe('template', () => {
@@ -80,23 +75,28 @@ describe('StatistikContainerComponent', () => {
 
         existsAsHtmlElement(fixture, evaluateAdditionalFieldsTestId);
       });
+    });
+  });
 
-      describe('output', () => {
-        describe('clickEmitter', () => {
-          it('should call handler', () => {
-            component.navigateToStatistikFieldsForm = jest.fn();
-            fixture.detectChanges();
+  describe('on init', () => {
+    const stateResource: StateResource<AggregationMappingListResource> = createStateResource(
+      createAggregationMappingListResource(),
+    );
 
-            triggerEvent({
-              fixture,
-              elementSelector: evaluateAdditionalFieldsTestId,
-              name: 'clickEmitter',
-            });
+    beforeEach(() => {
+      aggregationMappingService.getList.mockReturnValue(singleCold(stateResource));
+    });
 
-            expect(component.navigateToStatistikFieldsForm).toHaveBeenCalled();
-          });
-        });
-      });
+    it('should call service to get list', () => {
+      component.ngOnInit();
+
+      expect(aggregationMappingService.getList).toHaveBeenCalled();
+    });
+
+    it('should assign stateResource', () => {
+      component.ngOnInit();
+
+      expect(component.listStateResource$).toBeObservable(singleCold(stateResource));
     });
   });
 });
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts
index a00051de29e86232f267891b6f6c8324a726993a..90c3515896348b1c1d6ee77ba4f247428e79c4bf 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.ts
@@ -21,22 +21,29 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
+import { AggregationMappingListResource, AggregationMappingService } from '@admin-client/reporting-shared';
 import { ROUTES } from '@admin-client/shared';
-import { NavigationService } from '@alfa-client/navigation-shared';
+import { StateResource } from '@alfa-client/tech-shared';
 import { CommonModule } from '@angular/common';
-import { Component, inject } from '@angular/core';
-import { ButtonComponent } from '@ods/system';
+import { Component, inject, OnInit } from '@angular/core';
+import { RoutingButtonComponent } from '@ods/component';
+import { Observable } from 'rxjs';
 
 @Component({
   selector: 'admin-statistik-container',
   templateUrl: './statistik-container.component.html',
   standalone: true,
-  imports: [CommonModule, ButtonComponent],
+  imports: [CommonModule, RoutingButtonComponent],
+  providers: [AggregationMappingService],
 })
-export class StatistikContainerComponent {
-  private readonly navigationService = inject(NavigationService);
+export class StatistikContainerComponent implements OnInit {
+  private service = inject(AggregationMappingService);
 
-  public navigateToStatistikFieldsForm(): void {
-    this.navigationService.navigate(ROUTES.STATISTIK_NEU);
+  public listStateResource$: Observable<StateResource<AggregationMappingListResource>>;
+
+  public readonly ROUTES = ROUTES;
+
+  ngOnInit(): void {
+    this.listStateResource$ = this.service.getList();
   }
 }
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.html b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.html
index cef302fc15f148000041c0c968f1ccbefc446e83..27805c87fe074bae41311083bc1aed20d5aaeaef 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.html
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.html
@@ -1,37 +1,29 @@
 <h2 class="heading-2" data-test-id="statistik-fields-form-header-text">Felder zur Auswertung hinzufügen</h2>
 
 <div class="flex max-w-4xl flex-col gap-4">
-  <ods-text-input
-    [fieldControl]="formEngineFormControl"
-    label="Formengine"
-    placeholder="Tragen Sie hier die Formengine des Formulars ein."
-    data-test-id="form-engine-input"
-  ></ods-text-input>
-
-  <ods-text-input
-    [fieldControl]="formIdFormControl"
-    label="FormID"
-    placeholder="Tragen Sie hier die FormID des Formulars ein."
-    data-test-id="form-id-input"
-  ></ods-text-input>
-
-  @for (dataFieldControl of dataFieldsFormControls; track $index) {
-    <ods-text-input
-      [fieldControl]="dataFieldControl"
-      label="Pfad des Datenfeldes"
-      placeholder="Tragen Sie hier den gesamten Pfad des Datenfeldes ein, das Sie auswerten möchten."
-      [attr.data-test-id]="'data-statistik-field-' + $index"
-    ></ods-text-input>
-  }
-
-  <ods-button text="Datenfeld hinzufügen" (clickEmitter)="addDataField()" dataTestId="add-data-field-button">
-    <ods-plus-icon icon class="fill-whitetext"/>
+  <form class="form flex-col" [formGroup]="formService.form" class="flex flex-col gap-4">
+    <div [formGroupName]="StatistikFieldsFormService.FIELD_FORM_IDENTIFIER" class="flex flex-col gap-4">
+      <ods-text-editor
+        [formControlName]="StatistikFieldsFormService.FIELD_FORM_ENGINE_NAME"
+        label="Formengine"
+        placeholder="Tragen Sie hier die Formengine des Formulars ein."
+        data-test-id="form-engine-name-input"
+      ></ods-text-editor>
+      <ods-text-editor
+        [formControlName]="StatistikFieldsFormService.FIELD_FORM_ID"
+        label="FormID"
+        placeholder="Tragen Sie hier die FormID des Formulars ein."
+        data-test-id="form-id-input"
+      ></ods-text-editor>
+    </div>
+    <statistik-fields-form-mapping />
+  </form>
+  <ods-button text="Datenfeld hinzufügen" dataTestId="add-mapping-button" (clickEmitter)="formService.addMapping()">
+    <ods-plus-icon icon class="fill-whitetext" />
   </ods-button>
 
   <div class="mt-4 flex gap-4">
-    <ods-button text="Speichern" dataTestId="save-statistik-fields-button"></ods-button>
-    <ods-button text="Abbrechen" variant="outline" (clickEmitter)="onCancel()" dataTestId="cancel-statistik-fields-button">
-      <ods-close-icon icon class="fill-primary"/>
-    </ods-button>
+    <admin-save-button />
+    <admin-cancel-button [linkPath]="Routes.STATISTIK" />
   </div>
 </div>
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.spec.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.spec.ts
index 54502497cd68edcdec0876e2aad378126c2c28e3..a0154fd3137315cfbfd12187d70f0ffb43635df5 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.spec.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.spec.ts
@@ -1,86 +1,75 @@
-import { ROUTES } from '@admin-client/shared';
-import { NavigationService } from '@alfa-client/navigation-shared';
-import { existsAsHtmlElement, getElementComponentFromFixtureByCss, mock, Mock, triggerEvent } from '@alfa-client/test-utils';
+import { ADMIN_FORMSERVICE } from '@admin-client/shared';
+import { EMPTY_STRING } from '@alfa-client/tech-shared';
+import { dispatchEventFromFixture, existsAsHtmlElement, mock, Mock, MockEvent } from '@alfa-client/test-utils';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { FormBuilder } from '@angular/forms';
-import { TextInputComponent } from '@ods/system';
+import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
+import { TextEditorComponent } from '@ods/component';
+import { ButtonComponent, PlusIconComponent } from '@ods/system';
+import { MockComponent } from 'ng-mocks';
 import { getDataTestIdAttributeOf, getDataTestIdOf } from '../../../../../tech-shared/test/data-test';
+import { AdminCancelButtonComponent } from '../../../../shared/src/lib/admin-cancel-button/admin-cancel-button.component';
+import { AdminSaveButtonComponent } from '../../../../shared/src/lib/admin-save-button/admin-save-button.component';
 import { AdminStatistikFieldsFormComponent } from './admin-statistik-fields-form.component';
+import { AdminStatistikFieldsFormMappingComponent } from './statistik-fields-form-mapping/statistik-fields-form-mapping.component';
 import { StatistikFieldsFormService } from './statistik-fields.formservice';
 
 describe('AdminStatistikFieldsFormComponent', () => {
   let component: AdminStatistikFieldsFormComponent;
   let fixture: ComponentFixture<AdminStatistikFieldsFormComponent>;
 
-  const formEngineInputTestId: string = getDataTestIdOf('form-engine-input');
+  const formEngineNameInputTestId: string = getDataTestIdOf('form-engine-name-input');
   const formIdInputTestId: string = getDataTestIdOf('form-id-input');
-  const addDataFieldButtonTestId: string = getDataTestIdAttributeOf('add-data-field-button');
-  const saveButtonTestId: string = getDataTestIdAttributeOf('save-statistik-fields-button');
-  const cancelButtonTestId: string = getDataTestIdAttributeOf('cancel-statistik-fields-button');
-  const dataField1TestId: string = getDataTestIdOf('data-statistik-field-0');
+  const addMappingButton: string = getDataTestIdAttributeOf('add-mapping-button');
 
-  let formService: StatistikFieldsFormService;
-  let navigationService: Mock<NavigationService>;
+  const formBuilder: FormBuilder = new FormBuilder();
 
-  beforeEach(() => {
-    formService = new StatistikFieldsFormService(new FormBuilder());
-    navigationService = mock(NavigationService);
-  });
+  let formService: Mock<StatistikFieldsFormService>;
 
   beforeEach(async () => {
-    TestBed.overrideComponent(AdminStatistikFieldsFormComponent, {
-      set: {
-        providers: [
-          {
-            provide: StatistikFieldsFormService,
-            useValue: formService,
-          },
-          {
-            provide: NavigationService,
-            useValue: navigationService,
-          },
-        ],
-      },
+    const form: FormGroup = formBuilder.group({
+      [StatistikFieldsFormService.FIELD_FORM_IDENTIFIER]: formBuilder.group({
+        [StatistikFieldsFormService.FIELD_FORM_ENGINE_NAME]: new FormControl(EMPTY_STRING),
+        [StatistikFieldsFormService.FIELD_FORM_ID]: new FormControl(EMPTY_STRING),
+      }),
     });
 
+    formService = <any>{ ...mock(StatistikFieldsFormService), form };
+
     await TestBed.configureTestingModule({
-      imports: [AdminStatistikFieldsFormComponent],
-      providers: [{ provide: StatistikFieldsFormService, useValue: formService }],
-    }).compileComponents();
+      declarations: [
+        AdminStatistikFieldsFormComponent,
+        MockComponent(TextEditorComponent),
+        MockComponent(ButtonComponent),
+        MockComponent(PlusIconComponent),
+        MockComponent(AdminSaveButtonComponent),
+        MockComponent(AdminCancelButtonComponent),
+        MockComponent(AdminStatistikFieldsFormMappingComponent),
+      ],
+      imports: [ReactiveFormsModule],
+    })
+      .overrideComponent(AdminStatistikFieldsFormComponent, {
+        set: {
+          providers: [
+            {
+              provide: StatistikFieldsFormService,
+              useValue: formService,
+            },
+            {
+              provide: ADMIN_FORMSERVICE,
+              useValue: formService,
+            },
+          ],
+        },
+      })
+      .compileComponents();
 
     fixture = TestBed.createComponent(AdminStatistikFieldsFormComponent);
     component = fixture.componentInstance;
     fixture.detectChanges();
   });
 
-  describe('component', () => {
-    it('should create', () => {
-      expect(component).toBeTruthy();
-    });
-
-    it('should set form controls', () => {
-      expect(component.formEngineFormControl).toBeDefined();
-      expect(component.formIdFormControl).toBeDefined();
-      expect(component.dataFieldsFormControls).toBeDefined();
-    });
-
-    describe('addDataField', () => {
-      it('should call form service', () => {
-        formService.addDataField = jest.fn();
-
-        component.addDataField();
-
-        expect(formService.addDataField).toHaveBeenCalled();
-      });
-    });
-
-    describe('onCancel', () => {
-      it('should call navigation service', () => {
-        component.onCancel();
-
-        expect(navigationService.navigate).toHaveBeenCalledWith(ROUTES.STATISTIK);
-      });
-    });
+  it('should create', () => {
+    expect(component).toBeTruthy();
   });
 
   describe('template', () => {
@@ -88,18 +77,7 @@ describe('AdminStatistikFieldsFormComponent', () => {
       it('should exists', () => {
         fixture.detectChanges();
 
-        existsAsHtmlElement(fixture, formEngineInputTestId);
-      });
-
-      it('should have been called with inputs', () => {
-        fixture.detectChanges();
-
-        const formEngineInput: TextInputComponent = getElementComponentFromFixtureByCss<TextInputComponent>(
-          fixture,
-          formEngineInputTestId,
-        );
-
-        expect(formEngineInput.fieldControl).toEqual(component.formEngineFormControl);
+        existsAsHtmlElement(fixture, formEngineNameInputTestId);
       });
     });
 
@@ -109,91 +87,23 @@ describe('AdminStatistikFieldsFormComponent', () => {
 
         existsAsHtmlElement(fixture, formIdInputTestId);
       });
-
-      it('should have been called with inputs', () => {
-        fixture.detectChanges();
-
-        const formIdInput: TextInputComponent = getElementComponentFromFixtureByCss<TextInputComponent>(
-          fixture,
-          formIdInputTestId,
-        );
-
-        expect(formIdInput.fieldControl).toEqual(component.formIdFormControl);
-      });
-    });
-
-    describe('data field input', () => {
-      it('should exists', () => {
-        fixture.detectChanges();
-
-        existsAsHtmlElement(fixture, dataField1TestId);
-      });
-
-      it('should have been called with inputs', () => {
-        fixture.detectChanges();
-
-        const dataFieldInput: TextInputComponent = getElementComponentFromFixtureByCss<TextInputComponent>(
-          fixture,
-          dataField1TestId,
-        );
-
-        expect(dataFieldInput.fieldControl).toEqual(component.dataFieldsFormControls[0]);
-      });
-    });
-
-    describe('add data field button', () => {
-      it('should exists', () => {
-        fixture.detectChanges();
-
-        existsAsHtmlElement(fixture, addDataFieldButtonTestId);
-      });
-
-      describe('output', () => {
-        describe('clickEmitter', () => {
-          it('should call handler', () => {
-            fixture.detectChanges();
-            component.addDataField = jest.fn();
-
-            triggerEvent({
-              fixture,
-              elementSelector: addDataFieldButtonTestId,
-              name: 'clickEmitter',
-            });
-
-            expect(component.addDataField).toHaveBeenCalled();
-          });
-        });
-      });
-    });
-
-    describe('save button', () => {
-      it('should exists', () => {
-        fixture.detectChanges();
-
-        existsAsHtmlElement(fixture, saveButtonTestId);
-      });
     });
 
-    describe('cancel button', () => {
+    describe('add mapping button', () => {
       it('should exists', () => {
         fixture.detectChanges();
 
-        existsAsHtmlElement(fixture, cancelButtonTestId);
+        existsAsHtmlElement(fixture, addMappingButton);
       });
 
       describe('output', () => {
         describe('clickEmitter', () => {
-          it('should call handler', () => {
-            component.onCancel = jest.fn();
+          it('should call formService', () => {
             fixture.detectChanges();
 
-            triggerEvent({
-              fixture,
-              elementSelector: cancelButtonTestId,
-              name: 'clickEmitter',
-            });
+            dispatchEventFromFixture(fixture, addMappingButton, MockEvent.CLICK);
 
-            expect(component.onCancel).toHaveBeenCalled();
+            expect(formService.addMapping).toHaveBeenCalled();
           });
         });
       });
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.ts
index 59d083f34a2f5f727734c29c02f6b8de13c7d2d6..0298196202e623a3d080468c792f3c1c800a8750 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/admin-statistik-fields-form.component.ts
@@ -1,37 +1,30 @@
-import { ROUTES } from '@admin-client/shared';
-import { NavigationService } from '@alfa-client/navigation-shared';
-import { CommonModule } from '@angular/common';
+import { ADMIN_FORMSERVICE, AdminCancelButtonComponent, AdminSaveButtonComponent, ROUTES } from '@admin-client/shared';
 import { Component, inject } from '@angular/core';
-import { FormArray, FormControl, ReactiveFormsModule } from '@angular/forms';
-import { ButtonComponent, CloseIconComponent, PlusIconComponent, TextInputComponent } from '@ods/system';
+import { ReactiveFormsModule } from '@angular/forms';
+import { TextEditorComponent } from '@ods/component';
+import { ButtonComponent, DeleteIconComponent, PlusIconComponent } from '@ods/system';
+import { AdminStatistikFieldsFormMappingComponent } from './statistik-fields-form-mapping/statistik-fields-form-mapping.component';
 import { StatistikFieldsFormService } from './statistik-fields.formservice';
 
 @Component({
   selector: 'admin-statistik-fields-form',
-  standalone: true,
-  imports: [CommonModule, TextInputComponent, ButtonComponent, CloseIconComponent, ReactiveFormsModule, PlusIconComponent],
-  providers: [StatistikFieldsFormService],
   templateUrl: './admin-statistik-fields-form.component.html',
+  standalone: true,
+  imports: [
+    ButtonComponent,
+    PlusIconComponent,
+    ReactiveFormsModule,
+    TextEditorComponent,
+    DeleteIconComponent,
+    AdminSaveButtonComponent,
+    AdminCancelButtonComponent,
+    AdminStatistikFieldsFormMappingComponent,
+  ],
+  providers: [{ provide: ADMIN_FORMSERVICE, useClass: StatistikFieldsFormService }],
 })
 export class AdminStatistikFieldsFormComponent {
-  private readonly formService = inject(StatistikFieldsFormService);
-  private readonly navigationService = inject(NavigationService);
-
-  public readonly formEngineFormControl: FormControl = this.formService.form.controls[
-    StatistikFieldsFormService.FIELD_FORM_ENGINE
-  ] as FormControl;
-  public readonly formIdFormControl: FormControl = this.formService.form.controls[
-    StatistikFieldsFormService.FIELD_FORM_ID
-  ] as FormControl;
-  public readonly dataFieldsFormControls: FormControl[] = (
-    this.formService.form.controls[StatistikFieldsFormService.FIELD_DATA_FIELDS] as FormArray
-  ).controls as FormControl[];
-
-  public addDataField(): void {
-    this.formService.addDataField();
-  }
+  public readonly formService = <StatistikFieldsFormService>inject(ADMIN_FORMSERVICE);
 
-  public onCancel(): void {
-    this.navigationService.navigate(ROUTES.STATISTIK);
-  }
+  public readonly StatistikFieldsFormService = StatistikFieldsFormService;
+  public readonly Routes = ROUTES;
 }
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form-mapping/statistik-fields-form-mapping.component.html b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form-mapping/statistik-fields-form-mapping.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..2ce86b545b1039b795911cf172f154b9e2b97871
--- /dev/null
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form-mapping/statistik-fields-form-mapping.component.html
@@ -0,0 +1,27 @@
+<form [formGroup]="formService.form">
+  <div class="flex flex-col gap-4" [formArrayName]="StatistikFieldsFormService.FIELD_MAPPINGS">
+    <div
+      *ngFor="let mappingControl of formService.mappings.controls; let i = index"
+      [formGroupName]="i"
+      class="flex w-full gap-2"
+    >
+      <ods-text-editor
+        class="flex-1"
+        formControlName="sourcePath"
+        label="Pfad des Datenfeldes"
+        placeholder="Tragen Sie hier den gesamten Pfad des Datenfeldes ein, das Sie auswerten möchten."
+        [attr.data-test-id]="'mapping-field-' + i"
+      ></ods-text-editor>
+      <ods-button
+        class="self-end"
+        variant="ghost"
+        size="fit"
+        destructive="true"
+        (clickEmitter)="formService.removeMapping(i)"
+        [dataTestId]="'remove-mapping-button-' + i"
+      >
+        <ods-delete-icon icon />
+      </ods-button>
+    </div>
+  </div>
+</form>
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form-mapping/statistik-fields-form-mapping.component.spec.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form-mapping/statistik-fields-form-mapping.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..61cd006e429951cde3657be7688b30063cc2e6eb
--- /dev/null
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form-mapping/statistik-fields-form-mapping.component.spec.ts
@@ -0,0 +1,90 @@
+import { ADMIN_FORMSERVICE } from '@admin-client/shared';
+import { EMPTY_STRING } from '@alfa-client/tech-shared';
+import { dispatchEventFromFixture, existsAsHtmlElement, mock, Mock, MockEvent, mockGetValue } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
+import { TextEditorComponent } from '@ods/component';
+import { ButtonComponent, DeleteIconComponent } from '@ods/system';
+import { getDataTestIdOf, getDynamicDataTestIdAttributOf } from 'libs/tech-shared/test/data-test';
+import { MockComponent } from 'ng-mocks';
+import { StatistikFieldsFormService } from '../statistik-fields.formservice';
+import { AdminStatistikFieldsFormMappingComponent } from './statistik-fields-form-mapping.component';
+
+describe('AdminStatistikFieldsFormMappingComponent', () => {
+  let component: AdminStatistikFieldsFormMappingComponent;
+  let fixture: ComponentFixture<AdminStatistikFieldsFormMappingComponent>;
+
+  const mappingField: string = getDataTestIdOf('mapping-field-0');
+  const removeMappingButton: string = getDynamicDataTestIdAttributOf('remove-mapping-button-0');
+
+  const formBuilder: FormBuilder = new FormBuilder();
+
+  let formService: Mock<StatistikFieldsFormService>;
+
+  beforeEach(async () => {
+    const form: FormGroup = formBuilder.group({
+      [StatistikFieldsFormService.FIELD_MAPPINGS]: formBuilder.array([
+        new FormGroup({ sourcePath: new FormControl(EMPTY_STRING) }),
+      ]),
+    });
+
+    formService = <any>{
+      ...mock(StatistikFieldsFormService),
+      form,
+      addMapping: jest.fn(),
+      removeMapping: jest.fn(),
+    };
+
+    mockGetValue(
+      formService,
+      StatistikFieldsFormService.FIELD_MAPPINGS,
+      form.controls[StatistikFieldsFormService.FIELD_MAPPINGS],
+    );
+
+    await TestBed.configureTestingModule({
+      declarations: [
+        AdminStatistikFieldsFormMappingComponent,
+        MockComponent(TextEditorComponent),
+        MockComponent(ButtonComponent),
+        MockComponent(DeleteIconComponent),
+      ],
+      imports: [ReactiveFormsModule],
+      providers: [
+        {
+          provide: StatistikFieldsFormService,
+          useValue: formService,
+        },
+        {
+          provide: ADMIN_FORMSERVICE,
+          useValue: formService,
+        },
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(AdminStatistikFieldsFormMappingComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('template', () => {
+    describe('mapping input', () => {
+      it('should exists', () => {
+        fixture.detectChanges();
+
+        existsAsHtmlElement(fixture, mappingField);
+      });
+    });
+
+    describe('remove mapping button', () => {
+      it('should call formservice', () => {
+        dispatchEventFromFixture(fixture, removeMappingButton, MockEvent.CLICK);
+
+        expect(formService.removeMapping).toHaveBeenCalledWith(0);
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form-mapping/statistik-fields-form-mapping.component.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form-mapping/statistik-fields-form-mapping.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..48bc3eaddd2a2fe51b983939dd8920b02e7f8dae
--- /dev/null
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form-mapping/statistik-fields-form-mapping.component.ts
@@ -0,0 +1,29 @@
+import { ADMIN_FORMSERVICE, AdminCancelButtonComponent, AdminSaveButtonComponent, ROUTES } from '@admin-client/shared';
+import { CommonModule } from '@angular/common';
+import { Component, inject } from '@angular/core';
+import { ReactiveFormsModule } from '@angular/forms';
+import { TextEditorComponent } from '@ods/component';
+import { ButtonComponent, DeleteIconComponent, PlusIconComponent } from '@ods/system';
+import { StatistikFieldsFormService } from '../statistik-fields.formservice';
+
+@Component({
+  selector: 'statistik-fields-form-mapping',
+  templateUrl: './statistik-fields-form-mapping.component.html',
+  standalone: true,
+  imports: [
+    CommonModule,
+    ButtonComponent,
+    PlusIconComponent,
+    ReactiveFormsModule,
+    TextEditorComponent,
+    DeleteIconComponent,
+    AdminSaveButtonComponent,
+    AdminCancelButtonComponent,
+  ],
+})
+export class AdminStatistikFieldsFormMappingComponent {
+  public readonly formService = <StatistikFieldsFormService>inject(ADMIN_FORMSERVICE);
+
+  public readonly StatistikFieldsFormService = StatistikFieldsFormService;
+  public readonly Routes = ROUTES;
+}
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.spec.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..58a2273cb692762c4f930e583c8c49f210099517
--- /dev/null
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.spec.ts
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+import { AggregationMappingResource, AggregationMappingService } from '@admin-client/reporting-shared';
+import { EMPTY_STRING, StateResource, createStateResource } from '@alfa-client/tech-shared';
+import { Mock, mock } from '@alfa-client/test-utils';
+import { TestBed } from '@angular/core/testing';
+import { FormArray, FormControl, FormGroup } from '@angular/forms';
+import { createAggregationMapping, createAggregationMappingResource } from 'libs/admin/reporting-shared/test/aggregation-mapping';
+import { of } from 'rxjs';
+import { StatistikFieldsFormService } from './statistik-fields.formservice';
+
+describe('StatistikFieldsFormService', () => {
+  let formService: StatistikFieldsFormService;
+
+  let service: Mock<AggregationMappingService>;
+
+  beforeEach(() => {
+    service = mock(AggregationMappingService);
+
+    TestBed.configureTestingModule({
+      providers: [StatistikFieldsFormService, { provide: AggregationMappingService, useValue: service }],
+    });
+
+    formService = TestBed.inject(StatistikFieldsFormService);
+  });
+
+  it('should create', () => {
+    expect(formService).toBeTruthy();
+  });
+
+  describe('on do submit', () => {
+    const stateResource: StateResource<AggregationMappingResource> = createStateResource(createAggregationMappingResource());
+
+    beforeEach(() => {
+      service.create.mockReturnValue(of(stateResource));
+    });
+
+    it('should call service', () => {
+      formService.form = <any>createAggregationMapping();
+
+      formService.submit();
+
+      expect(service.create).toHaveBeenCalledWith(formService.form.value);
+    });
+  });
+
+  describe('add mapping', () => {
+    it('should add mapping control', () => {
+      formService.addMapping();
+
+      const mappingFormArray: FormArray = <FormArray>formService.form.controls[StatistikFieldsFormService.FIELD_MAPPINGS];
+      expect(mappingFormArray).toHaveLength(2);
+      expect(mappingFormArray.controls[0].value).toEqual({ sourcePath: EMPTY_STRING });
+    });
+  });
+
+  describe('remove mapping', () => {
+    it('should remove mapping control', () => {
+      (<FormArray>formService.form.controls[StatistikFieldsFormService.FIELD_MAPPINGS]).push(
+        new FormGroup({ sourcePath: new FormControl('controlToRemove') }),
+      );
+
+      formService.removeMapping(1);
+
+      const mappingFormArray: FormArray = <FormArray>formService.form.controls[StatistikFieldsFormService.FIELD_MAPPINGS];
+      expect(mappingFormArray).toHaveLength(1);
+      expect(mappingFormArray.controls[0].value).toEqual({ sourcePath: EMPTY_STRING });
+    });
+  });
+
+  describe('get mappings', () => {
+    it('should return mappings as array', () => {
+      const mappings: FormArray = formService.mappings;
+
+      expect(mappings).toHaveLength(1);
+      expect(mappings.controls[0].value).toEqual({ sourcePath: EMPTY_STRING });
+    });
+  });
+});
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts
index 229a7147d1b785c937d46c45c3ae65070a8b2608..1b746e12f42b44cc1261ce6de543380ea61d9ec4 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts
@@ -1,32 +1,50 @@
+import { AggregationMappingResource, AggregationMappingService } from '@admin-client/reporting-shared';
 import { AbstractFormService, EMPTY_STRING, StateResource } from '@alfa-client/tech-shared';
-import { Injectable } from '@angular/core';
-import { FormArray, FormControl, UntypedFormGroup } from '@angular/forms';
-import { Resource } from '@ngxp/rest';
-import { EMPTY, Observable } from 'rxjs';
+import { inject, Injectable } from '@angular/core';
+import { FormArray, FormControl, FormGroup, UntypedFormGroup } from '@angular/forms';
+import { Observable } from 'rxjs';
 
 @Injectable()
-export class StatistikFieldsFormService extends AbstractFormService<Resource> {
-  public static readonly FIELD_FORM_ENGINE: string = 'formEngine';
+export class StatistikFieldsFormService extends AbstractFormService<AggregationMappingResource> {
+  private service = inject(AggregationMappingService);
+
+  public static readonly FIELD_FORM_IDENTIFIER: string = 'formIdentifier';
+  public static readonly FIELD_FORM_ENGINE_NAME: string = 'formEngineName';
   public static readonly FIELD_FORM_ID: string = 'formId';
-  public static readonly FIELD_DATA_FIELDS: string = 'dataFields';
+
+  public static readonly FIELD_MAPPINGS: string = 'mappings';
 
   protected initForm(): UntypedFormGroup {
     return this.formBuilder.group({
-      [StatistikFieldsFormService.FIELD_FORM_ENGINE]: new FormControl(EMPTY_STRING),
-      [StatistikFieldsFormService.FIELD_FORM_ID]: new FormControl(EMPTY_STRING),
-      [StatistikFieldsFormService.FIELD_DATA_FIELDS]: new FormArray([new FormControl(EMPTY_STRING)]),
+      [StatistikFieldsFormService.FIELD_FORM_IDENTIFIER]: this.formBuilder.group({
+        [StatistikFieldsFormService.FIELD_FORM_ENGINE_NAME]: new FormControl(EMPTY_STRING),
+        [StatistikFieldsFormService.FIELD_FORM_ID]: new FormControl(EMPTY_STRING),
+      }),
+      [StatistikFieldsFormService.FIELD_MAPPINGS]: new FormArray([this.createArrayControl()]),
     });
   }
 
-  protected doSubmit(): Observable<StateResource<Resource>> {
-    return EMPTY;
+  protected doSubmit(): Observable<StateResource<AggregationMappingResource>> {
+    return this.service.create(this.getFormValue());
   }
 
   protected getPathPrefix(): string {
     return 'settingBody';
   }
 
-  public addDataField(): void {
-    (this.form.controls[StatistikFieldsFormService.FIELD_DATA_FIELDS] as FormArray).push(new FormControl(EMPTY_STRING));
+  public addMapping(): void {
+    this.mappings.push(this.createArrayControl());
+  }
+
+  private createArrayControl(): FormGroup {
+    return new FormGroup({ sourcePath: new FormControl(EMPTY_STRING) });
+  }
+
+  public removeMapping(index: number): void {
+    this.mappings.removeAt(index);
+  }
+
+  public get mappings(): FormArray {
+    return this.form.controls[StatistikFieldsFormService.FIELD_MAPPINGS] as FormArray;
   }
 }
diff --git a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.html b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.html
index bffb14da6bda5e9ae083f25f445a12b3d6854ae5..153e3e19deecd0653b83ae9fc7e516f85b6a8716 100644
--- a/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.html
+++ b/alfa-client/libs/admin/user/src/lib/user-list-container/user-list/user-list.component.html
@@ -24,9 +24,9 @@
 
 -->
 <h1 class="heading-1 mb-4">Benutzer & Rollen</h1>
-<ods-routing-button [linkPath]="ROUTES.BENUTZER_NEU" text="Benutzer hinzufügen" class="mb-4" dataTestId="add-user-button" />
+<ods-routing-button [linkPath]="ROUTES.BENUTZER_NEU" text="Benutzer hinzufügen" class="mb-4 w-fit" dataTestId="add-user-button" />
 <ods-list>
   @for (user of usersStateResource.resource; track $index) {
     <admin-user [user]="user" class="block w-full" />
   }
-</ods-list>
\ No newline at end of file
+</ods-list>
diff --git a/alfa-client/libs/authentication/src/lib/http-unauthorized.interceptor.spec.ts b/alfa-client/libs/authentication/src/lib/http-unauthorized.interceptor.spec.ts
index bf426ac9299c13c5440929e9b54d276e35f6be8e..8e32931929aab5f151b00cc4b14b3aaacc5c9142 100644
--- a/alfa-client/libs/authentication/src/lib/http-unauthorized.interceptor.spec.ts
+++ b/alfa-client/libs/authentication/src/lib/http-unauthorized.interceptor.spec.ts
@@ -22,12 +22,12 @@
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
 import { Mock, mock } from '@alfa-client/test-utils';
+import { HttpErrorResponse, HttpHandler, HttpRequest } from '@angular/common/http';
 import { TestBed } from '@angular/core/testing';
 import { MatDialogModule } from '@angular/material/dialog';
-import { HttpUnauthorizedInterceptor } from './http-unauthorized.interceptor';
-import { HttpErrorResponse, HttpHandler, HttpRequest } from '@angular/common/http';
 import { Subject, isEmpty } from 'rxjs';
 import { AuthenticationService } from './authentication.service';
+import { HttpUnauthorizedInterceptor } from './http-unauthorized.interceptor';
 
 describe('HttpUnauthorizedInterceptor', () => {
   let interceptor: HttpUnauthorizedInterceptor;
@@ -96,7 +96,7 @@ describe('HttpUnauthorizedInterceptor', () => {
     it('should rethrow error if not unauthorized status', () => {
       const anyError: any = new HttpErrorResponse({ status: 500 });
 
-      expect(() => interceptor.handleError(anyError)).toThrowError();
+      expect(() => interceptor.handleError(anyError)).toThrow();
     });
   });
 });
diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts
index d799453d615d41bd0e21b7940461d59c7131adf0..ab845cf6b4f7e3156ebb7a940e418780e9a410d2 100644
--- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts
+++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts
@@ -23,6 +23,7 @@
  */
 import { BinaryFileListResource, BinaryFileResource, BinaryFileService } from '@alfa-client/binary-file-shared';
 import { CommandOrder, CommandResource, CommandService, CreateCommandProps } from '@alfa-client/command-shared';
+import { PostfachService } from '@alfa-client/postfach-shared';
 import {
   ApiError,
   EMPTY_ARRAY,
@@ -80,7 +81,6 @@ import { BescheidService } from './bescheid.service';
 import { DocumentLinkRel } from './document.linkrel';
 import { DocumentResource } from './document.model';
 
-import { PostfachService } from '@alfa-client/postfach-shared';
 import * as DateUtil from '../../../tech-shared/src/lib/date.util';
 import * as BescheidUtil from './bescheid.util';
 
@@ -89,7 +89,7 @@ describe('BescheidService', () => {
 
   let facade: Mock<BescheidFacade>;
   let vorgangService: Mock<VorgangService>;
-  let resourceRepository: Mock<ResourceRepository>;
+  let resourceRepository: Mock<ResourceRepository<BescheidResource>>;
   let commandService: Mock<CommandService>;
   let vorgangCommandService: Mock<VorgangCommandService>;
   let binaryFileService: Mock<BinaryFileService>;
diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
index 3426c36b0868b332b4324580b8eadf6fcbab37f0..7b8a2f737d688302a3a9f30e218b126a9fad285e 100644
--- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
+++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
@@ -124,7 +124,7 @@ export class BescheidService {
     private readonly commandService: CommandService,
     private readonly vorgangCommandService: VorgangCommandService,
     private readonly binaryFileService: BinaryFileService,
-    private readonly repository: ResourceRepository,
+    private readonly repository: ResourceRepository<BescheidResource>,
     private readonly postfachService: PostfachService,
   ) {
     this.bescheidResourceService = new CommandResourceService(
@@ -132,7 +132,11 @@ export class BescheidService {
       repository,
       this.commandService,
     );
-    this.bescheidListResourceService = new ResourceListService(this.buildBescheidListServiceConfig(), repository);
+    this.bescheidListResourceService = new ResourceListService<
+      VorgangWithEingangResource,
+      BescheidListResource,
+      BescheidResource
+    >(this.buildBescheidListServiceConfig(), repository);
   }
 
   public getActiveStep(): Observable<BescheidWizardStep> {
diff --git a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration.request.formservice.spec.ts b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration.request.formservice.spec.ts
index 9af26540fdf4031d434bcb3d4000e2a3f56d3c96..d5726c77529ec251188d2323565ad95742986a58 100644
--- a/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration.request.formservice.spec.ts
+++ b/alfa-client/libs/collaboration/src/lib/collaboration-in-vorgang-container/collaboration-request-form/collaboration.request.formservice.spec.ts
@@ -22,11 +22,11 @@
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
 import { CollaborationListResource } from '@alfa-client/collaboration-shared';
-import { SnackBarService } from '@alfa-client/ui';
-import { TestBed } from '@angular/core/testing';
 import { CommandLinkRel, CommandResource } from '@alfa-client/command-shared';
 import { StateResource, createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared';
-import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
+import { Mock, mock } from '@alfa-client/test-utils';
+import { SnackBarService } from '@alfa-client/ui';
+import { TestBed } from '@angular/core/testing';
 import { UntypedFormBuilder } from '@angular/forms';
 import { CollaborationService } from 'libs/collaboration-shared/src/lib/collaboration.service';
 import { createCollaborationListResource } from 'libs/collaboration-shared/test/collaboration';
@@ -57,7 +57,6 @@ describe('CollaborationRequestFormService', () => {
     });
 
     formService = TestBed.inject(CollaborationRequestFormService);
-    TestBed.inject(CollaborationRequestFormService);
   });
 
   it('should create', () => {
diff --git a/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts b/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts
index 200b8572a2ed3faccb5d14a2346e085ca8262024..c7640cb221008d78f73dd470ae9d3f10287d4bcb 100644
--- a/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts
+++ b/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts
@@ -74,13 +74,13 @@ describe('CommandResourceService', () => {
 
   describe('doSave', () => {
     it('should throw error', () => {
-      expect(() => service.doSave(configResource, {})).toThrowError('Method not implemented.');
+      expect(() => service.doSave(configResource, {})).toThrow('Method not implemented.');
     });
   });
 
   describe('doPatch', () => {
     it('should throw error', () => {
-      expect(() => service.doPatch(configResource, {})).toThrowError('Method not implemented.');
+      expect(() => service.doPatch(configResource, {})).toThrow('Method not implemented.');
     });
   });
 
diff --git a/alfa-client/libs/design-component/src/lib/routing-button/routing-button.component.ts b/alfa-client/libs/design-component/src/lib/routing-button/routing-button.component.ts
index 2a25cd22e5df3e74e404a3fd986d737b29ab5a2c..98346f3903e1cff4b363c5f4f4dc49243ce84c7d 100644
--- a/alfa-client/libs/design-component/src/lib/routing-button/routing-button.component.ts
+++ b/alfa-client/libs/design-component/src/lib/routing-button/routing-button.component.ts
@@ -1,22 +1,26 @@
 import { CommonModule } from '@angular/common';
 import { Component, Input } from '@angular/core';
 import { RouterLink } from '@angular/router';
+import { ButtonVariants, buttonVariants } from '@ods/system';
 
 @Component({
   selector: 'ods-routing-button',
   standalone: true,
   imports: [CommonModule, RouterLink],
   host: { class: 'block' },
-  template: `<a
-    [routerLink]="'/' + linkPath"
-    [attr.data-test-id]="dataTestId"
-    class="block min-h-9 w-fit min-w-32 rounded bg-primary px-4 py-2 text-sm font-medium text-white shadow-sm outline-focus hover:bg-primary-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
-  >
-    {{ text }}
+  template: `<a [routerLink]="'/' + linkPath" [attr.data-test-id]="dataTestId" [ngClass]="buttonVariants({ size, variant })">
+    <ng-content select="[icon]" />
+    @if (text) {
+      <p class="flex-grow">{{ text }}</p>
+    }
   </a>`,
 })
 export class RoutingButtonComponent {
   @Input() linkPath: string;
   @Input() text: string;
   @Input() dataTestId: string;
+  @Input() variant: ButtonVariants['variant'];
+  @Input() size: ButtonVariants['size'];
+
+  readonly buttonVariants = buttonVariants;
 }
diff --git a/alfa-client/libs/design-system/src/index.ts b/alfa-client/libs/design-system/src/index.ts
index 467032047c06e4ae9c4a6e3948cc13a704b8761d..e7ae662925633f6c656ce0c64ba919debf94b774 100644
--- a/alfa-client/libs/design-system/src/index.ts
+++ b/alfa-client/libs/design-system/src/index.ts
@@ -52,6 +52,7 @@ export * from './lib/icons/bescheid-upload-icon/bescheid-upload-icon.component';
 export * from './lib/icons/check-circle-icon/check-circle-icon.component';
 export * from './lib/icons/check-icon/check-icon.component';
 export * from './lib/icons/close-icon/close-icon.component';
+export * from './lib/icons/delete-icon/delete-icon.component';
 export * from './lib/icons/delete-vorgang-finally-icon/delete-vorgang-finally-icon.component';
 export * from './lib/icons/discard-vorgang-icon/discard-vorgang-icon.component';
 export * from './lib/icons/edit-icon/edit-icon.component';
diff --git a/alfa-client/libs/design-system/src/lib/button/button.component.ts b/alfa-client/libs/design-system/src/lib/button/button.component.ts
index 46b0308c205dff5a889142e76693dd27cffc30bb..15a9b7efdc261b462f3dade0f93b2a6902e36507 100644
--- a/alfa-client/libs/design-system/src/lib/button/button.component.ts
+++ b/alfa-client/libs/design-system/src/lib/button/button.component.ts
@@ -64,22 +64,24 @@ export const buttonVariants = cva(
       {
         variant: 'primary',
         destructive: true,
-        class: '[&]:hover:enabled:bg-destructive-primary-hover [&]:bg-destructive [&]:outline-destructive',
+        class:
+          '[&]:hover:enabled:bg-destructive-primary-hover [&]:bg-destructive [&]:outline-destructive [&]:focus-visible:bg-destructive-primary-hover',
       },
       {
         variant: 'outline',
         destructive: true,
-        class: '[&]:border-destructive [&]:text-destructive [&]:hover:enabled:bg-destructive-hover',
+        class:
+          '[&]:border-destructive [&]:text-destructive [&]:hover:enabled:bg-destructive-hover [&]:focus-visible:bg-destructive-hover',
       },
       {
         variant: 'ghost',
         destructive: true,
-        class: '[&]:text-destructive [&]:hover:enabled:bg-destructive-hover',
+        class: '[&]:text-destructive [&]:hover:enabled:bg-destructive-hover [&]:focus-visible:bg-destructive-hover',
       },
     ],
   },
 );
-type ButtonVariants = VariantProps<typeof buttonVariants>;
+export type ButtonVariants = VariantProps<typeof buttonVariants>;
 
 @Component({
   selector: 'ods-button',
diff --git a/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts b/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts
index 5de77014fc3466b2a8a5768e2f003c61347d9dad..ca6a007c19e49ebb481ff0655b407cc3076a9c08 100644
--- a/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts
+++ b/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts
@@ -26,6 +26,7 @@ import { CommonModule } from '@angular/common';
 import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';
 import { FormControl, ReactiveFormsModule } from '@angular/forms';
 import { cva, VariantProps } from 'class-variance-authority';
+import { uniqueId } from 'lodash-es';
 
 const textInputVariants = cva(
   [
@@ -86,7 +87,7 @@ export class TextInputComponent {
 
   @Input({ required: true }) set label(label: string) {
     this.inputLabel = label;
-    this.id = convertForDataTest(label);
+    this.id = `${convertForDataTest(label)}-${uniqueId()}`;
   }
   @Input() placeholder: string = '';
   @Input() autocomplete: string = 'off';
diff --git a/alfa-client/libs/design-system/src/lib/icons/delete-icon/delete-icon.component.spec.ts b/alfa-client/libs/design-system/src/lib/icons/delete-icon/delete-icon.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..354449bdfb0652606ec23dee7b970a5d793fd292
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/icons/delete-icon/delete-icon.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { DeleteIconComponent } from './delete-icon.component';
+
+describe('DeleteIconComponent', () => {
+  let component: DeleteIconComponent;
+  let fixture: ComponentFixture<DeleteIconComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [DeleteIconComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(DeleteIconComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/alfa-client/libs/design-system/src/lib/icons/delete-icon/delete-icon.component.ts b/alfa-client/libs/design-system/src/lib/icons/delete-icon/delete-icon.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fc06f683c6790f219c7c08fb258764b35cdf2b6c
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/icons/delete-icon/delete-icon.component.ts
@@ -0,0 +1,27 @@
+import { CommonModule } from '@angular/common';
+import { Component, Input } from '@angular/core';
+import { twMerge } from 'tailwind-merge';
+import { IconVariants, iconVariants } from '../iconVariants';
+
+@Component({
+  selector: 'ods-delete-icon',
+  standalone: true,
+  imports: [CommonModule],
+  template: `<svg
+    viewBox="0 0 24 24"
+    xmlns="http://www.w3.org/2000/svg"
+    [ngClass]="[twMerge(iconVariants({ size }), 'fill-error', class)]"
+    aria-hidden="true"
+  >
+    <path
+      d="M7 21C6.45 21 5.97917 20.8042 5.5875 20.4125C5.19583 20.0208 5 19.55 5 19V6H4V4H9V3H15V4H20V6H19V19C19 19.55 18.8042 20.0208 18.4125 20.4125C18.0208 20.8042 17.55 21 17 21H7ZM17 6H7V19H17V6ZM9 17H11V8H9V17ZM13 17H15V8H13V17Z"
+    />
+  </svg> `,
+})
+export class DeleteIconComponent {
+  @Input() size: IconVariants['size'] = 'medium';
+  @Input() class: string = '';
+
+  readonly iconVariants = iconVariants;
+  readonly twMerge = twMerge;
+}
diff --git a/alfa-client/libs/design-system/src/lib/icons/delete-icon/delete-icon.stories.ts b/alfa-client/libs/design-system/src/lib/icons/delete-icon/delete-icon.stories.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4602289bc57c1be551e4bf2ba29003ab4bd7de31
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/icons/delete-icon/delete-icon.stories.ts
@@ -0,0 +1,27 @@
+import type { Meta, StoryObj } from '@storybook/angular';
+
+import { DeleteIconComponent } from './delete-icon.component';
+
+const meta: Meta<DeleteIconComponent> = {
+  title: 'Icons/Delete icon',
+  component: DeleteIconComponent,
+  excludeStories: /.*Data$/,
+  tags: ['autodocs'],
+};
+
+export default meta;
+type Story = StoryObj<DeleteIconComponent>;
+
+export const Default: Story = {
+  args: { size: 'large' },
+  argTypes: {
+    size: {
+      control: 'select',
+      options: ['small', 'medium', 'large', 'extra-large', 'full'],
+      description: 'Size of icon. Property "full" means 100%',
+      table: {
+        defaultValue: { summary: 'medium' },
+      },
+    },
+  },
+};
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts
index 02e4ff7ccc5ffa9a28b0295d44991618862758bb..60c4640d92c10a70d0bec7d763d80a8f9618ff33 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts
@@ -29,7 +29,7 @@ import { cold } from 'jest-marbles';
 import { DummyLinkRel, DummyListLinkRel } from 'libs/tech-shared/test/dummy';
 import { createDummyListResource, createDummyResource, createFilledDummyListResource } from 'libs/tech-shared/test/resource';
 import { BehaviorSubject, Observable, of } from 'rxjs';
-import { singleCold, singleHot } from '../../../test/marbles';
+import { multipleCold, singleCold, singleHot } from '../../../test/marbles';
 import { EMPTY_ARRAY } from '../tech.util';
 import { ResourceListService } from './list-resource.service';
 import { CreateResourceData, LinkRelationName, ListItemResource, ListResourceServiceConfig } from './resource.model';
@@ -311,25 +311,27 @@ describe('ListResourceService', () => {
 
   describe('create', () => {
     const toCreate: unknown = {};
+    const returnResource: Resource = createDummyResource();
 
     beforeEach(() => {
       service.listResource.value.resource = listResource;
+      resourceRepository.createResource.mockReturnValue(of(returnResource));
     });
 
     it('should throw error if link is not present', () => {
       service.listResource.next(createStateResource(createDummyListResource()));
 
-      expect(() => service.create(toCreate)).toThrowError('No creation link exists.');
+      expect(() => service.create(toCreate)).toThrow('No creation link exists.');
     });
 
     it('should throw error if list resource is empty', () => {
       service.listResource.next(createEmptyStateResource());
 
-      expect(() => service.create(toCreate)).toThrowError('No list resource available.');
+      expect(() => service.create(toCreate)).toThrow('No list resource available.');
     });
 
     it('should trigger resourceLoader', () => {
-      service.create(toCreate);
+      service.create(toCreate).subscribe();
 
       const createResourceData: CreateResourceData<ListResource> = {
         resource: listResource,
@@ -341,11 +343,11 @@ describe('ListResourceService', () => {
 
     it('should return value', () => {
       const returnResource: Resource = createDummyResource();
-      resourceRepository.createResource.mockReturnValue(singleHot(returnResource));
+      resourceRepository.createResource.mockReturnValue(singleCold(returnResource, '-a'));
 
-      const createdResource: Observable<Resource> = service.create(toCreate);
+      const createdResource: Observable<StateResource<Resource>> = service.create(toCreate);
 
-      expect(createdResource).toBeObservable(singleCold(returnResource));
+      expect(createdResource).toBeObservable(multipleCold(createEmptyStateResource(true), createStateResource(returnResource)));
     });
   });
 
@@ -443,7 +445,7 @@ describe('ListResourceService', () => {
     it('should throw error if prev link is not present', () => {
       service.listResource.next(createStateResource(listResource));
 
-      expect(() => service.prev()).toThrowError('There is no previous page.');
+      expect(() => service.prev()).toThrow('There is no previous page.');
     });
 
     it('should call resourceLoader with prev link', () => {
@@ -471,7 +473,7 @@ describe('ListResourceService', () => {
     it('should throw error if next link is not present', () => {
       service.listResource.next(createStateResource(listResource));
 
-      expect(() => service.next()).toThrowError('There is no next page.');
+      expect(() => service.next()).toThrow('There is no next page.');
     });
 
     it('should call resourceLoader with next link', () => {
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.ts b/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.ts
index 13df5d4cf6fa8f06588a096d454e598faa8a4fa3..852a8299c56d256d93bf778e9600ab0717edc00f 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.ts
@@ -58,7 +58,7 @@ export class ResourceListService<B extends Resource, T extends ListResource, I e
 
   constructor(
     private config: ListResourceServiceConfig<B>,
-    private repository: ResourceRepository,
+    private repository: ResourceRepository<I>,
   ) {}
 
   public getList(): Observable<StateResource<T>> {
@@ -106,9 +106,12 @@ export class ResourceListService<B extends Resource, T extends ListResource, I e
     this.listResource.next(createEmptyStateResource());
   }
 
-  public create(toCreate: unknown): Observable<Resource> {
+  public create(toCreate: unknown): Observable<StateResource<I>> {
     this.verifyBeforeCreation();
-    return this.repository.createResource(this.buildCreateResourceData(toCreate, this.config.createLinkRel));
+    return this.repository.createResource(this.buildCreateResourceData(toCreate, this.config.createLinkRel)).pipe(
+      map((listItemResource: I) => createStateResource(listItemResource)),
+      startWith(createEmptyStateResource<I>(true)),
+    );
   }
 
   private verifyBeforeCreation(): void {
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts
index 8a4081f31be113eaf2986e867f294603a9d56a6a..33d37b87af453f7fb777dd2ca69d8cf7a8f394c4 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts
@@ -28,7 +28,7 @@ import { CreateResourceData, LinkRelationName, SaveResourceData } from './resour
 import { ListResource } from './resource.util';
 
 @Injectable({ providedIn: 'root' })
-export class ResourceRepository {
+export class ResourceRepository<T extends Resource = Resource> {
   private resourceFactory = inject(ResourceFactory);
 
   static SEARCH_PARAM: string = 'searchBy';
@@ -45,7 +45,7 @@ export class ResourceRepository {
     return uri;
   }
 
-  public createResource(createResourceData: CreateResourceData<Resource>): Observable<Resource> {
+  public createResource(createResourceData: CreateResourceData<Resource>): Observable<T> {
     return this.resourceFactory.from(createResourceData.resource).post(createResourceData.linkRel, createResourceData.toCreate);
   }
 
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.service.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.service.spec.ts
index d7d188b8c526a9d439b934397b54c32e2332227a..87869c5c4e0aa1dff4a3050b95ed26abd476c0d6 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/resource.service.spec.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.service.spec.ts
@@ -503,7 +503,7 @@ describe('ResourceService', () => {
       const thrownError$: Observable<StateResource<unknown>> = service.handleError(error);
 
       expect.assertions(1);
-      expect(lastValueFrom(thrownError$)).rejects.toThrowError('Internal Server Error');
+      expect(lastValueFrom(thrownError$)).rejects.toThrow('Internal Server Error');
     });
   });
 
diff --git a/alfa-client/libs/tech-shared/test/data-test.ts b/alfa-client/libs/tech-shared/test/data-test.ts
index 98db6b1f6fb58fa31cc9353c8440c442bbfb4112..795b2dee30c083f71da5842c2cc64738c3dd9da4 100644
--- a/alfa-client/libs/tech-shared/test/data-test.ts
+++ b/alfa-client/libs/tech-shared/test/data-test.ts
@@ -38,3 +38,7 @@ export function getDataTestIdOf(value: string): string {
 export function getDataTestIdAttributeOf(value: string): string {
   return `[dataTestId="${value}"]`;
 }
+
+export function getDynamicDataTestIdAttributOf(value: string): string {
+  return `[ng-reflect-data-test-id="${value}"]`;
+}
diff --git a/alfa-client/libs/tech-shared/test/marbles.ts b/alfa-client/libs/tech-shared/test/marbles.ts
index ea8e04237504cc8104ddb569ce574dd66c6ad362..fecda8769f38a80dd34c693c9ca39bf175a69eef 100644
--- a/alfa-client/libs/tech-shared/test/marbles.ts
+++ b/alfa-client/libs/tech-shared/test/marbles.ts
@@ -34,3 +34,7 @@ export function singleCold(object: any, frame: string = 'a'): ObservableWithSubs
 export function singleColdCompleted(object: any, frame: string = 'a'): ObservableWithSubscriptions {
   return cold(`(${frame}|)`, { a: object });
 }
+
+export function multipleCold(first: any, second: any): ObservableWithSubscriptions {
+  return cold('ab', { a: first, b: second });
+}
diff --git a/alfa-client/libs/test-utils/src/lib/mocking.ts b/alfa-client/libs/test-utils/src/lib/mocking.ts
index a5e3137a17d3fed7c81cd72e350599195cd079f7..0fb616db60420994880e9acfddec1d0d37e10486 100644
--- a/alfa-client/libs/test-utils/src/lib/mocking.ts
+++ b/alfa-client/libs/test-utils/src/lib/mocking.ts
@@ -47,3 +47,9 @@ export function mockClass(clazz: any): Mock<any> {
 export function createSpy(clazz: any, functionName: string) {
   return jest.spyOn(clazz.prototype, functionName);
 }
+
+export function mockGetValue(object: any, name: string, returnValue: any): void {
+  Object.defineProperty(object, name, {
+    get: jest.fn(() => returnValue),
+  });
+}
diff --git a/alfa-client/libs/test-utils/src/lib/model.ts b/alfa-client/libs/test-utils/src/lib/model.ts
index d89ed415513a8528908c72641e609bc43c86c7c7..1094ac96376b5a8d2d81cf5a7ebf13c69aa2a550 100644
--- a/alfa-client/libs/test-utils/src/lib/model.ts
+++ b/alfa-client/libs/test-utils/src/lib/model.ts
@@ -29,3 +29,7 @@ export interface EventData<T> {
   name: string;
   data?: unknown;
 }
+
+export const MockEvent = {
+  CLICK: 'clickEmitter',
+};
diff --git a/alfa-client/tsconfig.base.json b/alfa-client/tsconfig.base.json
index 6850f74e4eb7c031308a264a51e8a4782fa9613b..f6bb4c8b2657d8acef026b997d32794971be5656 100644
--- a/alfa-client/tsconfig.base.json
+++ b/alfa-client/tsconfig.base.json
@@ -22,6 +22,7 @@
       "@admin-client/organisations-einheit-shared": ["libs/admin/organisations-einheit-shared/src/index.ts"],
       "@admin-client/postfach": ["libs/admin/postfach/src/index.ts"],
       "@admin-client/postfach-shared": ["libs/admin/postfach-shared/src/index.ts"],
+      "@admin-client/reporting-shared": ["libs/admin/reporting-shared/src/index.ts"],
       "@admin-client/settings-shared": ["libs/admin/settings-shared/src/index.ts"],
       "@admin-client/shared": ["libs/admin/shared/src/index.ts"],
       "@admin-client/statistik": ["libs/admin/statistik/src/index.ts"],