diff --git a/i18n/en.pot b/i18n/en.pot
index d25c0a8..50ecc1b 100644
--- a/i18n/en.pot
+++ b/i18n/en.pot
@@ -5,8 +5,8 @@ msgstr ""
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"POT-Creation-Date: 2024-03-14T01:55:56.426Z\n"
-"PO-Revision-Date: 2024-03-14T01:55:56.426Z\n"
+"POT-Creation-Date: 2024-03-16T16:23:42.597Z\n"
+"PO-Revision-Date: 2024-03-16T16:23:42.597Z\n"
 
 msgid "Cannot be blank: {{fieldName}}"
 msgstr ""
@@ -59,6 +59,11 @@ msgstr ""
 msgid "Save Config Analysis"
 msgstr ""
 
+msgid ""
+"No user with Capture rights and Organisation Unit associated to the issue "
+"was found"
+msgstr ""
+
 msgid "Updating Issue..."
 msgstr ""
 
@@ -74,6 +79,30 @@ msgstr ""
 msgid "Double click to edit"
 msgstr ""
 
+msgid "Yes"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "{{countryNames}} and {{moreCountriesCount}} more"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Countries"
+msgstr ""
+
+msgid "Periods"
+msgstr ""
+
+msgid "Action"
+msgstr ""
+
+msgid "Follow Up"
+msgstr ""
+
 msgid "Issue"
 msgstr ""
 
@@ -95,12 +124,6 @@ msgstr ""
 msgid "Azure URL"
 msgstr ""
 
-msgid "Follow Up"
-msgstr ""
-
-msgid "Action"
-msgstr ""
-
 msgid "Contact Emails"
 msgstr ""
 
@@ -146,7 +169,7 @@ msgstr ""
 msgid "Data Quality Analysis"
 msgstr ""
 
-msgid "Outliers detection analysis based on DHIS2 min-max standard functionality"
+msgid "Configuration"
 msgstr ""
 
 msgid "Algorithm"
@@ -155,42 +178,30 @@ msgstr ""
 msgid "Threshold"
 msgstr ""
 
-msgid "Run"
-msgstr ""
-
-msgid "Run to get results"
-msgstr ""
-
-msgid "No Issues found"
-msgstr ""
-
 msgid "Running analysis..."
 msgstr ""
 
-msgid "Missing disaggregates in selected catcombos"
-msgstr ""
-
 msgid "CatCombos"
 msgstr ""
 
-msgid "Medical doctors analysis: General Practicioners missing and double counts"
-msgstr ""
-
 msgid "Disaggregations"
 msgstr ""
 
 msgid "Double Counts Threshold"
 msgstr ""
 
-msgid "Missing nursing personnel when midwifery personnel is present"
-msgstr ""
-
 msgid "Loading"
 msgstr ""
 
 msgid "Validation Rule Group"
 msgstr ""
 
+msgid "Run"
+msgstr ""
+
+msgid "Run to get results"
+msgstr ""
+
 msgid "Activity Level"
 msgstr ""
 
@@ -215,34 +226,7 @@ msgstr ""
 msgid "Enrolled"
 msgstr ""
 
-msgid "Configuration"
-msgstr ""
-
-msgid "Outliers"
-msgstr ""
-
-msgid "Trends"
-msgstr ""
-
-msgid "Disaggregates"
-msgstr ""
-
-msgid "General Practitioners"
-msgstr ""
-
-msgid "Nursing"
-msgstr ""
-
-msgid "Nursing/Midwifery"
-msgstr ""
-
-msgid "Midwifery"
-msgstr ""
-
-msgid "Density"
-msgstr ""
-
-msgid "Other"
+msgid "No Issues found"
 msgstr ""
 
 msgid "Are you sure you want to {{action}} the selected rows?"
diff --git a/i18n/es.po b/i18n/es.po
index 5f96b35..a0779ca 100644
--- a/i18n/es.po
+++ b/i18n/es.po
@@ -1,7 +1,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: i18next-conv\n"
-"POT-Creation-Date: 2024-03-14T01:55:56.426Z\n"
+"POT-Creation-Date: 2024-03-16T16:23:42.597Z\n"
 "PO-Revision-Date: 2018-10-25T09:02:35.143Z\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -59,6 +59,11 @@ msgstr ""
 msgid "Save Config Analysis"
 msgstr ""
 
+msgid ""
+"No user with Capture rights and Organisation Unit associated to the issue "
+"was found"
+msgstr ""
+
 msgid "Updating Issue..."
 msgstr ""
 
@@ -74,6 +79,30 @@ msgstr ""
 msgid "Double click to edit"
 msgstr ""
 
+msgid "Yes"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "{{countryNames}} and {{moreCountriesCount}} more"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Countries"
+msgstr ""
+
+msgid "Periods"
+msgstr ""
+
+msgid "Action"
+msgstr ""
+
+msgid "Follow Up"
+msgstr ""
+
 msgid "Issue"
 msgstr ""
 
@@ -95,12 +124,6 @@ msgstr ""
 msgid "Azure URL"
 msgstr ""
 
-msgid "Follow Up"
-msgstr ""
-
-msgid "Action"
-msgstr ""
-
 msgid "Contact Emails"
 msgstr ""
 
@@ -146,8 +169,7 @@ msgstr ""
 msgid "Data Quality Analysis"
 msgstr ""
 
-msgid ""
-"Outliers detection analysis based on DHIS2 min-max standard functionality"
+msgid "Configuration"
 msgstr ""
 
 msgid "Algorithm"
@@ -156,43 +178,30 @@ msgstr ""
 msgid "Threshold"
 msgstr ""
 
-msgid "Run"
-msgstr ""
-
-msgid "Run to get results"
-msgstr ""
-
-msgid "No Issues found"
-msgstr ""
-
 msgid "Running analysis..."
 msgstr ""
 
-msgid "Missing disaggregates in selected catcombos"
-msgstr ""
-
 msgid "CatCombos"
 msgstr ""
 
-msgid ""
-"Medical doctors analysis: General Practicioners missing and double counts"
-msgstr ""
-
 msgid "Disaggregations"
 msgstr ""
 
 msgid "Double Counts Threshold"
 msgstr ""
 
-msgid "Missing nursing personnel when midwifery personnel is present"
-msgstr ""
-
 msgid "Loading"
 msgstr ""
 
 msgid "Validation Rule Group"
 msgstr ""
 
+msgid "Run"
+msgstr ""
+
+msgid "Run to get results"
+msgstr ""
+
 msgid "Activity Level"
 msgstr ""
 
@@ -217,34 +226,7 @@ msgstr ""
 msgid "Enrolled"
 msgstr ""
 
-msgid "Configuration"
-msgstr ""
-
-msgid "Outliers"
-msgstr ""
-
-msgid "Trends"
-msgstr ""
-
-msgid "Disaggregates"
-msgstr ""
-
-msgid "General Practitioners"
-msgstr ""
-
-msgid "Nursing"
-msgstr ""
-
-msgid "Nursing/Midwifery"
-msgstr ""
-
-msgid "Midwifery"
-msgstr ""
-
-msgid "Density"
-msgstr ""
-
-msgid "Other"
+msgid "No Issues found"
 msgstr ""
 
 msgid "Are you sure you want to {{action}} the selected rows?"
diff --git a/src/CompositionRoot.ts b/src/CompositionRoot.ts
index 6c1d0c2..238e61e 100644
--- a/src/CompositionRoot.ts
+++ b/src/CompositionRoot.ts
@@ -122,7 +122,13 @@ function getCompositionRoot(repositories: Repositories, metadata: MetadataItem)
                 repositories.settingsRepository
             ),
         },
-        issues: { save: new SaveIssueUseCase(repositories.qualityAnalysisRepository, metadata) },
+        issues: {
+            save: new SaveIssueUseCase(
+                repositories.qualityAnalysisRepository,
+                repositories.usersRepository,
+                metadata
+            ),
+        },
         settings: { get: new GetSettingsUseCase(repositories.settingsRepository) },
         nursingMidwifery: {
             getDisaggregations: new GetMidwiferyPersonnelDisaggregationsUseCase(
diff --git a/src/data/common/D2CategoryOption.ts b/src/data/common/D2CategoryOption.ts
index cd5d3f1..d67f1e6 100644
--- a/src/data/common/D2CategoryOption.ts
+++ b/src/data/common/D2CategoryOption.ts
@@ -3,6 +3,7 @@ import { FutureData, apiToFuture } from "../api-futures";
 import { Id } from "../../domain/entities/Ref";
 import _ from "../../domain/entities/generic/Collection";
 import { CategoryOption } from "../../domain/entities/CategoryOption";
+import { Maybe } from "$/utils/ts-utils";
 
 export class D2CategoryOption {
     constructor(private api: D2Api) {}
@@ -21,15 +22,21 @@ export class D2CategoryOption {
                 })
                 .map(d2Response => {
                     return d2Response.data.objects.map(d2CategoryOption => {
-                        return {
-                            id: d2CategoryOption.id,
-                            name:
-                                d2CategoryOption.displayShortName ||
-                                d2CategoryOption.displayFormName ||
-                                d2CategoryOption.displayName,
-                        };
+                        return { id: d2CategoryOption.id, name: this.getName(d2CategoryOption) };
                     });
                 })
         );
     }
+
+    private getName(d2Name: D2TranslatioName): string {
+        const name = d2Name.displayShortName || d2Name.displayFormName || d2Name.displayName;
+        if (name === "default") return "Total";
+        return name || "";
+    }
 }
+
+type D2TranslatioName = {
+    displayShortName: Maybe<string>;
+    displayFormName: Maybe<string>;
+    displayName: Maybe<string>;
+};
diff --git a/src/data/common/D2Country.ts b/src/data/common/D2Country.ts
index 7906a48..4480e32 100644
--- a/src/data/common/D2Country.ts
+++ b/src/data/common/D2Country.ts
@@ -1,37 +1,51 @@
-import { D2Api } from "../../types/d2-api";
+import { D2Api } from "$/types/d2-api";
 import { FutureData, apiToFuture } from "../api-futures";
-import { Id } from "../../domain/entities/Ref";
-import _ from "../../domain/entities/generic/Collection";
-import { Country } from "../../domain/entities/Country";
+import { Id } from "$/domain/entities/Ref";
+import _ from "$/domain/entities/generic/Collection";
+import { Country } from "$/domain/entities/Country";
+import { Future } from "$/domain/entities/generic/Future";
 
 export class D2OrgUnit {
     constructor(private api: D2Api) {}
 
     getByIds(ids: Id[]): FutureData<Country[]> {
-        return apiToFuture(
-            this.api.models.organisationUnits
-                .get({
-                    fields: {
-                        id: true,
-                        displayName: true,
-                        displayFormName: true,
-                        displayShortName: true,
-                        path: true,
-                    },
-                    filter: { id: { in: ids } },
-                })
-                .map(d2Response => {
-                    return d2Response.data.objects.map(d2OrgUnit => {
-                        return {
-                            id: d2OrgUnit.id,
-                            name:
-                                d2OrgUnit.displayShortName ||
-                                d2OrgUnit.displayFormName ||
-                                d2OrgUnit.displayName,
-                            path: d2OrgUnit.path,
-                        };
+        const $requests = Future.sequential(
+            _(ids)
+                .chunk(50)
+                .map(countriesIds => {
+                    return apiToFuture(
+                        this.api.models.organisationUnits.get({
+                            fields: {
+                                id: true,
+                                displayName: true,
+                                displayFormName: true,
+                                displayShortName: true,
+                                path: true,
+                            },
+                            filter: { id: { in: countriesIds } },
+                        })
+                    ).map(d2Response => {
+                        return d2Response.objects.map((d2OrgUnit): Country => {
+                            return {
+                                id: d2OrgUnit.id,
+                                name:
+                                    d2OrgUnit.displayShortName ||
+                                    d2OrgUnit.displayFormName ||
+                                    d2OrgUnit.displayName,
+                                path: d2OrgUnit.path,
+                                writeAccess: false,
+                            };
+                        });
                     });
                 })
+                .value()
         );
+
+        return Future.sequential([$requests]).flatMap(countries => {
+            const first = _(countries).first();
+            if (!first) return Future.success([]);
+            const allCountries = _(first).flatten().value();
+            return Future.success(allCountries);
+        });
     }
 }
diff --git a/src/data/common/D2User.ts b/src/data/common/D2User.ts
index 9291ab6..baf455c 100644
--- a/src/data/common/D2User.ts
+++ b/src/data/common/D2User.ts
@@ -1,10 +1,41 @@
-import { User } from "../../domain/entities/User";
-import { D2Api, MetadataPick } from "../../types/d2-api";
+import { UserGroup } from "$/domain/entities/UserGroup";
+import { Future } from "$/domain/entities/generic/Future";
+import { User } from "$/domain/entities/User";
+import { D2Api, MetadataPick } from "$/types/d2-api";
 import { apiToFuture, FutureData } from "../api-futures";
+import _ from "$/domain/entities/generic/Collection";
 
 export class D2User {
     constructor(private api: D2Api) {}
 
+    getByIds(ids: string[]): FutureData<User[]> {
+        const $requests = Future.sequential(
+            _(ids)
+                .chunk(50)
+                .map(usersIds => {
+                    return apiToFuture(
+                        this.api.models.users.get({
+                            fields: userFields,
+                            filter: { id: { in: usersIds } },
+                            paging: false,
+                        })
+                    ).map(d2Response => {
+                        return d2Response.objects.map((d2User): User => {
+                            return this.buildUser(d2User);
+                        });
+                    });
+                })
+                .value()
+        );
+
+        return Future.sequential([$requests]).flatMap(users => {
+            const first = _(users).first();
+            if (!first) return Future.success([]);
+            const allUsers = _(first).flatten().value();
+            return Future.success(allUsers);
+        });
+    }
+
     getCurrent(): FutureData<User> {
         return apiToFuture(this.api.currentUser.get({ fields: userFields })).map(d2User => {
             return this.buildUser(d2User);
@@ -24,10 +55,24 @@ export class D2User {
     }
 
     private buildUser(d2User: D2UserEntity) {
+        const readAccessCountries = d2User.teiSearchOrganisationUnits.map(d2OrgUnit => {
+            return { ...d2OrgUnit, writeAccess: false };
+        });
+        const writeAccessCountries = d2User.organisationUnits.map(d2OrgUnit => {
+            return { ...d2OrgUnit, writeAccess: true };
+        });
         return new User({
             id: d2User.id,
             name: d2User.displayName,
-            userGroups: d2User.userGroups,
+            userGroups: d2User.userGroups.map(d2UserGroup => {
+                return UserGroup.build({
+                    id: d2UserGroup.id,
+                    name: d2UserGroup.name,
+                    usersIds: d2UserGroup.users.map(d2User => d2User.id),
+                }).get();
+            }),
+            countries: [...readAccessCountries, ...writeAccessCountries],
+            email: d2User.email,
             ...d2User.userCredentials,
         });
     }
@@ -36,8 +81,15 @@ export class D2User {
 const userFields = {
     id: true,
     displayName: true,
-    userGroups: { id: true, name: true },
-    userCredentials: { username: true, userRoles: { id: true, name: true, authorities: true } },
+    email: true,
+    userGroups: { id: true, name: true, users: true },
+    userCredentials: {
+        lastLogin: true,
+        username: true,
+        userRoles: { id: true, name: true, authorities: true },
+    },
+    teiSearchOrganisationUnits: { id: true, name: true, path: true },
+    organisationUnits: { id: true, name: true, path: true },
 } as const;
 
 type D2UserEntity = MetadataPick<{ users: { fields: typeof userFields } }>["users"][number];
diff --git a/src/data/repositories/AnalysisSectionD2Repository.ts b/src/data/repositories/AnalysisSectionD2Repository.ts
index a7bd46e..e692f83 100644
--- a/src/data/repositories/AnalysisSectionD2Repository.ts
+++ b/src/data/repositories/AnalysisSectionD2Repository.ts
@@ -11,6 +11,7 @@ export class AnalysisSectionD2Repository implements AnalysisSectionRepository {
         const sections = this.metadata.programs.qualityIssues.programStages.map(programStage => {
             return QualityAnalysisSection.create({
                 id: programStage.id,
+                description: programStage.description,
                 name: programStage.name,
                 issues: [],
                 status: "",
diff --git a/src/data/repositories/IssueD2Repository.ts b/src/data/repositories/IssueD2Repository.ts
index 64fdef5..e38a393 100644
--- a/src/data/repositories/IssueD2Repository.ts
+++ b/src/data/repositories/IssueD2Repository.ts
@@ -39,6 +39,7 @@ export class IssueD2Repository implements IssueRepository {
 
     get(options: GetIssuesOptions): FutureData<RowsPaginated<QualityAnalysisIssue>> {
         const { filters, pagination } = options;
+        const filtersParams = this.buildFilters(options.filters);
         return apiToFuture(
             this.api.tracker.events.get({
                 programStage: filters.sectionId ? filters.sectionId : undefined,
@@ -49,10 +50,9 @@ export class IssueD2Repository implements IssueRepository {
                 pageSize: pagination.pageSize,
                 // TODO: order and filter does not work together
                 // ERROR: Query failed because of a syntax error (SqlState: 42703)",
-                order: options.filters.name
-                    ? undefined
-                    : this.buildOrder(options.sorting) || undefined,
-                filter: this.buildFilters(options.filters),
+                // disabling order if any filter is present
+                order: filtersParams ? undefined : this.buildOrder(options.sorting) || undefined,
+                filter: filtersParams,
                 event: filters.id ? filters.id : undefined,
             })
         ).flatMap(d2Response => {
@@ -160,7 +160,7 @@ export class IssueD2Repository implements IssueRepository {
                         },
                         {
                             id: this.metadata.dataElements.followUp.id,
-                            value: issue.followUp ? "true" : "",
+                            value: issue.followUp ? "true" : "false",
                         },
                         {
                             id: this.metadata.dataElements.contactEmails.id,
@@ -325,10 +325,56 @@ export class IssueD2Repository implements IssueRepository {
             ? `${this.metadata.dataElements.issueNumber.id}:LIKE:${filter.name}`
             : undefined;
 
-        const allFilters = _([numberFilter]).compact().value();
+        const periodsFilter = this.buildFilterMultipleValue(
+            filter.periods,
+            this.metadata.dataElements.period.id
+        );
+
+        const statusFilter = this.buildFilterMultipleValue(
+            filter.status,
+            this.metadata.dataElements.status.id
+        );
+
+        const actionsFilter = this.buildFilterMultipleValue(
+            filter.actions,
+            this.metadata.dataElements.action.id
+        );
+
+        const countriesFilter = this.buildFilterMultipleValue(
+            filter.countries,
+            this.metadata.dataElements.country.id
+        );
+
+        const followUpFilter = this.buildFollowUpFilter(filter.followUp);
+
+        const allFilters = _([
+            numberFilter,
+            periodsFilter,
+            statusFilter,
+            actionsFilter,
+            countriesFilter,
+            followUpFilter,
+        ])
+            .compact()
+            .value();
 
         return allFilters.length > 0 ? allFilters.join(",") : undefined;
     }
+
+    private buildFilterMultipleValue(value: Maybe<string[]>, dataElementId: Id): Maybe<string> {
+        const valueSeparatedByComma = value ? value.join(";") : undefined;
+        return valueSeparatedByComma ? `${dataElementId}:IN:${valueSeparatedByComma}` : undefined;
+    }
+
+    private buildFollowUpFilter(followUpValue: Maybe<string>): Maybe<string> {
+        if (followUpValue === "1") {
+            return `${this.metadata.dataElements.followUp.id}:eq:true`;
+        } else if (followUpValue === "0") {
+            return `${this.metadata.dataElements.followUp.id}:eq:false`;
+        } else {
+            return undefined;
+        }
+    }
 }
 
 type DataElementKey = keyof MetadataItem["dataElements"];
diff --git a/src/data/repositories/MetadataD2Repository.ts b/src/data/repositories/MetadataD2Repository.ts
index 4d2e818..07d78f4 100644
--- a/src/data/repositories/MetadataD2Repository.ts
+++ b/src/data/repositories/MetadataD2Repository.ts
@@ -39,6 +39,10 @@ const metadataCodes = {
         correlative: "NHWA_DQI_Issue_Correlative_Number",
     },
     dataSets: { module1: "NHWA-M1-2023", module2: "NHWA-M2-2023" },
+    userGroups: {
+        dataCaptureModule1: "NHWA _DATA Capture Module 1",
+        dataCaptureModule2And4: "NHWA _DATA Capture Module 2-4",
+    },
 };
 
 const metadataFields = {
@@ -75,6 +79,10 @@ const metadataFields = {
         },
         filter: { code: { in: rec(metadataCodes.programs).values() } },
     },
+    userGroups: {
+        fields: { id: true, name: true, code: true, users: true },
+        filter: { name: { in: rec(metadataCodes.userGroups).values() } },
+    },
 };
 
 export class MetadataD2Repository implements MetadataRepository {
diff --git a/src/data/repositories/QualityAnalysisD2Repository.ts b/src/data/repositories/QualityAnalysisD2Repository.ts
index 174f890..c75fa27 100644
--- a/src/data/repositories/QualityAnalysisD2Repository.ts
+++ b/src/data/repositories/QualityAnalysisD2Repository.ts
@@ -134,18 +134,28 @@ export class QualityAnalysisD2Repository implements QualityAnalysisRepository {
         });
     }
 
-    remove(id: Id[]): FutureData<void> {
+    remove(id: Id): FutureData<void> {
         return apiToFuture(
-            this.api.tracker.post(
+            this.api.tracker.postAsync(
                 { importStrategy: "DELETE" },
-                { trackedEntities: id.map(id => ({ trackedEntity: id })) }
+                { trackedEntities: [{ trackedEntity: id }] }
             )
-        ).flatMap(d2Response => {
-            if (d2Response.status === "ERROR") {
-                return Future.error(new Error(d2Response.message));
-            } else {
-                return Future.success(undefined);
-            }
+        ).flatMap(d2JobResponse => {
+            return apiToFuture(
+                // this rule is being applied outside the context of testing-library
+                // more info here: https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/await-async-utils.md
+                // eslint-disable-next-line testing-library/await-async-utils
+                this.api.system.waitFor("TRACKER_IMPORT_JOB", d2JobResponse.response.id)
+            ).flatMap(d2Response => {
+                if (d2Response?.status === "ERROR") {
+                    return Future.error(new Error(d2Response.message));
+                } else {
+                    const dataStore = this.api.dataStore(DATA_QUALITY_NAMESPACE);
+                    return apiToFuture(dataStore.delete(id)).flatMap(() => {
+                        return Future.success(undefined);
+                    });
+                }
+            });
         });
     }
 
@@ -384,7 +394,7 @@ export class QualityAnalysisD2Repository implements QualityAnalysisRepository {
             },
             {
                 dataElement: this.metadata.dataElements.followUp.id,
-                value: issue.followUp ? "true" : "",
+                value: issue.followUp ? "true" : "false",
             },
             {
                 dataElement: this.metadata.dataElements.issueNumber.id,
@@ -540,6 +550,7 @@ export class QualityAnalysisD2Repository implements QualityAnalysisRepository {
             return new QualityAnalysisSection({
                 id: programStage.id,
                 name: programStage.name,
+                description: programStage.description,
                 issues: qaIssues.filter(issue => issue.type === programStage.id),
                 status: sectionData?.status || "",
             });
diff --git a/src/data/repositories/UserD2Repository.ts b/src/data/repositories/UserD2Repository.ts
index 339fa4e..51ab15b 100644
--- a/src/data/repositories/UserD2Repository.ts
+++ b/src/data/repositories/UserD2Repository.ts
@@ -1,8 +1,8 @@
-import { User } from "../../domain/entities/User";
-import { UserRepository } from "../../domain/repositories/UserRepository";
-import { D2Api } from "../../types/d2-api";
-import { FutureData } from "../api-futures";
-import { D2User } from "../common/D2User";
+import { User } from "$/domain/entities/User";
+import { UserRepository } from "$/domain/repositories/UserRepository";
+import { D2Api } from "$/types/d2-api";
+import { FutureData } from "$/data/api-futures";
+import { D2User } from "$/data/common/D2User";
 
 export class UserD2Repository implements UserRepository {
     private d2User: D2User;
@@ -10,6 +10,10 @@ export class UserD2Repository implements UserRepository {
         this.d2User = new D2User(this.api);
     }
 
+    getByIds(ids: string[]): FutureData<User[]> {
+        return this.d2User.getByIds(ids);
+    }
+
     public getCurrent(): FutureData<User> {
         return this.d2User.getCurrent();
     }
diff --git a/src/data/repositories/UserTestRepository.ts b/src/data/repositories/UserTestRepository.ts
index 51805c6..4fa0a89 100644
--- a/src/data/repositories/UserTestRepository.ts
+++ b/src/data/repositories/UserTestRepository.ts
@@ -1,10 +1,13 @@
-import { User } from "../../domain/entities/User";
-import { createAdminUser } from "../../domain/entities/__tests__/userFixtures";
-import { Future } from "../../domain/entities/generic/Future";
-import { UserRepository } from "../../domain/repositories/UserRepository";
-import { FutureData } from "../api-futures";
+import { User } from "$/domain/entities/User";
+import { createAdminUser } from "$/domain/entities/__tests__/userFixtures";
+import { Future } from "$/domain/entities/generic/Future";
+import { UserRepository } from "$/domain/repositories/UserRepository";
+import { FutureData } from "$/data/api-futures";
 
 export class UserTestRepository implements UserRepository {
+    getByIds(): FutureData<User[]> {
+        throw new Error("Method not implemented.");
+    }
     getByUsernames(_: string[]): FutureData<User[]> {
         throw new Error("Method not implemented.");
     }
diff --git a/src/domain/entities/Country.ts b/src/domain/entities/Country.ts
index b0e5bb7..97a5955 100644
--- a/src/domain/entities/Country.ts
+++ b/src/domain/entities/Country.ts
@@ -1,3 +1,3 @@
 import { NamedRef } from "./Ref";
 
-export type Country = NamedRef & { path: string };
+export type Country = NamedRef & { path: string; writeAccess: boolean };
diff --git a/src/domain/entities/MetadataItem.ts b/src/domain/entities/MetadataItem.ts
index eaea019..e6e9c35 100644
--- a/src/domain/entities/MetadataItem.ts
+++ b/src/domain/entities/MetadataItem.ts
@@ -1,4 +1,4 @@
-import { Id, NamedCodeRef, NamedRef } from "./Ref";
+import { Id, NamedCodeRef, NamedRef, Ref } from "./Ref";
 
 export interface OptionSet extends NamedCodeRef {
     options: Array<{ id: Id; name: string; code: string }>;
@@ -40,4 +40,8 @@ export interface MetadataItem {
         correlative: NamedCodeRef;
     };
     programs: { qualityIssues: NamedRef & { programStages: ProgramStage[] } };
+    userGroups: {
+        dataCaptureModule1: NamedCodeRef & { users: Ref[] };
+        dataCaptureModule2And4: NamedCodeRef & { users: Ref[] };
+    };
 }
diff --git a/src/domain/entities/QualityAnalysisSection.ts b/src/domain/entities/QualityAnalysisSection.ts
index 01bf629..a3e4c5d 100644
--- a/src/domain/entities/QualityAnalysisSection.ts
+++ b/src/domain/entities/QualityAnalysisSection.ts
@@ -5,12 +5,19 @@ import { Id } from "./Ref";
 export interface QualityAnalysisSectionAttrs {
     id: Id;
     name: string;
+    description: string;
     issues: QualityAnalysisIssue[];
     status: string;
 }
 
+const SECTION_PENDING_STATE = "pending";
+
 export class QualityAnalysisSection extends Struct<QualityAnalysisSectionAttrs>() {
     static getInitialStatus(): string {
-        return "pending";
+        return SECTION_PENDING_STATE;
+    }
+
+    static isPending(section: QualityAnalysisSection): boolean {
+        return section.status === SECTION_PENDING_STATE;
     }
 }
diff --git a/src/domain/entities/User.ts b/src/domain/entities/User.ts
index 9323f57..9cc469d 100644
--- a/src/domain/entities/User.ts
+++ b/src/domain/entities/User.ts
@@ -1,12 +1,18 @@
+import { Maybe } from "$/utils/ts-utils";
+import { Country } from "./Country";
 import { Struct } from "./generic/Struct";
-import { NamedRef } from "./Ref";
+import { DateISOString, NamedRef } from "./Ref";
+import { UserGroup } from "./UserGroup";
 
 export interface UserAttrs {
     id: string;
+    email: string;
     name: string;
     username: string;
+    lastLogin: Maybe<DateISOString>;
     userRoles: UserRole[];
-    userGroups: NamedRef[];
+    userGroups: UserGroup[];
+    countries: Country[];
 }
 
 export interface UserRole extends NamedRef {
diff --git a/src/domain/entities/UserGroup.ts b/src/domain/entities/UserGroup.ts
new file mode 100644
index 0000000..af99546
--- /dev/null
+++ b/src/domain/entities/UserGroup.ts
@@ -0,0 +1,36 @@
+import { Id } from "./Ref";
+import { Either } from "./generic/Either";
+import { ValidationError } from "./generic/Errors";
+import { Struct } from "./generic/Struct";
+import { validateRequired } from "./generic/validations";
+
+type UserGroupAttrs = {
+    id: Id;
+    name: string;
+    usersIds: Id[];
+};
+
+export class UserGroup extends Struct<UserGroupAttrs>() {
+    static build(attrs: UserGroupAttrs): Either<ValidationError<UserGroup>[], UserGroup> {
+        const userGroup = new UserGroup(attrs);
+
+        const errors: ValidationError<UserGroup>[] = [
+            {
+                property: "name" as const,
+                errors: validateRequired(userGroup.name),
+                value: userGroup.name,
+            },
+            {
+                property: "id" as const,
+                errors: validateRequired(userGroup.id),
+                value: userGroup.id,
+            },
+        ].filter(validation => validation.errors.length > 0);
+
+        if (errors.length === 0) {
+            return Either.success(userGroup);
+        } else {
+            return Either.error(errors);
+        }
+    }
+}
diff --git a/src/domain/entities/__tests__/User.spec.ts b/src/domain/entities/__tests__/User.spec.ts
index 49bfcb4..d781ff9 100644
--- a/src/domain/entities/__tests__/User.spec.ts
+++ b/src/domain/entities/__tests__/User.spec.ts
@@ -1,5 +1,6 @@
 import { describe, expect, it } from "vitest";
 import { createAdminUser, createNonAdminUser, createUserWithGroups } from "./userFixtures";
+import { UserGroup } from "../UserGroup";
 
 describe("User", () => {
     it("should be admin if has a role with authority ALL", () => {
@@ -15,7 +16,9 @@ describe("User", () => {
     it("should return belong to user group equal to false when the id exist", () => {
         const userGroupId = "BwyMfDBLih9";
 
-        const user = createUserWithGroups([{ id: userGroupId, name: "Group 1" }]);
+        const user = createUserWithGroups([
+            UserGroup.build({ id: userGroupId, name: "Group 1", usersIds: [] }).get(),
+        ]);
 
         expect(user.belongToUserGroup(userGroupId)).toBe(true);
     });
@@ -23,7 +26,9 @@ describe("User", () => {
         const existedUserGroupId = "BwyMfDBLih9";
         const nonExistedUserGroupId = "f31IM13BgwJ";
 
-        const user = createUserWithGroups([{ id: existedUserGroupId, name: "Group 1" }]);
+        const user = createUserWithGroups([
+            UserGroup.build({ id: existedUserGroupId, name: "Group 1", usersIds: [] }).get(),
+        ]);
 
         expect(user.belongToUserGroup(nonExistedUserGroupId)).toBe(false);
     });
diff --git a/src/domain/entities/__tests__/userFixtures.ts b/src/domain/entities/__tests__/userFixtures.ts
index 28c6290..aae60dc 100644
--- a/src/domain/entities/__tests__/userFixtures.ts
+++ b/src/domain/entities/__tests__/userFixtures.ts
@@ -1,5 +1,5 @@
 import { User, UserRole } from "../User";
-import { NamedRef } from "../Ref";
+import { UserGroup } from "../UserGroup";
 
 export function createAdminUser(): User {
     const adminRoles = [{ id: "Hg7n0MwzUQn", name: "Super user", authorities: ["ALL"] }];
@@ -11,21 +11,27 @@ export function createNonAdminUser(): User {
 
     return createUser(nonAdminRoles, []);
 }
-export function createUserWithGroups(userGroups: NamedRef[] = []): User {
+export function createUserWithGroups(userGroups: UserGroup[] = []): User {
     return new User({
         id: "YjJdEO6d38H",
         name: "John Traore",
         username: "user",
         userRoles: [],
         userGroups,
+        countries: [],
+        email: "john@company.com",
+        lastLogin: "",
     });
 }
-function createUser(userRoles: UserRole[], userGroups: NamedRef[] = []): User {
+function createUser(userRoles: UserRole[], userGroups: UserGroup[] = []): User {
     return new User({
         id: "kQiwoyMYHBS",
         name: "John Traore",
         username: "user",
         userRoles,
         userGroups,
+        countries: [],
+        email: "john@company.com",
+        lastLogin: "",
     });
 }
diff --git a/src/domain/repositories/IssueRepository.ts b/src/domain/repositories/IssueRepository.ts
index 77d6a48..3d9ea54 100644
--- a/src/domain/repositories/IssueRepository.ts
+++ b/src/domain/repositories/IssueRepository.ts
@@ -1,5 +1,5 @@
 import { RowsPaginated } from "$/domain/entities/Pagination";
-import { Id } from "$/domain/entities/Ref";
+import { Id, Period } from "$/domain/entities/Ref";
 import { Maybe } from "$/utils/ts-utils";
 import { FutureData } from "../../data/api-futures";
 import { QualityAnalysisIssue } from "../entities/QualityAnalysisIssue";
@@ -14,12 +14,14 @@ export type GetIssuesOptions = {
     pagination: Pick<Pagination, "page" | "pageSize">;
     sorting: { field: string; order: "asc" | "desc" };
     filters: {
-        endDate: Maybe<string>;
+        actions: Maybe<string[]>;
+        countries: string[];
         name: Maybe<string>;
-        startDate: Maybe<string>;
-        status: Maybe<string>;
+        periods: Period[];
+        status: Maybe<string[]>;
         analysisIds: Maybe<Id[]>;
         sectionId: Maybe<Id>;
         id: Maybe<Id>;
+        followUp: Maybe<string>;
     };
 };
diff --git a/src/domain/repositories/QualityAnalysisRepository.ts b/src/domain/repositories/QualityAnalysisRepository.ts
index 4258bd7..ae856f0 100644
--- a/src/domain/repositories/QualityAnalysisRepository.ts
+++ b/src/domain/repositories/QualityAnalysisRepository.ts
@@ -7,7 +7,7 @@ export interface QualityAnalysisRepository {
     get(options: QualityAnalysisOptions): FutureData<QualityAnalysisPaginated>;
     getById(id: Id): FutureData<QualityAnalysis>;
     save(qualityAnalysis: QualityAnalysis[]): FutureData<void>;
-    remove(id: Id[]): FutureData<void>;
+    remove(id: Id): FutureData<void>;
 }
 
 export type Pagination = {
diff --git a/src/domain/repositories/UserRepository.ts b/src/domain/repositories/UserRepository.ts
index 8f64b5e..2b365b8 100644
--- a/src/domain/repositories/UserRepository.ts
+++ b/src/domain/repositories/UserRepository.ts
@@ -3,5 +3,6 @@ import { User } from "../entities/User";
 
 export interface UserRepository {
     getCurrent(): FutureData<User>;
+    getByIds(ids: string[]): FutureData<User[]>;
     getByUsernames(usernames: string[]): FutureData<User[]>;
 }
diff --git a/src/domain/usecases/GetMissingDisaggregatesUseCase.ts b/src/domain/usecases/GetMissingDisaggregatesUseCase.ts
index ca8216d..d309ed1 100644
--- a/src/domain/usecases/GetMissingDisaggregatesUseCase.ts
+++ b/src/domain/usecases/GetMissingDisaggregatesUseCase.ts
@@ -20,7 +20,6 @@ import { getCurrentSection } from "./common/utils";
 import { SettingsRepository } from "../repositories/SettingsRepository";
 import { SectionDisaggregation, SectionSetting, Settings } from "$/domain/entities/Settings";
 import { MissingComboValue } from "$/domain/entities/MissingComboValue";
-import { disaggregateKey } from "$/webapp/pages/analysis/steps";
 
 const separator = " - ";
 export class GetMissingDisaggregatesUseCase {
@@ -63,7 +62,7 @@ export class GetMissingDisaggregatesUseCase {
             );
 
             return this.issueUseCase
-                .getTotalIssuesBySection(analysis, disaggregateKey)
+                .getTotalIssuesBySection(analysis, options.sectionId)
                 .flatMap(totalIssues => {
                     const missingDisaggregateValues = missingValues.flatMap(missingValue =>
                         missingValue.type === "dataElements" ? missingValue.values : []
@@ -76,13 +75,15 @@ export class GetMissingDisaggregatesUseCase {
                     const issues = this.createIssuesFromMissingAggregate(
                         missingDisaggregateValues as MissingDisaggregates[],
                         analysis,
-                        totalIssues
+                        totalIssues,
+                        options
                     );
 
                     const issues2 = this.createIssuesFromMissingCombos(
                         missingComboValues as MissingComboValue[],
                         analysis,
-                        totalIssues + issues.length
+                        totalIssues + issues.length,
+                        options
                     );
 
                     const allIssues = [...issues, ...issues2];
@@ -90,7 +91,7 @@ export class GetMissingDisaggregatesUseCase {
                     return this.issueUseCase.save(allIssues, analysis.id).flatMap(() => {
                         const analysisUpdate = this.analysisUseCase.updateAnalysis(
                             analysis,
-                            disaggregateKey,
+                            options.sectionId,
                             allIssues.length
                         );
                         return this.analysisRepository.save([analysisUpdate]).flatMap(() => {
@@ -104,9 +105,10 @@ export class GetMissingDisaggregatesUseCase {
     private createIssuesFromMissingAggregate(
         missingValues: MissingDisaggregates[],
         analysis: QualityAnalysis,
-        totalIssues: number
+        totalIssues: number,
+        options: GetMissingDisaggregatesOptions
     ): QualityAnalysisIssue[] {
-        const section = getCurrentSection(analysis, disaggregateKey);
+        const section = getCurrentSection(analysis, options.sectionId);
 
         const onlyMissing = missingValues.filter(missingValue => missingValue.hasMissingValues);
         let acumulativeIssueNumber = totalIssues;
@@ -152,9 +154,10 @@ export class GetMissingDisaggregatesUseCase {
     private createIssuesFromMissingCombos(
         missingValues: MissingComboValue[],
         analysis: QualityAnalysis,
-        totalIssues: number
+        totalIssues: number,
+        options: GetMissingDisaggregatesOptions
     ): QualityAnalysisIssue[] {
-        const section = getCurrentSection(analysis, disaggregateKey);
+        const section = getCurrentSection(analysis, options.sectionId);
 
         const onlyMissing = missingValues.filter(missingValue => missingValue.hasMissingValues);
 
@@ -203,7 +206,7 @@ export class GetMissingDisaggregatesUseCase {
     ): MissingValues[] {
         const keys = _(dataValues).keys().value();
 
-        const sectionSetting = this.getSectionSetting(settings);
+        const sectionSetting = this.getSectionSetting(settings, options);
         const selectedDisaggregations = sectionSetting.disaggregations.filter(disaggregation => {
             return options.disaggregationsIds.includes(disaggregation.id);
         });
@@ -355,7 +358,7 @@ export class GetMissingDisaggregatesUseCase {
         settings: Settings
     ): FutureData<{ dataValues: Record<string, DataValue[]>; dataElements: DataElement[] }> {
         const { module } = analysis;
-        const sectionSetting = this.getSectionSetting(settings);
+        const sectionSetting = this.getSectionSetting(settings, options);
         const selectedDisaggregations = sectionSetting.disaggregations.filter(disaggregation => {
             return options.disaggregationsIds.includes(disaggregation.id);
         });
@@ -415,21 +418,6 @@ export class GetMissingDisaggregatesUseCase {
         });
     }
 
-    private validateDisaggregation(
-        selectedDisaggregations: SectionDisaggregation[],
-        dataElement: DataElement
-    ): Maybe<SectionDisaggregation> {
-        if (!dataElement.disaggregation) return undefined;
-
-        return selectedDisaggregations.find(d => {
-            if (d.type === "combos") {
-                return d.disaggregationId === dataElement.disaggregation?.id;
-            } else {
-                return d.id === dataElement.disaggregation?.id;
-            }
-        });
-    }
-
     private getDataValues(analysis: QualityAnalysis) {
         return this.dataValueUseCase.get(
             analysis.countriesAnalysis,
@@ -438,9 +426,12 @@ export class GetMissingDisaggregatesUseCase {
         );
     }
 
-    private getSectionSetting(settings: Settings): SectionSetting {
-        const sectionSetting = settings.sections.find(section => section.id === disaggregateKey);
-        if (!sectionSetting) throw Error(`Cannot found section in settings: ${disaggregateKey}`);
+    private getSectionSetting(
+        settings: Settings,
+        options: GetMissingDisaggregatesOptions
+    ): SectionSetting {
+        const sectionSetting = settings.sections.find(section => section.id === options.sectionId);
+        if (!sectionSetting) throw Error(`Cannot found section in settings: ${options.sectionId}`);
         return sectionSetting;
     }
 }
@@ -448,6 +439,7 @@ export class GetMissingDisaggregatesUseCase {
 type GetMissingDisaggregatesOptions = {
     analysisId: Id;
     disaggregationsIds: Id[];
+    sectionId: Id;
 };
 
 type MissingValues = {
diff --git a/src/domain/usecases/RemoveQualityUseCase.ts b/src/domain/usecases/RemoveQualityUseCase.ts
index 7fdedb6..bf60ec3 100644
--- a/src/domain/usecases/RemoveQualityUseCase.ts
+++ b/src/domain/usecases/RemoveQualityUseCase.ts
@@ -1,11 +1,19 @@
 import { FutureData } from "$/data/api-futures";
 import { Id } from "$/domain/entities/Ref";
 import { QualityAnalysisRepository } from "$/domain/repositories/QualityAnalysisRepository";
+import { Future } from "$/domain/entities/generic/Future";
 
 export class RemoveQualityUseCase {
     constructor(private qualityAnalysisRepository: QualityAnalysisRepository) {}
 
     execute(qualityAnalysisIds: Id[]): FutureData<void> {
-        return this.qualityAnalysisRepository.remove(qualityAnalysisIds);
+        const concurrencyRequest = 5;
+        const $requests = Future.parallel(
+            qualityAnalysisIds.map(issue => this.qualityAnalysisRepository.remove(issue)),
+            { concurrency: concurrencyRequest }
+        );
+        return $requests.flatMap(() => {
+            return Future.success(undefined);
+        });
     }
 }
diff --git a/src/domain/usecases/RunOutlierUseCase.ts b/src/domain/usecases/RunOutlierUseCase.ts
index 2babd77..2594a8e 100644
--- a/src/domain/usecases/RunOutlierUseCase.ts
+++ b/src/domain/usecases/RunOutlierUseCase.ts
@@ -3,17 +3,15 @@ import { IssueStatus } from "$/domain/entities/IssueStatus";
 import { Outlier } from "$/domain/entities/Outlier";
 import { QualityAnalysis } from "$/domain/entities/QualityAnalysis";
 import { QualityAnalysisIssue } from "$/domain/entities/QualityAnalysisIssue";
-import { QualityAnalysisSection } from "$/domain/entities/QualityAnalysisSection";
 import { Id } from "$/domain/entities/Ref";
 import { Future } from "$/domain/entities/generic/Future";
 import { getUid } from "$/utils/uid";
-import { outlierKey } from "$/webapp/pages/analysis/steps";
-import { IssueRepository } from "../repositories/IssueRepository";
-import { OutlierRepository } from "../repositories/OutlierRepository";
-import { QualityAnalysisRepository } from "../repositories/QualityAnalysisRepository";
+import { IssueRepository } from "$/domain/repositories/IssueRepository";
+import { OutlierRepository } from "$/domain/repositories/OutlierRepository";
+import { QualityAnalysisRepository } from "$/domain/repositories/QualityAnalysisRepository";
 import _ from "$/domain/entities/generic/Collection";
-import { ModuleRepository } from "../repositories/ModuleRepository";
-import { DataElement } from "../entities/DataElement";
+import { ModuleRepository } from "$/domain/repositories/ModuleRepository";
+import { DataElement } from "$/domain/entities/DataElement";
 import { UCIssue } from "./common/UCIssue";
 import { UCAnalysis } from "./common/UCAnalysis";
 
@@ -41,14 +39,14 @@ export class RunOutlierUseCase {
                     dataElements.map(dataElement => dataElement.id)
                 ).flatMap(outliers => {
                     return this.issueUseCase
-                        .getTotalIssuesBySection(analysis, outlierKey)
+                        .getTotalIssuesBySection(analysis, options.sectionId)
                         .flatMap(totalIssues => {
                             return this.saveIssues(outliers, analysis, totalIssues, options);
                         })
                         .flatMap(() => {
                             const analysisToUpdate = this.analysisUseCase.updateAnalysis(
                                 analysis,
-                                outlierKey,
+                                options.sectionId,
                                 outliers.length
                             );
                             return this.analysisRepository
@@ -100,21 +98,20 @@ export class RunOutlierUseCase {
         totalIssues: number,
         options: RunOutlierUseCaseOptions
     ): FutureData<void> {
-        const section = this.getCurrentSection(analysis);
         if (outliers.length === 0) return Future.success(undefined);
         const issuesToSave = outliers.map((outlier, index) => {
             const currentNumber = totalIssues + 1 + index;
             const correlative = currentNumber < 10 ? `0${currentNumber}` : currentNumber;
             const issueNumber = `${analysis.sequential.value}-S01-I${correlative}`;
             return new QualityAnalysisIssue({
-                id: getUid(`issue-event_${outlierKey}_${new Date().getTime()}`),
+                id: getUid(`issue-event_${options.sectionId}_${new Date().getTime()}`),
                 number: issueNumber,
                 azureUrl: "",
                 period: outlier.period,
-                country: { id: outlier.countryId, name: "", path: "" },
+                country: { id: outlier.countryId, name: "", path: "", writeAccess: false },
                 dataElement: { id: outlier.dataElementId, name: "" },
                 categoryOption: { id: outlier.categoryOptionId, name: "" },
-                description: "",
+                description: this.getDescriptionIssue(outlier, options),
                 followUp: false,
                 status: IssueStatus.create({
                     id: "",
@@ -122,8 +119,8 @@ export class RunOutlierUseCase {
                     name: "",
                 }),
                 action: undefined,
-                actionDescription: this.getActionDescription(outlier, options),
-                type: section.id,
+                actionDescription: "",
+                type: options.sectionId,
                 comments: "",
                 contactEmails: "",
                 correlative: String(currentNumber),
@@ -132,13 +129,7 @@ export class RunOutlierUseCase {
         return this.issueUseCase.save(issuesToSave, analysis.id);
     }
 
-    private getCurrentSection(analysis: QualityAnalysis): QualityAnalysisSection {
-        const section = analysis.sections.find(section => section.name === outlierKey);
-        if (!section) throw Error(`Cannot found section: ${outlierKey}`);
-        return section;
-    }
-
-    private getActionDescription(outlier: Outlier, options: RunOutlierUseCaseOptions): string {
+    private getDescriptionIssue(outlier: Outlier, options: RunOutlierUseCaseOptions): string {
         return outlier.zScore
             ? `An outlier was detected using ${
                   options.algorithm
@@ -153,4 +144,5 @@ type RunOutlierUseCaseOptions = {
     qualityAnalysisId: Id;
     algorithm: string;
     threshold: string;
+    sectionId: Id;
 };
diff --git a/src/domain/usecases/RunPractitionersValidationUseCase.ts b/src/domain/usecases/RunPractitionersValidationUseCase.ts
index f227267..440c466 100644
--- a/src/domain/usecases/RunPractitionersValidationUseCase.ts
+++ b/src/domain/usecases/RunPractitionersValidationUseCase.ts
@@ -12,7 +12,6 @@ import { DataValue } from "$/domain/entities/DataValue";
 import { DataValueRepository } from "$/domain/repositories/DataValueRepository";
 import { QualityAnalysis } from "$/domain/entities/QualityAnalysis";
 import { QualityAnalysisIssue } from "$/domain/entities/QualityAnalysisIssue";
-import { practitionersKey } from "$/webapp/pages/analysis/steps";
 import { IssueRepository } from "$/domain/repositories/IssueRepository";
 import { UCIssue } from "./common/UCIssue";
 import { UCAnalysis } from "./common/UCAnalysis";
@@ -54,7 +53,7 @@ export class RunPractitionersValidationUseCase {
                 const practitionerDataElements = this.groupDataElements(dataElements);
 
                 return this.issueUseCase
-                    .getTotalIssuesBySection(analysis, practitionersKey)
+                    .getTotalIssuesBySection(analysis, options.sectionId)
                     .flatMap(totalIssues => {
                         return this.getDataValues(analysis).flatMap(dataValues => {
                             const practitionerDataValues = this.getPractitionerDataValues(
@@ -97,7 +96,7 @@ export class RunPractitionersValidationUseCase {
 
                             const analysisToUpdate = this.analysysUseCase.updateAnalysis(
                                 analysis,
-                                practitionersKey,
+                                options.sectionId,
                                 issues.length
                             );
 
@@ -172,7 +171,8 @@ export class RunPractitionersValidationUseCase {
                 `Values for ${dataElement.dataElementParent.name} subcategories are missing`,
                 dataValue,
                 totalIssues + (index + 1),
-                analysis
+                analysis,
+                options
             );
         });
 
@@ -196,7 +196,8 @@ export class RunPractitionersValidationUseCase {
                 description,
                 dataValue,
                 totalIssues + missingIssues.length + (index + 1),
-                analysis
+                analysis,
+                options
             );
         });
 
@@ -209,9 +210,10 @@ export class RunPractitionersValidationUseCase {
         description: string,
         dataValue: DataValue,
         currentNumber: number,
-        analysis: QualityAnalysis
+        analysis: QualityAnalysis,
+        options: PractitionersValidationOptions
     ) {
-        const section = getCurrentSection(analysis, practitionersKey);
+        const section = getCurrentSection(analysis, options.sectionId);
         const { dataElementId, period, countryId, categoryOptionComboId } = dataValue;
         const prefix = `${analysis.sequential.value}-S04`;
         const issueNumber = this.issueUseCase.generateIssueNumber(currentNumber, prefix);
@@ -400,8 +402,9 @@ export class RunPractitionersValidationUseCase {
 
 type PractitionersValidationOptions = {
     analysisId: Id;
-    threshold: number;
     dissagregationsIds: Id[];
+    sectionId: Id;
+    threshold: number;
 };
 
 type DataElementsLevel = {
diff --git a/src/domain/usecases/SaveIssueUseCase.ts b/src/domain/usecases/SaveIssueUseCase.ts
index 2b05db7..084e535 100644
--- a/src/domain/usecases/SaveIssueUseCase.ts
+++ b/src/domain/usecases/SaveIssueUseCase.ts
@@ -1,37 +1,120 @@
 import { FutureData } from "$/data/api-futures";
-import { IssueAction } from "../entities/IssueAction";
-import { IssueStatus } from "../entities/IssueStatus";
-import { MetadataItem } from "../entities/MetadataItem";
-import { QualityAnalysis } from "../entities/QualityAnalysis";
-import { IssuePropertyName, QualityAnalysisIssue } from "../entities/QualityAnalysisIssue";
-import { QualityAnalysisSection } from "../entities/QualityAnalysisSection";
-import { Id } from "../entities/Ref";
-import { QualityAnalysisRepository } from "../repositories/QualityAnalysisRepository";
+import { User } from "$/domain/entities/User";
+import { IssueAction } from "$/domain/entities/IssueAction";
+import { IssueStatus } from "$/domain/entities/IssueStatus";
+import { MetadataItem } from "$/domain/entities/MetadataItem";
+import { QualityAnalysis } from "$/domain/entities/QualityAnalysis";
+import { IssuePropertyName, QualityAnalysisIssue } from "$/domain/entities/QualityAnalysisIssue";
+import { QualityAnalysisSection } from "$/domain/entities/QualityAnalysisSection";
+import { Id } from "$/domain/entities/Ref";
+import { Future } from "$/domain/entities/generic/Future";
+import { QualityAnalysisRepository } from "$/domain/repositories/QualityAnalysisRepository";
+import { UserRepository } from "$/domain/repositories/UserRepository";
+import _ from "$/domain/entities/generic/Collection";
+import { Maybe } from "$/utils/ts-utils";
 
 export class SaveIssueUseCase {
     constructor(
         private analysisRepository: QualityAnalysisRepository,
+        private userRepository: UserRepository,
         private metadata: MetadataItem
     ) {}
 
-    execute(options: SaveIssueOptions): FutureData<void> {
+    execute(options: SaveIssueOptions): FutureData<SaveIssueResponse> {
         return this.getAnalysis(options).flatMap(analysis => {
-            const analysisUpdate = QualityAnalysis.build({
-                ...analysis,
-                sections: analysis.sections.map(section => {
-                    if (section.id !== options.issue.type) return section;
-                    return QualityAnalysisSection.create({
-                        ...section,
-                        issues: [this.buildIssueWithNewValue(options)],
-                    });
-                }),
-            }).get();
-
-            return this.analysisRepository.save([analysisUpdate]);
+            return this.generateContactEmails(analysis, options).flatMap(contactEmails => {
+                const issueToUpdate = this.buildIssueWithNewValue(options, contactEmails);
+                const analysisUpdate = QualityAnalysis.build({
+                    ...analysis,
+                    sections: analysis.sections.map(section => {
+                        if (section.id !== options.issue.type) return section;
+                        return QualityAnalysisSection.create({
+                            ...section,
+                            issues: [issueToUpdate],
+                        });
+                    }),
+                }).get();
+
+                return this.analysisRepository.save([analysisUpdate]).flatMap(() => {
+                    return Future.success({ contactEmailsChanged: Boolean(contactEmails) });
+                });
+            });
+        });
+    }
+
+    private generateContactEmails(
+        analysis: QualityAnalysis,
+        options: SaveIssueOptions
+    ): FutureData<Maybe<ContactEmailsUsers>> {
+        if (options.propertyToUpdate === "followUp" && options.valueToUpdate === true) {
+            const usersIds = this.getUsersIdsFromGroup(analysis);
+            if (usersIds.length === 0) return Future.success(undefined);
+
+            return this.getUsersByIds(usersIds, options.issue).flatMap(users => {
+                const contactEmails = this.getContactEmailsUsers(users);
+                return Future.success(contactEmails);
+            });
+        }
+        return Future.success(undefined);
+    }
+
+    private getContactEmailsUsers(users: User[]): Maybe<ContactEmailsUsers> {
+        const firstUser = _(users).first();
+        if (!firstUser) return undefined;
+        const ccUsers = users.slice(1);
+        return { to: firstUser, cc: ccUsers };
+    }
+
+    private getUsersByIds(userIds: Id[], issue: QualityAnalysisIssue): FutureData<User[]> {
+        return this.userRepository.getByIds(userIds).flatMap(users => {
+            const loggedInUsersWithEmail = this.getLoggedInUsersWithEmail(users);
+            const usersInCountry = this.getUsersInIssueCountry(loggedInUsersWithEmail, issue);
+            return Future.success(usersInCountry);
         });
     }
 
-    private buildIssueWithNewValue(options: SaveIssueOptions): QualityAnalysisIssue {
+    private getUsersInIssueCountry(users: User[], issue: QualityAnalysisIssue): User[] {
+        return _(users)
+            .map(user => {
+                const userIsInIssueCountry = user.countries.some(
+                    country => country.writeAccess && country.id === issue.country?.id
+                );
+                return userIsInIssueCountry ? user : undefined;
+            })
+            .compact()
+            .value();
+    }
+
+    private getLoggedInUsersWithEmail(users: User[]): User[] {
+        return _(users)
+            .map(user => {
+                if (!user.email || !user.lastLogin) return undefined;
+                return user;
+            })
+            .compact()
+            .sortBy(user => user.lastLogin, {
+                compareFn: (first, second) => {
+                    if (!first || !second) return 0;
+                    return first < second ? 1 : first > second ? -1 : 0;
+                },
+            })
+            .value();
+    }
+
+    private getUsersIdsFromGroup(analysis: QualityAnalysis): Id[] {
+        if (analysis.module.name.toLocaleLowerCase().includes("module 1")) {
+            return this.metadata.userGroups.dataCaptureModule1.users.map(user => user.id);
+        } else if (analysis.module.name.toLocaleLowerCase().includes("module 2")) {
+            return this.metadata.userGroups.dataCaptureModule2And4.users.map(user => user.id);
+        } else {
+            return [];
+        }
+    }
+
+    private buildIssueWithNewValue(
+        options: SaveIssueOptions,
+        contactEmails: Maybe<ContactEmailsUsers>
+    ): QualityAnalysisIssue {
         switch (options.propertyToUpdate) {
             case "azureUrl": {
                 return this.setNewValue(options);
@@ -83,9 +166,13 @@ export class SaveIssueUseCase {
                 });
             }
             case "followUp": {
+                const value = options.valueToUpdate as boolean;
                 return QualityAnalysisIssue.create({
                     ...options.issue,
-                    followUp: options.valueToUpdate as boolean,
+                    contactEmails: value
+                        ? this.getContactEmailsString(contactEmails)
+                        : options.issue.contactEmails,
+                    followUp: value,
                 });
             }
             default:
@@ -93,6 +180,13 @@ export class SaveIssueUseCase {
         }
     }
 
+    private getContactEmailsString(contactEmails: Maybe<ContactEmailsUsers>): string {
+        if (!contactEmails) return "";
+        const to = `TO: ${contactEmails.to.email}`;
+        const cc = contactEmails.cc.map(user => user.email).join(";");
+        return cc ? `${to} || CC:${cc}` : to;
+    }
+
     private setNewValue(options: SaveIssueOptions): QualityAnalysisIssue {
         return QualityAnalysisIssue.create({
             ...options.issue,
@@ -111,3 +205,9 @@ type SaveIssueOptions = {
     propertyToUpdate: IssuePropertyName;
     valueToUpdate: string | boolean;
 };
+
+type ContactEmailsUsers = { to: User; cc: User[] };
+
+type SaveIssueResponse = {
+    contactEmailsChanged: boolean;
+};
diff --git a/src/domain/usecases/ValidateMidwiferyAndPersonnelUseCase.ts b/src/domain/usecases/ValidateMidwiferyAndPersonnelUseCase.ts
index 44f2bd8..abf030a 100644
--- a/src/domain/usecases/ValidateMidwiferyAndPersonnelUseCase.ts
+++ b/src/domain/usecases/ValidateMidwiferyAndPersonnelUseCase.ts
@@ -1,3 +1,5 @@
+import _ from "lodash";
+
 import { FutureData } from "$/data/api-futures";
 import { DataElement } from "$/domain/entities/DataElement";
 import { QualityAnalysis } from "$/domain/entities/QualityAnalysis";
@@ -6,16 +8,16 @@ import { Future } from "$/domain/entities/generic/Future";
 import { DataValueRepository } from "$/domain/repositories/DataValueRepository";
 import { ModuleRepository } from "$/domain/repositories/ModuleRepository";
 import { QualityAnalysisRepository } from "$/domain/repositories/QualityAnalysisRepository";
-import _ from "lodash";
-import { UCAnalysis } from "./common/UCAnalysis";
-import { UCDataValue } from "./common/UCDataValue";
 import { DataValue } from "$/domain/entities/DataValue";
 import { MidwiferyNursing } from "$/domain/entities/MidwiferyPersonnel";
-import { SettingsRepository } from "../repositories/SettingsRepository";
+import { SettingsRepository } from "$/domain/repositories/SettingsRepository";
 import { SectionDisaggregation } from "$/domain/entities/Settings";
 import { UCIssue } from "./common/UCIssue";
 import { QualityAnalysisIssue } from "$/domain/entities/QualityAnalysisIssue";
-import { IssueRepository } from "../repositories/IssueRepository";
+import { IssueRepository } from "$/domain/repositories/IssueRepository";
+
+import { UCAnalysis } from "./common/UCAnalysis";
+import { UCDataValue } from "./common/UCDataValue";
 import { getCurrentSection } from "./common/utils";
 
 export class ValidateMidwiferyAndPersonnelUseCase {
diff --git a/src/domain/usecases/common/UCAnalysis.ts b/src/domain/usecases/common/UCAnalysis.ts
index 840a7ab..479acda 100644
--- a/src/domain/usecases/common/UCAnalysis.ts
+++ b/src/domain/usecases/common/UCAnalysis.ts
@@ -11,16 +11,12 @@ export class UCAnalysis {
         return this.analysisRepository.getById(id);
     }
 
-    updateAnalysis(
-        analysis: QualityAnalysis,
-        sectionName: string,
-        totalIssues: number
-    ): QualityAnalysis {
+    updateAnalysis(analysis: QualityAnalysis, sectionId: Id, totalIssues: number): QualityAnalysis {
         return QualityAnalysis.build({
             ...analysis,
             lastModification: new Date().toISOString(),
             sections: analysis.sections.map(section => {
-                if (section.name !== sectionName) return section;
+                if (section.id !== sectionId) return section;
                 return QualityAnalysisSection.create({
                     ...section,
                     status: totalIssues === 0 ? "success" : "success_with_issues",
diff --git a/src/domain/usecases/common/UCIssue.ts b/src/domain/usecases/common/UCIssue.ts
index 8f07140..166a56b 100644
--- a/src/domain/usecases/common/UCIssue.ts
+++ b/src/domain/usecases/common/UCIssue.ts
@@ -7,7 +7,6 @@ import { IssueStatus } from "$/domain/entities/IssueStatus";
 import _ from "$/domain/entities/generic/Collection";
 import { FutureData } from "$/data/api-futures";
 import { QualityAnalysis } from "$/domain/entities/QualityAnalysis";
-import { getCurrentSection } from "./utils";
 
 export class UCIssue {
     constructor(private issueRepository: IssueRepository) {}
@@ -42,7 +41,7 @@ export class UCIssue {
             number: issueNumber,
             azureUrl: "",
             period: period,
-            country: { id: countryId, name: "", path: "" },
+            country: { id: countryId, name: "", path: "", writeAccess: false },
             dataElement: { id: dataElementId, name: "" },
             categoryOption: { id: categoryOptionComboId, name: "" },
             description: description,
@@ -67,18 +66,19 @@ export class UCIssue {
         return issueNumber;
     }
 
-    getTotalIssuesBySection(analysis: QualityAnalysis, sectionName: string): FutureData<number> {
-        const section = getCurrentSection(analysis, sectionName);
+    getTotalIssuesBySection(analysis: QualityAnalysis, sectionId: string): FutureData<number> {
         return this.issueRepository
             .get({
                 filters: {
-                    endDate: undefined,
+                    actions: undefined,
+                    countries: [],
                     analysisIds: [analysis.id],
                     name: undefined,
-                    sectionId: section?.id,
-                    startDate: undefined,
+                    sectionId: sectionId,
+                    periods: [],
                     status: undefined,
                     id: undefined,
+                    followUp: undefined,
                 },
                 pagination: { page: 1, pageSize: 10 },
                 sorting: { field: "number", order: "asc" },
diff --git a/src/domain/usecases/common/utils.ts b/src/domain/usecases/common/utils.ts
index 79cdee7..12ced4d 100644
--- a/src/domain/usecases/common/utils.ts
+++ b/src/domain/usecases/common/utils.ts
@@ -30,10 +30,10 @@ export function getQualityAnalysis(
 
 export function getCurrentSection(
     analysis: QualityAnalysis,
-    sectionName: string
+    sectionId: Id
 ): QualityAnalysisSection {
-    const section = analysis.sections.find(section => section.name === sectionName);
-    if (!section) throw Error(`Cannot found section: ${sectionName}`);
+    const section = analysis.sections.find(section => section.id === sectionId);
+    if (!section) throw Error(`Cannot found section: ${sectionId}`);
     return section;
 }
 
@@ -46,13 +46,15 @@ export function getIssues(
     return issueRepository
         .get({
             filters: {
-                endDate: undefined,
+                actions: undefined,
+                countries: [],
+                periods: [],
                 analysisIds: [analysis.id],
                 name: undefined,
                 sectionId: section?.id,
-                startDate: undefined,
                 status: undefined,
                 id: undefined,
+                followUp: undefined,
             },
             pagination: { page: 1, pageSize: 10 },
             sorting: { field: "number", order: "asc" },
diff --git a/src/webapp/components/configuration-form/ConfigurationForm.tsx b/src/webapp/components/configuration-form/ConfigurationForm.tsx
index 6d36944..6e9f6e4 100644
--- a/src/webapp/components/configuration-form/ConfigurationForm.tsx
+++ b/src/webapp/components/configuration-form/ConfigurationForm.tsx
@@ -13,7 +13,7 @@ import { Country } from "$/domain/entities/Country";
 import styled from "styled-components";
 import { getDefaultModules } from "$/data/common/D2Module";
 
-function getIdFromCountriesPaths(paths: string[]): string[] {
+export function getIdFromCountriesPaths(paths: string[]): string[] {
     return _(paths)
         .map(path => {
             return _(path.split("/")).last() || undefined;
@@ -49,7 +49,7 @@ export function useCountries(props: UseCountriesProps) {
 
 export const ConfigurationForm: React.FC<ConfigurationFormProps> = React.memo(props => {
     const { initialCountries, initialData, onSave } = props;
-    const { api, metadata } = useAppContext();
+    const { api, currentUser, metadata } = useAppContext();
     const { countries } = useCountries({ ids: initialData.countriesAnalysis });
     const [formData, setFormData] = React.useState<QualityAnalysis>(() => {
         return initialData;
@@ -159,7 +159,7 @@ export const ConfigurationForm: React.FC<ConfigurationFormProps> = React.memo(pr
                         selected={selectedOrgUnits}
                         levels={[1, 2, 3]}
                         selectableLevels={[1, 2, 3]}
-                        rootIds={initialCountries}
+                        rootIds={currentUser.countries.map(country => country.id)}
                         withElevation={false}
                     />
                 </OrgUnitContainer>
diff --git a/src/webapp/components/country-selector/CountrySelector.tsx b/src/webapp/components/country-selector/CountrySelector.tsx
new file mode 100644
index 0000000..d933fee
--- /dev/null
+++ b/src/webapp/components/country-selector/CountrySelector.tsx
@@ -0,0 +1,33 @@
+import React from "react";
+import { OrgUnitsSelector } from "@eyeseetea/d2-ui-components";
+
+import { D2Api } from "$/types/d2-api";
+import { Id } from "$/domain/entities/Ref";
+import _ from "$/domain/entities/generic/Collection";
+
+export const CountrySelector: React.FC<CountrySelectorProps> = props => {
+    const { api, onChange, rootIds, selectedCountriesIds: selectedOrgUnits } = props;
+
+    const onOrgUnitsChange = (ids: Id[]) => {
+        onChange(ids);
+    };
+
+    return (
+        <OrgUnitsSelector
+            api={api}
+            onChange={onOrgUnitsChange}
+            selected={selectedOrgUnits}
+            levels={[1, 2, 3]}
+            selectableLevels={[1, 2, 3]}
+            rootIds={rootIds}
+            withElevation={false}
+        />
+    );
+};
+
+type CountrySelectorProps = {
+    api: D2Api;
+    onChange: (ids: Id[]) => void;
+    rootIds: Id[];
+    selectedCountriesIds: Id[];
+};
diff --git a/src/webapp/components/issues/EditIssueValue.tsx b/src/webapp/components/issues/EditIssueValue.tsx
index ad837cd..3c2671a 100644
--- a/src/webapp/components/issues/EditIssueValue.tsx
+++ b/src/webapp/components/issues/EditIssueValue.tsx
@@ -5,7 +5,7 @@ import { IssuePropertyName, QualityAnalysisIssue } from "$/domain/entities/Quali
 import { CheckboxInline } from "./CheckboxInline";
 import { SelectorInline } from "./SelectorInline";
 import { useAppContext } from "$/webapp/contexts/app-context";
-import { useLoading, useSnackbar } from "@eyeseetea/d2-ui-components";
+import { SnackbarState, useLoading, useSnackbar } from "@eyeseetea/d2-ui-components";
 import { Id } from "$/domain/entities/Ref";
 import i18n from "$/utils/i18n";
 import { useParams } from "react-router-dom";
@@ -14,10 +14,26 @@ type UpdateIssuePropertyProps = {
     analysisId: Id;
     issue: QualityAnalysisIssue;
     field: IssuePropertyName;
+    setRefresh?: React.Dispatch<React.SetStateAction<number>>;
 };
 
+function getContactEmailNotification(
+    field: IssuePropertyName,
+    value: boolean,
+    emailChanged: boolean,
+    snackbar: SnackbarState
+) {
+    if (field === "followUp" && value === true && !emailChanged) {
+        snackbar.warning(
+            i18n.t(
+                "No user with Capture rights and Organisation Unit associated to the issue was found"
+            )
+        );
+    }
+}
+
 export function useUpdateIssueProperty(props: UpdateIssuePropertyProps) {
-    const { analysisId, field, issue } = props;
+    const { analysisId, field, issue, setRefresh } = props;
     const { compositionRoot } = useAppContext();
     const loading = useLoading();
     const snackbar = useSnackbar();
@@ -33,9 +49,16 @@ export function useUpdateIssueProperty(props: UpdateIssuePropertyProps) {
                     valueToUpdate: value,
                 })
                 .run(
-                    () => {
+                    result => {
                         loading.hide();
                         snackbar.success(i18n.t("Issue Updated"));
+                        if (setRefresh) setRefresh(refresh => refresh + 1);
+                        getContactEmailNotification(
+                            field,
+                            value as boolean,
+                            Boolean(result.contactEmailsChanged),
+                            snackbar
+                        );
                     },
                     err => {
                         snackbar.error(err.message);
@@ -43,7 +66,7 @@ export function useUpdateIssueProperty(props: UpdateIssuePropertyProps) {
                     }
                 );
         },
-        [compositionRoot.issues.save, loading, snackbar, issue, analysisId, field]
+        [compositionRoot.issues.save, loading, snackbar, issue, analysisId, field, setRefresh]
     );
 
     return { updateIssue };
@@ -52,11 +75,12 @@ export function useUpdateIssueProperty(props: UpdateIssuePropertyProps) {
 export const EditIssueValue: React.FC<EditIssueValueProps> = React.memo(props => {
     const { id } = useParams<{ id: string }>();
     const { metadata } = useAppContext();
-    const { issue, field } = props;
+    const { issue, field, setRefresh } = props;
     const { updateIssue } = useUpdateIssueProperty({
         analysisId: id,
         field: field,
         issue: issue,
+        setRefresh,
     });
 
     const onSave = (value: string | boolean) => {
@@ -67,7 +91,13 @@ export const EditIssueValue: React.FC<EditIssueValueProps> = React.memo(props =>
         case "comments":
             return <InputInline value={issue.comments} onSave={onSave} />;
         case "contactEmails":
-            return <InputInline value={issue.contactEmails} onSave={onSave} />;
+            return (
+                <InputInline
+                    key={issue.contactEmails}
+                    value={issue.contactEmails}
+                    onSave={onSave}
+                />
+            );
         case "description":
             return <InputInline value={issue.description} onSave={onSave} />;
         case "actionDescription":
@@ -101,4 +131,8 @@ export const EditIssueValue: React.FC<EditIssueValueProps> = React.memo(props =>
     }
 });
 
-type EditIssueValueProps = { issue: QualityAnalysisIssue; field: IssuePropertyName };
+type EditIssueValueProps = {
+    issue: QualityAnalysisIssue;
+    field: IssuePropertyName;
+    setRefresh?: React.Dispatch<React.SetStateAction<number>>;
+};
diff --git a/src/webapp/components/issues/IssueFilters.tsx b/src/webapp/components/issues/IssueFilters.tsx
new file mode 100644
index 0000000..2b3399d
--- /dev/null
+++ b/src/webapp/components/issues/IssueFilters.tsx
@@ -0,0 +1,178 @@
+import React from "react";
+
+import { Id, Period } from "$/domain/entities/Ref";
+import { GetIssuesOptions } from "$/domain/repositories/IssueRepository";
+import { SelectMultiCheckboxes } from "../selectmulti-checkboxes/SelectMultiCheckboxes";
+import { periods } from "../analysis-filter/AnalysisFilter";
+import { Maybe } from "$/utils/ts-utils";
+import i18n from "$/utils/i18n";
+import { useAppContext } from "$/webapp/contexts/app-context";
+import { Dropdown, useSnackbar } from "@eyeseetea/d2-ui-components";
+import styled from "styled-components";
+import { Button, Dialog, DialogActions, TextField } from "@material-ui/core";
+import { CountrySelector } from "../country-selector/CountrySelector";
+import { getIdFromCountriesPaths } from "../configuration-form/ConfigurationForm";
+import { Country } from "$/domain/entities/Country";
+
+const followUpItems = [
+    {
+        value: "1",
+        text: i18n.t("Yes"),
+    },
+    {
+        value: "0",
+        text: i18n.t("No"),
+    },
+];
+
+function extractCountriesNames(countries: Country[], totalCountriesSelected: number) {
+    const countryNames = countries
+        .map(country => country.name)
+        .slice(0, 2)
+        .join(", ");
+
+    const moreCountriesCount = totalCountriesSelected - 2;
+
+    const countryNamesString =
+        moreCountriesCount > 0
+            ? i18n.t("{{countryNames}} and {{moreCountriesCount}} more", {
+                  countryNames,
+                  moreCountriesCount,
+              })
+            : countryNames;
+
+    return countryNamesString;
+}
+
+export const IssueFilters: React.FC<IssueFiltersProps> = props => {
+    const { api, compositionRoot, currentUser, metadata } = useAppContext();
+    const snackbar = useSnackbar();
+    const { initialFilters, onChange } = props;
+    const [openCountry, setOpenCountry] = React.useState(false);
+    const [selectedCountriesIds, setSelectedCountriesIds] = React.useState<Id[]>([]);
+    const [countries, setCountries] = React.useState<Country[]>([]);
+
+    const onFilterChange = React.useCallback<
+        (value: Maybe<string> | string[], filterAttribute: string) => void
+    >(
+        (value, filterAttribute) => {
+            onChange(prev => ({ ...prev, [filterAttribute]: value }));
+        },
+        [onChange]
+    );
+
+    const actions = metadata.optionSets.nhwaAction.options.map(option => {
+        return { value: option.code, text: option.name };
+    });
+
+    const status = metadata.optionSets.nhwaStatus.options.map(option => {
+        return { value: option.code, text: option.name };
+    });
+
+    const onClickCountry = () => {
+        setOpenCountry(true);
+    };
+
+    const onChangeFilterCountry = (action: "save" | "close") => {
+        if (action === "save") {
+            const countriesIds = getIdFromCountriesPaths(selectedCountriesIds);
+            compositionRoot.countries.getByIds.execute(countriesIds.slice(0, 2)).run(
+                countries => {
+                    onFilterChange(countriesIds, "countries");
+                    setCountries(countries);
+                    setOpenCountry(false);
+                },
+                error => {
+                    snackbar.error(error.message);
+                }
+            );
+        } else {
+            setOpenCountry(false);
+        }
+    };
+
+    const onCountrySelected = (paths: Id[]) => {
+        setSelectedCountriesIds(paths);
+    };
+
+    const countryNamesString = extractCountriesNames(countries, selectedCountriesIds.length);
+
+    return (
+        <FilterContainer>
+            <Dialog fullWidth maxWidth="lg" open={openCountry}>
+                <CountrySelector
+                    api={api}
+                    onChange={onCountrySelected}
+                    rootIds={currentUser.countries.map(country => country.id)}
+                    selectedCountriesIds={selectedCountriesIds}
+                />
+                <DialogActions>
+                    <Button onClick={() => onChangeFilterCountry("close")} color="primary">
+                        {i18n.t("Close")}
+                    </Button>
+                    <Button onClick={() => onChangeFilterCountry("save")} color="primary">
+                        {i18n.t("Save")}
+                    </Button>
+                </DialogActions>
+            </Dialog>
+            <div>
+                <TextField
+                    name="countries"
+                    label={i18n.t("Countries")}
+                    onClick={onClickCountry}
+                    title={countryNamesString}
+                    value={countryNamesString}
+                />
+            </div>
+
+            <SelectMultiCheckboxes
+                label={i18n.t("Periods")}
+                onChange={values => onFilterChange(values, "periods")}
+                options={periods}
+                value={initialFilters.periods}
+            />
+
+            <SelectMultiCheckboxes
+                label={i18n.t("Status")}
+                onChange={values => onFilterChange(values, "status")}
+                options={status}
+                value={initialFilters.status || []}
+            />
+
+            <SelectMultiCheckboxes
+                label={i18n.t("Action")}
+                onChange={values => onFilterChange(values, "actions")}
+                options={actions}
+                value={initialFilters.actions || []}
+            />
+
+            <Dropdown
+                className="config-form-selector"
+                label={i18n.t("Follow Up")}
+                items={followUpItems}
+                onChange={value => onFilterChange(value, "followUp")}
+                value={initialFilters.followUp}
+            />
+        </FilterContainer>
+    );
+};
+
+type IssueFiltersProps = {
+    initialFilters: IssueFilterState;
+    onChange: React.Dispatch<React.SetStateAction<GetIssuesOptions["filters"]>>;
+};
+
+export type IssueFilterState = {
+    countries: Id[];
+    actions: Maybe<Id[]>;
+    followUp: Maybe<string>;
+    periods: Period[];
+    status: Maybe<Id[]>;
+};
+
+const FilterContainer = styled.div`
+    padding: 0 1rem;
+    align-items: center;
+    display: flex;
+    gap: 1rem;
+`;
diff --git a/src/webapp/components/issues/IssueTable.tsx b/src/webapp/components/issues/IssueTable.tsx
index fd64a1d..b556c3c 100644
--- a/src/webapp/components/issues/IssueTable.tsx
+++ b/src/webapp/components/issues/IssueTable.tsx
@@ -9,6 +9,7 @@ import { Id } from "$/domain/entities/Ref";
 import { EditIssueValue } from "./EditIssueValue";
 
 export function useTableConfig() {
+    const [refresh, setRefresh] = React.useState(0);
     const tableConfig = React.useMemo<TableConfig<QualityAnalysisIssue>>(() => {
         return {
             actions: [],
@@ -21,19 +22,11 @@ export function useTableConfig() {
                     name: "categoryOption",
                     text: i18n.t("Category"),
                     sortable: false,
-                    getValue: value => {
-                        return value.categoryOption?.name === "default"
-                            ? "Total"
-                            : value.categoryOption?.name;
-                    },
                 },
                 {
                     name: "description",
                     text: i18n.t("Description"),
                     sortable: false,
-                    getValue: value => {
-                        return <EditIssueValue key={value.id} field="description" issue={value} />;
-                    },
                 },
                 {
                     name: "status",
@@ -47,6 +40,7 @@ export function useTableConfig() {
                     name: "azureUrl",
                     text: i18n.t("Azure URL"),
                     sortable: false,
+                    hidden: true,
                     getValue: value => {
                         return <EditIssueValue key={value.id} field="azureUrl" issue={value} />;
                     },
@@ -56,7 +50,12 @@ export function useTableConfig() {
                     text: i18n.t("Follow Up"),
                     sortable: false,
                     getValue: value => (
-                        <EditIssueValue key={value.id} field="followUp" issue={value} />
+                        <EditIssueValue
+                            key={value.id}
+                            field="followUp"
+                            issue={value}
+                            setRefresh={setRefresh}
+                        />
                     ),
                 },
                 {
@@ -71,7 +70,6 @@ export function useTableConfig() {
                     name: "contactEmails",
                     text: i18n.t("Contact Emails"),
                     sortable: false,
-                    hidden: true,
                     getValue: value => {
                         return (
                             <EditIssueValue key={value.id} field="contactEmails" issue={value} />
@@ -109,14 +107,15 @@ export function useTableConfig() {
         };
     }, []);
 
-    return { tableConfig };
+    return { tableConfig, refresh };
 }
 
 export function useGetRows(
     filters: GetIssuesOptions["filters"],
     reloadKey: number,
     analysisId: Id,
-    sectionId: Id
+    sectionId: Id,
+    refreshIssue: number
 ) {
     const { compositionRoot } = useAppContext();
     const [loading, setLoading] = React.useState(false);
@@ -124,7 +123,7 @@ export function useGetRows(
     const getRows = React.useCallback<GetRows<QualityAnalysisIssue>>(
         (search, pagination, sorting) => {
             return new Promise((resolve, reject) => {
-                if (reloadKey < 0)
+                if (reloadKey < 0 || refreshIssue < 0)
                     return resolve({
                         pager: { page: 1, pageCount: 1, pageSize: 10, total: 0 },
                         objects: [],
@@ -135,13 +134,15 @@ export function useGetRows(
                         pagination: { page: pagination.page, pageSize: pagination.pageSize },
                         sorting: { field: sorting.field, order: sorting.order },
                         filters: {
+                            actions: filters.actions,
+                            countries: filters.countries,
                             name: search,
-                            endDate: filters.endDate,
-                            startDate: filters.startDate,
+                            periods: filters.periods,
                             status: filters.status,
                             analysisIds: [analysisId],
                             sectionId: sectionId,
                             id: undefined,
+                            followUp: filters.followUp,
                         },
                     })
                     .run(
@@ -158,12 +159,15 @@ export function useGetRows(
         },
         [
             compositionRoot.outlier.get,
-            filters.endDate,
-            filters.startDate,
+            filters.actions,
+            filters.followUp,
+            filters.periods,
             filters.status,
+            filters.countries,
             sectionId,
             analysisId,
             reloadKey,
+            refreshIssue,
         ]
     );
 
diff --git a/src/webapp/pages/analysis/AnalysisPage.tsx b/src/webapp/pages/analysis/AnalysisPage.tsx
index 10c3c2f..a6e174d 100644
--- a/src/webapp/pages/analysis/AnalysisPage.tsx
+++ b/src/webapp/pages/analysis/AnalysisPage.tsx
@@ -1,25 +1,78 @@
 import React from "react";
-import { Wizard } from "@eyeseetea/d2-ui-components";
+import { Wizard, WizardStep } from "@eyeseetea/d2-ui-components";
 import { PageHeader } from "$/webapp/components/page-header/PageHeader";
-import { outlierKey, steps } from "./steps";
+import { getComponentFromSectionName } from "./steps";
 import styled from "styled-components";
-import { useHistory } from "react-router-dom";
+import { useHistory, useParams } from "react-router-dom";
 import { PageContainer } from "$/webapp/components/page-container/PageContainer";
+import { useAnalysisById } from "$/webapp/hooks/useAnalysis";
+import { QualityAnalysis } from "$/domain/entities/QualityAnalysis";
+import { ConfigurationStep } from "./steps/ConfigurationStep";
+import i18n from "$/utils/i18n";
+import _ from "$/domain/entities/generic/Collection";
+import { QualityAnalysisSection } from "$/domain/entities/QualityAnalysisSection";
+import { Maybe } from "$/utils/ts-utils";
 
-type PageProps = { name: string };
+function buildStepsFromSections(
+    analysis: QualityAnalysis,
+    updateAnalysis: UpdateAnalysisState
+): WizardStep[] {
+    const sectionSteps = _(analysis.sections)
+        .map(section => {
+            const StepComponent = getComponentFromSectionName(section.name);
+            if (!StepComponent) return undefined;
+
+            return {
+                id: section.id,
+                key: section.name.toLowerCase(),
+                label: section.name,
+                component: () => (
+                    <StepComponent
+                        analysis={analysis}
+                        section={section}
+                        title={section.description || section.name}
+                        updateAnalysis={updateAnalysis}
+                    />
+                ),
+                completed: !QualityAnalysisSection.isPending(section),
+            };
+        })
+        .compact()
+        .value();
+
+    return [
+        {
+            key: "configuration",
+            label: i18n.t("Configuration"),
+            component: ConfigurationStep,
+            completed: true,
+        },
+        ...sectionSteps,
+    ];
+}
 
 export const AnalysisPage: React.FC<PageProps> = React.memo(props => {
     const { name } = props;
+    const id = useParams<{ id: string }>();
     const history = useHistory();
 
     const onBack = () => {
         history.push("/");
     };
 
+    const { analysis, setAnalysis } = useAnalysisById(id);
+
+    const analysisSteps = React.useMemo(() => {
+        if (!analysis) return [];
+        return buildStepsFromSections(analysis, setAnalysis);
+    }, [analysis, setAnalysis]);
+
+    if (!analysis) return null;
+
     return (
         <PageContainer>
             <PageHeader title={name} onBackClick={onBack} />
-            <Stepper initialStepKey={outlierKey} steps={steps} />
+            <Stepper initialStepKey="outliers" steps={analysisSteps} />
         </PageContainer>
     );
 });
@@ -29,3 +82,14 @@ const Stepper = styled(Wizard)`
         overflow-x: scroll;
     }
 `;
+
+type PageProps = { name: string };
+
+export type PageStepProps = {
+    analysis: QualityAnalysis;
+    section: QualityAnalysisSection;
+    updateAnalysis: UpdateAnalysisState;
+    title: string;
+};
+
+export type UpdateAnalysisState = React.Dispatch<React.SetStateAction<Maybe<QualityAnalysis>>>;
diff --git a/src/webapp/pages/analysis/steps.ts b/src/webapp/pages/analysis/steps.ts
index f0530b0..f58214f 100644
--- a/src/webapp/pages/analysis/steps.ts
+++ b/src/webapp/pages/analysis/steps.ts
@@ -1,83 +1,31 @@
-import { ConfigurationStep } from "./steps/ConfigurationStep";
-import { DensityStep } from "./steps/DensityStep";
 import { GeneralPractitionersStep } from "./steps/4-general-practitioners/GeneralPractitionersStep";
 import { DisaggregatesStep } from "./steps/3-disaggregates/DisaggregatesStep";
-import { MidwiferyStep } from "./steps/MidwiferyStep";
 import { NursingMidwiferyStep } from "./steps/7-nursingMidwifery/NursingMidwiferyStep";
-import { NursingStep } from "./steps/NursingStep";
 import { OutliersStep } from "./steps/1-outliers/OutliersStep";
-import { ValidationStep } from "./steps/9-validation/ValidationStep";
-import { TrendsStep } from "./steps/TrendsStep";
-import i18n from "$/utils/i18n";
 
-export const outlierKey =
-    "1. Outliers detection analysis based on DHIS2 min-max standard functionality";
-
-export const disaggregateKey = "3. Missing disaggregates in selected catcombos ";
-
-export const practitionersKey =
-    "4. Medical doctors analysis: General Practicioners missing and double counts";
-
-export const missingNursing = "7. Missing nursing personnel when midwifery personnel is present";
-
-export const steps = [
+const sectionsComponents = [
     {
-        key: "configuration",
-        label: i18n.t("Configuration"),
-        component: ConfigurationStep,
-        completed: true,
-    },
-    {
-        key: outlierKey,
-        label: i18n.t("Outliers"),
+        name: "Outliers",
         component: OutliersStep,
-        completed: true,
-    },
-    {
-        key: "trends",
-        label: i18n.t("Trends"),
-        component: TrendsStep,
-        completed: false,
     },
     {
-        key: "disaggregates",
-        label: i18n.t("Disaggregates"),
+        name: "Disaggregates",
         component: DisaggregatesStep,
-        completed: false,
     },
     {
-        key: practitionersKey,
-        label: i18n.t("General Practitioners"),
+        name: "General Practitioners",
         component: GeneralPractitionersStep,
-        completed: false,
     },
     {
-        key: "nursing",
-        label: i18n.t("Nursing"),
-        component: NursingStep,
-        completed: false,
-    },
-    {
-        key: missingNursing,
-        label: i18n.t("Nursing/Midwifery"),
+        name: "Nursing/Midwifery",
         component: NursingMidwiferyStep,
-        completed: false,
-    },
-    {
-        key: "midwifery",
-        label: i18n.t("Midwifery"),
-        component: MidwiferyStep,
-        completed: false,
-    },
-    {
-        key: "density",
-        label: i18n.t("Density"),
-        component: DensityStep,
-        completed: false,
-    },
-    {
-        key: "other",
-        label: i18n.t("Other"),
-        component: ValidationStep,
     },
 ];
+
+export function getComponentFromSectionName(name: string) {
+    const sectionComponent = sectionsComponents.find(
+        component => component.name.toLowerCase() === name.toLowerCase()
+    );
+    if (!sectionComponent) return undefined;
+    return sectionComponent.component;
+}
diff --git a/src/webapp/pages/analysis/steps/1-outliers/OutliersStep.tsx b/src/webapp/pages/analysis/steps/1-outliers/OutliersStep.tsx
index 8c33c10..c7aa55a 100644
--- a/src/webapp/pages/analysis/steps/1-outliers/OutliersStep.tsx
+++ b/src/webapp/pages/analysis/steps/1-outliers/OutliersStep.tsx
@@ -1,42 +1,34 @@
 import React from "react";
+import { Dropdown } from "@eyeseetea/d2-ui-components";
+
 import i18n from "$/utils/i18n";
-import styled from "styled-components";
-import { Typography, Button } from "@material-ui/core";
-import { Dropdown, ObjectsTable, useObjectsTable } from "@eyeseetea/d2-ui-components";
-import { EmptyState } from "$/webapp/components/empty-state/EmptyState";
-import { useParams } from "react-router-dom";
-import { useGetRows, useTableConfig } from "$/webapp/components/issues/IssueTable";
-import { GetIssuesOptions } from "$/domain/repositories/IssueRepository";
-import { initialFilters } from "$/webapp/utils/issues";
-import { useAnalysisById } from "$/webapp/hooks/useAnalysis";
 import { algorithmList, thresholdList, useAnalysisOutlier } from "./useOutliers";
 import { Maybe } from "$/utils/ts-utils";
-import { outlierKey } from "../../steps";
+import { StepAnalysis } from "../StepAnalysis";
+import { PageStepProps } from "../../AnalysisPage";
 
 const defaultOutlierParams = { algorithm: "Z_SCORE", threshold: "3" };
 
-export const OutliersStep: React.FC<PageProps> = React.memo(() => {
-    const params = useParams<{ id: string }>();
+export const OutliersStep: React.FC<PageStepProps> = React.memo(props => {
+    const { title, analysis, section, updateAnalysis } = props;
+
     const [reload, refreshReload] = React.useState(0);
     const [qualityFilters, setQualityFilters] = React.useState(defaultOutlierParams);
-    const [filters, _] = React.useState<GetIssuesOptions["filters"]>(initialFilters);
-
-    const { tableConfig } = useTableConfig();
-    const { analysis, setAnalysis } = useAnalysisById({ id: params.id });
 
-    const section = analysis?.sections.find(section => section.name === outlierKey);
-
-    const { getRows, loading } = useGetRows(filters, reload, params.id, section?.id || "");
-    const config = useObjectsTable(tableConfig, getRows);
     const { runAnalysisOutlier } = useAnalysisOutlier({
         onSucess: qualityAnalysis => {
             refreshReload(reload + 1);
-            setAnalysis(qualityAnalysis);
+            updateAnalysis(qualityAnalysis);
         },
     });
 
     const runAnalysis = () => {
-        runAnalysisOutlier(qualityFilters.algorithm, params.id, qualityFilters.threshold);
+        runAnalysisOutlier(
+            qualityFilters.algorithm,
+            analysis.id,
+            section.id,
+            qualityFilters.threshold
+        );
     };
 
     const onFilterChange = React.useCallback<
@@ -45,82 +37,30 @@ export const OutliersStep: React.FC<PageProps> = React.memo(() => {
         setQualityFilters(prev => ({ ...prev, [filterAttribute]: value }));
     }, []);
 
-    const isPending = section?.status === "pending";
+    if (!analysis) return null;
 
     return (
-        <Container>
-            <>
-                <AnalysisHeader>
-                    <StyledTypography variant="h2">
-                        {i18n.t(
-                            "Outliers detection analysis based on DHIS2 min-max standard functionality"
-                        )}
-                    </StyledTypography>
-                    {isPending && (
-                        <FiltersContainer>
-                            <Dropdown
-                                hideEmpty
-                                items={algorithmList}
-                                onChange={value => onFilterChange(value, "algorithm")}
-                                value={qualityFilters.algorithm}
-                                label={i18n.t("Algorithm")}
-                            />
-                            <Dropdown
-                                hideEmpty
-                                items={thresholdList}
-                                onChange={value => onFilterChange(value, "threshold")}
-                                value={qualityFilters.threshold}
-                                label={i18n.t("Threshold")}
-                            />
-                            <Button
-                                variant="contained"
-                                color="primary"
-                                size="small"
-                                onClick={() => runAnalysis()}
-                            >
-                                {i18n.t("Run")}
-                            </Button>
-                        </FiltersContainer>
-                    )}
-                </AnalysisHeader>
-                {isPending && (
-                    <EmptyState message={i18n.t("Run to get results")} variant="neutral" />
-                )}
-                {section?.status === "success" && (
-                    <EmptyState message={i18n.t("No Issues found")} variant="success" />
-                )}
-            </>
-            {section?.status === "success_with_issues" && (
-                <ObjectsTable loading={loading} {...config} />
-            )}
-        </Container>
+        <StepAnalysis
+            id={analysis.id}
+            onRun={runAnalysis}
+            reload={reload}
+            section={section}
+            title={title}
+        >
+            <Dropdown
+                hideEmpty
+                items={algorithmList}
+                onChange={value => onFilterChange(value, "algorithm")}
+                value={qualityFilters.algorithm}
+                label={i18n.t("Algorithm")}
+            />
+            <Dropdown
+                hideEmpty
+                items={thresholdList}
+                onChange={value => onFilterChange(value, "threshold")}
+                value={qualityFilters.threshold}
+                label={i18n.t("Threshold")}
+            />
+        </StepAnalysis>
     );
 });
-
-const Container = styled.section``;
-
-const AnalysisHeader = styled.div`
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    height: 5rem;
-    gap: 1rem;
-    margin-block-end: 1.75rem;
-    flex-wrap: wrap;
-`;
-
-const StyledTypography = styled(Typography)`
-    font-size: 1.2rem;
-    font-weight: 500;
-    max-width: 22rem;
-`;
-
-const FiltersContainer = styled.div`
-    display: flex;
-    align-items: center;
-    gap: 1rem;
-`;
-
-interface PageProps {
-    name: string;
-}
diff --git a/src/webapp/pages/analysis/steps/1-outliers/useOutliers.ts b/src/webapp/pages/analysis/steps/1-outliers/useOutliers.ts
index e9e0148..77301c4 100644
--- a/src/webapp/pages/analysis/steps/1-outliers/useOutliers.ts
+++ b/src/webapp/pages/analysis/steps/1-outliers/useOutliers.ts
@@ -4,6 +4,7 @@ import { useLoading, useSnackbar } from "@eyeseetea/d2-ui-components";
 import i18n from "$/utils/i18n";
 import { useAppContext } from "$/webapp/contexts/app-context";
 import { QualityAnalysis } from "$/domain/entities/QualityAnalysis";
+import { Id } from "$/domain/entities/Ref";
 
 export const thresholdList = [
     { value: "1", text: "1.0" },
@@ -30,10 +31,15 @@ export function useAnalysisOutlier(props: UseRunAnalysisProps) {
     const loading = useLoading();
 
     const runAnalysisOutlier = React.useCallback(
-        (algorithm: string, id: string, threshold: string) => {
+        (algorithm: string, analysisId: Id, sectionId: Id, threshold: string) => {
             loading.show(true, i18n.t("Running analysis..."));
             compositionRoot.outlier.run
-                .execute({ algorithm: algorithm, qualityAnalysisId: id, threshold: threshold })
+                .execute({
+                    sectionId: sectionId,
+                    algorithm: algorithm,
+                    qualityAnalysisId: analysisId,
+                    threshold: threshold,
+                })
                 .run(
                     qualityAnalysis => {
                         loading.hide();
diff --git a/src/webapp/pages/analysis/steps/3-disaggregates/DisaggregatesStep.tsx b/src/webapp/pages/analysis/steps/3-disaggregates/DisaggregatesStep.tsx
index dbc0e49..0f07ab5 100644
--- a/src/webapp/pages/analysis/steps/3-disaggregates/DisaggregatesStep.tsx
+++ b/src/webapp/pages/analysis/steps/3-disaggregates/DisaggregatesStep.tsx
@@ -4,18 +4,16 @@ import styled from "styled-components";
 import { useDisaggregatesStep } from "./useDisaggregatesStep";
 import { SelectMultiCheckboxes } from "$/webapp/components/selectmulti-checkboxes/SelectMultiCheckboxes";
 import { StepAnalysis } from "../StepAnalysis";
-import { useParams } from "react-router-dom";
-import { disaggregateKey } from "../../steps";
+import { PageStepProps } from "../../AnalysisPage";
 
-export const DisaggregatesStep: React.FC<PageProps> = React.memo(() => {
-    const { id } = useParams<{ id: string }>();
-
-    const { analysis, disaggregations, handleChange, reload, runAnalysis, selectedDisagregations } =
+export const DisaggregatesStep: React.FC<PageStepProps> = React.memo(props => {
+    const { analysis, section, title, updateAnalysis } = props;
+    const { disaggregations, handleChange, reload, runAnalysis, selectedDisagregations } =
         useDisaggregatesStep({
-            analysisId: id,
+            analysis: analysis,
+            updateAnalysis,
+            sectionId: section.id,
         });
-    const section = analysis?.sections.find(section => section.name === disaggregateKey);
-    if (!analysis?.id || !section) return null;
 
     const onClick = () => {
         runAnalysis();
@@ -27,7 +25,7 @@ export const DisaggregatesStep: React.FC<PageProps> = React.memo(() => {
             onRun={onClick}
             reload={reload}
             section={section}
-            title={i18n.t("Missing disaggregates in selected catcombos")}
+            title={title}
         >
             <FiltersContainer>
                 <SelectMultiCheckboxes
@@ -46,5 +44,3 @@ const FiltersContainer = styled.div`
     align-items: center;
     gap: 1rem;
 `;
-
-type PageProps = { name: string };
diff --git a/src/webapp/pages/analysis/steps/3-disaggregates/useDisaggregatesStep.tsx b/src/webapp/pages/analysis/steps/3-disaggregates/useDisaggregatesStep.tsx
index 866d295..40e5d70 100644
--- a/src/webapp/pages/analysis/steps/3-disaggregates/useDisaggregatesStep.tsx
+++ b/src/webapp/pages/analysis/steps/3-disaggregates/useDisaggregatesStep.tsx
@@ -3,40 +3,32 @@ import { useLoading, useSnackbar } from "@eyeseetea/d2-ui-components";
 
 import i18n from "$/utils/i18n";
 import { useAppContext } from "$/webapp/contexts/app-context";
-import { useAnalysisById } from "$/webapp/hooks/useAnalysis";
 import { Id } from "$/domain/entities/Ref";
 import { Option } from "$/webapp/components/selectmulti-checkboxes/SelectMultiCheckboxes";
-import { disaggregateKey } from "../../steps";
 import _ from "$/domain/entities/generic/Collection";
+import { UpdateAnalysisState } from "../../AnalysisPage";
+import { QualityAnalysis } from "$/domain/entities/QualityAnalysis";
 
 export function useDisaggregatesStep(props: UseDisaggregatesStepProps) {
-    const { analysisId } = props;
+    const { analysis, sectionId, updateAnalysis } = props;
     const { compositionRoot } = useAppContext();
     const snackbar = useSnackbar();
     const loading = useLoading();
 
     const [reload, refreshReload] = React.useState(0);
-    const { analysis, setAnalysis } = useAnalysisById({ id: analysisId });
+
     const [disaggregations, setDisaggregations] = React.useState<Option[]>([]);
     const [selectedDisagregations, setSelectedDisagregations] = React.useState<string[]>([]);
 
     React.useEffect(() => {
-        if (!analysis) return;
-
-        const section = analysis.sections.find(section => section.name === disaggregateKey);
-
-        compositionRoot.disaggregates.getCategoriesCombos.execute(section?.name || "").run(
+        compositionRoot.disaggregates.getCategoriesCombos.execute(sectionId).run(
             settingSection => {
-                const initialDisaggregations =
-                    _(settingSection.disaggregations)
-                        .map(disaggregation => {
-                            return {
-                                value: disaggregation.id,
-                                text: disaggregation.name,
-                            };
-                        })
-                        .sortBy(item => item.text)
-                        .value() || [];
+                const initialDisaggregations = _(settingSection.disaggregations)
+                    .map(disaggregation => {
+                        return { value: disaggregation.id, text: disaggregation.name };
+                    })
+                    .sortBy(item => item.text)
+                    .value();
                 setDisaggregations(initialDisaggregations);
                 setSelectedDisagregations(initialDisaggregations.map(item => item.value));
             },
@@ -44,7 +36,7 @@ export function useDisaggregatesStep(props: UseDisaggregatesStepProps) {
                 snackbar.error(err.message);
             }
         );
-    }, [analysis, compositionRoot.disaggregates.getCategoriesCombos, snackbar]);
+    }, [analysis, compositionRoot.disaggregates.getCategoriesCombos, snackbar, sectionId]);
 
     const handleChange = (values: string[]) => {
         setSelectedDisagregations(values);
@@ -54,11 +46,15 @@ export function useDisaggregatesStep(props: UseDisaggregatesStepProps) {
         if (!analysis) return false;
         loading.show(true, i18n.t("Running analysis..."));
         compositionRoot.missingDisaggregates.get
-            .execute({ analysisId: analysis.id, disaggregationsIds: selectedDisagregations })
+            .execute({
+                analysisId: analysis.id,
+                disaggregationsIds: selectedDisagregations,
+                sectionId: sectionId,
+            })
             .run(
                 result => {
                     refreshReload(reload + 1);
-                    setAnalysis(result);
+                    updateAnalysis(result);
                     loading.hide();
                 },
                 err => {
@@ -78,4 +74,8 @@ export function useDisaggregatesStep(props: UseDisaggregatesStepProps) {
     };
 }
 
-type UseDisaggregatesStepProps = { analysisId: Id };
+type UseDisaggregatesStepProps = {
+    analysis: QualityAnalysis;
+    sectionId: Id;
+    updateAnalysis: UpdateAnalysisState;
+};
diff --git a/src/webapp/pages/analysis/steps/4-general-practitioners/GeneralPractitionersStep.tsx b/src/webapp/pages/analysis/steps/4-general-practitioners/GeneralPractitionersStep.tsx
index f88282f..9adc74f 100644
--- a/src/webapp/pages/analysis/steps/4-general-practitioners/GeneralPractitionersStep.tsx
+++ b/src/webapp/pages/analysis/steps/4-general-practitioners/GeneralPractitionersStep.tsx
@@ -1,24 +1,18 @@
 import React from "react";
-import { useParams } from "react-router-dom";
 import { Dropdown } from "@eyeseetea/d2-ui-components";
 
 import i18n from "$/utils/i18n";
 import { StepAnalysis } from "$/webapp/pages/analysis/steps/StepAnalysis";
-import { practitionersKey } from "$/webapp/pages/analysis/steps";
 
 import styled from "styled-components";
 import { useGeneralPractitionersStep } from "./useGeneralPractitionersStep";
 import { SelectMultiCheckboxes } from "$/webapp/components/selectmulti-checkboxes/SelectMultiCheckboxes";
+import { PageStepProps } from "../../AnalysisPage";
 
-interface PageProps {
-    name: string;
-}
-
-export const GeneralPractitionersStep: React.FC<PageProps> = React.memo(() => {
-    const { id } = useParams<{ id: string }>();
+export const GeneralPractitionersStep: React.FC<PageStepProps> = React.memo(props => {
+    const { analysis, section, title, updateAnalysis } = props;
 
     const {
-        analysis,
         disaggregations,
         doubleCountsList,
         reload,
@@ -27,15 +21,16 @@ export const GeneralPractitionersStep: React.FC<PageProps> = React.memo(() => {
         threshold,
         handleChange,
         valueChange,
-    } = useGeneralPractitionersStep({ analysisId: id });
-    const section = analysis?.sections.find(section => section.name === practitionersKey);
+    } = useGeneralPractitionersStep({
+        analysis: analysis,
+        section: section,
+        updateAnalysis: updateAnalysis,
+    });
 
     const onClick = () => {
         runAnalysis();
     };
 
-    if (!analysis?.id || !section) return null;
-
     return (
         <div>
             <StepAnalysis
@@ -43,10 +38,7 @@ export const GeneralPractitionersStep: React.FC<PageProps> = React.memo(() => {
                 onRun={onClick}
                 reload={reload}
                 section={section}
-                title={i18n.t(
-                    "Medical doctors analysis: General Practicioners missing and double counts",
-                    { nsSeparator: true }
-                )}
+                title={title}
             >
                 <SelectMultiCheckboxes
                     options={disaggregations}
diff --git a/src/webapp/pages/analysis/steps/4-general-practitioners/useGeneralPractitionersStep.tsx b/src/webapp/pages/analysis/steps/4-general-practitioners/useGeneralPractitionersStep.tsx
index 5120630..01e7f2a 100644
--- a/src/webapp/pages/analysis/steps/4-general-practitioners/useGeneralPractitionersStep.tsx
+++ b/src/webapp/pages/analysis/steps/4-general-practitioners/useGeneralPractitionersStep.tsx
@@ -1,9 +1,11 @@
+import { QualityAnalysis } from "$/domain/entities/QualityAnalysis";
+import { QualityAnalysisSection } from "$/domain/entities/QualityAnalysisSection";
 import { Id } from "$/domain/entities/Ref";
 import i18n from "$/utils/i18n";
 import { useAppContext } from "$/webapp/contexts/app-context";
-import { useAnalysisById } from "$/webapp/hooks/useAnalysis";
 import { useLoading, useSnackbar } from "@eyeseetea/d2-ui-components";
 import React from "react";
+import { UpdateAnalysisState } from "../../AnalysisPage";
 
 const doubleCountsList = [
     {
@@ -29,13 +31,12 @@ const doubleCountsList = [
 ];
 
 export function useGeneralPractitionersStep(props: UseGeneralPractitionersStepProps) {
-    const { analysisId } = props;
+    const { analysis, section, updateAnalysis } = props;
     const { compositionRoot } = useAppContext();
     const snackbar = useSnackbar();
     const loading = useLoading();
 
     const [reload, refreshReload] = React.useState(0);
-    const { analysis, setAnalysis } = useAnalysisById({ id: analysisId });
     const [disaggregations, setDisaggregations] = React.useState<{ value: Id; text: string }[]>([]);
     const [selectedDisaggregations, setSelectedDissagregations] = React.useState<string[]>([]);
     const [threshold, setThreshold] = React.useState<string>("1");
@@ -71,18 +72,18 @@ export function useGeneralPractitionersStep(props: UseGeneralPractitionersStepPr
     }, [analysis?.module.id, compositionRoot.modules.getDisaggregations, snackbar]);
 
     const runAnalysis = React.useCallback(() => {
-        if (!analysis) return false;
         loading.show(true, i18n.t("Running analysis..."));
         compositionRoot.practitioners.run
             .execute({
                 analysisId: analysis.id,
                 threshold: Number(threshold),
                 dissagregationsIds: selectedDisaggregations,
+                sectionId: section.id,
             })
             .run(
                 analysis => {
                     refreshReload(reload + 1);
-                    setAnalysis(analysis);
+                    updateAnalysis(analysis);
                     loading.hide();
                 },
                 err => {
@@ -92,10 +93,11 @@ export function useGeneralPractitionersStep(props: UseGeneralPractitionersStepPr
             );
     }, [
         analysis,
+        section.id,
         compositionRoot.practitioners.run,
         loading,
         reload,
-        setAnalysis,
+        updateAnalysis,
         snackbar,
         threshold,
         selectedDisaggregations,
@@ -109,12 +111,14 @@ export function useGeneralPractitionersStep(props: UseGeneralPractitionersStepPr
         runAnalysis,
         reload,
         selectedDisaggregations,
-        setAnalysis,
+        updateAnalysis,
         valueChange,
         threshold,
     };
 }
 
 type UseGeneralPractitionersStepProps = {
-    analysisId: Id;
+    analysis: QualityAnalysis;
+    section: QualityAnalysisSection;
+    updateAnalysis: UpdateAnalysisState;
 };
diff --git a/src/webapp/pages/analysis/steps/7-nursingMidwifery/NursingMidwiferyStep.tsx b/src/webapp/pages/analysis/steps/7-nursingMidwifery/NursingMidwiferyStep.tsx
index c4aa35a..a5f2b83 100644
--- a/src/webapp/pages/analysis/steps/7-nursingMidwifery/NursingMidwiferyStep.tsx
+++ b/src/webapp/pages/analysis/steps/7-nursingMidwifery/NursingMidwiferyStep.tsx
@@ -1,56 +1,30 @@
 import React from "react";
 import i18n from "$/utils/i18n";
-import styled from "styled-components";
+
 import { useNursingMidwiferyStep } from "./useNursingMidwiferyStep";
 import { SelectMultiCheckboxes } from "$/webapp/components/selectmulti-checkboxes/SelectMultiCheckboxes";
-import { useParams } from "react-router-dom";
 import { StepAnalysis } from "../StepAnalysis";
-import { missingNursing } from "../../steps";
-
-interface PageProps {
-    name: string;
-}
-
-export const NursingMidwiferyStep: React.FC<PageProps> = React.memo(() => {
-    const { id } = useParams<{ id: string }>();
-    const {
-        analysis,
-        disaggregations,
-        selectedDisaggregations,
-        handleChange,
-        reload,
-        runAnalysis,
-    } = useNursingMidwiferyStep({ analysisId: id });
-    const section = analysis?.sections.find(section => section.name === missingNursing);
+import { PageStepProps } from "../../AnalysisPage";
 
-    if (!analysis || !section) return null;
+export const NursingMidwiferyStep: React.FC<PageStepProps> = React.memo(props => {
+    const { analysis, section, title, updateAnalysis } = props;
+    const { disaggregations, selectedDisaggregations, handleChange, reload, runAnalysis } =
+        useNursingMidwiferyStep({ analysis, section, updateAnalysis });
 
     return (
-        <Container>
-            <StepAnalysis
-                id={analysis.id}
-                section={section}
-                reload={reload}
-                title={i18n.t("Missing nursing personnel when midwifery personnel is present")}
-                onRun={runAnalysis}
-            >
-                <FiltersContainer>
-                    <SelectMultiCheckboxes
-                        options={disaggregations}
-                        onChange={handleChange}
-                        value={selectedDisaggregations}
-                        label={i18n.t("CatCombos")}
-                    />
-                </FiltersContainer>
-            </StepAnalysis>
-        </Container>
+        <StepAnalysis
+            id={analysis.id}
+            section={section}
+            reload={reload}
+            title={title}
+            onRun={runAnalysis}
+        >
+            <SelectMultiCheckboxes
+                options={disaggregations}
+                onChange={handleChange}
+                value={selectedDisaggregations}
+                label={i18n.t("CatCombos")}
+            />
+        </StepAnalysis>
     );
 });
-
-const Container = styled.section``;
-
-const FiltersContainer = styled.div`
-    display: flex;
-    align-items: center;
-    gap: 1rem;
-`;
diff --git a/src/webapp/pages/analysis/steps/7-nursingMidwifery/useNursingMidwiferyStep.tsx b/src/webapp/pages/analysis/steps/7-nursingMidwifery/useNursingMidwiferyStep.tsx
index b18c28a..36f035c 100644
--- a/src/webapp/pages/analysis/steps/7-nursingMidwifery/useNursingMidwiferyStep.tsx
+++ b/src/webapp/pages/analysis/steps/7-nursingMidwifery/useNursingMidwiferyStep.tsx
@@ -2,29 +2,25 @@ import React from "react";
 import { useLoading, useSnackbar } from "@eyeseetea/d2-ui-components";
 
 import i18n from "$/utils/i18n";
-import { useAnalysisById } from "$/webapp/hooks/useAnalysis";
 import { Id } from "$/domain/entities/Ref";
 import { useAppContext } from "$/webapp/contexts/app-context";
-import { missingNursing } from "../../steps";
+import { QualityAnalysis } from "$/domain/entities/QualityAnalysis";
+import { QualityAnalysisSection } from "$/domain/entities/QualityAnalysisSection";
+import { UpdateAnalysisState } from "../../AnalysisPage";
 
 export function useNursingMidwiferyStep(props: UseNursingMidwiferyStepProps) {
-    const { analysisId } = props;
+    const { analysis, section, updateAnalysis } = props;
     const { compositionRoot } = useAppContext();
     const snackbar = useSnackbar();
     const loading = useLoading();
 
     const [reload, refreshReload] = React.useState(0);
-    const { analysis, setAnalysis } = useAnalysisById({ id: analysisId });
     const [disaggregations, setDisaggregations] = React.useState<{ value: Id; text: string }[]>([]);
     const [selectedDisaggregations, setSelectedDissagregations] = React.useState<string[]>([]);
 
     React.useEffect(() => {
-        if (!analysis) return;
-        const section = analysis?.sections.find(section => section.name === missingNursing);
-        if (!section) return;
-
         loading.show(true, i18n.t("Loading"));
-        compositionRoot.nursingMidwifery.getDisaggregations.execute(section.name).run(
+        compositionRoot.nursingMidwifery.getDisaggregations.execute(section.id).run(
             result => {
                 const selectedDisaggregations = result.map(item => ({
                     value: item.id,
@@ -39,27 +35,24 @@ export function useNursingMidwiferyStep(props: UseNursingMidwiferyStepProps) {
                 snackbar.error(error.message);
             }
         );
-    }, [analysis, compositionRoot.nursingMidwifery.getDisaggregations, loading, snackbar]);
+    }, [section.id, compositionRoot.nursingMidwifery.getDisaggregations, loading, snackbar]);
 
     const handleChange = (values: string[]) => {
         setSelectedDissagregations(values);
     };
 
     const runAnalysis = React.useCallback(() => {
-        if (!analysis) return false;
-        const section = analysis?.sections.find(section => section.name === missingNursing);
-        if (!section) return false;
         loading.show(true, i18n.t("Running analysis..."));
         compositionRoot.nursingMidwifery.validate
             .execute({
                 analysisId: analysis.id,
                 disaggregationsIds: selectedDisaggregations,
-                sectionId: section.name,
+                sectionId: section.id,
             })
             .run(
                 analysis => {
                     refreshReload(reload + 1);
-                    setAnalysis(analysis);
+                    updateAnalysis(analysis);
                     loading.hide();
                 },
                 err => {
@@ -72,9 +65,10 @@ export function useNursingMidwiferyStep(props: UseNursingMidwiferyStepProps) {
         compositionRoot.nursingMidwifery.validate,
         loading,
         reload,
-        setAnalysis,
+        updateAnalysis,
         snackbar,
         selectedDisaggregations,
+        section.id,
     ]);
 
     return {
@@ -87,4 +81,8 @@ export function useNursingMidwiferyStep(props: UseNursingMidwiferyStepProps) {
     };
 }
 
-type UseNursingMidwiferyStepProps = { analysisId: Id };
+type UseNursingMidwiferyStepProps = {
+    analysis: QualityAnalysis;
+    section: QualityAnalysisSection;
+    updateAnalysis: UpdateAnalysisState;
+};
diff --git a/src/webapp/pages/analysis/steps/StepAnalysis.tsx b/src/webapp/pages/analysis/steps/StepAnalysis.tsx
index 15e4126..85e5039 100644
--- a/src/webapp/pages/analysis/steps/StepAnalysis.tsx
+++ b/src/webapp/pages/analysis/steps/StepAnalysis.tsx
@@ -7,21 +7,25 @@ import i18n from "$/utils/i18n";
 import { Id } from "$/domain/entities/Ref";
 import { EmptyState } from "$/webapp/components/empty-state/EmptyState";
 import { useGetRows, useTableConfig } from "$/webapp/components/issues/IssueTable";
-import { GetIssuesOptions } from "$/domain/repositories/IssueRepository";
-import { initialFilters } from "$/webapp/utils/issues";
 import { QualityAnalysisSection } from "$/domain/entities/QualityAnalysisSection";
+import { IssueFilters } from "$/webapp/components/issues/IssueFilters";
+import { initialFilters } from "$/webapp/utils/issues";
 
 export const StepAnalysis: React.FC<StepContainerProps> = React.memo(props => {
     const { children, id, onRun, reload, section, title } = props;
 
-    const [filters, _] = React.useState<GetIssuesOptions["filters"]>(initialFilters);
+    const [filters, setFilters] = React.useState(initialFilters);
 
-    const { tableConfig } = useTableConfig();
-    const { getRows, loading } = useGetRows(filters, reload, id, section.id || "");
+    const { tableConfig, refresh } = useTableConfig();
+    const { getRows, loading } = useGetRows(filters, reload, id, section.id, refresh);
     const config = useObjectsTable(tableConfig, getRows);
 
     const isPending = section.status === "pending";
 
+    const filterComponents = React.useMemo(() => {
+        return <IssueFilters initialFilters={filters} onChange={setFilters} />;
+    }, [filters]);
+
     return (
         <Container>
             <>
@@ -49,7 +53,7 @@ export const StepAnalysis: React.FC<StepContainerProps> = React.memo(props => {
                 )}
             </>
             {section.status === "success_with_issues" && (
-                <ObjectsTable loading={loading} {...config} />
+                <ObjectsTable loading={loading} {...config} filterComponents={filterComponents} />
             )}
         </Container>
     );
diff --git a/src/webapp/pages/app/App.css b/src/webapp/pages/app/App.css
index cfdb46c..20a7151 100644
--- a/src/webapp/pages/app/App.css
+++ b/src/webapp/pages/app/App.css
@@ -16,6 +16,12 @@ li {
     min-height: 40px !important;
 }
 
+.config-form-selector > label {
+    color: #494949;
+    font-size: 1em;
+    top: 0 !important;
+}
+
 .config-form-selector.disabled > div {
     cursor: none;
     opacity: 0.7;
diff --git a/src/webapp/utils/issues.ts b/src/webapp/utils/issues.ts
index b36db67..03a8c3d 100644
--- a/src/webapp/utils/issues.ts
+++ b/src/webapp/utils/issues.ts
@@ -1,11 +1,13 @@
 import { GetIssuesOptions } from "$/domain/repositories/IssueRepository";
 
 export const initialFilters: GetIssuesOptions["filters"] = {
-    endDate: undefined,
+    actions: [],
+    countries: [],
+    periods: [],
     name: undefined,
-    startDate: undefined,
-    status: undefined,
+    status: [],
     analysisIds: undefined,
     sectionId: "",
     id: undefined,
+    followUp: undefined,
 };