diff --git a/src/libs/routes/enrollment.js b/src/libs/routes/enrollment.js
index a3a25119d7067e08456e71056a3cff02a99b743b..aa202f482ee272d2575429306dc449f735627751 100644
--- a/src/libs/routes/enrollment.js
+++ b/src/libs/routes/enrollment.js
@@ -467,4 +467,207 @@ enrollmentApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
 
 enrollmentApp.get('/download', passport.authenticate('bearer', { session: false }), rqf.parse(), rqf.build(), download('matricula', 'mapping_matricula'));
 
+enrollmentApp.get('/diagnosis', rqf.parse(), (req, res, next) => {
+    req.dims = {};
+    req.dims.school_year = true;
+    req.dims.location = true;
+    req.dims.adm_dependency_detailed = true;
+
+    req.sql.field('COUNT(*)', 'total')
+    .field("'Brasil'", 'name')
+    .field('matricula.ano_censo', 'year')
+    .from('matricula')
+    .group('matricula.ano_censo')
+    .order('matricula.ano_censo')
+    .where('matricula.tipo<=3');
+
+    next();
+}, rqf.build(), query, id2str.transform(), (req, res, next) => {
+    let enrollments = req.result;
+
+    // Gera a relação etapa de ensino X ano escolar
+    let educationSchoolYear = {};
+    for(let i = 10; i < 80; ++i) {
+        if(id2str.schoolYear(i) !== id2str.schoolYear(99)) {
+            let educationLevelId = Math.floor(i/10);
+            educationSchoolYear[i] = {
+                id: educationLevelId,
+                name: id2str.educationLevelShort(educationLevelId),
+            };
+        }
+    }
+
+    let result = [];
+    let educationLevelSet = new Set();
+    let schoolYearSet = new Set();
+    let i = 0;
+    while(i < enrollments.length) {
+        let enrollment = enrollments[i];
+        let educationLevelHash = '' + enrollment.year + educationSchoolYear[enrollment.school_year_id].id;
+        let schoolYearHash = '' + enrollment.year + enrollment.school_year_id;
+
+        let currentEducation = null;
+        // Busca ou cria a etapa de ensino adequada
+        if(educationLevelSet.has(educationLevelHash)) {
+            let j = 0;
+            let edu = result[j];
+            while(j < result.length && (edu.year != enrollment.year || edu.education_level_school_year_id != educationSchoolYear[enrollment.school_year_id].id)) {
+                ++j;
+                edu = result[j];
+            }
+            if(j >= result.length) --j;
+            edu = result[j];
+
+            currentEducation = edu;
+        } else {
+            educationLevelSet.add(educationLevelHash);
+            let obj = {
+                year: enrollment.year,
+                name: enrollment.name,
+                education_level_school_year_id: educationSchoolYear[enrollment.school_year_id].id,
+                education_level_school_year_name: educationSchoolYear[enrollment.school_year_id].name,
+                total: 0,
+                adm_dependencies: [
+                    {
+                        adm_dependency_detailed_id: enrollment.adm_dependency_detailed_id,
+                        adm_dependency_detailed_name: enrollment.adm_dependency_detailed_name,
+                        total: 0
+                    }
+                ],
+                locations: [
+                    {
+                        location_id: enrollment.location_id,
+                        location_name: enrollment.location_name,
+                        total: 0
+                    }
+                ]
+            };
+
+            result.push(obj);
+            currentEducation = obj;
+        }
+
+        let currentSchoolYear = null;
+        // Busca ou cria a série adequada
+        if(schoolYearSet.has(schoolYearHash)) {
+            let j = 0;
+            let edu = result[j];
+            while(j < result.length && (edu.year != enrollment.year || edu.education_level_school_year_id != enrollment.school_year_id)) {
+                ++j;
+                edu = result[j];
+            }
+            if(j >= result.length) --j;
+            edu = result[j];
+
+            currentSchoolYear = edu;
+        } else {
+            schoolYearSet.add(schoolYearHash);
+            let obj = {
+                year: enrollment.year,
+                name: enrollment.name,
+                education_level_school_year_id: enrollment.school_year_id,
+                education_level_school_year_name: enrollment.school_year_name,
+                total: 0,
+                adm_dependencies: [
+                    {
+                        adm_dependency_detailed_id: enrollment.adm_dependency_detailed_id,
+                        adm_dependency_detailed_name: enrollment.adm_dependency_detailed_name,
+                        total: 0
+                    }
+                ],
+                locations: [
+                    {
+                        location_id: enrollment.location_id,
+                        location_name: enrollment.location_name,
+                        total: 0
+                    }
+                ]
+            };
+
+            result.push(obj);
+            currentSchoolYear = obj;
+        }
+
+        // Adiciona ao total
+        currentEducation.total += enrollment.total;
+        currentSchoolYear.total += enrollment.total;
+
+        // Adiciona ao total da dependência administrativa
+        let admDependencyIndex = 0;
+        let admDependency = currentEducation.adm_dependencies[admDependencyIndex];
+        while (admDependencyIndex < currentEducation.adm_dependencies.length && enrollment.adm_dependency_detailed_id > admDependency.adm_dependency_detailed_id) {
+            ++admDependencyIndex;
+            admDependency = currentEducation.adm_dependencies[admDependencyIndex];
+        }
+        if(admDependencyIndex >= currentEducation.adm_dependencies.length || admDependency.adm_dependency_detailed_id != enrollment.adm_dependency_detailed_id) { // não encontrou
+            let obj = {
+                adm_dependency_detailed_id: enrollment.adm_dependency_detailed_id,
+                adm_dependency_detailed_name: enrollment.adm_dependency_detailed_name,
+                total: 0
+            }
+            currentEducation.adm_dependencies.splice(admDependencyIndex, 0, obj);
+            admDependency = obj;
+        }
+        admDependency.total += enrollment.total;
+
+        admDependencyIndex = 0;
+        admDependency = currentSchoolYear.adm_dependencies[admDependencyIndex];
+        while (admDependencyIndex < currentSchoolYear.adm_dependencies.length && enrollment.adm_dependency_detailed_id > admDependency.adm_dependency_detailed_id) {
+            ++admDependencyIndex;
+            admDependency = currentSchoolYear.adm_dependencies[admDependencyIndex];
+        }
+        if(admDependencyIndex >= currentSchoolYear.adm_dependencies.length || admDependency.adm_dependency_detailed_id != enrollment.adm_dependency_detailed_id) { // não encontrou
+            let obj = {
+                adm_dependency_detailed_id: enrollment.adm_dependency_detailed_id,
+                adm_dependency_detailed_name: enrollment.adm_dependency_detailed_name,
+                total: 0
+            }
+            currentSchoolYear.adm_dependencies.splice(admDependencyIndex, 0, obj);
+            admDependency = obj;
+        }
+        admDependency.total += enrollment.total;
+
+        // Adiciona ao total da localidade
+        let locationIndex = 0;
+        let location = currentEducation.locations[locationIndex];
+        while (locationIndex < currentEducation.locations.length && enrollment.location_id > location.location_id) {
+            ++locationIndex;
+            location = currentEducation.locations[locationIndex];
+        }
+        if(locationIndex >= currentEducation.locations.length || location.location_id != enrollment.location_id) {
+            let obj = {
+                location_id: enrollment.location_id,
+                location_name: enrollment.location_name,
+                total: 0
+            }
+            currentEducation.locations.splice(locationIndex, 0, obj);
+            location = obj;
+        }
+        location.total += enrollment.total;
+
+        locationIndex = 0;
+        location = currentSchoolYear.locations[locationIndex];
+        while (locationIndex < currentSchoolYear.locations.length && enrollment.location_id > location.location_id) {
+            ++locationIndex;
+            location = currentSchoolYear.locations[locationIndex];
+        }
+        if(locationIndex >= currentSchoolYear.locations.length || location.location_id != enrollment.location_id) {
+            let obj = {
+                location_id: enrollment.location_id,
+                location_name: enrollment.location_name,
+                total: 0
+            }
+            currentSchoolYear.locations.splice(locationIndex, 0, obj);
+            location = obj;
+        }
+        location.total += enrollment.total;
+
+        ++i;
+    }
+
+    req.result = result;
+
+    next();
+}, response('enrollment_diagnosis') );
+
 module.exports = enrollmentApp;