diff --git a/src/libs/convert/ageRangeAggregate.js b/src/libs/convert/ageRangeAggregate.js
new file mode 100644
index 0000000000000000000000000000000000000000..850f00387ec1c5edf45ae72b3696244fc3d9e364
--- /dev/null
+++ b/src/libs/convert/ageRangeAggregate.js
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+   
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function ageRangeAggregate(id) {
+    switch (id) {
+        case 1:
+        return '0 a 3 anos';
+        case 2:
+        return '4 a 5 anos';
+        case 3:
+        return '6 a 10 anos';
+        case 4:
+        return '11 a 14 anos';
+        case 5:
+        return '15 a 17 anos';
+        case 6:
+        return '18 anos ou mais';
+        default:
+        return 'Não declarada';
+    }
+};
diff --git a/src/libs/convert/ageRangeEntity.js b/src/libs/convert/ageRangeEntity.js
new file mode 100644
index 0000000000000000000000000000000000000000..f9ca149b249603d1928cb01f7938e5b4837eab33
--- /dev/null
+++ b/src/libs/convert/ageRangeEntity.js
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+   
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function ageRangeEntity(id) {
+    switch (id) {
+        case 1:
+        return 'Até 24 anos';
+        case 2:
+        return '25 a 29 anos';
+        case 3:
+        return '30 a 39 anos';
+        case 4:
+        return '40 a 49 anos';
+        case 5:
+        return '50 a 54 anos';
+        case 6:
+        return '55 a 59 anos';
+        case 7:
+        return '60 anos ou mais';
+        default:
+        return 'Não declarada';
+    }
+};
diff --git a/src/libs/convert/attendedModality.js b/src/libs/convert/attendedModality.js
index fd6162a5d5e690fd865c1614af0cb29ab40b5211..9168afc5bcdf05479fb35cbf2239abd234920c0c 100644
--- a/src/libs/convert/attendedModality.js
+++ b/src/libs/convert/attendedModality.js
@@ -38,8 +38,6 @@ module.exports = function attendedModality(id) {
         return 'Educação profissional - técnica integrada';
         case 9:
         return 'Educação profissional - técnica concomitante e subsequente';
-        case 10:
-        return 'Ensino Médio Regular e Profissional articulado';
         case 11:
         return 'EJA - Ensino Médio';
         case 12:
diff --git a/src/libs/convert/capitalCode.js b/src/libs/convert/capitalCode.js
index fe7c0862591b81561c96d326d5f824467d9ffaba..658ce5541772f7c79290175d3ff8aa4d93454ca7 100644
--- a/src/libs/convert/capitalCode.js
+++ b/src/libs/convert/capitalCode.js
@@ -74,6 +74,7 @@ module.exports = function capitalCode(id) {
         return 'Goiânia';
         case 53:
         return 'Brasília';
+		case null:
         case 99:
         return 'Não é capital';
         default:
diff --git a/src/libs/convert/diffLocation.js b/src/libs/convert/diffLocation.js
index f239f0041cf4101cf646d980a859b87058261f1f..aadc9cf6fd341dc51214c58682b8ded5e371a055 100644
--- a/src/libs/convert/diffLocation.js
+++ b/src/libs/convert/diffLocation.js
@@ -28,5 +28,9 @@ module.exports = function location(id) {
             return 'Terra indígena';
         case 3: 
             return 'Área remanescente de quilombos';
+		case 8:
+			return 'Área onde se localizam povos e comunidades tradicionais';
+        default:
+            return 'Não definido';
     }
 };
diff --git a/src/libs/convert/educationDegreeEntity.js b/src/libs/convert/educationDegreeEntity.js
new file mode 100644
index 0000000000000000000000000000000000000000..e16ba13f906bb28a28d6e26a150353e084fa2947
--- /dev/null
+++ b/src/libs/convert/educationDegreeEntity.js
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function educationDegreeEntity(id) {
+    switch (id) {
+        case 1:
+            return 'Ensino Fundamental';
+        case 2:
+            return 'Ensino Médio';
+        case 3:
+            return 'Graduação Com Licenciatura';
+        case 4:
+            return 'Graduação Sem Licenciatura';
+    }
+};
diff --git a/src/libs/convert/educationLevelBasic.js b/src/libs/convert/educationLevelBasic.js
index 3d166fe525019ab06f6ecbb59ede4e382ca57fa6..7c242b07072d8e51530677207c3f5c05a605f436 100644
--- a/src/libs/convert/educationLevelBasic.js
+++ b/src/libs/convert/educationLevelBasic.js
@@ -24,11 +24,11 @@ module.exports = function educationLevelBasic(id) {
         return 'Creche';
         case 2:
         return 'Pré-Escola';
-        case 4:
+        case 3:
         return 'Ensino Fundamental - anos iniciais';
-        case 5:
+        case 4:
         return 'Ensino Fundamental - anos finais';
-        case 6:
+        case 5:
         return 'Ensino Médio';
         default:
         return 'Não classificada';
diff --git a/src/libs/convert/educationLevelModAgg.js b/src/libs/convert/educationLevelModAgg.js
new file mode 100644
index 0000000000000000000000000000000000000000..6ebfa6274210a5f8956aebfe937aabae6faf07ea
--- /dev/null
+++ b/src/libs/convert/educationLevelModAgg.js
@@ -0,0 +1,48 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function educationLevelMod(id) {
+    switch (id) {
+        case 1:
+        return 'Creche';
+        case 2:
+        return 'Pré-Escola';
+        case 3:
+        return 'Ensino Fundamental - anos iniciais';
+        case 4:
+        return 'Ensino Fundamental - anos finais';
+        case 5:
+        return 'Ensino Médio';
+        case 6:
+        return 'Ensino Medio Integrado ou Normal - tecnico';
+        case 7:
+        return 'EJA - Ensino Fundamental';
+        case 8:
+        return 'EJA - Ensino Médio';
+        case 9:
+        return 'EJA - EF e EM Integrado - tecnico';
+        case 10:
+        return 'Educacao Profissional - concomitante e subsequente';
+        case 11:
+        return 'suporte_total'
+        default:
+        return 'Não classificada';
+    }
+};
diff --git a/src/libs/convert/educationLevelModDoc.js b/src/libs/convert/educationLevelModDoc.js
new file mode 100644
index 0000000000000000000000000000000000000000..2113df92081f06273bbb0e47f749135f8b602cc6
--- /dev/null
+++ b/src/libs/convert/educationLevelModDoc.js
@@ -0,0 +1,42 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function educationLevelModDoc(id) {
+    switch (id) {
+        case 1:
+        return 'Creche';
+        case 2:
+        return 'Pré-Escola';
+        case 3:
+        return 'Ensino Fundamental - anos iniciais';
+        case 4:
+        return 'Ensino Fundamental - anos finais';
+        case 5:
+        return 'Ensino Médio';
+        case 6:
+        return 'Profissional';
+        case 7:
+        return 'EJA - Ensino Fundamental';
+        case 8:
+        return 'EJA - Ensino Médio';
+        default:
+        return 'Não classificada';
+    }
+};
diff --git a/src/libs/convert/educationLevelModEntityAgg.js b/src/libs/convert/educationLevelModEntityAgg.js
new file mode 100644
index 0000000000000000000000000000000000000000..a9fb4fbcf6c53d8a683e8bdf6ecd1f90b61ce3b3
--- /dev/null
+++ b/src/libs/convert/educationLevelModEntityAgg.js
@@ -0,0 +1,56 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+   
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function educationLevelShort(id) {
+    switch (id) {
+        case 1:
+        return 'Creche';
+        case 2:
+        return 'Pré-Escola';
+        case 3:
+        return 'Ensino Fundamental - anos iniciais';
+        case 4:
+        return 'Ensino Fundamental - anos finais';
+        case 5:
+        return 'Ensino Médio Propedêutico';
+        case 6:
+        return 'Ensino Médio Normal Magistério';
+        case 7:
+        return 'Ensino Médio Integrado';
+        case 8:
+        return 'Educação Profissional Técnica - Associado ao Nível Médio';
+        case 9:
+        return 'Educação Profissional Técnica - Concomitante';
+        case 10:
+        return 'Educação Profissional Técnica - Subsequente';
+        case 11:
+        return 'Educação Profissional - Misto';
+        case 12:
+        return 'Educação Profissional FIC Concomitante';
+        case 13:
+        return 'Educacao Profissional FIC Integrado EJA';
+        case 14:
+        return 'EJA Ensino Fundamental';
+        case 15:
+        return 'EJA Ensino Médio';
+        default:
+        return 'Não classificada';
+    }
+};
diff --git a/src/libs/convert/educationLevelModEntitySeg.js b/src/libs/convert/educationLevelModEntitySeg.js
new file mode 100644
index 0000000000000000000000000000000000000000..fedf7d562230a31f35e235d0523c8281f99e4f94
--- /dev/null
+++ b/src/libs/convert/educationLevelModEntitySeg.js
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+   
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function educationLevelShort(id) {
+    switch (id) {
+        case 1:
+        return 'Educação Infantil';
+        case 2:
+        return 'Ensino Fundamental';
+        case 3:
+        return 'Ensino Médio';
+        case 4:
+        return 'Educação Profissional';
+        case 5:
+        return 'Educação Profissional Técnica de Nível Médio';
+        case 6:
+        return 'Educação Profissional FIC';
+        case 7:
+        return 'EJA';
+        default:
+        return 'Não classificada';
+    }
+};
diff --git a/src/libs/convert/incomeRange.js b/src/libs/convert/incomeRange.js
index fee5189b4a4100e42940108ce3f173e655ef13ee..a38446aa56ac3012edbe034bf1037772085004f8 100644
--- a/src/libs/convert/incomeRange.js
+++ b/src/libs/convert/incomeRange.js
@@ -36,5 +36,7 @@ module.exports = function incomeRange(id) {
         return 'Mais de 5 salários mínimos';
         case 9: 
         return 'Não informado ou ignorado';
+        case 10:
+        return "Ignorado"
     }
 };
diff --git a/src/libs/convert/metroCode.js b/src/libs/convert/metroCode.js
index 0442f2c757a31b81828e28574b55bb50783c873b..36bf507089c1e7c18dd6d9c82e555f02d9685023 100644
--- a/src/libs/convert/metroCode.js
+++ b/src/libs/convert/metroCode.js
@@ -62,6 +62,7 @@ module.exports = function metroCode(id) {
         return 'Região Metropolitana de Vale do Rio Cuiabá';
         case 52:
         return 'Região Metropolitana de Goiânia';
+		case null:
         case 99:
         return 'Não é região metropolitana ou região administrativa integrada';
         default:
diff --git a/src/libs/convert/modalityShift.js b/src/libs/convert/modalityShift.js
index 7cde03d02bb8f4da76c7e4a998b582fd81dc63b5..91a47b401e6a518268a016ea9b75bbe6a81e1cd4 100644
--- a/src/libs/convert/modalityShift.js
+++ b/src/libs/convert/modalityShift.js
@@ -35,6 +35,7 @@ module.exports = function modalityShift(id) {
         case 7:
         return 'EaD ou semipresencial';
         case 9:
+		case null:
         return 'Não informado';
         case 99:
         return 'Não frequenta instituição de ensino';
diff --git a/src/libs/convert/postGraduationEntity.js b/src/libs/convert/postGraduationEntity.js
new file mode 100644
index 0000000000000000000000000000000000000000..49e8d08af7f0eaafe9cd5a14d0482b0accf9b337
--- /dev/null
+++ b/src/libs/convert/postGraduationEntity.js
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+   
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function ageRange(id) {
+    switch (id) {
+        case 1:
+        return 'Pós-Graduação Especialização';
+        case 2:
+        return 'Pós-Graduação Mestrado';
+        case 3:
+        return 'Pós-Graduação Doutorado';
+        default:
+        return '';
+    }
+};
diff --git a/src/libs/convert/specialEducation.js b/src/libs/convert/specialEducation.js
new file mode 100644
index 0000000000000000000000000000000000000000..aac420d29f5aff4dd1d38287b93794e2c5576962
--- /dev/null
+++ b/src/libs/convert/specialEducation.js
@@ -0,0 +1,31 @@
+/*
+Copyright (C) 2022 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function specialEducation(id) {
+    switch (id) {
+        case 1:
+        return 'Inclusiva';
+        case 2:
+        return 'Exclusiva';
+        default:
+        return 'Não definido';
+    }
+};
+  
diff --git a/src/libs/convert/specialEducationDoc.js b/src/libs/convert/specialEducationDoc.js
new file mode 100644
index 0000000000000000000000000000000000000000..7ec9335c840b2d7dee008b84ed5eddad3f8d197b
--- /dev/null
+++ b/src/libs/convert/specialEducationDoc.js
@@ -0,0 +1,31 @@
+/*
+Copyright (C) 2022 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function specialEducationDoc(id) {
+    switch (id) {
+        case 1:
+        return 'Classe Comum';
+        case 2:
+        return 'Classe Especial';
+        default:
+        return 'Não definido';
+    }
+};
+  
diff --git a/src/libs/convert/specialEducationEntity.js b/src/libs/convert/specialEducationEntity.js
new file mode 100644
index 0000000000000000000000000000000000000000..b358c4edaba32b3c18220a73279a74568aa59a97
--- /dev/null
+++ b/src/libs/convert/specialEducationEntity.js
@@ -0,0 +1,31 @@
+/*
+Copyright (C) 2022 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function specialEducation(id) {
+    switch (id) {
+        case 1:
+        return 'Classe Comum';
+        case 2:
+        return 'Classe Exclusiva';
+        default:
+        return 'Não definido';
+    }
+};
+  
diff --git a/src/libs/convert/totalDoc.js b/src/libs/convert/totalDoc.js
new file mode 100644
index 0000000000000000000000000000000000000000..09f947c834c9958e971949b67533044111171d19
--- /dev/null
+++ b/src/libs/convert/totalDoc.js
@@ -0,0 +1,23 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function totalDoc(id) {
+    return '';
+};
diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js
new file mode 100644
index 0000000000000000000000000000000000000000..eed373ddbbfd98c4a30fc4615823bb5d91a01fc4
--- /dev/null
+++ b/src/libs/middlewares/aggregateData.js
@@ -0,0 +1,104 @@
+const id2str = require(`./id2str`);
+
+/*
+    Middleware que tem como função formatar dados agregados.
+    Dados agregados não podem ser 'puxados' do banco de dados da mesma maneira que os dados tradicioanis, dessa maneira é
+    necessário formatá-los para que sigam o padrão.
+*/
+
+// Faz o mapeamento dos filtros com seus respectivos 'id2str'
+const convert = {
+    adm_dependency_detailed: 'admDependencyPriv',
+    location: 'location',
+    diff_location: 'diffLocation',
+    region: 'regionCode',
+    state: 'stateName',
+    age_range: 'ageRangeAggregate',
+    gender: 'gender',
+    ethnic_group: 'ethnicGroup',
+    education_level_mod_agg: 'educationLevelModAgg',
+    integral_time_agg: 'integralTime',
+    period_agg: 'period',
+    modality_integral_time: 'educationLevelBasic',
+    special_education: 'specialEducation',
+    special_education_doc: 'specialEducationDoc',
+    special_education_entity: 'specialEducationEntity',
+    education_level_mod_doc: 'educationLevelModDoc',
+    education_level_mod_entity_seg: 'educationLevelModEntitySeg',
+    education_level_mod_entity_agg: 'educationLevelModEntityAgg',
+    adm_dependency_entity_agg: 'newPnadAdmDependency',
+    adm_dependency_entity: 'admDependency',
+    location_entity: 'location',
+    gender_entity: 'gender',
+    age_range_entity: 'ageRangeEntity',
+    post_graduation_entity: 'postGraduationEntity',
+    contract_type_entity: 'contractType',
+    total_doc: "totalDoc",
+    education_degree_entity: "educationDegreeEntity",
+    government_agreement: "governmentAgreement"
+}
+
+function aggregateData(req, res, next) {
+    if (req.query.dims) {
+        const newResult = []
+        const aggregateFields = [
+            'gender', 
+            'age_range', 
+            'ethnic_group', 
+            'education_level_mod_agg',
+            'education_level_mod_doc',
+            'integral_time_agg', 
+            'period_agg', 
+            'modality_integral_time', 
+            'special_education',
+            'special_education_doc',
+            'special_education_entity',
+            'education_level_mod_entity_seg',
+            'education_level_mod_entity_agg',
+            'adm_dependency_entity_agg',
+            'adm_dependency_entity',
+            'location_entity',
+            'gender_entity',
+            'age_range_entity',
+            'post_graduation_entity',
+            'contract_type_entity',
+            'education_degree_entity'
+        ]
+        let id;
+        const fields = req.query.dims.split(',');
+        let currentAggregateField;
+        let currentNonAggregateField;
+    
+        // Verifica se o filtro passado está presente nos filtros agregados
+        fields.forEach(field => {if (aggregateFields.includes(field)) currentAggregateField = field; else currentNonAggregateField = field});
+        if (currentAggregateField) {
+            req.result.forEach((r) => {
+                // Alguns filtros começam com o id = 0 outros id = 1
+                id = ['ethnic_group', 'integral_time_agg'].includes(currentAggregateField) ? 0 : 1;
+                for (const property in r) {
+                    // Dados agregados são identificados com a substring 'total_' em sua chave
+                    if (property.includes('total_')) {
+                        let data = {
+                            total: r[property],
+                            year: r.year,
+                            [`${currentAggregateField}_id`]: id,
+                            [`${currentAggregateField}_name`]: id2str[convert[currentAggregateField]](id)
+                        }
+        
+                        if (currentNonAggregateField) {
+                            data[`${currentNonAggregateField}_id`] = r[`${currentNonAggregateField}_id`];
+                            data[`${currentNonAggregateField}_name`] = id2str[convert[currentNonAggregateField]](r[`${currentNonAggregateField}_id`]);
+                        }
+        
+                        newResult.push(data)
+                        ++id;
+                    }
+                }
+            })
+            req.result = newResult;
+        }
+    }
+    next();
+}
+
+module.exports = aggregateData;
\ No newline at end of file
diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js
index 77706527ebf00e6e9043dcea637e37f67e46efc1..d6c763c9e3d281b3763c8be632d1b4dca5a0e78f 100644
--- a/src/libs/middlewares/id2str.js
+++ b/src/libs/middlewares/id2str.js
@@ -32,6 +32,7 @@ const agreement = require(`${libs}/convert/agreement`);
 const booleanVariable = require(`${libs}/convert/booleanVariable`);
 const educationLevel = require(`${libs}/convert/educationLevel`);
 const educationLevelMod = require(`${libs}/convert/educationLevelMod`);
+const educationLevelModAgg = require(`${libs}/convert/educationLevelModAgg`);
 const educationLevelShort = require(`${libs}/convert/educationLevelShort`);
 const educationType = require(`${libs}/convert/educationType`);
 const citySize = require(`${libs}/convert/citySize`);
@@ -114,6 +115,17 @@ const regionCode = require(`${libs}/convert/regionCode`);
 const metroCode =  require(`${libs}/convert/metroCode`);
 const modalityShift = require(`${libs}/convert/modalityShift`);
 const incomeRange = require(`${libs}/convert/incomeRange`);
+const ageRangeAggregate = require(`${libs}/convert/ageRangeAggregate`);
+const specialEducation = require(`${libs}/convert/specialEducation`);
+const specialEducationDoc = require(`${libs}/convert/specialEducationDoc`);
+const specialEducationEntity = require(`${libs}/convert/specialEducationEntity`);
+const educationLevelModDoc = require(`${libs}/convert/educationLevelModDoc`);
+const educationLevelModEntitySeg = require(`${libs}/convert/educationLevelModEntitySeg`);
+const educationLevelModEntityAgg = require(`${libs}/convert/educationLevelModEntityAgg`);
+const ageRangeEntity = require(`${libs}/convert/ageRangeEntity`);
+const postGraduationEntity = require(`${libs}/convert/postGraduationEntity`);
+const totalDoc = require(`${libs}/convert/totalDoc`);
+const educationDegreeEntity = require(`${libs}/convert/educationDegreeEntity`);
 
 const ids = {
     gender_id: gender,
@@ -122,6 +134,7 @@ const ids = {
     education_level_id: educationLevel,
     education_level_basic_id: educationLevelBasic,
     education_level_mod_id: educationLevelMod,
+    education_level_mod_agg_id: educationLevelModAgg,
     education_level_short_id: educationLevelShort,
     adm_dependency_id: admDependency,
     adm_dependency_detailed_id: admDependencyPriv,
@@ -149,6 +162,7 @@ const ids = {
     ethnic_group_pnad_id: ethnicGroupPnad,
     age_range_id: ageRange,
     age_range_all_id: ageRangeAll,
+    age_range_aggregate_id: ageRangeAggregate,
     full_age_range_id: fullAgeRange,
     gender_pnad_id: genderPnad,
     fifth_household_income_id: fifthHouseholdIncome,
@@ -220,7 +234,17 @@ const ids = {
     region_id: regionCode,
     metro_code_id: metroCode,
     modality_shift_id: modalityShift,
-    income_range_id: incomeRange
+    income_range_id: incomeRange,
+    special_education: specialEducation,
+    special_education_doc: specialEducationDoc,
+    education_level_mod_doc: educationLevelModDoc,
+    education_level_mod_entity_seg: educationLevelModEntitySeg,
+    education_level_mod_entity_agg: educationLevelModEntityAgg,
+    age_range_entity: ageRangeEntity,
+    post_graduation_entity: postGraduationEntity,
+    special_education_entity: specialEducationEntity,
+    total_doc: totalDoc,
+    education_degree_entity: educationDegreeEntity
 };
 
 function transform(removeId=false) {
@@ -268,6 +292,7 @@ module.exports = {
     educationLevel,
     educationLevelBasic,
     educationLevelMod,
+    educationLevelModAgg,
     educationLevelShort,
     educationLevelSchoolYear,
     admDependency,
@@ -285,6 +310,7 @@ module.exports = {
     contractType,
     ethnicGroupPnad,
     ageRange,
+    ageRangeAggregate,
     ageRangeAll,
     ageStudentCode,
     fullAgeRange,
@@ -350,5 +376,15 @@ module.exports = {
     regionCode,
     metroCode,
     modalityShift,
-    incomeRange
+    incomeRange,
+    specialEducation,
+    specialEducationDoc,
+    educationLevelModDoc,
+    educationLevelModEntitySeg,
+    educationLevelModEntityAgg,
+    ageRangeEntity,
+    postGraduationEntity,
+    specialEducationEntity,
+    totalDoc,
+    educationDegreeEntity
 };
diff --git a/src/libs/routes_v1/api.js b/src/libs/routes_v1/api.js
index dc0116101fd604db133344f66e91a06de077df92..2799dac6bdcf29bb6c7b60a21ecfa175f9234335 100644
--- a/src/libs/routes_v1/api.js
+++ b/src/libs/routes_v1/api.js
@@ -143,12 +143,29 @@ const activity = require(`${libs}/routes_v1/activity`);
 
 const newPnad = require(`${libs}/routes_v1/newPnad`);
 
+const rateSchoolNew = require(`${libs}/routes_v1/rateSchoolNew`)
+
+const enrollmentAggregate = require(`${libs}/routes_v1/enrollmentAggregate`);
+
+const employeesAggregate = require(`${libs}/routes_v1/employeesAggregate`);
+
+const courseAggregate = require(`${libs}/routes_v1/courseAggregate`);
+
+const federativeEntity = require(`${libs}/routes_v1/federativeEntity`);
+
 const email = require(`${libs}/routes_v1/email`);
 
+
 const aggregateClass = require(`${libs}/routes_v1/aggregateClass`);
 
 const instructionLevel = require(`${libs}/routes_v1/instructionLevel`);
 
+const uniLocalOfferAggregate = require(`${libs}/routes_v1/uniLocalOfferAggregate`)
+
+const basicEducationConclusion = require(`${libs}/routes_v1/basicEducationConclusion`);
+
+const iliteracyRate = require(`${libs}/routes_v1/iliteracyRate`);
+
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API v1 is running' });
 });
@@ -211,6 +228,14 @@ api.use('/course_students', courseStudents);
 api.use('/new_pnad', newPnad);
 api.use('/aggregate_class', aggregateClass);
 api.use('/instruction_level', instructionLevel)
+api.use('/rate_school_new', rateSchoolNew)
+api.use('/enrollmentAggregate', enrollmentAggregate);
+api.use('/employeesAggregate', employeesAggregate);
+api.use('/course_aggregate', courseAggregate);
+api.use('/federativeEntity', federativeEntity);
+api.use('/uni_offer_aggregate', uniLocalOfferAggregate);
+api.use('/basic_education_conclusion', basicEducationConclusion);
+api.use('/iliteracy_rate', iliteracyRate);
 
 //Publication 
 api.use('/publication', publication);
diff --git a/src/libs/routes_v1/basicEducationConclusion.js b/src/libs/routes_v1/basicEducationConclusion.js
new file mode 100644
index 0000000000000000000000000000000000000000..fb7452990b4a1be888247802cea0e9e424af606c
--- /dev/null
+++ b/src/libs/routes_v1/basicEducationConclusion.js
@@ -0,0 +1,620 @@
+/*
+Copyright (C) 2024 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+
+const basicEducationConclusion = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const multiQuery = require(`${libs}/middlewares/multiQuery`);
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+const config = require(`${libs}/config`); 
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+basicEducationConclusion.use(cache('15 day'));
+
+basicEducationConclusion.get('/years', (req, res, next) => {
+    req.sql.from('pnad_novo')
+    .field('DISTINCT pnad_novo.ano_ref', 'year')
+    .where('pnad_novo.ano_ref >= 2019')
+    next();
+}, query, response('years'));
+
+basicEducationConclusion.get('/illiteracy', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i < 2; i++) {
+        req.result.push({
+            id: i, name: id2str.illiteracy(i)
+        });
+
+    }
+    req.result.push({id: 9, name: id2str.illiteracy(9)});
+    next();
+}, response('illiteracy'));
+
+basicEducationConclusion.get('/years_of_study', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i < 17; i++) {
+        req.result.push({
+            id: i, name: id2str.yearsOfStudy(i)
+        });
+    }
+
+    req.result.push({id: 99, name: id2str.yearsOfStudy(99)});
+    next();
+}, response('years_of_study'));
+
+basicEducationConclusion.get('/instruction_level', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i < 8; i++) {
+        req.result.push({
+            id: i, name: id2str.instructionLevel(i)
+        });
+    }
+    req.result.push({id: 99, name: id2str.instructionLevel(99)});
+    next();
+}, response('instruction_level'));
+
+basicEducationConclusion.get('/new_pnad_adm_dependency', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.newPnadAdmDependency(i)
+        });
+    }
+    req.result.push({id: 99, name: id2str.newPnadAdmDependency(99)});
+    next();
+}, response('new_pnad_adm_dependency'));
+
+basicEducationConclusion.get('/region', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 6; i++) {
+        req.result.push({
+            id: i, name: id2str.regionCode(i)
+        });
+    }
+
+    next();
+}, response('region'));
+
+basicEducationConclusion.get('/cap_code', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.capitalCode(i) !== 'Não informado') {
+        req.result.push({
+            id: i, name: id2str.capitalCode(i)
+        });
+        }
+    }
+    req.result.push({id: 99, name: id2str.capitalCode(99)});
+
+    next();
+}, response('cap_code'));
+
+basicEducationConclusion.get('/metro_code', (req, res, next) => {
+    req.result = []
+    for (let i = 13; i < 53; i++) {
+        if (id2str.metroCode(i) !== 'Não informado') {
+        req.result.push({
+            id: i, name: id2str.metroCode(i)
+        });
+        }
+    }
+    req.result.push({id: 99, name: id2str.metroCode(99)});
+
+    next();
+}, response('metro_code'));
+
+basicEducationConclusion.get('/attended_modality', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 16; i++) {
+        req.result.push({
+            id: i, name: id2str.attendedModality(i)
+        });
+    }
+    // Remove the option with id equals 10 => This option exists in the database, a better solution to this would be remove the option from the database
+    req.result.splice(req.result.findIndex((item) => item.id === 10), 1);
+    req.result.push({id: 99, name: id2str.attendedModality(99)});
+    next();
+}, response('attended_modality'));
+
+basicEducationConclusion.get('/income_range', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 8; i++) {
+        req.result.push({
+            id: i, name: id2str.incomeRange(i)
+        });
+    }
+    req.result.push({id: 10, name: id2str.incomeRange(10)});
+    next();
+}, response('income_range'));
+
+basicEducationConclusion.get('/attends_school', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.attendsSchool(i)
+        });
+    }
+    next();
+}, response('attends_school'));
+
+basicEducationConclusion.get('/gender', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.gender(i)
+        });
+    }
+    next();
+}, response('gender'));
+
+basicEducationConclusion.get('/new_pnad_ethnic_group', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 6; i++) {
+        req.result.push({
+            id: i, name: id2str.ethnicGroupNewPnad(i)
+        });
+    }
+    req.result.push({id: 9, name: id2str.ethnicGroupNewPnad(9)});
+    next();
+}, response('new_pnad_ethnic_group'));
+
+basicEducationConclusion.get('/bolsa_familia', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.attendsSchool(i)
+        });
+    }
+    req.result.push({id: 9, name: id2str.attendsSchool(9)});
+    next();
+}, response('bolsa_familia'));
+
+basicEducationConclusion.get('/modality', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 4; i++) {
+        req.result.push({
+            id: i, name: id2str.modality(i)
+        });
+    }
+    req.result.push({id: 99, name: id2str.modality(99)});
+    next();
+}, response('modality'));
+
+basicEducationConclusion.get('/modality_shift', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 8; i++) {
+        req.result.push({
+            id: i, name: id2str.modalityShift(i)
+        });
+    }
+    req.result.push({id: 9, name: id2str.modalityShift(9)});
+    req.result.push({id: 99, name: id2str.modalityShift(99)});
+    next();
+}, response('modality_shift'));
+
+basicEducationConclusion.get('/state', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.stateName(i) !== 'Não declarada') {
+            req.result.push({
+                id: i, name: id2str.stateName(i)
+            });
+        }
+    }
+    req.result.push({id: 99, name: id2str.stateName(99)});
+
+    next();
+}, response('state'));
+
+basicEducationConclusion.get('/age_range_all', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 12; i++) {
+        req.result.push({
+            id: i, name: id2str.ageRangeAll(i)
+        });
+    }
+
+    next();
+}, response('age_range_all'));
+
+basicEducationConclusion.get('/location', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.location(i)
+        });
+    }
+
+    next();
+}, response('location'));
+
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'id',
+    table: 'pnad_novo',
+    tableField: 'id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: ['id', 'nome'],
+    resultField: ['state_id', 'state_nome'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'pnad_novo'
+    }
+}).addValue({
+    name: 'state_not',
+    table: 'estado',
+    tableField: ['nome', 'id'],
+    resultField: ['state_name', 'state_id'],
+    where: {
+        relation: '<>',
+        type: 'integer',
+        field: 'cod_uf',
+        table: 'pnad_novo'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'pnad_novo'
+    }
+}).addValue({
+    name: 'years_of_study',
+    table: 'pnad_novo',
+    tableField: 'anos_de_estudo',
+    resultField: 'years_of_study_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'anos_de_estudo'
+    }
+}).addValue({
+    name: 'instruction_level',
+    table: 'pnad_novo',
+    tableField: 'nivel_de_instrucao',
+    resultField: 'instruction_level_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'nivel_de_instrucao'
+    }
+}).addValue({
+    name: 'new_pnad_adm_dependency',
+    table: 'pnad_novo',
+    tableField: 'dependencia_adm',
+    resultField: 'new_pnad_adm_dependency_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm'
+    }
+}).addValue({
+    name: 'attends_school',
+    table: 'pnad_novo',
+    tableField: 'frequenta_escola',
+    resultField: 'attends_school_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'frequenta_escola'
+    }
+}).addValue({
+    name: 'modality',
+    table: 'pnad_novo',
+    tableField: 'modalidade',
+    resultField: 'modality_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'modalidade'
+    }
+}).addValue({
+    name: 'attended_modality',
+    table: 'pnad_novo',
+    tableField: 'nivel_etapa_modalidade_freq',
+    resultField: 'attended_modality_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'nivel_etapa_modalidade_freq'
+    }
+}).addValue({
+    name: 'illiteracy',
+    table: 'pnad_novo',
+    tableField: 'analfabetismo',
+    resultField: 'illiteracy_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'analfabetismo'
+    }
+}).addValue({
+    name: 'modality_shift',
+    table: 'pnad_novo',
+    tableField: 'turno_nivel_etapa',
+    resultField: 'modality_shift_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'turno_nivel_etapa'
+    }
+}).addValue({
+    name: 'bolsa_familia',
+    table: 'pnad_novo',
+    tableField: 'recebeu_rendimentos_de_programa_bolsa_familia',
+    resultField: 'bolsa_familia_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'recebeu_rendimentos_de_programa_bolsa_familia'
+    }
+}).addValue({
+    name: 'new_pnad_ethnic_group',
+    table: 'pnad_novo',
+    tableField: 'cor_raca',
+    resultField: 'new_pnad_ethnic_group_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cor_raca'
+    }
+}).addValue({
+    name: 'age_range_all',
+    table: 'pnad_novo',
+    tableField: 'faixa_etaria',
+    resultField: 'age_range_all_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'faixa_etaria'
+    }
+}).addValue({
+    name: 'income_range',
+    table: 'pnad_novo',
+    tableField: 'faixa_rendimento_aux_tx',
+    resultField: 'income_range_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'faixa_rendimento_aux_tx'
+    }
+}).addValue({
+    name: 'gender',
+    table: 'pnad_novo',
+    tableField: 'sexo',
+    resultField: 'gender_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'sexo'
+    }
+}).addValue({
+    name: 'cap_code',
+    table: 'pnad_novo',
+    tableField: 'cod_cap',
+    resultField: 'cap_code_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_cap'
+    }
+}).addValue({
+    name: 'region',
+    table: 'pnad_novo',
+    tableField: 'cod_regiao',
+    resultField: 'region_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_regiao'
+    }
+}).addValue({
+    name: 'metro_code',
+    table: 'pnad_novo',
+    tableField: 'cod_rm_ride',
+    resultField: 'metro_code_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_rm_ride'
+    }
+}).addValue({
+    name: 'location',
+    table: 'pnad_novo',
+    tableField: 'situacao_domicilio',
+    resultField: 'location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'situacao_domicilio'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'pnad_novo',
+    tableField: 'ano_ref',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_ref'
+    }
+}).addValue({
+    name: 'max_year',
+    table: 'pnad_novo',
+    tableField: '',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_ref'
+    }
+}).addField({
+    name: 'search',
+    field: false,
+    where: true
+}).addValueToField({
+    name: 'name',
+    table: 'pnad_novo',
+    tableField: 'nome',
+    where: {
+        relation: 'LIKE',
+        type: 'string',
+        field: 'nome'
+    }
+}, 'search').addValue({
+    name: 'mesoregion',
+    table: 'pnad_novo',
+    tableField: 'mesorregiao_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'mesorregiao_id'
+    }
+}).addValue({
+    name: 'microregion',
+    table: 'pnad_novo',
+    tableField: 'microrregiao_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'microrregiao_id'
+    }
+});
+
+function matchQueries(queryPartial, queryTotal) {
+    let match = [];
+    queryTotal.forEach((result) => {
+        let newObj = {};
+        let keys = Object.keys(result);
+        keys.forEach((key) => {
+            newObj[key] = result[key];
+        });
+        let index = keys.indexOf('total');
+        if(index > -1) keys.splice(index, 1);
+        let objMatch = null;
+
+        for(let i = 0; i < queryPartial.length; ++i) {
+            let partial = queryPartial[i];
+            let foundMatch = true;
+            for(let j = 0; j < keys.length; ++j) {
+                let key = keys[j];
+                if(partial[key] !== result[key]) {
+                    foundMatch = false;
+                    break;
+                }
+            }
+            if(foundMatch) {
+                objMatch = partial;
+                break;
+            }
+        }
+
+        if(objMatch) {
+            newObj.denominator = result.total;
+            newObj.partial = objMatch.total;
+            newObj.total = (objMatch.total / result.total) * 100;
+            match.push(newObj);
+        }
+    });
+
+    return match;
+}
+
+basicEducationConclusion.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+    req.querySet = [];
+    
+    // Subquery para total_pop_maior_19 com filtros dinâmicos
+    let totalPopMaior19 = req.sql.clone();
+        totalPopMaior19.from("pnad_novo")
+        .field("ano_ref", "year")
+        .field("SUM(peso_domicilio_pessoas_com_cal)", "total")
+        .where("idade_morador_31_03 >= 19")
+        .where("ano_ref >= 2019")
+        .group("ano_ref")
+        .order("ano_ref");
+
+    // Subquery para total_pop_ed_bas_maior_19 com filtros dinâmicos
+    let totalPopEdBasMaior19 = req.sql.clone();
+        totalPopEdBasMaior19.from("pnad_novo")
+        .field("ano_ref", "year")
+        .field("SUM(peso_domicilio_pessoas_com_cal)", "total")
+        .where("idade_morador_31_03 >= 19")
+        .where("nivel_de_instruc_mais_elevad_para_o_fundam_com_duracao_9_anos IN (5, 6, 7)")
+        .where("ano_ref >= 2019")
+        .group("ano_ref")
+        .order("ano_ref");
+
+    if (req.query.dims && req.query.dims.includes("income_range")) {
+        totalPopMaior19.where("faixa_rendimento_aux_tx is not null");
+        totalPopEdBasMaior19.where("faixa_rendimento_aux_tx is not null");
+    }
+
+    req.querySet.push(totalPopEdBasMaior19);
+    req.querySet.push(totalPopMaior19);
+
+    next();
+}, multiQuery, (req, res, next) => {
+        // The multiple requests are made. Then we need to calculate the percetange. So the function
+        // below is used
+        let newObj = matchQueries(req.result[0], req.result[1]);
+        req.result = newObj;
+    next();
+}, id2str.transform(false), response('basic_education_conclusion'));
+
+
+module.exports = basicEducationConclusion;
diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
new file mode 100644
index 0000000000000000000000000000000000000000..78ae89a71035adf992cdc43f1e8253fc5dbef575
--- /dev/null
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -0,0 +1,412 @@
+/*
+Copyright (C) 2024 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+
+const CourseAggregateApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+const config = require(`${libs}/config`); 
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+CourseAggregateApp.use(cache('15 day'));
+
+CourseAggregateApp.get('/years', (req, res, next) => {
+    req.sql.from('curso_superior_agregado')
+    .field('DISTINCT curso_superior_agregado.ano_censo', 'year')
+    next();
+}, query, response('years'));
+
+CourseAggregateApp.get('/upper_adm_dependency', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 7; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.upperAdmDependency(i)
+        });
+    };
+    next();
+}, response('upper_adm_dependency'));
+
+CourseAggregateApp.get('/academic_organization', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 5; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.academicOrganization(i)
+        });
+    };
+    next();
+}, response('academic_organization'));
+
+CourseAggregateApp.get('/academic_level', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 4; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.academicLevel(i)
+        });
+    };
+    next();
+}, response('academic_level'));
+
+CourseAggregateApp.get('/upper_education_mod', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 2; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.upperEducationMod(i)
+        });
+    };
+    next();
+}, response('upper_education_mod'));
+
+CourseAggregateApp.get('/region', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 6; i++) {
+        req.result.push({
+            id: i, name: id2str.regionCode(i)
+        });
+    }
+
+    next();
+}, response('region'));
+
+CourseAggregateApp.get('/cap_code', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.capitalCode(i) !== 'Não informado') {
+        req.result.push({
+            id: i, name: id2str.capitalCode(i)
+        });
+        }
+    }
+    req.result.push({id: 99, name: id2str.capitalCode(99)});
+
+    next();
+}, response('cap_code'));
+
+CourseAggregateApp.get('/metro_code', (req, res, next) => {
+    req.result = []
+    for (let i = 13; i < 53; i++) {
+        if (id2str.metroCode(i) !== 'Não informado') {
+        req.result.push({
+            id: i, name: id2str.metroCode(i)
+        });
+        }
+    }
+    req.result.push({id: 99, name: id2str.metroCode(99)});
+
+    next();
+}, response('metro_code'));
+
+CourseAggregateApp.get('/is_free', (req, res, next) => {
+    req.result = [
+        {id: null, name: 'Não Classificado'},
+        {id: 0, name: 'Não'},
+        {id: 1, name: 'Sim'}
+    ];
+    next();
+}, response('is_free'));
+
+
+CourseAggregateApp.get('/cine_geral', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 10; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.cineGeral(i)
+        });
+    };
+    next();
+}, response('cine_geral'));
+
+CourseAggregateApp.get('/cine_specific', (req, res, next) => {
+    req.result = [];
+    const defaultCase = null;
+    for(let i = 1; i <= 104; ++i) {
+        let obj = {
+            id: i,
+            name: id2str.cineSpecific(i)
+        };
+        if (obj.name !== id2str.cineSpecific(defaultCase)){
+            req.result.push(obj);
+        }
+    };
+    req.result.push({
+        id: defaultCase,
+        name: id2str.cineSpecific(defaultCase)
+    });
+    next();
+}, response('cine_specific'));
+
+CourseAggregateApp.get('/cine_detailed', (req, res, next) => {
+    req.result = [];
+    const defaultCase = null;
+    for(let i = 11; i <= 1041; ++i) {
+        let obj = {
+            id: i,
+            name: id2str.cineDetailed(i)
+        };
+        if (obj.name !== id2str.cineDetailed(defaultCase)){
+            req.result.push(obj);
+        }
+    };
+    req.result.push({
+        id: defaultCase,
+        name: id2str.cineDetailed(defaultCase)
+    });
+    next();
+}, response('cine_detailed'));
+
+CourseAggregateApp.get('/university', (req, res, next) => {
+    req.sql.from('curso_superior_agregado')
+    .field('DISTINCT curso_superior_agregado.cod_ies', 'cod')
+    .field('ies_ens_superior.nome_ies', 'nome')
+    .join('ies_ens_superior', null, 'curso_superior_agregado.cod_ies = ies_ens_superior.cod_ies and curso_superior_agregado.ano_censo = ies_ens_superior.ano_censo')
+    next();
+}, query, response('university'));
+
+CourseAggregateApp.get('/state', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.stateName(i) !== 'Não declarada') {
+            req.result.push({
+                id: i, name: id2str.stateName(i)
+            });
+        }
+    }
+    req.result.push({id: 99, name: id2str.stateName(99)});
+
+    next();
+}, response('state'));
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'upper_adm_dependency',
+    table: 'curso_superior_agregado',
+    tableField: 'tp_categ_adm',
+    resultField: 'upper_adm_dependency_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'tp_categ_adm'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: ['id', 'nome'],
+    resultField: ['state_id', 'state_nome'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'curso_superior_agregado'
+    }
+}).addValue({
+    name: 'academic_organization',
+    table: 'curso_superior_agregado',
+    tableField: 'tp_org_acad',
+    resultField: 'academic_organization_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'tp_org_acad'
+    }
+}).addValue({
+    name: 'academic_level',
+    table: 'curso_superior_agregado',
+    tableField: 'tp_grau_acad',
+    resultField: 'academic_level_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'tp_grau_acad'
+    }
+}).addValue({
+    name: 'upper_education_mod',
+    table: 'curso_superior_agregado',
+    tableField: 'tp_modal_ens',
+    resultField: 'upper_education_mod_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'tp_modal_ens'
+    }
+}).addValue({
+    name: 'is_free',
+    table: 'curso_superior_agregado',
+    tableField: 'in_gratuito',
+    resultField: 'is_free_id',
+    where: {
+        relation: '=',
+        type: 'boolean',
+        field: 'in_gratuito'
+    }
+}).addValue({
+    name: 'cine_geral',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_cine_area_geral',
+    resultField: 'cine_geral_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_cine_area_geral'
+    }
+}).addValue({
+    name: 'cine_specific',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_cine_area_esp',
+    resultField: 'cine_specific_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_cine_area_esp'
+    }
+}).addValue({
+    name: 'cine_detailed',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_cine_area_detalhada',
+    resultField: 'cine_detailed_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_cine_area_detalhada'
+    }
+}).addValue({
+    name: 'uni_offer_aggregate',
+    table: 'ies_ens_superior',
+    tableField: ['cod_ies', 'nome_ies'],
+    resultField: ['university_id', 'university_name'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_ies'
+    },
+    join: {
+        primary: ['cod_ies', 'ano_censo'],
+        foreign: ['cod_ies', 'ano_censo'],
+        foreignTable: 'curso_superior_agregado'
+    }
+}).addValue({
+    name: 'cap_code',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_cap',
+    resultField: 'cap_code_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_cap'
+    }
+}).addValue({
+    name: 'region',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_reg',
+    resultField: 'region_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_reg'
+    }
+}).addValue({
+    name: 'metro_code',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_rm_ride',
+    resultField: 'metro_code_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_rm_ride'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'curso_superior_agregado',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'max_year',
+    table: 'curso_superior_agregado',
+    tableField: '',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['id', 'nome'],
+    resultField: ['city_id', 'city_name'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_mun',
+        foreignTable: 'curso_superior_agregado'
+    }
+});
+
+CourseAggregateApp.get('/', rqf.parse(), rqf.build(),  (req, res, next) => {
+    req.sql.from('curso_superior_agregado')
+    .field('count(distinct(cod_curso))', 'total')
+    .field('curso_superior_agregado.ano_censo', 'year')
+    .where('curso_superior_agregado.tp_nivel_acad = 1 AND qtd_cursos = 1')
+    .group('curso_superior_agregado.ano_censo')
+    .order('curso_superior_agregado.ano_censo')
+    console.log(req.sql.toString())
+    next();
+}, query, id2str.transform(false), response('course_aggregate'));
+
+module.exports = CourseAggregateApp;
diff --git a/src/libs/routes_v1/employees.js b/src/libs/routes_v1/employees.js
index 1ef4e7fd0a3b29ae0b2725b1cbdc3cd1b318f7e4..22aa7d07dc1a75111cf498fcf945528280f98568 100644
--- a/src/libs/routes_v1/employees.js
+++ b/src/libs/routes_v1/employees.js
@@ -489,6 +489,8 @@ function formatFunction(queryOriginal,reqDims) {
         qtde_secretario: "Secretário",
         qtde_seguranca: "Segurança",
         qtde_monitores: "Monitores",
+        qtde_gestores: "Gestores",
+        qtde_assistente_social: "Assistente Social",
         qtde_null: "Não Classificado"
     }
     let resultObj = []
@@ -613,6 +615,8 @@ employeesApp.get('/', rqfSchool.parse(), (req, res, next) => {
         .field('SUM(CASE WHEN escola.qtde_prof_secretario = 88888 THEN 0 ELSE escola.qtde_prof_secretario END)','qtde_secretario')
         .field('SUM(CASE WHEN escola.qtde_prof_seguranca = 88888 THEN 0 ELSE escola.qtde_prof_seguranca END)','qtde_seguranca')
         .field('SUM(CASE WHEN escola.qtde_prof_monitores = 88888 THEN 0 ELSE escola.qtde_prof_monitores END)', 'qtde_monitores')
+        .field('SUM(CASE WHEN (escola.qtde_gestores = 88888 OR escola.qtde_gestores IS NULL) THEN 0 ELSE escola.qtde_gestores END)', 'qtde_gestores')
+        .field('SUM(CASE WHEN (escola.qtde_assistente_social = 88888 OR escola.qtde_assistente_social IS NULL) THEN 0 ELSE escola.qtde_assistente_social END)', 'qtde_assistente_social')
         .field("'Brasil'", 'name')
         .field('escola.ano_censo', 'year')
         .from('escola')
@@ -621,7 +625,7 @@ employeesApp.get('/', rqfSchool.parse(), (req, res, next) => {
         .where('(escola.situacao_funcionamento_pareada = 1) AND (escola.ensino_regular = 1 OR escola.ensino_eja = 1 OR escola.educacao_profissional = 1) AND (escola.dependencia_adm_id = 2 OR escola.dependencia_adm_id = 3 OR escola.dependencia_adm_id = 4) and ano_censo >= 2019');
         delete req.dims.function;
     } else {
-        req.sql.field('SUM(CASE WHEN escola.qt_prof_admin = 88888 THEN 0 ELSE escola.qt_prof_admin END) + SUM(CASE WHEN escola.qtde_prof_servicos_gerais = 88888 THEN 0 ELSE escola.qtde_prof_servicos_gerais END) + SUM(CASE WHEN escola.qtde_prof_bibliotecario = 88888 THEN 0 ELSE escola.qtde_prof_bibliotecario END) + SUM(CASE WHEN escola.qtde_prof_saude = 88888 THEN 0 ELSE escola.qtde_prof_saude END) + SUM(CASE WHEN escola.qtde_prof_coordenador = 88888 THEN 0 ELSE escola.qtde_prof_coordenador END) + SUM(CASE WHEN escola.qtde_prof_fono = 88888 THEN 0 ELSE escola.qtde_prof_fono END) + SUM(CASE WHEN escola.qtde_prof_nutricionista = 88888 THEN 0 ELSE escola.qtde_prof_nutricionista END) + SUM(CASE WHEN escola.qtde_prof_psicologo = 88888 THEN 0 ELSE escola.qtde_prof_psicologo END) + SUM(CASE WHEN escola.qtde_prof_alimentacao = 88888 THEN 0 ELSE escola.qtde_prof_alimentacao END) + SUM(CASE WHEN escola.qtde_prof_pedagogia = 88888 THEN 0 ELSE escola.qtde_prof_pedagogia END) + SUM(CASE WHEN escola.qtde_prof_secretario = 88888 THEN 0 ELSE escola.qtde_prof_secretario END) + SUM(CASE WHEN escola.qtde_prof_seguranca = 88888 THEN 0 ELSE escola.qtde_prof_seguranca END) + SUM(CASE WHEN escola.qtde_prof_monitores = 88888 THEN 0 ELSE escola.qtde_prof_monitores END)', 'total')
+        req.sql.field('SUM(CASE WHEN escola.qt_prof_admin = 88888 THEN 0 ELSE escola.qt_prof_admin END) + SUM(CASE WHEN escola.qtde_prof_servicos_gerais = 88888 THEN 0 ELSE escola.qtde_prof_servicos_gerais END) + SUM(CASE WHEN escola.qtde_prof_bibliotecario = 88888 THEN 0 ELSE escola.qtde_prof_bibliotecario END) + SUM(CASE WHEN escola.qtde_prof_saude = 88888 THEN 0 ELSE escola.qtde_prof_saude END) + SUM(CASE WHEN escola.qtde_prof_coordenador = 88888 THEN 0 ELSE escola.qtde_prof_coordenador END) + SUM(CASE WHEN escola.qtde_prof_fono = 88888 THEN 0 ELSE escola.qtde_prof_fono END) + SUM(CASE WHEN escola.qtde_prof_nutricionista = 88888 THEN 0 ELSE escola.qtde_prof_nutricionista END) + SUM(CASE WHEN escola.qtde_prof_psicologo = 88888 THEN 0 ELSE escola.qtde_prof_psicologo END) + SUM(CASE WHEN escola.qtde_prof_alimentacao = 88888 THEN 0 ELSE escola.qtde_prof_alimentacao END) + SUM(CASE WHEN escola.qtde_prof_pedagogia = 88888 THEN 0 ELSE escola.qtde_prof_pedagogia END) + SUM(CASE WHEN escola.qtde_prof_secretario = 88888 THEN 0 ELSE escola.qtde_prof_secretario END) + SUM(CASE WHEN escola.qtde_prof_seguranca = 88888 THEN 0 ELSE escola.qtde_prof_seguranca END) + SUM(CASE WHEN escola.qtde_prof_monitores = 88888 THEN 0 ELSE escola.qtde_prof_monitores END) + SUM(CASE WHEN (escola.qtde_gestores = 88888 OR escola.qtde_gestores IS NULL) THEN 0 ELSE escola.qtde_gestores END) + SUM(CASE WHEN (escola.qtde_assistente_social = 88888 OR escola.qtde_assistente_social IS NULL) THEN 0 ELSE escola.qtde_assistente_social END)', 'total')
         .field("'Brasil'", 'name')
         .field('escola.ano_censo', 'year')
         .from('escola')
diff --git a/src/libs/routes_v1/employeesAggregate.js b/src/libs/routes_v1/employeesAggregate.js
new file mode 100644
index 0000000000000000000000000000000000000000..ab5102ceb21e8e2d5297035cd4afa90ebbc191b4
--- /dev/null
+++ b/src/libs/routes_v1/employeesAggregate.js
@@ -0,0 +1,316 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+const { result } = require('lodash');
+
+const employeesAggregateApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const log = require(`${libs}/log`)(module);
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const aggregateData = require(`${libs}/middlewares/aggregateData`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+const config = require(`${libs}/config`);
+
+const addMissing = require(`${libs}/middlewares/addMissing`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+employeesAggregateApp.use(cache('15 day'));
+
+let rqf = new ReqQueryFields();
+
+employeesAggregateApp.get('/years', (req, res, next) => {
+    req.sql.from('escola')
+    .field('DISTINCT escola.ano_censo', 'year')
+    .where('escola.ano_censo >= 2021')
+    next();
+}, query, response('years'));
+
+employeesAggregateApp.get('/education_level_mod_doc', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 8; i++) {
+        req.result.push({
+            id: i, name: id2str.educationLevelModDoc(i)
+        });
+    }
+    next();
+}, response('education_level_mod_doc'));
+
+employeesAggregateApp.get('/special_education_doc', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.specialEducationDoc(i)
+        });
+    }
+
+    next();
+}, response('special_education_doc'));
+
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: ['nome', 'id'],
+    resultField: ['region_name', 'region_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'regiao_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'mesoregion',
+    table: 'municipio',
+    tableField: ['nome_mesorregiao', 'mesorregiao_id'],
+    resultField: ['mesoregion_name', 'mesoregion_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'mesorregiao_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'microregion',
+    table: 'municipio',
+    tableField: ['nome_microrregiao', 'microrregiao_id'],
+    resultField: ['microregion_name', 'microregion_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'microrregiao_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'escola',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo',
+    },
+}).addValue({
+    name: 'max_year',
+    table: 'escola',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo',
+    },
+}).addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: ['nome', 'id'],
+    resultField: ['state_name', 'state_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}, 'filter').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['nome', 'id'],
+    resultField: ['city_name', 'city_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}, 'filter').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: ['nome_escola', 'id'],
+    resultField: ['school_name', 'school_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'locale_id',
+    table: 'escola',
+    tableField: 'localizacao_id',
+    resultField: 'locale_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_id'
+    }
+}, 'dims').addValueToField({
+    name: 'school_id',
+    table: 'escola',
+    tableField: 'id',
+    resultField: 'school_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: 'nome_escola',
+    resultField: 'school_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'filter');
+
+// Return all cities
+employeesAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+
+    if ((req.query.filter && !req.query.filter.includes('school')) || req.query.filter == undefined)
+        throw 'Filtro escola deve ser selecionado.';
+
+    if (req.query.dims && req.query.dims.includes('education_level_mod_doc')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_doc_inf_cre)', 'total_cre')
+        .field('SUM(escola.qt_doc_inf_pre)', 'total_pre')
+        .field('SUM(escola.qt_doc_fund_ai)', 'total_fund_ai')
+        .field('SUM(escola.qt_doc_fund_af)', 'total_fund_af')
+        .field('SUM(escola.qt_doc_med)', 'total_med')
+        .field('SUM(escola.qt_doc_prof)', 'total_prof')
+        .field('SUM(escola.qt_doc_eja_fund)', 'total_eja_fund')
+        .field('SUM(escola.qt_doc_eja_med)', 'total_eja_med')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)');
+    }
+    else if (req.query.dims && req.query.dims.includes('special_education_doc')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_doc_esp_cc)', 'total_esp_cc')
+        .field('SUM(escola.qt_doc_esp_ce)', 'total_esp_ce')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)');
+    }
+    else {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_doc_bas)', 'total')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)');
+    }
+    next();
+}, query, aggregateData, id2str.transform(false), response('employees_aggregate'));
+
+module.exports = employeesAggregateApp;
diff --git a/src/libs/routes_v1/enrollmentAggregate.js b/src/libs/routes_v1/enrollmentAggregate.js
new file mode 100644
index 0000000000000000000000000000000000000000..7e8cd3faece61c7999d16db913c50938de4e51fb
--- /dev/null
+++ b/src/libs/routes_v1/enrollmentAggregate.js
@@ -0,0 +1,626 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+const { result } = require('lodash');
+
+const enrollmentAggregateApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const log = require(`${libs}/log`)(module);
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const aggregateData = require(`${libs}/middlewares/aggregateData`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+const config = require(`${libs}/config`);
+
+const addMissing = require(`${libs}/middlewares/addMissing`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+enrollmentAggregateApp.use(cache('15 day'));
+
+let rqf = new ReqQueryFields();
+
+enrollmentAggregateApp.get('/years', (req, res, next) => {
+    req.sql.from('escola')
+    .field('DISTINCT escola.ano_censo', 'year')
+    .where('escola.ano_censo >= 2021')
+    next();
+}, query, response('years'));
+
+enrollmentAggregateApp.get('/adm_dependency', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.admDependency(i)
+        });
+    }
+    next();
+}, response('adm_dependency'));
+
+enrollmentAggregateApp.get('/adm_dependency_detailed', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 8; i++) {
+        req.result.push({
+            id: i, name: id2str.admDependencyPriv(i)
+        });
+    }
+    next();
+}, response('adm_dependency_detailed'));
+
+enrollmentAggregateApp.get('/government_agreement', (req, res, next) => {
+    req.result = []
+    
+    for(let i = 1; i <= 6; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.governmentAgreement(i)
+        });
+    };
+    next();
+}, response('government_agreement'));
+
+enrollmentAggregateApp.get('/education_level_mod_agg', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 13; i++) {
+        req.result.push({
+            id: i, name: id2str.educationLevelMod(i)
+        });
+    }
+    next();
+}, response('education_level_mod_agg'));
+
+enrollmentAggregateApp.get('/integral_time_agg', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 3; i++) {
+        req.result.push({
+            id: i, name: id2str.integralTime(i)
+        });
+    }
+    next();
+}, response('integral_time_agg')); 
+
+enrollmentAggregateApp.get('/location', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.location(i)
+        });
+    }
+    next();
+}, response('location'));
+
+enrollmentAggregateApp.get('/diff_location', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i < 4; i++) {
+        req.result.push({
+            id: i, name: id2str.diffLocation(i)
+        });
+    }
+
+    req.result.push({
+        id: 8, name: 'Área onde se localizam povos e comunidades tradicionais'
+    })
+
+    next();
+}, response('diff_location'));
+
+enrollmentAggregateApp.get('/modality_integral_time', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 7; i++) {
+        req.result.push({
+            id: i, name: id2str.educationLevelBasic(i)
+        });
+    }
+
+    next();
+}, response('modality_integral_time'));
+
+enrollmentAggregateApp.get('/gender', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.gender(i)
+        });
+    }
+
+    next();
+}, response('gender'));
+
+enrollmentAggregateApp.get('/age_range', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 7; i++) {
+        req.result.push({
+            id: i, name: id2str.ageRangeAggregate(i)
+        });
+    }
+
+    next();
+}, response('age_range'));
+
+enrollmentAggregateApp.get('/ethnic_group', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 6; i++) {
+        req.result.push({
+            id: i, name: id2str.ethnicGroup(i)
+        });
+    }
+
+    next();
+}, response('ethnic_group'));
+
+enrollmentAggregateApp.get('/period_agg', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.period(i)
+        });
+    }
+
+    next();
+}, response('period_agg'));
+
+enrollmentAggregateApp.get('/region', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.regionCode(i)
+        });
+    }
+
+    next();
+}, response('period_agg'));
+
+enrollmentAggregateApp.get('/state', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.stateName(i) !== 'Não declarada') {
+            req.result.push({
+                id: i, name: id2str.stateName(i)
+            });
+        }
+    }
+
+    next();
+}, response('state'));
+
+enrollmentAggregateApp.get('/special_education', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.specialEducation(i)
+        });
+    }
+
+    next();
+}, response('special_education'));
+
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'adm_dependency',
+    table: 'escola',
+    tableField: 'dependencia_adm_id',
+    resultField: 'adm_dependency_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm_id'
+    }
+}).addValue({
+    name: 'adm_dependency_detailed',
+    table: 'escola',
+    tableField: 'dependencia_adm_priv',
+    resultField: 'adm_dependency_detailed_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm_priv'
+    }
+}).addValue({
+    name: 'education_level_mod',
+    table: 'escola',
+    tableField: 'etapas_mod_ensino_segmento_id',
+    resultField: 'education_level_mod_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'etapas_mod_ensino_segmento_id'
+    }
+}).addValue({
+    name:'integral_time',
+    table: 'escola',
+    tableField: 'tempo_integral',
+    resultField: 'integral_time_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'tempo_integral'
+    }
+  }).addValue({
+    name: 'education_level_short',
+    table: 'escola',
+    tableField: 'etapa_resumida',
+    resultField: 'education_level_short_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'etapa_resumida'
+    }
+}).addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: ['nome', 'id'],
+    resultField: ['region_name', 'region_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'regiao_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'mesoregion',
+    table: 'municipio',
+    tableField: ['nome_mesorregiao', 'mesorregiao_id'],
+    resultField: ['mesoregion_name', 'mesoregion_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'mesorregiao_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'microregion',
+    table: 'municipio',
+    tableField: ['nome_microrregiao', 'microrregiao_id'],
+    resultField: ['microregion_name', 'microregion_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'microrregiao_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'escola',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo',
+    },
+}).addValue({
+    name: 'max_year',
+    table: 'escola',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo',
+    },
+}).addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: ['nome', 'id'],
+    resultField: ['state_name', 'state_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}, 'filter').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['nome', 'id'],
+    resultField: ['city_name', 'city_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}, 'filter').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: ['nome_escola', 'id'],
+    resultField: ['school_name', 'school_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'locale_id',
+    table: 'escola',
+    tableField: 'localizacao_id',
+    resultField: 'locale_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_id'
+    }
+}, 'dims').addValueToField({
+    name: 'school_id',
+    table: 'escola',
+    tableField: 'id',
+    resultField: 'school_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: 'nome_escola',
+    resultField: 'school_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'filter').addValue({
+    name: 'location',
+    table: 'escola',
+    tableField: 'localizacao_id',
+    resultField: 'location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_id'
+    }
+}).addValue({
+    name: 'diff_location',
+    table: 'escola',
+    tableField: 'localizacao_diferenciada_par',
+    resultField: 'diff_location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_diferenciada_par',
+    }
+}).addValue({
+    name: 'government_agreement',
+    table: 'escola',
+    tableField: 'dependencia_convenio_publico',
+    resultField: 'government_agreement_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_convenio_publico'
+    }
+});
+
+// Return all cities
+enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+
+    console.log(req.query);
+
+    if (req.query.dims && req.query.dims.includes('gender'))
+    {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_bas_masc)', 'total_mas')
+        .field('SUM(escola.qt_mat_bas_fem)', 'total_fem')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
+    }
+    else if (req.query.dims && req.query.dims.includes('age_range')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_bas_0_3)', 'total_0_3')
+        .field('SUM(escola.qt_mat_bas_4_5)', 'total_4_5')
+        .field('SUM(escola.qt_mat_bas_6_10)', 'total_6_10')
+        .field('SUM(escola.qt_mat_bas_11_14)', 'total_11_14')
+        .field('SUM(escola.qt_mat_bas_15_17)', 'total_15_17')
+        .field('SUM(escola.qt_mat_bas_18_mais)', 'total_18_mais')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null')
+    }
+    else if (req.query.dims && req.query.dims.includes('ethnic_group')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_bas_nd)', 'total_nd')
+        .field('SUM(escola.qt_mat_bas_branca)', 'total_branca')
+        .field('SUM(escola.qt_mat_bas_preta)', 'total_preta')
+        .field('SUM(escola.qt_mat_bas_parda)', 'total_parda')
+        .field('SUM(escola.qt_mat_bas_amarela)', 'total_amarela')
+        .field('SUM(escola.qt_mat_bas_indigena)', 'total_indigena')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null')
+    }
+    else if (req.query.dims && req.query.dims.includes('education_level_mod_agg')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_inf_cre)', 'total_cre')
+        .field('SUM(escola.qt_mat_inf_pre)', 'total_pre')
+        .field('SUM(escola.qt_mat_fund_ai)', 'total_fund_ai')
+        .field('SUM(escola.qt_mat_fund_af)', 'total_fund_af')
+        .field('SUM(escola.qt_mat_med_agg)', 'total_med')
+        .field('SUM(escola.qt_mat_med_ct + escola.qt_mat_med_nm)', 'total_med_in')
+        .field('SUM(escola.qt_mat_eja_fund_agg)', 'total_eja_fund')
+        .field('SUM(escola.qt_mat_eja_med_agg)', 'total_eja_med')
+        .field('SUM(escola.qt_mat_eja_fund_fic + escola.qt_mat_eja_med_fic + escola.qt_mat_eja_med_tec)', 'total_tec')
+        .field('SUM(escola.qt_mat_prof_agg)', 'total_prof')
+        .field('SUM(escola.qt_mat_bas)', 'total_total')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
+
+    }
+    else if (req.query.dims && req.query.dims.includes('integral_time_agg')) {
+        req.sql.from('turma,escola')
+        .field('SUM(CASE WHEN turma.tempo_integral=0 then turma.num_matricula ELSE 0 END)', 'total_int_nao')
+        .field('SUM(CASE WHEN turma.tempo_integral=1 then turma.num_matricula ELSE 0 END)', 'total_int')
+        .field('SUM(CASE WHEN turma.tempo_integral=2 then turma.num_matricula ELSE 0 END)', 'total_int_nao_aplica')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo and escola.localizacao_diferenciada_par is not null');
+    }
+    else if (req.query.dims && req.query.dims.includes('period_agg')) {
+        req.sql.from('turma,escola')
+        .field('SUM(CASE WHEN turma.turma_turno_id=1 then turma.num_matricula ELSE 0 END)', 'total_qt_mat_bas_matutino')
+        .field('SUM(CASE WHEN turma.turma_turno_id=2 then turma.num_matricula ELSE 0 END)', 'total_qt_mat_bas_vespertino')
+        .field('SUM(CASE WHEN turma.turma_turno_id=3 then turma.num_matricula ELSE 0 END)', 'total_qt_mat_bas_noturno')
+        .field('SUM(CASE WHEN turma.turma_turno_id=4 then turma.num_matricula ELSE 0 END)', 'total_qt_mat_bas_integral')
+        .field('SUM(CASE WHEN turma.turma_turno_id=99 then turma.num_matricula ELSE 0 END)', 'total_qt_mat_bas_semi_ead')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo and escola.localizacao_diferenciada_par is not null');
+    }
+    else if (req.query.dims && req.query.dims.includes('modality_integral_time')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_inf_cre_int)', 'total_qt_mat_inf_cre_int')
+        .field('SUM(escola.qt_mat_inf_pre_int)', 'total_qt_mat_inf_pre_int')
+        .field('SUM(escola.qt_mat_fund_ai_int)', 'total_qt_mat_fund_ai_int')
+        .field('SUM(escola.qt_mat_fund_af_int)', 'total_qt_mat_fund_af_int')
+        .field('SUM(escola.qt_mat_med_int)', 'total_qt_mat_med_int')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
+    }
+    else if (req.query.dims && req.query.dims.includes('special_education')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_esp_cc)', 'total_qt_mat_esp_cc')
+        .field('SUM(escola.qt_mat_esp_ce)', 'total_qt_mat_esp_ce')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
+    }
+    else {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_bas)', 'total')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
+    }
+    next();
+}, query, aggregateData, id2str.transform(false), response('enrollment_aggregate'));
+
+module.exports = enrollmentAggregateApp;
diff --git a/src/libs/routes_v1/federativeEntity.js b/src/libs/routes_v1/federativeEntity.js
new file mode 100644
index 0000000000000000000000000000000000000000..661907c54256a9b8ef48c4d26401d01269251042
--- /dev/null
+++ b/src/libs/routes_v1/federativeEntity.js
@@ -0,0 +1,646 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+const { result } = require('lodash');
+
+const federativeEntityApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const log = require(`${libs}/log`)(module);
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const aggregateData = require(`${libs}/middlewares/aggregateData`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+const config = require(`${libs}/config`);
+
+const addMissing = require(`${libs}/middlewares/addMissing`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+federativeEntityApp.use(cache('15 day'));
+
+let rqf = new ReqQueryFields();
+
+federativeEntityApp.get('/years', (req, res, next) => {
+    req.sql.from('escola')
+    .field('DISTINCT escola.ano_censo', 'year')
+    .where('escola.ano_censo >= 2021')
+    next();
+}, query, response('years'));
+
+federativeEntityApp.get('/adm_dependency', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.admDependency(i)
+        });
+    }
+    next();
+}, response('adm_dependency'));
+
+federativeEntityApp.get('/education_degree_entity', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 4; i++) {
+        req.result.push({
+            id: i, name: id2str.educationDegreeEntity(i)
+        });
+    }
+    next();
+}, response('education_degree_entity'));
+
+federativeEntityApp.get('/adm_dependency_detailed', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 9; i++) {
+        req.result.push({
+            id: i, name: id2str.admDependencyPriv(i)
+        });
+    }
+    next();
+}, response('adm_dependency_detailed'));
+
+federativeEntityApp.get('/education_level_mod_agg', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 13; i++) {
+        req.result.push({
+            id: i, name: id2str.educationLevelMod(i)
+        });
+    }
+    next();
+}, response('education_level_mod_agg'));
+
+federativeEntityApp.get('/integral_time_agg', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 3; i++) {
+        req.result.push({
+            id: i, name: id2str.integralTime(i)
+        });
+    }
+    next();
+}, response('integral_time_agg')); 
+
+federativeEntityApp.get('/location', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.location(i)
+        });
+    }
+    next();
+}, response('location'));
+
+federativeEntityApp.get('/diff_location', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 4; i++) {
+        req.result.push({
+            id: i, name: id2str.diffLocation(i)
+        });
+    }
+
+    req.result.push({
+        id: 8, name: 'Área onde se localizam povos e comunidades tradicionais'
+    })
+
+    next();
+}, response('diff_location'));
+
+federativeEntityApp.get('/modality_integral_time', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 7; i++) {
+        req.result.push({
+            id: i, name: id2str.educationLevelBasic(i)
+        });
+    }
+
+    next();
+}, response('modality_integral_time'));
+
+federativeEntityApp.get('/gender', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.gender(i)
+        });
+    }
+
+    next();
+}, response('gender'));
+
+federativeEntityApp.get('/age_range', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 7; i++) {
+        req.result.push({
+            id: i, name: id2str.ageRangeAggregate(i)
+        });
+    }
+
+    next();
+}, response('age_range'));
+
+federativeEntityApp.get('/ethnic_group', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 6; i++) {
+        req.result.push({
+            id: i, name: id2str.ethnicGroup(i)
+        });
+    }
+
+    next();
+}, response('ethnic_group'));
+
+federativeEntityApp.get('/period_agg', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.period(i)
+        });
+    }
+
+    next();
+}, response('period_agg'));
+
+federativeEntityApp.get('/region', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.regionCode(i)
+        });
+    }
+
+    next();
+}, response('period_agg'));
+
+federativeEntityApp.get('/state', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.stateName(i) !== 'Não declarada') {
+            req.result.push({
+                id: i, name: id2str.stateName(i)
+            });
+        }
+    }
+
+    next();
+}, response('state'));
+
+federativeEntityApp.get('/special_education_entity', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.specialEducationEntity(i)
+        });
+    }
+
+    next();
+}, response('special_education_entity'));
+
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: ['nome', 'id'],
+    resultField: ['region_name', 'region_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_reg',
+        foreignTable: 'docentes_sinopse'
+    }
+}).addValue({
+    name: 'mesoregion',
+    table: 'municipio',
+    tableField: ['nome_mesorregiao', 'mesorregiao_id'],
+    resultField: ['mesoregion_name', 'mesoregion_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'mesorregiao_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'microregion',
+    table: 'municipio',
+    tableField: ['nome_microrregiao', 'microrregiao_id'],
+    resultField: ['microregion_name', 'microregion_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'microrregiao_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'docentes_sinopse',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo',
+    },
+}).addValue({
+    name: 'max_year',
+    table: 'docentes_sinopse',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo',
+    },
+}).addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: ['nome', 'id'],
+    resultField: ['state_name', 'state_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'docentes_sinopse'
+    }
+}, 'dims').addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'docentes_sinopse'
+    }
+}, 'filter').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['nome', 'id'],
+    resultField: ['city_name', 'city_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_mun',
+        foreignTable: 'docentes_sinopse'
+    }
+}, 'dims').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_mun',
+        foreignTable: 'docentes_sinopse'
+    }
+}, 'filter').addValueToField({
+    name: 'school',
+    table: 'docentes_sinopse',
+    tableField: ['nome_escola', 'id'],
+    resultField: ['school_name', 'school_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'locale_id',
+    table: 'docentes_sinopse',
+    tableField: 'localizacao_id',
+    resultField: 'locale_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_id'
+    }
+}, 'dims').addValueToField({
+    name: 'school_id',
+    table: 'docentes_sinopse',
+    tableField: 'id',
+    resultField: 'school_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'school',
+    table: 'docentes_sinopse',
+    tableField: 'nome_escola',
+    resultField: 'school_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'filter').addValue({
+    name: 'location',
+    table: 'docentes_sinopse',
+    tableField: 'localizacao_id',
+    resultField: 'location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_id'
+    }
+});
+
+federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+    let whereRule = '';
+    const filtersObject = {}
+
+    req.query.filter.split(',').forEach((filter) => {
+        let [key, value] = filter.split(':');
+        filtersObject[key] = Number(JSON.parse(value));
+    })
+
+    if (req.query.filter && req.query.filter.includes('city')) {
+        whereRule = 'docentes_sinopse.cod_mun = ' + filtersObject.city;
+    }
+    else if (req.query.filter && req.query.filter.includes('state')) {
+        whereRule = 'docentes_sinopse.cod_uf = ' + filtersObject.state + 
+            ((req.query.dims && req.query.dims.includes('city')) ? '' : ' AND docentes_sinopse.cod_mun = 0');
+    }
+    else if (req.query.filter && req.query.filter.includes('region')) {
+        whereRule = 'docentes_sinopse.cod_reg = ' + filtersObject.region + 
+            ((req.query.dims !== undefined && req.query.dims.includes('state')) 
+                ? ' AND docentes_sinopse.cod_mun = 0'
+                : (req.query.dims !== undefined && req.query.dims.includes('city')) 
+                    ? '' 
+                    : ' AND docentes_sinopse.cod_uf = 0');
+                
+    }
+    else {
+        whereRule = (req.query.dims && req.query.dims.includes('region')) 
+            ? 'docentes_sinopse.cod_uf = 0'
+            : (req.query.dims && req.query.dims.includes('state'))
+                ? 'docentes_sinopse.cod_mun = 0' 
+                : (req.query.dims && req.query.dims.includes('city'))
+                    ? ''
+                    : 'docentes_sinopse.cod_reg = 0'
+                
+    }
+
+    console.log(whereRule);
+
+    if (req.query.dims && req.query.dims.includes('education_level_mod_entity_seg'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_inf_total)', 'total_doc_ed_inf_total')
+        .field('SUM(docentes_sinopse.num_doc_en_fund_total)', 'total_doc_en_fund_total')
+        .field('SUM(docentes_sinopse.num_doc_en_medio_total)', 'total_doc_en_medio_total')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_total)', 'total_doc_ed_prof_total')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_tec_total)', 'total_doc_ed_prof_tec_total')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_fic_total)', 'total_doc_ed_prof_fic_total')
+        .field('SUM(docentes_sinopse.num_doc_eja_total)', 'total_doc_eja_total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else if (req.query.dims && req.query.dims.includes('education_level_mod_entity_agg'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_inf_creche)', 'total_doc_ed_inf_creche')
+        .field('SUM(docentes_sinopse.num_doc_ed_inf_pre_escola)', 'total_doc_ed_inf_pre_escola')
+        .field('SUM(docentes_sinopse.num_doc_en_fund_anos_iniciais)', 'total_doc_en_fund_anos_iniciais')
+        .field('SUM(docentes_sinopse.num_doc_en_fund_anos_finais)', 'total_doc_en_fund_anos_finais')
+        .field('SUM(docentes_sinopse.num_doc_en_medio_propedeutico)', 'total_doc_en_medio_propedeutico')
+        .field('SUM(docentes_sinopse.num_doc_en_medio_normal_magisterio)', 'total_doc_en_medio_normal_magisterio')
+        .field('SUM(docentes_sinopse.num_doc_en_medio_integrado)', 'total_doc_en_medio_integrado')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_en_medio)', 'total_doc_ed_prof_en_medio')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_tec_concomitante)', 'total_doc_ed_prof_tec_concomitante')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_tec_subsequente)', 'total_doc_ed_prof_tec_subsequente')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_tec_misto)', 'total_doc_ed_prof_tec_misto')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_fic_concomitante)', 'total_doc_ed_prof_fic_concomitante')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_fic_integrado_eja)', 'total_doc_ed_prof_fic_integrado_eja')
+        .field('SUM(docentes_sinopse.num_doc_eja_en_fund)', 'total_doc_eja_en_fund')
+        .field('SUM(docentes_sinopse.num_doc_eja_en_medio)', 'total_doc_eja_en_medio')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else if (req.query.dims && req.query.dims.includes('special_education_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_especial_classe_comum)', 'total_doc_ed_especial_classe_comum')
+        .field('SUM(docentes_sinopse.num_doc_ed_especial_classe_exclusiva)', 'total_doc_ed_especial_classe_exclusiva')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else if (req.query.dims && req.query.dims.includes('adm_dependency_entity_agg'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_pub)', 'total_doc_dependencia_adm_pub')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_priv)', 'total_doc_dependencia_adm_priv')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else if (req.query.dims && req.query.dims.includes('adm_dependency_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_federal)', 'total_doc_dependencia_adm_federal')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_estadual)', 'total_doc_dependencia_adm_estadual')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_municipal)', 'total_doc_dependencia_adm_municipal')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_priv)', 'total_doc_dependencia_adm_priv')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else if (req.query.dims && req.query.dims.includes('education_degree_entity'))
+        {
+            req.sql.from('docentes_sinopse')
+            .field('SUM(docentes_sinopse.num_doc_esc_en_fund)', 'total_num_doc_esc_en_fund')
+            .field('SUM(docentes_sinopse.num_doc_esc_en_medio)', 'total_num_doc_esc_en_medio')
+            .field('SUM(docentes_sinopse.num_doc_esc_grad_com_licenciatura)', 'total_num_doc_esc_grad_com_licenciatura')
+            .field('SUM(docentes_sinopse.num_doc_esc_grad_sem_licenciatura)', 'total_num_doc_esc_grad_sem_licenciatura')
+            .field('docentes_sinopse.ano_censo', 'year')
+            .group('docentes_sinopse.ano_censo')
+            .order('docentes_sinopse.ano_censo')
+            .where(whereRule);
+        }
+    else if (req.query.dims && req.query.dims.includes('location_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_loc_urbana_total)', 'total_doc_loc_urbana_total')
+        .field('SUM(docentes_sinopse.num_doc_loc_rural_total)', 'total_doc_loc_rural_total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else if (req.query.dims && req.query.dims.includes('gender_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_masc_total)', 'total_doc_masc_total')
+        .field('SUM(docentes_sinopse.num_doc_fem_total)', 'total_doc_fem_total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else if (req.query.dims && req.query.dims.includes('age_range_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_fem_24 + docentes_sinopse.num_doc_masc_24)', 'total_doc_24')
+        .field('SUM(docentes_sinopse.num_doc_fem_25_29 + docentes_sinopse.num_doc_masc_25_29)', 'total_doc_25_29')
+        .field('SUM(docentes_sinopse.num_doc_fem_30_39 + docentes_sinopse.num_doc_masc_30_39)', 'total_doc_30_39')
+        .field('SUM(docentes_sinopse.num_doc_fem_40_49 + docentes_sinopse.num_doc_masc_40_49)', 'total_doc_40_49')
+        .field('SUM(docentes_sinopse.num_doc_fem_50_54 + docentes_sinopse.num_doc_masc_50_54)', 'total_doc_50_54')
+        .field('SUM(docentes_sinopse.num_doc_fem_55_59 + docentes_sinopse.num_doc_masc_55_59)', 'total_doc_55_59')
+        .field('SUM(docentes_sinopse.num_doc_fem_60_mais + docentes_sinopse.num_doc_masc_60_mais)', 'total_doc_60_mais')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else if (req.query.dims && req.query.dims.includes('post_graduation_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_esc_pos_grad_especializacao)', 'total_doc_esc_pos_grad_especializacao')
+        .field('SUM(docentes_sinopse.num_doc_esc_pos_grad_mestrado)', 'total_doc_esc_pos_grad_mestrado')
+        .field('SUM(docentes_sinopse.num_doc_esc_pos_grad_doutorado)', 'total_doc_esc_pos_grad_doutorado')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else if (req.query.dims && req.query.dims.includes('contract_type_entity'))
+    {
+            req.sql.from('docentes_sinopse')
+            .field('SUM(docentes_sinopse.num_doc_vinc_concursado_efetivo_estavel_total)', 'total_doc_vinc_concursado_efetivo_estavel_total')
+            .field('SUM(docentes_sinopse.num_doc_vinc_contrato_temp_total)', 'total_doc_vinc_contrato_temp_total')
+            .field('SUM(docentes_sinopse.num_doc_vinc_contrato_terceirizado_total)', 'total_doc_vinc_contrato_terceirizado_total')
+            .field('SUM(docentes_sinopse.num_doc_vinc_contrato_clt_total)', 'total_doc_vinc_contrato_clt_total')
+            .field('docentes_sinopse.ano_censo', 'year')
+            .group('docentes_sinopse.ano_censo')
+            .order('docentes_sinopse.ano_censo')
+            .where(whereRule);
+    }
+    else if ((req.query.dims && req.query.dims.includes('state')) || (req.query.filter && req.query.filter.includes('state'))) {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_bas_total)', 'total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else if ((req.query.dims && req.query.dims.includes('region')) || (req.query.filter && req.query.filter.includes('region'))) {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_bas_total)', 'total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    else {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_bas_total)', 'total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where(whereRule);
+    }
+    next();
+}, query, aggregateData, id2str.transform(false), response('federative_entity'));
+
+module.exports = federativeEntityApp;
diff --git a/src/libs/routes_v1/iliteracyRate.js b/src/libs/routes_v1/iliteracyRate.js
new file mode 100644
index 0000000000000000000000000000000000000000..25b97d5dbaf3236653632ed6ad6b779209a97811
--- /dev/null
+++ b/src/libs/routes_v1/iliteracyRate.js
@@ -0,0 +1,613 @@
+/*
+Copyright (C) 2024 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+
+const iliteracyRate = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const multiQuery = require(`${libs}/middlewares/multiQuery`);
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+const config = require(`${libs}/config`); 
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+iliteracyRate.use(cache('15 day'));
+
+iliteracyRate.get('/years', (req, res, next) => {
+    req.sql.from('pnad_novo')
+    .field('DISTINCT pnad_novo.ano_ref', 'year')
+    .where('pnad_novo.ano_ref >= 2019')
+    next();
+}, query, response('years'));
+
+iliteracyRate.get('/illiteracy', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i < 2; i++) {
+        req.result.push({
+            id: i, name: id2str.illiteracy(i)
+        });
+
+    }
+    req.result.push({id: 9, name: id2str.illiteracy(9)});
+    next();
+}, response('illiteracy'));
+
+iliteracyRate.get('/years_of_study', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i < 17; i++) {
+        req.result.push({
+            id: i, name: id2str.yearsOfStudy(i)
+        });
+    }
+
+    req.result.push({id: 99, name: id2str.yearsOfStudy(99)});
+    next();
+}, response('years_of_study'));
+
+iliteracyRate.get('/instruction_level', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i < 8; i++) {
+        req.result.push({
+            id: i, name: id2str.instructionLevel(i)
+        });
+    }
+    req.result.push({id: 99, name: id2str.instructionLevel(99)});
+    next();
+}, response('instruction_level'));
+
+iliteracyRate.get('/new_pnad_adm_dependency', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.newPnadAdmDependency(i)
+        });
+    }
+    req.result.push({id: 99, name: id2str.newPnadAdmDependency(99)});
+    next();
+}, response('new_pnad_adm_dependency'));
+
+iliteracyRate.get('/region', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 6; i++) {
+        req.result.push({
+            id: i, name: id2str.regionCode(i)
+        });
+    }
+
+    next();
+}, response('region'));
+
+iliteracyRate.get('/cap_code', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.capitalCode(i) !== 'Não informado') {
+        req.result.push({
+            id: i, name: id2str.capitalCode(i)
+        });
+        }
+    }
+    req.result.push({id: 99, name: id2str.capitalCode(99)});
+
+    next();
+}, response('cap_code'));
+
+iliteracyRate.get('/metro_code', (req, res, next) => {
+    req.result = []
+    for (let i = 13; i < 53; i++) {
+        if (id2str.metroCode(i) !== 'Não informado') {
+        req.result.push({
+            id: i, name: id2str.metroCode(i)
+        });
+        }
+    }
+    req.result.push({id: 99, name: id2str.metroCode(99)});
+
+    next();
+}, response('metro_code'));
+
+iliteracyRate.get('/attended_modality', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 16; i++) {
+        req.result.push({
+            id: i, name: id2str.attendedModality(i)
+        });
+    }
+    // Remove the option with id equals 10 => This option exists in the database, a better solution to this would be remove the option from the database
+    req.result.splice(req.result.findIndex((item) => item.id === 10), 1);
+    req.result.push({id: 99, name: id2str.attendedModality(99)});
+    next();
+}, response('attended_modality'));
+
+iliteracyRate.get('/income_range', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 10; i++) {
+        req.result.push({
+            id: i, name: id2str.incomeRange(i)
+        });
+    }
+    next();
+}, response('income_range'));
+
+iliteracyRate.get('/attends_school', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.attendsSchool(i)
+        });
+    }
+    next();
+}, response('attends_school'));
+
+iliteracyRate.get('/gender', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.gender(i)
+        });
+    }
+    next();
+}, response('gender'));
+
+iliteracyRate.get('/new_pnad_ethnic_group', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 6; i++) {
+        req.result.push({
+            id: i, name: id2str.ethnicGroupNewPnad(i)
+        });
+    }
+    req.result.push({id: 9, name: id2str.ethnicGroupNewPnad(9)});
+    next();
+}, response('new_pnad_ethnic_group'));
+
+iliteracyRate.get('/bolsa_familia', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.attendsSchool(i)
+        });
+    }
+    req.result.push({id: 9, name: id2str.attendsSchool(9)});
+    next();
+}, response('bolsa_familia'));
+
+iliteracyRate.get('/modality', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 4; i++) {
+        req.result.push({
+            id: i, name: id2str.modality(i)
+        });
+    }
+    req.result.push({id: 99, name: id2str.modality(99)});
+    next();
+}, response('modality'));
+
+iliteracyRate.get('/modality_shift', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 8; i++) {
+        req.result.push({
+            id: i, name: id2str.modalityShift(i)
+        });
+    }
+    req.result.push({id: 9, name: id2str.modalityShift(9)});
+    req.result.push({id: 99, name: id2str.modalityShift(99)});
+    next();
+}, response('modality_shift'));
+
+iliteracyRate.get('/state', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.stateName(i) !== 'Não declarada') {
+            req.result.push({
+                id: i, name: id2str.stateName(i)
+            });
+        }
+    }
+    req.result.push({id: 99, name: id2str.stateName(99)});
+
+    next();
+}, response('state'));
+
+iliteracyRate.get('/age_range_all', (req, res, next) => {
+    req.result = []
+    for (let i = 5; i < 12; i++) {
+        req.result.push({
+            id: i, name: id2str.ageRangeAll(i)
+        });
+    }
+
+    next();
+}, response('age_range_all'));
+
+iliteracyRate.get('/location', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.location(i)
+        });
+    }
+
+    next();
+}, response('location'));
+
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'id',
+    table: 'pnad_novo',
+    tableField: 'id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: ['id', 'nome'],
+    resultField: ['state_id', 'state_nome'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'pnad_novo'
+    }
+}).addValue({
+    name: 'state_not',
+    table: 'estado',
+    tableField: ['nome', 'id'],
+    resultField: ['state_name', 'state_id'],
+    where: {
+        relation: '<>',
+        type: 'integer',
+        field: 'cod_uf',
+        table: 'pnad_novo'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'pnad_novo'
+    }
+}).addValue({
+    name: 'years_of_study',
+    table: 'pnad_novo',
+    tableField: 'anos_de_estudo',
+    resultField: 'years_of_study_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'anos_de_estudo'
+    }
+}).addValue({
+    name: 'instruction_level',
+    table: 'pnad_novo',
+    tableField: 'nivel_de_instrucao',
+    resultField: 'instruction_level_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'nivel_de_instrucao'
+    }
+}).addValue({
+    name: 'new_pnad_adm_dependency',
+    table: 'pnad_novo',
+    tableField: 'dependencia_adm',
+    resultField: 'new_pnad_adm_dependency_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm'
+    }
+}).addValue({
+    name: 'attends_school',
+    table: 'pnad_novo',
+    tableField: 'frequenta_escola',
+    resultField: 'attends_school_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'frequenta_escola'
+    }
+}).addValue({
+    name: 'modality',
+    table: 'pnad_novo',
+    tableField: 'modalidade',
+    resultField: 'modality_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'modalidade'
+    }
+}).addValue({
+    name: 'attended_modality',
+    table: 'pnad_novo',
+    tableField: 'nivel_etapa_modalidade_freq',
+    resultField: 'attended_modality_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'nivel_etapa_modalidade_freq'
+    }
+}).addValue({
+    name: 'illiteracy',
+    table: 'pnad_novo',
+    tableField: 'analfabetismo',
+    resultField: 'illiteracy_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'analfabetismo'
+    }
+}).addValue({
+    name: 'modality_shift',
+    table: 'pnad_novo',
+    tableField: 'turno_nivel_etapa',
+    resultField: 'modality_shift_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'turno_nivel_etapa'
+    }
+}).addValue({
+    name: 'bolsa_familia',
+    table: 'pnad_novo',
+    tableField: 'recebeu_rendimentos_de_programa_bolsa_familia',
+    resultField: 'bolsa_familia_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'recebeu_rendimentos_de_programa_bolsa_familia'
+    }
+}).addValue({
+    name: 'new_pnad_ethnic_group',
+    table: 'pnad_novo',
+    tableField: 'cor_raca',
+    resultField: 'new_pnad_ethnic_group_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cor_raca'
+    }
+}).addValue({
+    name: 'age_range_all',
+    table: 'pnad_novo',
+    tableField: 'faixa_etaria',
+    resultField: 'age_range_all_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'faixa_etaria'
+    }
+}).addValue({
+    name: 'income_range',
+    table: 'pnad_novo',
+    tableField: 'faixa_rendimento_aux',
+    resultField: 'income_range_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'faixa_rendimento_aux'
+    }
+}).addValue({
+    name: 'gender',
+    table: 'pnad_novo',
+    tableField: 'sexo',
+    resultField: 'gender_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'sexo'
+    }
+}).addValue({
+    name: 'cap_code',
+    table: 'pnad_novo',
+    tableField: 'cod_cap',
+    resultField: 'cap_code_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_cap'
+    }
+}).addValue({
+    name: 'region',
+    table: 'pnad_novo',
+    tableField: 'cod_regiao',
+    resultField: 'region_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_regiao'
+    }
+}).addValue({
+    name: 'metro_code',
+    table: 'pnad_novo',
+    tableField: 'cod_rm_ride',
+    resultField: 'metro_code_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_rm_ride'
+    }
+}).addValue({
+    name: 'location',
+    table: 'pnad_novo',
+    tableField: 'situacao_domicilio',
+    resultField: 'location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'situacao_domicilio'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'pnad_novo',
+    tableField: 'ano_ref',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_ref'
+    }
+}).addValue({
+    name: 'max_year',
+    table: 'pnad_novo',
+    tableField: '',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_ref'
+    }
+}).addField({
+    name: 'search',
+    field: false,
+    where: true
+}).addValueToField({
+    name: 'name',
+    table: 'pnad_novo',
+    tableField: 'nome',
+    where: {
+        relation: 'LIKE',
+        type: 'string',
+        field: 'nome'
+    }
+}, 'search').addValue({
+    name: 'mesoregion',
+    table: 'pnad_novo',
+    tableField: 'mesorregiao_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'mesorregiao_id'
+    }
+}).addValue({
+    name: 'microregion',
+    table: 'pnad_novo',
+    tableField: 'microrregiao_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'microrregiao_id'
+    }
+});
+
+function matchQueries(queryPartial, queryTotal) {
+    let match = [];
+    queryTotal.forEach((result) => {
+        let newObj = {};
+        let keys = Object.keys(result);
+        keys.forEach((key) => {
+            newObj[key] = result[key];
+        });
+        let index = keys.indexOf('total');
+        if(index > -1) keys.splice(index, 1);
+        let objMatch = null;
+
+        for(let i = 0; i < queryPartial.length; ++i) {
+            let partial = queryPartial[i];
+            let foundMatch = true;
+            for(let j = 0; j < keys.length; ++j) {
+                let key = keys[j];
+                if(partial[key] !== result[key]) {
+                    foundMatch = false;
+                    break;
+                }
+            }
+            if(foundMatch) {
+                objMatch = partial;
+                break;
+            }
+        }
+
+        if(objMatch) {
+            newObj.denominator = result.total;
+            newObj.partial = objMatch.total;
+            newObj.total = (objMatch.total / result.total) * 100;
+            newObj.total = newObj.total.toFixed(1);
+            match.push(newObj);
+        }
+    });
+
+    return match;
+}
+
+iliteracyRate.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+    req.querySet = [];
+    
+    // Subquery para total_pop_maior_19 com filtros dinâmicos
+    let totalAnalfabetismo = req.sql.clone();
+        totalAnalfabetismo.from("pnad_novo")
+        .field("ano_ref", "year")
+        .field("SUM(peso_domicilio_pessoas_com_cal)", "total")
+        .where("analfabetismo = 1")
+        .where("ano_ref >= 2019")
+        .group("ano_ref")
+        .order("ano_ref");
+
+    // Subquery para total_pop_ed_bas_maior_19 com filtros dinâmicos
+    let totalPop = req.sql.clone();
+        totalPop.from("pnad_novo")
+        .field("ano_ref", "year")
+        .field("SUM(peso_domicilio_pessoas_com_cal)", "total")
+        .where("analfabetismo = 0 or analfabetismo = 1")
+        .where("ano_ref >= 2019")
+        .group("ano_ref")
+        .order("ano_ref");
+
+    req.querySet.push(totalAnalfabetismo);
+    req.querySet.push(totalPop);
+
+    next();
+}, multiQuery, (req, res, next) => {
+        // The multiple requests are made. Then we need to calculate the percetange. So the function
+        // below is used
+        let newObj = matchQueries(req.result[0], req.result[1]);
+        req.result = newObj;
+    next();
+}, id2str.transform(false), response('iliteracy_rate'));
+
+module.exports = iliteracyRate;
diff --git a/src/libs/routes_v1/newPnad.js b/src/libs/routes_v1/newPnad.js
index bab8cdf981e2411b839f1da33a2f24ca5f17a72c..5bfb7b8a23e5badace6614815f84ba4ae40515b3 100644
--- a/src/libs/routes_v1/newPnad.js
+++ b/src/libs/routes_v1/newPnad.js
@@ -143,6 +143,8 @@ PnadNovoApp.get('/attended_modality', (req, res, next) => {
             id: i, name: id2str.attendedModality(i)
         });
     }
+    // Remove the option with id equals 10 => This option exists in the database, a better solution to this would be remove the option from the database
+    req.result.splice(req.result.findIndex((item) => item.id === 10), 1);
     req.result.push({id: 99, name: id2str.attendedModality(99)});
     next();
 }, response('attended_modality'));
diff --git a/src/libs/routes_v1/school.js b/src/libs/routes_v1/school.js
index 768325c314d7c6e9bdd0059bd8a420880ebdf83a..54932c51bd78ff629dff89625be3a93c24a8042f 100644
--- a/src/libs/routes_v1/school.js
+++ b/src/libs/routes_v1/school.js
@@ -64,6 +64,7 @@ schoolApp.get('/diff_location', cache('15 day'), (req, res, next) => {
         {id: 1, name: "Área de assentamento"},
         {id: 2, name: "Terra indígena"},
         {id: 3, name: "Terra remanescente de quilombos"},
+        {id: 8, name: "Área onde se localizam povos e comunidades tradicionais"}
     ];
     next();
 }, response('diff_location'));
diff --git a/src/libs/routes_v1/uniLocalOfferAggregate.js b/src/libs/routes_v1/uniLocalOfferAggregate.js
new file mode 100644
index 0000000000000000000000000000000000000000..f50afff10d25cb8e73f9399dfef810795ad01bc1
--- /dev/null
+++ b/src/libs/routes_v1/uniLocalOfferAggregate.js
@@ -0,0 +1,124 @@
+/*
+Copyright (C) 2024 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+
+const uniLocalOfferAggregateApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const config = require(`${libs}/config`); 
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+uniLocalOfferAggregateApp.use(cache('15 day'));
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'min_year',
+    table: 'curso_superior_agregado',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'max_year',
+    table: 'curso_superior_agregado',
+    tableField: '',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'region',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_reg',
+    resultField: 'region_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_reg'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: ['id', 'nome'],
+    resultField: ['state_id', 'state_nome'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'curso_superior_agregado'
+    }
+}).addValue({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['id', 'nome'],
+    resultField: ['city_id', 'city_name'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_mun',
+        foreignTable: 'curso_superior_agregado'
+    }
+});
+
+uniLocalOfferAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+    req.sql.from('curso_superior_agregado')
+    .field('DISTINCT curso_superior_agregado.cod_ies', 'id')
+    .field('ies_ens_superior.nome_ies', 'name')
+    .field('curso_superior_agregado.cod_mun', 'city_id')
+    .field('curso_superior_agregado.cod_uf', 'state_id')
+    .field('curso_superior_agregado.cod_reg', 'region_id')
+    .join('ies_ens_superior', null, 'curso_superior_agregado.cod_ies = ies_ens_superior.cod_ies and curso_superior_agregado.ano_censo = ies_ens_superior.ano_censo')
+    .order('curso_superior_agregado.cod_ies')
+    next();
+}, query, response('uni_offer_aggregate'));
+
+module.exports = uniLocalOfferAggregateApp;
\ No newline at end of file
diff --git a/src/libs/routes_v1/universityLocalOffer.js b/src/libs/routes_v1/universityLocalOffer.js
index 535094c492915b6b3d38a5e02a267a4196910c36..88ed5ac03989c127d9624e55ced1d30c63858050 100644
--- a/src/libs/routes_v1/universityLocalOffer.js
+++ b/src/libs/routes_v1/universityLocalOffer.js
@@ -84,7 +84,7 @@ rqf.addField({
     },
     join: {
         primary: 'nome',
-        foreign: 'nome_regiao_ies',
+        foreign: 'nome_regiao',
         foreignTable: 'localoferta_ens_superior'
     }