diff --git a/.gitignore b/.gitignore
index 57a123473780458b523e29b006d60602a8e201f0..40bc57be252f5cfd19a9fad5a7fc841f65f25dc2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,9 @@
 node_modules/
 config.js
+config_test.js
 logs/
 *.swp
+nohup.out
+package-lock.json
+coverage/
+.nyc_output/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d50a056e2f15105029c81a3c1b16b437bed9490f
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,26 @@
+stages:
+  - test
+
+services:
+  - postgres
+variables:
+  NODE_ENV: 'test'
+
+before_script:
+  - npm install --global mocha gulp
+  - npm install
+  - apt-get update
+  - apt-get install postgresql-contrib -y
+  - /etc/init.d/postgresql start
+  - su postgres -c "createuser -drS root" #create posgresql user with permission to create databases and roles
+run_tests:
+  stage: test
+  script:
+    - mv config_test.js.example  config_test.js
+    - gulp test
+  tags:
+    - node
+    - postgres
+  cache:
+    paths:
+      - node_modules/
diff --git a/config.js.example b/config.js.example
index b2deb06c586c934a283170344e7321bf42f22b2e..1846bae3e073ab0b34827a5bcc14a28e7e9aaff5 100644
--- a/config.js.example
+++ b/config.js.example
@@ -8,33 +8,8 @@ config.db_config = {
     port: 5432
 };
 
-config.mail = {
-    port: 25
-    , host: 'localhost'
-    , ignoreTLS: true
-    , secure: false
-    , from: 'noreply@simmc.c3sl.ufpr.br'
-};
-
-config.report_config = {
-    imagesPath: './reports/reports/images/'
-    , outputPath: './tmp/reports'
-};
-
-config.alert_config = {
-    alertsPath: '/home/simmc/simmc/scripts/alerts/'
-};
-
-config.fqdn = 'simmc.c3sl.ufpr.br';
-
-config.agentVersion = 1.0;
-
-config.secret = '123mudar';
+config.webservice_config = {
+    ip: "127.0.0.1"
+}
 
-// Uncomment to enable memcached
-//
-// config.memcached = {
-//     server: 'localhost:11211',
-//     options: { retries: 1, timeout: 1000, poolSize: 1 },
-//     lifetime: 3600 // 1 hour in seconds
-// };
+config.agentVersion = 0.0;
diff --git a/config_test.js.example b/config_test.js.example
new file mode 100644
index 0000000000000000000000000000000000000000..3a80276e7414581f10a2b34d52403530016b77d5
--- /dev/null
+++ b/config_test.js.example
@@ -0,0 +1,15 @@
+var config = module.exports = {};
+
+config.db_config = {
+    user: 'test',
+    password: 'test',
+    database: 'test',
+    host: 'localhost',
+    port: 5432
+};
+
+config.webservice_config = {
+    ip: "127.0.0.1"
+}
+
+config.agentVersion = 0.0;
diff --git a/config_test_error.js b/config_test_error.js
new file mode 100644
index 0000000000000000000000000000000000000000..7e9c26ef68f9762b47c9a77b652e9fecdb6b2ebd
--- /dev/null
+++ b/config_test_error.js
@@ -0,0 +1,16 @@
+var config = module.exports = {};
+
+config.db_config = {
+    user: 'error',
+    password: 'error',
+    database: 'error',
+    host: 'localhost',
+    port: 5432
+};
+
+config.webservice_config = {
+    ip: "127.0.0.1"
+}
+
+
+config.agentVersion = 0.0;
diff --git a/database/create/schema/bd.sql b/database/create/schema/bd.sql
new file mode 100755
index 0000000000000000000000000000000000000000..f3cfd94af79fb59ecc390892c4a738b22c26dc6d
--- /dev/null
+++ b/database/create/schema/bd.sql
@@ -0,0 +1,100 @@
+START TRANSACTION;
+
+
+CREATE TABLE session(
+    sessionSer BIGINT,
+    SessionNum INT,
+    Comment VARCHAR(254),
+    HstryUserName VARCHAR(32),
+    HstryTimeStamp TIMESTAMP,
+    HstryDateTime TIMESTAMP,
+    HstryTaskName VARCHAR(32),
+    CourseSer BIGINT,
+    CONSTRAINT pk_session primary key(sessionSer)
+);
+
+CREATE TABLE SessionProcedurePart(
+    RadiationSer BIGINT,
+    ImageType VARCHAR(32),
+    SequenceNumber INT,
+    SessionProcedurePartSer BIGINT,
+    AcqAdjustment FLOAT,
+    AutoSave INT,
+    DoseAccumulation INT,
+    Continuous INT,
+    BeamOff INT,
+    DeviationImage INT,
+    DevEnergy INT,
+    DevDoseRate INT,
+    DevGeometry INT,
+    JawState FLOAT,
+    DevCollX1 FLOAT,
+    DevCollX2 FLOAT,
+    DevCollY1 FLOAT,
+    DevCollY2 FLOAT,
+    MUSubtraction INT,
+    AcquisitionMode VARCHAR(64),
+    HstryUserName VARCHAR(32),
+    HstryTimeStamp TIMESTAMP,
+    HstryDateTime TIMESTAMP,
+    HstryTaskName VARCHAR(32),
+    SessionProcedureSer BIGINT,
+    ImageModality VARCHAR(16),
+    RTPlanSer BIGINT,
+    CONSTRAINT pk_SessionProcedurePart primary key(SessionProcedurePartSer)
+);
+
+CREATE TABLE Course(
+    CourseSer BIGINT,
+    PatientSer BIGINT,
+    CourseId VARCHAR(16),
+    StartDateTime TIMESTAMP,
+    ClinicalStatus VARCHAR(16),
+    CompletedByUserName VARCHAR(32),
+    CompletedDateTime TIMESTAMP,
+    Comment VARCHAR(254),
+    ClinicalProtocolDir VARCHAR(254),
+    HstryUserName VARCHAR(32) not null,
+    HstryTimeStamp TIMESTAMP,
+    HstryDateTime TIMESTAMP,
+    HstryTaskName VARCHAR(32),
+    TransactionId VARCHAR(255),
+    CONSTRAINT pk_Course primary key(CourseSer)
+);
+
+CREATE TABLE MachineUse(
+    Pacient_id VARCHAR(254),
+    Pacient_name VARCHAR(254),
+    Energy VARCHAR(254),
+    Use_date TIMESTAMP,
+    Field_name VARCHAR(254),
+    Machine_id VARCHAR(254),
+    Fk_agent int
+);
+
+CREATE TABLE Agent (
+    Id BIGSERIAL primary key,
+    Hospital_name VARCHAR(16),
+    Geo_long FLOAT,
+    Geo_lat FLOAT
+);
+
+
+CREATE MATERIALIZED VIEW ResumeUsesMonth AS
+    SELECT date_trunc('month', use_date) AS date, count(*) as uses, fk_agent
+    FROM machineuse
+    GROUP BY date, fk_agent;
+    
+CREATE MATERIALIZED VIEW ResumeUsesDay AS
+    SELECT date_trunc('day', use_date) AS date, count(*) as uses, fk_agent
+    FROM machineuse
+    GROUP BY date, fk_agent;
+
+
+ALTER TABLE session ADD CONSTRAINT fk_session_1 FOREIGN KEY(CourseSer) REFERENCES Course(CourseSer);
+ALTER TABLE SessionProcedurePart ADD CONSTRAINT fk_SessionProcedurePart_2 FOREIGN KEY(SessionProcedurePartSer) REFERENCES session(sessionSer);
+ALTER TABLE SessionProcedurePart ADD CONSTRAINT unique_SessionProcedurePart UNIQUE(SessionProcedurePartSer);
+
+ALTER TABLE MachineUse ADD CONSTRAINT Fk_Agent FOREIGN KEY(Fk_Agent) REFERENCES Agent(Id);
+
+COMMIT;
diff --git a/database/create_database.sh b/database/create_database.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4f48ea1936d6d698b4c1580a141028a89c13fda5
--- /dev/null
+++ b/database/create_database.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+# Copyright (C) 2007-2013 Centro de Computacao Cientifica e Software Livre
+# Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+#
+# This file is part of database
+#
+# database 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 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
+
+
+#DB_LINK_LOCATION=/usr/share/postgresql/9.1/extension/dblink.sql
+#DATABASE_DIR=$(pwd)
+
+DATABASE_DIR="`dirname \"$0\"`"
+DATABASE_DIR="`( cd \"$DATABASE_DIR\" && pwd )`"
+SCHEMA_DIR="${DATABASE_DIR}/create/schema/"
+DATA_DIR="${DATABASE_DIR}/create/data/"
+
+
+
+function print_help() {
+    echo -e ""
+    echo -e "usage: $0 database_name"
+    echo -e ""
+}
+
+if [[ $1 != "-"* && $# != "0" ]]; then
+    DB_NAME=$1
+    shift
+else
+    print_help
+    exit 1
+fi
+
+function error_exit() {
+    dropdb $DB_NAME
+    exit 1
+}
+
+# check if db exists3
+if psql -lqt | cut -d \| -f 1 | grep -qw "$DB_NAME"; then
+	echo "Database with name $DB_NAME already exists.";
+	read -p "Drop Database and create new one? (Warning, this will delete all existing data) [y/N]:" yn
+	case $yn in
+        y | Y | yes | YES )
+		echo "Dropping database $DB_NAME"
+		dropdb $DB_NAME
+		;;
+       * )
+		echo "Exiting script."
+		exit 0
+		;;
+    esac
+fi
+
+# create db
+echo "INFO: Creating database: $DB_NAME";
+createdb  $DB_NAME
+
+
+# creating database tables and structure
+echo "INFO: Creating database tables and structure";
+for file in $(ls -B "${SCHEMA_DIR}"); do
+	echo "--- Executing: $file";
+	psql -d $DB_NAME -f $SCHEMA_DIR$file || error_exit
+done
diff --git a/database/create_user.sh b/database/create_user.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1ed5f05284c7ece7ad8af11872ba1242c2c534c0
--- /dev/null
+++ b/database/create_user.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+USERNAME=
+PASSWORD=
+SCHEMA_NAME=
+PRIVILAGES="SELECT, INSERT, UPDATE, DELETE"
+
+
+
+function print_help() {
+    echo -e ""
+    echo -e "usage: $0 username password database_name "
+    echo -e ""
+}
+
+
+if [ $# -ne 3 ]
+  then
+    print_help
+    exit 1
+fi
+
+USERNAME=$1
+PASSWORD=$2
+DATABASE_NAME=$3
+SCHEMA_NAME="public"
+
+psql  -d "$DATABASE_NAME" -tAc "SELECT 1 FROM pg_roles WHERE rolname='test'" | grep -q 1
+
+HAS_USER=$?
+if [[ "$HAS_USER" -eq 0 ]]; then
+  echo "User with name $USERNAME already exists.";
+  if psql -lqt | cut -d \| -f 1 | grep -qw "$DB_NAME"; then
+    read -p "Revoke all privilages of $USERNAME on $DATABASE_NAME? [y/N]:" yn
+  	case $yn in
+          y | Y | yes | YES )
+  		echo "Dropping user $USERNAME"
+      psql -d "$DATABASE_NAME" -c "REVOKE ALL ON DATABASE \"$DATABASE_NAME\" FROM \"$USERNAME\";"
+      psql -d "$DATABASE_NAME" -c "REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA \"$SCHEMA_NAME\" FROM \"$USERNAME\";"
+  		;;
+         * )
+  		echo "Exiting script."
+  		exit 0
+  		;;
+      esac
+    fi
+
+else
+  CREATE_QUERY="CREATE USER \"$USERNAME\" WITH PASSWORD '${PASSWORD}';"
+  psql -d "$DATABASE_NAME" -c "${CREATE_QUERY}"
+fi
+
+GRANT_QUERY="GRANT ${PRIVILAGES} ON ALL TABLES IN SCHEMA  \"${SCHEMA_NAME}\" to \"${USERNAME}\";"
+psql -d "${DATABASE_NAME}" -c "${GRANT_QUERY}"
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..8ac6a94562c283b0d68cdd9a529f646d0f7b56af
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,90 @@
+/*jshint esversion:6*/
+const gulp   = require('gulp');
+const jshint = require('gulp-jshint');
+const shell = require('gulp-shell');
+const mocha = require('gulp-mocha');
+const istanbul = require('gulp-istanbul');
+
+var js_files = "**/*.js";
+
+const app_state = (process.env.NODE_ENV || 'development').trim().toLowerCase();
+
+//dev config
+var dev_config_file = './config.js';
+
+var test_config_file = './config_test.js';
+
+//var config = require(configFile);
+
+// define the default task and add the watch task to it
+gulp.task('default', ['run','watch']);
+
+// configure the jshint task
+gulp.task('jshint', function() {
+  return gulp.src([js_files, "!node_modules/**/*.js", "!coverage/*"])
+    .pipe(jshint({
+      "esversion": 6
+    }))
+    .pipe(jshint.reporter('jshint-stylish'));
+});
+
+// configure which files to watch and what tasks to use on file changes
+gulp.task('watch', function() {
+  gulp.watch(js_files/*, ['jshint']*/);
+});
+
+gulp.task('run', function(){
+  return gulp.src("*")
+    .pipe(shell('npm start'));
+});
+
+//Run as a user with CREATE permission and permission to create users on postgresql
+gulp.task('create_database_test', function(){
+
+  var config = require(test_config_file);
+
+  return gulp.src("database")
+      .pipe(shell("yes | ./database/create_database.sh " + config.db_config.database))
+      .pipe(shell("yes | ./database/create_user.sh " + config.db_config.user + " " + config.db_config.password + " " + config.db_config.database ));
+});
+
+
+gulp.task('pre-test', () => {
+    return gulp.src(['src/**/*.js'])
+        .pipe(istanbul({includeUntested: true}))
+        .pipe(istanbul.hookRequire());
+});
+
+gulp.task('test',['create_database_test','pre-test'], function(){
+
+  gulp.src(['test/**/*.js'], {read: false})
+    .pipe(mocha({timeout: 60000}))
+    .pipe(istanbul.writeReports())
+    .pipe(istanbul.enforceThresholds({
+        thresholds: {
+            global: {
+                statements: 80,
+                branches: 70,
+                lines: 80,
+                functions: 80
+            }
+        }
+    }))
+    .on('error', () => {
+        process.exit(1);
+    })
+    .on('end', () => {
+        process.exit();
+    });
+
+
+  // return gulp.src(['test/*.js'])
+  //     .pipe(mocha({
+  //       reporter : 'spec'
+  //     }));
+
+});
+
+
+
+module.exports = gulp;
diff --git a/lib/agentbuilder.js b/lib/agentbuilder.js
deleted file mode 100644
index 24cb61e90f345951f3d2b660620fd9034952648a..0000000000000000000000000000000000000000
--- a/lib/agentbuilder.js
+++ /dev/null
@@ -1,35 +0,0 @@
-var exec = require('child_process').exec;
-
-exports.build = function(id_point, os, proxy, callback) {
-    var buildScript,
-        proxyParams = "";
-
-    if (isNaN(id_point)) {
-        return callback({error: 'invalid_id_point'});
-    }
-
-    if (os === 'windows')
-        buildScript = __dirname + '/../scripts/build-windows-installer.sh';
-    else
-        buildScript = __dirname + '/../scripts/build-linux-installer.sh';
-
-    if (proxy) {
-        // the replace method removes whitespaces that are not allowed in this fields
-        var host = (proxy.host || '').replace(/ /g, ''),
-            port = (proxy.port || '').replace(/ /g, ''),
-            user = (proxy.user || '').replace(/ /g, ''),
-            pass = (proxy.pass || '').replace(/ /g, '');
-
-        // check if the port number is actually a number or an empty string
-        if ( (port !== '') && (isNaN(parseInt(port),10)) ) {
-            return callback({error: 'invalid_proxy_port'});
-        }
-
-        proxyParams = '"'+host+'" "'+port+'" "'+user+'" "'+pass+'"';
-    }
-
-    var cmdline = buildScript + ' ' + id_point + ' ' + proxyParams;
-    exec(cmdline, function (err, stdout, stderr) {
-        callback(err, stdout);
-    });
-};
\ No newline at end of file
diff --git a/lib/mail.js b/lib/mail.js
deleted file mode 100644
index 602c5cd3513833eba09ec440ec80d4f8bff91d15..0000000000000000000000000000000000000000
--- a/lib/mail.js
+++ /dev/null
@@ -1,37 +0,0 @@
-var nodemailer = require('nodemailer');
-var smtpTransport = require('nodemailer-smtp-transport');
-var htmlToText = require('nodemailer-html-to-text').htmlToText;
-
-module.exports = function(config) {
-
-    var options = smtpTransport({
-        port: config.port
-        , host: config.host
-        , ignoreTLS: config.ignoreTLS
-        , secure: config.secure
-    });
-
-    // create reusable transporter object using SMTP transport
-    var transporter = nodemailer.createTransport(options);
-
-    // set transporter to compile html do text automagically
-    transporter.use('compile', htmlToText());
-
-    // NB! No need to recreate the transporter object. You can use
-    // the same transporter object for all e-mails
-
-    // setup e-mail data with unicode symbols
-    var mail = {
-        from: config.from // sender address
-    };
-
-    return {
-        send: function(to, subject, html, callback) {
-            // send mail with defined transport object
-            mail.to = to;
-            mail.subject = subject;
-            mail.html = html;
-            transporter.sendMail(mail, callback);
-        }
-    };
-};
diff --git a/lib/utils.js b/lib/utils.js
deleted file mode 100644
index 59659ae08a646bbcee61be69624b68bb635c22d6..0000000000000000000000000000000000000000
--- a/lib/utils.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2012 Centro de Computacao Cientifica e Software Livre
- * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
- *
- * This file is part of simmc
- *
- * simmc 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 2
- * of the License, or (at your option) any later version.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-var crypto = require('crypto');
-
-// Returns a filename starting with prefix (if not null) plus a md5-hash
-// representing the obj given as argument, with "ext" as extension.
-exports.hashFilename = function(prefix, obj, ext) {
-    var txt = "";
-    for (i in obj) {
-        txt += i + obj[i]
-    }
-    var hash = crypto.createHash('md5').update(txt).digest('hex');
-    return (prefix? prefix + '_' + hash :  hash) + '.' + ext;
-};
-
-// returns a filename in the format:  type project_date(day+month+year+'_'+hours+minutes).ext
-exports.reportFilename = function(prefix, ext) {
-    var date = formatDateReport(new Date());
-    return prefix+ '_'+ date + '.' + ext;
-};
-
-// returns the date in the format day+month+year_hours+minutes
-function formatDateReport(date) {
-    var day = date.getUTCDate(),
-        month = date.getUTCMonth() + 1, //Months are zero based
-        year = date.getUTCFullYear(),
-        hours = date.getHours(),
-        minutes = date.getMinutes();
-
-    if (day < 10)   day = '0' + day;
-    if (month < 10) month = '0' + month;
-    if (hours < 10) hours = '0' + hours;
-    if (minutes < 10) minutes = '0' + minutes;
-
-    return day + month + year + '_' + hours + minutes;
-}
-
-
-// returns the sum of every element in a array or object
-exports.sum = function(x) {
-    var total = 0;
-    if (x.constructor == Array) {
-        for (var i=0; i<x.length; i++) {
-            total += x[i];
-        }
-    } else {
-        for (var i in x) {
-            total += x[i];
-        }
-    }
-    return total;
-}
-
-exports.checkEmail = function(email) {
-    if (email.length < 4) {
-        return "Email deve conter pelo menos 4 caracteres.";
-    }
-
-    if (email.length > 255) {
-        return "Email deve conter no máximo 255 caracteres.";
-    }
-
-    if (!email.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)) {
-        return "Email não está em um formato válido.";
-    }
-
-    return false;
-}
diff --git a/middleware/cache.js b/middleware/cache.js
deleted file mode 100644
index e8809908bdef74f85be346443811411dee8ec1d9..0000000000000000000000000000000000000000
--- a/middleware/cache.js
+++ /dev/null
@@ -1,37 +0,0 @@
-module.exports = function (config) {
-    var memcached = null;
-    if (config) { // require memcached module only if configured
-        var Memcached = require('memcached');
-        memcached = new Memcached(config.server || 'localhost:11211', config.options || {});
-    }
-
-    return {
-        try: function (req, res, next) {
-            if (!memcached) { // memcached not configured
-                next();
-                return;
-            }
-
-            memcached.get(req.url, function (err, data) {
-                if (err) {
-                    console.log('Memcached error:\n');
-                    console.log(err);
-                    next();
-                }
-                else if (data) {
-                    if (config.debug) console.log('cached response to '+req.url);
-                    res.status(200).send(data);
-                }
-                else {
-                    // provide a method for the route to cache its response
-                    res.cache = function (data, cb) {
-                        if (config.debug) console.log('caching '+req.url);
-                        memcached.set(req.url, data, config.lifetime || 3600, cb || function (err) {});
-                    }
-
-                    next();
-                }
-            });
-        }
-    };
-};
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index cacdd20788a057d68cb3d94fc52698dae4fe108a..0000000000000000000000000000000000000000
--- a/package-lock.json
+++ /dev/null
@@ -1,480 +0,0 @@
-{
-  "name": "webservice-pinsis",
-  "version": "0.0.0",
-  "lockfileVersion": 1,
-  "dependencies": {
-    "accepts": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
-      "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo="
-    },
-    "ap": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/ap/-/ap-0.2.0.tgz",
-      "integrity": "sha1-rglCYAspkS8NKxTsYMRejzMLYRA="
-    },
-    "array-flatten": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
-      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
-    },
-    "async": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
-      "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw=="
-    },
-    "balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-      "optional": true
-    },
-    "body-parser": {
-      "version": "1.17.2",
-      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz",
-      "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4="
-    },
-    "brace-expansion": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
-      "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
-      "optional": true
-    },
-    "browser-fingerprint": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/browser-fingerprint/-/browser-fingerprint-0.0.1.tgz",
-      "integrity": "sha1-jfPNyiW/fVs1QtYVRdcwBT/OYEo="
-    },
-    "buffer-writer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.1.tgz",
-      "integrity": "sha1-Iqk2kB4wKa/NdUfrRIfOtpejvwg="
-    },
-    "bunyan": {
-      "version": "1.8.10",
-      "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.10.tgz",
-      "integrity": "sha1-IB/t0mxwgLYy9BYHL1OpC5pSmBw="
-    },
-    "bytes": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
-      "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk="
-    },
-    "concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-      "optional": true
-    },
-    "content-disposition": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
-      "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
-    },
-    "content-type": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
-      "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0="
-    },
-    "cookie": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
-      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
-    },
-    "cookie-signature": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
-      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
-    },
-    "core-js": {
-      "version": "1.2.7",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
-      "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
-    },
-    "cuid": {
-      "version": "1.3.8",
-      "resolved": "https://registry.npmjs.org/cuid/-/cuid-1.3.8.tgz",
-      "integrity": "sha1-S4deCWm612T37AcGz0T1+wgx9rc="
-    },
-    "debug": {
-      "version": "2.6.7",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz",
-      "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4="
-    },
-    "depd": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
-      "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM="
-    },
-    "destroy": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
-      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
-    },
-    "dtrace-provider": {
-      "version": "0.8.3",
-      "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.3.tgz",
-      "integrity": "sha1-uhv8ZJMoXM/PxqtpzVxh10wqQ78=",
-      "optional": true
-    },
-    "ee-first": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
-      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
-    },
-    "encodeurl": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
-      "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
-    },
-    "escape-html": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
-      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
-    },
-    "etag": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz",
-      "integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE="
-    },
-    "express": {
-      "version": "4.15.3",
-      "resolved": "https://registry.npmjs.org/express/-/express-4.15.3.tgz",
-      "integrity": "sha1-urZdDwOqgMNYQIly/HAPkWlEtmI="
-    },
-    "finalhandler": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.3.tgz",
-      "integrity": "sha1-70fneVDpmXgOhgIqVg4yF+DQzIk="
-    },
-    "forwarded": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz",
-      "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M="
-    },
-    "fresh": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz",
-      "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44="
-    },
-    "generic-pool": {
-      "version": "2.4.3",
-      "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.4.3.tgz",
-      "integrity": "sha1-eAw29p360FpaBF3Te+etyhGk9v8="
-    },
-    "glob": {
-      "version": "6.0.4",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
-      "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
-      "optional": true
-    },
-    "http-errors": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.1.tgz",
-      "integrity": "sha1-X4uO2YrKVFZWv1cplzh/kEpyIlc="
-    },
-    "iconv-lite": {
-      "version": "0.4.15",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
-      "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es="
-    },
-    "inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-      "optional": true
-    },
-    "inherits": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
-    },
-    "ipaddr.js": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.3.0.tgz",
-      "integrity": "sha1-HgOlL9rYOou7KyXL9JmLTP/NPew="
-    },
-    "lodash": {
-      "version": "4.17.4",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
-      "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
-    },
-    "media-typer": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
-      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
-    },
-    "merge-descriptors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
-      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
-    },
-    "methods": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
-      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
-    },
-    "mime": {
-      "version": "1.3.4",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
-      "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
-    },
-    "mime-db": {
-      "version": "1.27.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz",
-      "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE="
-    },
-    "mime-types": {
-      "version": "2.1.15",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz",
-      "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0="
-    },
-    "minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-      "optional": true
-    },
-    "minimist": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-      "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
-    },
-    "mkdirp": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-      "optional": true,
-      "dependencies": {
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "optional": true
-        }
-      }
-    },
-    "moment": {
-      "version": "2.18.1",
-      "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
-      "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=",
-      "optional": true
-    },
-    "ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
-    },
-    "mv": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
-      "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=",
-      "optional": true
-    },
-    "nan": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz",
-      "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=",
-      "optional": true
-    },
-    "ncp": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
-      "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=",
-      "optional": true
-    },
-    "negotiator": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
-      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
-    },
-    "node-fingerprint": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/node-fingerprint/-/node-fingerprint-0.0.2.tgz",
-      "integrity": "sha1-Mcur63GmeufdWn3AQuUcPHWGhQE="
-    },
-    "object-assign": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
-      "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A="
-    },
-    "on-finished": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
-      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc="
-    },
-    "once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E="
-    },
-    "packet-reader": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-0.3.1.tgz",
-      "integrity": "sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc="
-    },
-    "parseurl": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz",
-      "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY="
-    },
-    "path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
-      "optional": true
-    },
-    "path-to-regexp": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
-      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
-    },
-    "pg": {
-      "version": "6.4.0",
-      "resolved": "https://registry.npmjs.org/pg/-/pg-6.4.0.tgz",
-      "integrity": "sha1-y3a6Lnwuq4n8ZL96n+ZIztckNtw="
-    },
-    "pg-connection-string": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz",
-      "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc="
-    },
-    "pg-copy-streams": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/pg-copy-streams/-/pg-copy-streams-1.2.0.tgz",
-      "integrity": "sha1-ez+d7gtsX8IGj1nED6IY4MHXQkk="
-    },
-    "pg-pool": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-1.8.0.tgz",
-      "integrity": "sha1-9+xzgkw3oD8Hb1G/33DjQBR8Tzc="
-    },
-    "pg-types": {
-      "version": "1.12.0",
-      "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.12.0.tgz",
-      "integrity": "sha1-itO3uJfj/UY+Yt4kGtX8ZAtKZvA="
-    },
-    "pgpass": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz",
-      "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY="
-    },
-    "postgres-array": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.2.tgz",
-      "integrity": "sha1-jgsy6wO/d6XAp4UeBEHBaaJWojg="
-    },
-    "postgres-bytea": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
-      "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
-    },
-    "postgres-date": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.3.tgz",
-      "integrity": "sha1-4tiXAu/bJY/52c7g/pG9BpdSV6g="
-    },
-    "postgres-interval": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.1.0.tgz",
-      "integrity": "sha1-EDHnusNFZBMoYq3J62xtLzqnW7Q="
-    },
-    "proxy-addr": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.4.tgz",
-      "integrity": "sha1-J+VF9pYKRKYn2bREZ+NcG2tM4vM="
-    },
-    "qs": {
-      "version": "6.4.0",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
-      "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM="
-    },
-    "range-parser": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
-      "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
-    },
-    "raw-body": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz",
-      "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y="
-    },
-    "rimraf": {
-      "version": "2.4.5",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
-      "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=",
-      "optional": true
-    },
-    "safe-json-stringify": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.0.4.tgz",
-      "integrity": "sha1-gaCY9Efku8P/MxKiQ1IbwGDvWRE=",
-      "optional": true
-    },
-    "semver": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz",
-      "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c="
-    },
-    "send": {
-      "version": "0.15.3",
-      "resolved": "https://registry.npmjs.org/send/-/send-0.15.3.tgz",
-      "integrity": "sha1-UBP5+ZAj31DRvZiSwZ4979HVMwk="
-    },
-    "serve-static": {
-      "version": "1.12.3",
-      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.3.tgz",
-      "integrity": "sha1-n0uhni8wMMVH+K+ZEHg47DjVseI="
-    },
-    "setprototypeof": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
-      "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
-    },
-    "split": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz",
-      "integrity": "sha1-xDlc5oOrzSVLwo/h2rtuXCfc/64="
-    },
-    "statuses": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
-      "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
-    },
-    "through": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
-    },
-    "type-is": {
-      "version": "1.6.15",
-      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
-      "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA="
-    },
-    "unpipe": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
-      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
-    },
-    "utils-merge": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
-      "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg="
-    },
-    "vary": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz",
-      "integrity": "sha1-Z1Neu2lMHVIldFeYRmUyP1h+jTc="
-    },
-    "wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
-    },
-    "xtend": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
-      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
-    }
-  }
-}
diff --git a/package.json b/package.json
index 38d2e9f5cfdfbac4453bf90536576dc1c0cb907c..4821f8d0cdf966a48ab4c661e2c208e553636af8 100644
--- a/package.json
+++ b/package.json
@@ -3,18 +3,40 @@
   "version": "0.0.0",
   "description": "Webservice para receber dados do agente PInSIS",
   "author": "Davisson Paulino <dhpaulino@gmail.com>",
+  "license": "GPL-3.0",
   "main": "server.js",
+  "repository": {
+    "type": "git",
+    "url": "git@gitlab.c3sl.ufpr.br:PInSIS/webservice-pinsis.git"
+  },
   "scripts": {
-    "start": "node server.js"
+    "start": "node src/server.js"
   },
   "dependencies": {
-    "express": "^4.13.3",
     "async": "^2.1.2",
     "body-parser": "^1.14.1",
+    "bunyan": "^1.0.1",
+    "collect-webservice": "git+https://gitlab.c3sl.ufpr.br/c3sl/collect-webservice.git",
+    "cuid": "^1.2.4",
+    "ejs": "^2.5.7",
+    "express": "^4.13.3",
+    "minimist": "1.2.0",
     "pg": "^6.1.0",
     "pg-copy-streams": "^1.2.0",
-    "minimist": "1.2.0",
-    "cuid": "^1.2.4",
-    "bunyan": "^1.0.1"
+    "squel": "^5.10.0",
+    "xlsx": "^0.12.2"
+  },
+  "devDependencies": {
+    "chai": "^4.1.0",
+    "chai-http": "^3.0.0",
+    "gulp": "^3.9.1",
+    "gulp-istanbul": "^1.1.2",
+    "gulp-jshint": "^2.0.4",
+    "gulp-mocha": "^v3.0.1",
+    "gulp-shell": "^0.6.3",
+    "jshint": "latest",
+    "jshint-stylish": "^2.2.1",
+    "mocha": "^3.5.0",
+    "nyc": "^11.1.0"
   }
 }
diff --git a/routes/agent.js b/routes/agent.js
deleted file mode 100644
index 9b2560cf2c5623058403e8b927b64f0287854f82..0000000000000000000000000000000000000000
--- a/routes/agent.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2012-2017 Centro de Computacao Cientifica e Software Livre
- * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
- *
- * This file is part of simmc
- *
- * simmc 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 2
- * of the License, or (at your option) any later version.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-var async = require('async');
-
-function isSubSet (array1, array2) {
-    return array1.every(function(item1) {
-        return array2.some(function(item2) {
-            return item1 == item2;
-        });
-    });
-}
-
-function dateFormat (date) {
-
-    if (!date) {
-        return null;
-    }
-
-    return date.getFullYear() + '-' +
-           ("0" + (date.getMonth() + 1)).slice(-2) + '-' +
-           ("0" + date.getDate()).slice(-2);
-}
-
-function timeFormat (date) {
-
-    if (!date) {
-        return null;
-    }
-
-    return ("0" + date.getHours()).slice(-2) + ':' +
-           ("0" + date.getMinutes()).slice(-2) + ':' +
-           ("0" + date.getSeconds()).slice(-2);
-}
-
-var routes =  {
-    /*"net_usage": {
-        validation: function(body) {
-            if(!body) {
-                return false;
-            }
-            else {
-                var keys = [
-                    'id_point',
-                    'mac_address',
-                    'bytes_recived',
-                    'bytes_transmited',
-                    'collect_time',
-                    'packets_recived',
-                    'packets_transmited',
-                ];
-                return isSubSet(Object.keys(body), keys);
-            }
-        },
-        parser: function(body) {
-            return [
-                dateFormat(new Date()),
-                body.id_point,
-                body.mac_address,
-                dateFormat(body.collect_time),
-                timeFormat(body.collect_time),
-                body.bytes_recived,
-                body.packets_recived,
-                body.bytes_transmited,
-                body.packets_transmited,
-            ];
-        },
-        query: 'collect/net_usage.sql'
-    }*/
-};
-
-module.exports = function(agentVersion) {
-    return {
-        collect: function(req, res) {
-            var route = routes[req.params.type];
-            if(!route) {
-                return res.status(400).json({error: 'invalid_parameter'});
-            }
-            if(route.validation(req.body)) {
-                var data = route.parser(req.body);
-                req.db.connect(function(err, conn, done) {
-                    if (err) {
-                        req.log.error(err);
-                        res.status(500).json({error: 'db_connection_failed'});
-                        return;
-                    }
-                    async.waterfall([
-                        conn.transaction,
-                        function(callback) {
-                            conn.queryFromFile(route.query, data, callback);
-                        },
-                        conn.commit
-                    ], function (err, result) {
-                        if(err) {
-                            req.log.error(err);
-                            res.staus(500).json({error: 'db_query_failed'});
-                            conn.rollback(done);
-                            return;
-                        }
-                        res.status(200).json({});
-                        done();
-                    });
-                });
-            }
-            else {
-                return res.status(400).json({error: 'invalid_body'});
-            }
-        },
-        version : function (req, res) {
-            return res.status(200).json({version: agentVersion});
-        }
-    };
-};
diff --git a/Dockerfile b/src/Dockerfile
similarity index 100%
rename from Dockerfile
rename to src/Dockerfile
diff --git a/src/db/query_builder.js b/src/db/query_builder.js
new file mode 100644
index 0000000000000000000000000000000000000000..57a5697c11e2b6c7edc4922e5d989a21986f9817
--- /dev/null
+++ b/src/db/query_builder.js
@@ -0,0 +1,25 @@
+squel = require("squel").useFlavour('postgres');
+
+module.exports =  {
+  set_from_attr : function (query, obj){
+    for (var property in obj) {
+      if (obj.hasOwnProperty(property)) {
+        query.set(property, obj[property]);
+      }
+    }
+    return query;
+  },
+  insert: function (table, obj){
+    var q = squel.insert().into(table);
+    this.set_from_attr(q, obj);
+    return q;
+  },
+  
+  select: function(table, conditions){
+    var q = squel.select().from(table);
+    for(c in conditions){
+      q = q.where(c+" = "+"'"+conditions[c]+"'");
+    }
+    return q;
+  }
+};
diff --git a/lib/logger.js b/src/lib/logger.js
similarity index 99%
rename from lib/logger.js
rename to src/lib/logger.js
index cfd4c5b0405e67c847723329a5be32b0cf421711..fc62ffb61a72a7f119fc04be0c81ffa7a85b334d 100644
--- a/lib/logger.js
+++ b/src/lib/logger.js
@@ -20,6 +20,7 @@
  * USA.
  */
 
+/*jshint sub:true*/
 
 var os = require('os');
 var cluster = require('cluster');
@@ -69,7 +70,7 @@ function responseSerializer(res) {
     return {
         statusCode: res.statusCode,
         responseTime: responseTime
-    }
+    };
 }
 
 // Make sure the logs dir exist
@@ -125,7 +126,7 @@ exports.expressAccess = function (req, res, next) {
 
     // Log the response
     req.log.debug({res: res}, 'response');
-}
+};
 
 // Export the express error logger (log errors during request processing)
 exports.expressError = function (err, req, res, next) {
@@ -134,4 +135,4 @@ exports.expressError = function (err, req, res, next) {
     }
 
     next();
-}
+};
diff --git a/middleware/db.js b/src/middleware/db.js
similarity index 64%
rename from middleware/db.js
rename to src/middleware/db.js
index 5f70a2707bd68ba8dc036bc043f5d9c9858d8bd3..c506f7baf06a9f49e71dc35c97e99e695ac27e58 100644
--- a/middleware/db.js
+++ b/src/middleware/db.js
@@ -66,23 +66,27 @@ function namedPatch(client) {
 
 exports.pool = function (config) {
     return function (req, res, next) {
+        var pool = new pg.Pool(config);
         req.db = {
             connect: function (callback) {
-                pg.on('error', function(err) {
+                pool.on('error', function(err) {
+                    pool.end();
                     return;
                 });
-                pg.connect(config, function (err, client, done) {
+                pool.connect(function (err, client, done) {
                     if (err) {
-                        setTimeout(req.db.connect, 5000, callback);
+                        callback(err, null, done);
                         return;
                     }
 
                     namedPatch(client);
                     callback(null, new Connection(client), done);
                 });
+                
+                pool.end();
             }
         };
-
+        
         next();
     };
 };
@@ -102,38 +106,38 @@ function Connection(client) {
         };
     };
 
-    this.queryFromFile = function(file, params, callback) {
-        var queries_dir = __dirname + "/../queries/";
-
-        fs.readFile(queries_dir + file, 'utf8', function (err, data) {
-            if (err) {
-                return callback(err);
-            }
-
-            if (typeof params === 'undefined') {
-                params = [];
-            }
-
-            client.query(data, params, callback);
-        });
-    };
-
-    this.executeFromFile = function(file, params) {
-        var $this = this;
-
-        return function (callback) {
-            $this.queryFromFile(file, params, function (err) {
-                callback(err);
-            });
-        };
-    };
-
-    this.copyFrom = function (query, callback) {
-        var stream = client.query(copyFrom(query));
-        stream.on('end', callback);
-        stream.on('error', callback);
-        return stream;
-    };
+    // this.queryFromFile = function(file, params, callback) {
+    //     var queries_dir = __dirname + "/../queries/";
+    //
+    //     fs.readFile(queries_dir + file, 'utf8', function (err, data) {
+    //         if (err) {
+    //             return callback(err);
+    //         }
+    //
+    //         if (typeof params === 'undefined') {
+    //             params = [];
+    //         }
+    //
+    //         client.query(data, params, callback);
+    //     });
+    // };
+
+    // this.executeFromFile = function(file, params) {
+    //     var $this = this;
+    //
+    //     return function (callback) {
+    //         $this.queryFromFile(file, params, function (err) {
+    //             callback(err);
+    //         });
+    //     };
+    // };
+    //
+    // this.copyFrom = function (query, callback) {
+    //     var stream = client.query(copyFrom(query));
+    //     stream.on('end', callback);
+    //     stream.on('error', callback);
+    //     return stream;
+    // };
 
     this.transaction = function (callback) {
         client.query('BEGIN;', function (err) {
@@ -153,16 +157,16 @@ function Connection(client) {
         });
     };
 
-    this.auth = function (user, ip, action, comment) {
-        return function (callback) {
-            if (!(user && user.id))
-                return callback('not_logged_in');
-
-            client.query('SELECT auth.user_action($1, $2, $3, $4);',
-                              [user.id, ip, action, comment],
-                              function (err) {
-                                  callback(err);
-                              });
-        };
-    };
-};
+    // this.auth = function (user, ip, action, comment) {
+    //     return function (callback) {
+    //         if (!(user && user.id))
+    //             return callback('not_logged_in');
+    //
+    //         client.query('SELECT auth.user_action($1, $2, $3, $4);',
+    //                           [user.id, ip, action, comment],
+    //                           function (err) {
+    //                               callback(err);
+    //                           });
+    //     };
+    // };
+}
diff --git a/src/middleware/populate.js b/src/middleware/populate.js
new file mode 100644
index 0000000000000000000000000000000000000000..44f23f62e4e52400a5abca59b52fbbf0cbd856bf
--- /dev/null
+++ b/src/middleware/populate.js
@@ -0,0 +1,232 @@
+var _ = require('lodash');
+var pg = require('pg'),
+    copyFrom = require('pg-copy-streams').from,
+    fs = require('fs');
+
+var async = require('async');
+    
+var XLSX = require('xlsx');
+
+
+function namedPatch(client) { 
+    var originalQuery = client.query;
+
+    if (originalQuery.patched) return client;
+
+    originalQuery = originalQuery.bind(client);
+
+    var patchedQuery = function(config, values, callback) {
+        if (arguments.length === 1) {
+            return originalQuery(config);
+        }
+        else if (arguments.length === 2 && _.isFunction(values)) {
+            return originalQuery(config, values);
+        }
+        else if (_.isArray(values)) {
+            return originalQuery(config, values, callback);
+        } else {
+            var reparameterized = numericFromNamed(config, values);
+            return originalQuery(reparameterized.sql, reparameterized.values, callback);
+        }
+    };
+
+    client.query = patchedQuery;
+    client.query.patched = true;
+
+    return client;
+}
+
+
+function Connection(client) {
+    this.query = function (query, params, callback) {
+        return client.query(query, params, callback);
+    };
+
+    this.execute = function (query, params) {
+        var $this = this;
+
+        return function (callback) {
+            $this.query(query, params, function (err) {
+                callback(err);
+            });
+        };
+    };
+
+    this.transaction = function (callback) {
+        client.query('BEGIN;', function (err) {
+            callback(err);
+        });
+    };
+
+    this.commit = function (callback) {
+        client.query('COMMIT;', function (err) {
+            callback(err);
+        });
+    };
+
+    this.rollback = function (callback) {
+        client.query('ROLLBACK;', function (err) {
+            callback(err);
+        });
+    };
+
+}
+
+var sheet2arr = function(sheet){
+    var i = 5;
+    var rows = [];
+    while(true){
+        
+        if(!sheet["A"+(i+1)]  &&  !sheet["A"+i]){
+            return rows;
+        }    
+        if(sheet["A"+(i+1)]  &&  !sheet["A"+i]){
+            i+=1;
+        }
+        
+        if(sheet["A"+i]["v"] == "ID do paciente"){
+            
+            var paciente_id = sheet["D"+i]["w"];
+            var paciente_nome = sheet["L"+i]["w"];
+            
+            
+            if(!sheet["A"+(i+1)]){
+                i+=1;
+            }
+            
+            i+=4;
+        }
+        
+        
+        if(sheet["G"+i]){
+            var field_name = sheet["J"+i] ? sheet["J"+i]["w"] : "";
+            var use_date = sheet["B"+i]["w"].split(" ");
+            use_date = new Date(
+                use_date[0].split("/")[2],
+                parseInt(use_date[0].split("/")[1])-1,
+                use_date[0].split("/")[0],
+                use_date[1].split(":")[0],
+                use_date[1].split(":")[1]
+            );
+            rows.push({
+                Pacient_id: paciente_id,
+                Pacient_name: paciente_nome,
+                Energy: sheet["G"+i]["w"],
+                Use_date: use_date.toISOString(),
+                Field_name: field_name,
+                Machine_id: sheet["M"+i]["w"],
+                Fk_agent: 1,
+            });
+        }
+        i+=1;
+        
+    }
+    
+};
+
+function waterfall_queries(queries, config, cb_w){
+    var pool = new pg.Pool(config);
+    var temp_db = {
+        connect: function (callback) {
+            pool.on('error', function(err) {
+                throw(err);
+                cb_w();
+            });
+            pool.connect(function (err, client, done) {
+                if (err) {
+                    setTimeout(temp_db.connect, 5000, callback);
+                    done();
+                    return;
+                }
+
+                namedPatch(client);
+                callback(null, new Connection(client), done);
+            });
+            
+            pool.end();
+        }
+    };
+        
+    temp_db.connect(function(err, conn, done) {
+        if (err) {
+          throw(err);
+        }
+        
+        async.waterfall([
+          conn.transaction,
+          function(callback) {
+            async.everySeries(queries,  function(q, cb){
+                conn.query(q.toParam().text, q.toParam().values, cb);
+            }, function(err, result){
+              callback(err);
+            });
+          },
+          conn.commit
+        ], function (err, result) {
+          if(err) {
+            throw(err);
+            conn.rollback(done);
+            cb_w();
+            return;
+          }
+          done();
+          cb_w();
+        });
+    });
+}
+
+
+exports.populateAgent = function(file, config, callback = function(){}){
+    var workbook = XLSX.readFile(file);
+    var sheet_name_list = workbook.SheetNames;
+    var sheetName = Object.keys(workbook.Sheets)[0];
+    var s = workbook.Sheets[sheetName];
+    
+    var consultas = sheet2arr(s);
+    
+    var queries = [];
+    
+    //TODO: Create a config file that will be used to populate this table
+    var q = qb.insert("agent",{
+        Hospital_name: "Erasto Gaertner",
+        Geo_lat: -25.4696528,
+        Geo_long: -49.261403
+    });
+    
+    queries.push(q);
+    waterfall_queries(queries, config, callback);
+    
+}
+
+exports.populeMachineuse = function (file,config, callback = function(){}){
+    var workbook = XLSX.readFile(file);
+    var sheet_name_list = workbook.SheetNames;
+    var sheetName = Object.keys(workbook.Sheets)[0];
+    var s = workbook.Sheets[sheetName];
+    
+    var consultas = sheet2arr(s);
+    
+    var queries = [];
+    
+    for(var x in consultas){
+        var q = qb.insert("machineuse",consultas[x]);
+        queries.push(q);
+    }
+    
+    var refresh_views_query = {
+        toParam: function refresh_views(){
+            return {
+                values: [],
+                text:
+                    "REFRESH materialized view ResumeUsesMonth;"+
+                    "REFRESH materialized view ResumeUsesDay;"
+            }
+        }
+    }
+    
+    queries.push(refresh_views_query);
+    waterfall_queries(queries, config, callback);
+    
+    
+}
+
diff --git a/src/routes/agent.js b/src/routes/agent.js
new file mode 100644
index 0000000000000000000000000000000000000000..4359b7f5e234d300a8b60822821e2c2e5bb1e5e6
--- /dev/null
+++ b/src/routes/agent.js
@@ -0,0 +1,87 @@
+/*
+* Copyright (C) 2012-2017 Centro de Computacao Cientifica e Software Livre
+* Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+*
+* This file is part of simmc
+*
+* simmc 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+* USA.
+*/
+
+var async = require('async');
+
+
+
+module.exports = function(agentVersion) {
+  qb = require("../db/query_builder.js");
+
+  return {
+    collect: function(req, res) {
+      var queries = [];
+      if(req.body.hasOwnProperty("courses")){
+        for(var i=0;i < req.body.courses.length; i++){
+          var course = req.body.courses[i];
+          var q = qb.insert('Course', course);
+          queries.push(q);
+        }
+
+      }
+
+      if(req.body.hasOwnProperty("sessions")){
+        req.body.sessions.forEach(function(session){
+          queries.push(qb.insert('Session', session));
+        });
+
+      }
+
+      if(req.body.hasOwnProperty("sessionProcedureParts")){
+        req.body.sessionProcedureParts.forEach(function(spp){
+          queries.push(qb.insert('sessionProcedurePart', spp));
+        });
+
+      }
+      req.db.connect(function(err, conn, done) {
+        if (err) {
+          req.log.error(err);
+          res.status(500).json({error: 'db_connection_failed'});
+          return;
+        }
+        async.waterfall([
+          conn.transaction,
+          function(callback) {
+            async.everySeries(queries,  function(q, cb){
+                conn.query(q.toParam().text, q.toParam().values, cb);
+            }, function(err, result){
+              callback(err);
+            });
+          },
+          conn.commit
+        ], function (err, result) {
+          if(err) {
+            req.log.error(err);
+            res.status(500).json({error: 'db_query_failed'});
+            conn.rollback(done);
+            return;
+          }
+          res.status(200).json({});
+          done();
+        });
+      });
+    },
+    version : function (req, res) {
+      return res.status(200).json({version: agentVersion});
+    }
+  };
+};
diff --git a/src/routes/data.js b/src/routes/data.js
new file mode 100644
index 0000000000000000000000000000000000000000..f4053339f693137d4cb873ccea54fcb121497d3c
--- /dev/null
+++ b/src/routes/data.js
@@ -0,0 +1,63 @@
+/*
+* Copyright (C) 2012-2017 Centro de Computacao Cientifica e Software Livre
+* Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+*
+* This file is part of simmc
+*
+* simmc 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+* USA.
+*/
+
+var async = require('async');
+
+module.exports = function(agentVersion) {
+  qb = require("../db/query_builder.js");
+
+  return {
+    listTable : function (req, res, table) {
+      req.db.connect(function(err, conn, done) {
+      
+        if (err) {
+          req.log.error(err);
+          res.status(500).json({error: 'db_connection_failed'});
+          done();
+          return;
+        }
+
+        var parameters = {};
+        
+        switch(table){
+          case 'ResumeUsesMonth':
+          case 'ResumeUsesDay':
+            if(req.query['hospital_id']) parameters["fk_agent"] = parseInt(req.query['hospital_id']);
+            break;
+        }
+        
+        
+        var q = qb.select(table,parameters);
+                
+        conn.query(q.toParam().text,q.toParam().values, function(err,data,fields){
+            if (err) req.log.error(err);
+            res.header("Access-Control-Allow-Origin", "*");
+            res.header("Access-Control-Allow-Headers", "X-Requested-With");
+            done();
+            return res.status(200).json(data.rows);
+        });
+        
+      });
+      
+    }
+  };
+};
diff --git a/routes/ping.js b/src/routes/ping.js
similarity index 100%
rename from routes/ping.js
rename to src/routes/ping.js
diff --git a/server.js b/src/server.js
similarity index 67%
rename from server.js
rename to src/server.js
index a0cb67db8f602d6fd7bd13579779f413422457de..c236018abcccaef6f2cdacc2a24db180a7f65eb7 100644
--- a/server.js
+++ b/src/server.js
@@ -24,6 +24,8 @@
 //
 // Libraries
 //
+/*jshint esversion: 6*/
+
 var os = require('os');
 var fs = require('fs');
 var cluster = require('cluster');
@@ -32,6 +34,7 @@ var express = require('express');
 var minimist = require('minimist');
 var path = require('path');
 var exec = require('child_process').execFile;
+var collect = require('collect-webservice');
 
 //
 // Parse command line arguments
@@ -53,7 +56,18 @@ if (argv.help || argv.h) {
     return 0;
 }
 
-var configFile = argv.config || argv.c || 'config.js';
+const app_mode = (process.env.NODE_ENV || 'development').trim().toLowerCase();
+
+
+var configFile;
+
+//test config
+if(app_mode === 'test'){
+  configFile = argv.config || argv.c || 'config_test.js';
+}else{
+  configFile = argv.config || argv.c || 'config.js';
+}
+
 var config;
 try {
     config = require(path.resolve('.', configFile));
@@ -79,9 +93,10 @@ var port = parseInt(argv.port || argv.p || process.env.PORT) || 3000;
 var secureCookies = !argv.insecure;
 var numWorkers = parseInt(argv['num-workers'] || argv.n) || (os.cpus().length * 2);
 var daemon = argv.daemon || argv.d || false;
-var pidfile = argv['pid-file'] || config.pid_file || process.env.PID_FILE || path.resolve('.', 'simmc.pid');
+var pidfile = argv['pid-file'] || config.pid_file || process.env.PID_FILE || path.resolve('.', 'pinsis.pid');
+
 
-if (devMode) {
+if (app_mode === 'development' || app_mode === 'test') {
     secureCookies = false;
 
     // Limit to only 1 worker in dev mode because sessions stored
@@ -99,17 +114,106 @@ var logger = require('./lib/logger.js');
 var log = logger.default;
 
 
+//
+// Middlewares
+//
+
+var db = require('./middleware/db.js');
+
+//
+// Routes
+//
+
+var ping = require('./routes/ping.js');
+var agent = require('./routes/agent.js')(config.agentVersion);
+var data = require('./routes/data.js')(config.agentVersion);
+
+//Data validation
+var ct_validator = require('./validation/course_treatment.js');
+
+//
+// Setup express app
+//
+var app = express();
+app.use(logger.expressAccess);
+app.use(logger.expressError);
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({extended: true}));
+
+
+
+app.use(db.pool(config.db_config));
+
+
+
+// acquire user id and ip address
+app.use(function (req, res, next) {
+    req.ip = req.ips[0] || req.ip || null;
+    next();
+});
+
+app.engine('html', require('ejs').renderFile);
+app.set('view engine', 'html');
+
+var populate = require("./middleware/populate.js");
+
+
+//
+// Setup routes
+//
+
+app.get('/api/ping', ping.get);
+
+
+var collect_mw  = collect(ct_validator());
+app.post('/api/agent/collect/:type(course_treatment)', collect_mw, agent.collect);
+app.get('/api/agent/version', agent.version);
+
+
+
+app.get('/api/data/listAgents', function(req, res) {
+    data.listTable(req,res,"agent");
+});
+
+app.get('/api/data/ResumeUsesDay', function(req, res) {
+    data.listTable(req,res,"ResumeUsesDay");
+});
+
+app.get('/api/data/ResumeUsesMonth', function(req, res) {
+    data.listTable(req,res,"ResumeUsesMonth");
+});
+
+
+app.get('/pinsis.js', function(req, res) {
+    res.render(path.join(__dirname + '/static/pinsis.ejs'),{ip:config.webservice_config.ip});
+});
+
+app.get('/exemplo.html', function(req, res) {
+    res.render(path.join(__dirname + '/static/exemplo.html'),{ip:config.webservice_config.ip});
+});
+
+
+
+var exit = function exit() {
+    log.info('Server exiting...');
+
+    process.exit(0);
+};
+
 //
 // Fork process
 //
 if (cluster.isMaster) {
+    //Here is where should be populated the tables
+    
+
     // daemonize the process (useful for init.d scripts and similar)
     if (argv.daemon) {
         require('daemon')();
         fs.writeFileSync(pidfile, process.pid+"\n");
     }
 
-    log.info('Starting server in '+ (devMode ? 'development' : 'production') +
+    log.info('Starting server in '+ app_mode +
         ' mode, spawning ' + numWorkers + ' workers');
 
     for (var i = 0; i < numWorkers; i++) {
@@ -126,65 +230,13 @@ if (cluster.isMaster) {
         }
     });
 
-    function exit() {
-        log.info('Server exiting...');
 
-        process.exit(0);
-    }
 
     process.on('SIGTERM', exit);
     process.on('SIGHUP', exit);
     process.on('SIGINT', exit);
 }
 else {
-    //
-    // Middlewares
-    //
-  
-    var db = require('./middleware/db.js');
-    var utils = require('./lib/utils.js');
-
-    //
-    // Routes
-    //
-   
-    var ping = require('./routes/ping.js');
-    var agent = require('./routes/agent.js')(config.agentVersion);
-
-
-    //
-    // Setup express app
-    //
-    var app = express();
-    app.use(logger.expressAccess);
-    app.use(logger.expressError);
-    app.use(bodyParser.json());
-    app.use(bodyParser.urlencoded({extended: true}));
-
-
-   
-    app.use(db.pool(config.db_config));
-
-   
-
-    // acquire user id and ip address
-    app.use(function (req, res, next) {
-        req.ip = req.ips[0] || req.ip || null;
-        next();
-    });
-
-    
-
-
-
-    //
-    // Setup routes
-    //
-  
-    app.get('/api/ping', ping.get);
-
-    app.post('/api/agent/collect/:type(inventory|net_usage)', agent.collect);
-    app.get('/api/agent/version', agent.version);
 
     //
     // Listen for incoming connections
@@ -201,3 +253,4 @@ else {
         app.listen(port);
     }
 }
+module.exports = app;
diff --git a/src/static/exemplo.html b/src/static/exemplo.html
new file mode 100644
index 0000000000000000000000000000000000000000..7c78735d1e32aeab82f419fabbd1a192e4442b2a
--- /dev/null
+++ b/src/static/exemplo.html
@@ -0,0 +1,133 @@
+<html>
+	<header>
+		<meta charset="utf-8">
+		
+		<style>
+		.SEPARADOR{
+		  margin-top:20px;
+		  margin-bottom:20px;
+		  width:100%;
+		  outline-width:1px;
+		  outline-style:solid;
+		  outline-color:rgba(0,0,0,0.3);
+		  text-align:center;
+		  background-color:rgba(0,0,0,0.3);
+		}
+		</style>
+
+
+		<script src="http://<%= ip %>:3000/pinsis.js"></script>
+		<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
+		<script>
+			
+			function get_attribute_list(object_list, key){
+				return object_list.map(function(x){return x[key];});
+			}
+
+			function plot_uses_by(uses,groupby, divname){
+				var plot1_data_x = get_attribute_list(uses,"date");
+				var plot2_data_x = plot1_data_x;
+				
+				
+				var plot1_data_y = get_attribute_list(uses,"uses");
+				var plot2_data_y = [];
+				
+				
+				for(i in plot1_data_x){
+					plot2_data_y[i]  = plot1_data_y[i] - parseInt(plot1_data_y[i]*Math.random()); 
+					plot1_data_y[i] -= plot2_data_y[i]; 
+				}
+				
+				
+				var susColor = 'green';
+				var othersColor = 'blue';
+				
+				var plot_data = [
+				  {
+					x: plot1_data_x,
+					y: plot1_data_y,
+					type: 'bar',
+					name: 'Outros',
+					marker: {color: othersColor},
+				  },
+				  {
+					x: plot2_data_x,
+					y: plot2_data_y,
+					type: 'bar',
+					name: 'SUS',
+					marker: {color: susColor},
+				  }
+				];
+
+				Plotly.newPlot(divname, plot_data, {barmode: 'group'});
+				
+				
+				var sum = function(x,y){return x+y;}
+				
+				var data = [{
+				  values: [plot2_data_y.reduce(sum),plot1_data_y.reduce(sum)],
+				  labels: ['SUS', 'Outros'],
+				  type: 'pie',
+				  marker:{colors:[susColor, othersColor]},
+				}];
+
+				var layout = {
+				  height: 400,
+				  width: 500
+				};
+
+				Plotly.newPlot(divname+"_pizza", data, layout);
+
+			}
+			
+			var hospitals;
+			
+			function plot(groupby, hospital){
+				switch(groupby){
+				case "days":
+					Pinsis.lastUsesByDay(function(err, data){
+						if(err) console.log(err);
+						plot_uses_by(data,groupby,"myDiv");					
+					}, hospital.id);
+					break;
+				case "months":
+					Pinsis.lastUsesByMonth(function(err, data){
+						if(err) console.log(err);
+						plot_uses_by(data,groupby,"myDiv");					
+					},hospital.id);
+					break;
+				}
+				
+				document.getElementById("hospital_name").innerHTML = hospital.hospital_name;
+			}
+			
+			
+			Pinsis.hospitals(function(err, data){
+				if(err) console.log(err);
+				hospitals = data;
+				console.log(data);
+				plot("days",hospitals[0]);
+			});
+			
+			
+		</script>
+	</header>
+	<body>
+		<center>
+			<button onClick="plot('months', hospitals[0])" > MESES </button>
+			<button onClick="plot('days',   hospitals[0])" > DIAS </button>
+		</center>
+		
+		<center><h1>Monitoramento: <span id="hospital_name"></span></h1>
+			<div class="SEPARADOR"></div>
+			<div id="myDiv"></div>
+			<div id="myDiv_pizza"></div>
+			<div class="SEPARADOR"></div>
+		</center>
+		
+		<br><br>
+		
+	</body>
+
+
+</html>
diff --git a/src/static/pinsis.ejs b/src/static/pinsis.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..724d23f782cf27bdf5d13517c4808181b2310433
--- /dev/null
+++ b/src/static/pinsis.ejs
@@ -0,0 +1,47 @@
+var Pinsis = {
+	
+	getJson: function(callback, url){
+		var xmlhttp = new XMLHttpRequest();
+			
+		xmlhttp.onreadystatechange = function() {
+			if (this.readyState == 4 && this.status == 200) {
+				var myArr = JSON.parse(this.responseText);
+				callback(null, myArr);
+			}
+			
+			if (this.readyState == 4 && this.status != 200) {
+				callback({status: this.status}, null)
+			}
+		};
+		xmlhttp.open("GET", url, true);
+		xmlhttp.send();
+	},
+	
+	lastUsesByDay: function(callback, hospital_id){
+		var url = "http://<%= ip %>:3000/api/data/ResumeUsesDay";
+		if(hospital_id) url+="?hospital_id="+hospital_id;
+		this.getJson(
+			callback,
+			url
+		);
+	},
+	
+	lastUsesByMonth: function(callback, hospital_id){
+		var url = "http://<%= ip %>:3000/api/data/ResumeUsesMonth";
+		if(hospital_id) url+="?hospital_id="+hospital_id;
+		this.getJson(
+			callback,
+			url
+		);
+		
+	},
+	
+	hospitals: function(callback){
+		this.getJson(
+			callback,
+			"http://<%= ip %>:3000/api/data/listAgents"
+		);
+	},
+	
+	
+}
diff --git a/src/validation/course_treatment.js b/src/validation/course_treatment.js
new file mode 100644
index 0000000000000000000000000000000000000000..72b00c60cd34ff0779242cc8d360a850444ee04c
--- /dev/null
+++ b/src/validation/course_treatment.js
@@ -0,0 +1,307 @@
+/*
+* Copyright (C) 2012-2017 Centro de Computacao Cientifica e Software Livre
+* Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+*
+* This file is part of simmc
+*
+* simmc 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 2
+* of the License, or (at your option) any later version.
+*
+* This program 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 this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+* USA.
+*/
+
+
+var config = {
+  global: {
+    fromBody: false,
+    param: "type"
+  },
+  filters: {},
+  collect_types: {
+    "course_treatment": {
+      "courses":{
+        required: false,
+        isArray: true,
+        filters: [],
+        inner:{
+          "CourseSer" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "PatientSer" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "CourseId" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "StartDateTime" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "ClinicalStatus" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "CompletedByUserName" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "CompletedDateTime" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "Comment" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "ClinicalProtocolDir" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryUserName" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryTimeStamp" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryDateTime" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "TransactionId" : {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryTaskName" : {
+            required: true,
+            isArray: false,
+            filters: []
+          }
+
+        }
+      },
+      "sessions":{
+        required: false,
+        isArray: true,
+        filters: [],
+        inner:{
+          "sessionSer": {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "SessionNum":  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "Comment":  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryUserName":  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryTimeStamp":  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryDateTime":  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryTaskName":  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "CourseSer":  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+
+        }
+      },
+      "sessionProcedureParts":{//FIXME: Is it required?
+        required: false,
+        isArray: true,
+        filters: [],
+        inner:{
+          "RadiationSer" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "ImageType" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "SequenceNumber" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "SessionProcedurePartSer" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "AcqAdjustment" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "AutoSave" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "DoseAccumulation" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "Continuous" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "BeamOff" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "DeviationImage" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "DevEnergy" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "DevDoseRate" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "DevGeometry" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "JawState" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "DevCollX1" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "DevCollX2" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "DevCollY1" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "DevCollY2" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "MUSubtraction" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "AcquisitionMode" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryUserName" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryTimeStamp" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryDateTime" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "HstryTaskName" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "SessionProcedureSer" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "ImageModality" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          },
+          "RTPlanSer" :  {
+            required: true,
+            isArray: false,
+            filters: []
+          }
+        }
+      }
+    }
+  }
+};
+
+module.exports = function() {
+
+  return config;
+};
diff --git a/test/db/query_builder.js b/test/db/query_builder.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6e86ec775cbb8485d91145ed0945ff9601d7b7e
--- /dev/null
+++ b/test/db/query_builder.js
@@ -0,0 +1,37 @@
+/*jshint esversion: 6*/
+process.env.NODE_ENV = 'test';
+let chai = require('chai');
+let should = chai.should();
+
+
+
+var toType = function(obj) {
+  return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
+};
+
+describe('Query builder',() => {
+  const qb = require('../../src/db/query_builder.js');
+  var squel = require("squel").useFlavour('postgres');
+
+  it('insert return a valid query ', (done) => {
+      const table = 'tb';
+      const obj = {
+        attr1: "v1",
+        attr2: 2
+      };
+      var trueq = squel.insert()
+                        .into(table)
+                        .set('attr1', obj.attr1)
+                        .set('attr2', obj.attr2);
+
+      var resultq = qb.insert(table, obj);
+
+      resultq.should.be.an('object');
+      resultq.toString().should.equal(trueq.toString());
+
+      done();
+  });
+
+
+
+});
diff --git a/test/routes/agent.js b/test/routes/agent.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae61c9a88eb2e26dc5bcbb69dffb2c7e350042c6
--- /dev/null
+++ b/test/routes/agent.js
@@ -0,0 +1,113 @@
+/*jshint esversion: 6*/
+
+process.env.NODE_ENV = 'test';
+let chai = require('chai');
+let chaiHttp = require('chai-http');
+const src_dir='../../src/';
+const server = require(src_dir + 'server.js');
+let should = chai.should();
+
+chai.use(chaiHttp);
+
+
+//console.log("lol");
+//console.log(server);
+describe('course_treatment', () => {
+
+  let courses = [{
+    "CourseSer" : "1",
+    "PatientSer" : "1",
+    "CourseId" : "1",
+    "StartDateTime" : "11-11-11 11:11:11",
+    "ClinicalStatus" : "CS1",
+    "CompletedByUserName" : "CByU1",
+    "CompletedDateTime" : "11-11-11 11:11:11",
+    "Comment" : "Comment1",
+    "ClinicalProtocolDir" : "CPD1",
+    "HstryUserName" : "HUN1",
+    "HstryTimeStamp" : "11-11-11 11:11:11",
+    "HstryDateTime" : "11-11-11 11:11:11",
+    "TransactionId" : "1",
+    "HstryTaskName" : "HTN1"
+  }];
+
+  let sessions = [{
+          "sessionSer": "1",
+          "SessionNum":  "1",
+          "Comment":  "C1",
+          "HstryUserName":  "HUN1",
+          "HstryTimeStamp":  "1111-11-11 11:11:11",
+          "HstryDateTime":  "1111-11-11 11:11:11",
+          "HstryTaskName":  "HTN1",
+          "CourseSer":  "1"
+	}];
+
+  let sessionProcedureParts = [{
+	          "RadiationSer" :  "1",
+	          "ImageType" :  "IT1",
+	          "SequenceNumber" :  "1",
+	          "SessionProcedurePartSer" :  "1",
+	          "AcqAdjustment" :  "1",
+	          "AutoSave" :  "1",
+	          "DoseAccumulation" :  "1",
+	          "Continuous" :  "1",
+	          "BeamOff" :  "1",
+	          "DeviationImage" :  "1",
+	          "DevEnergy" :  "1",
+	          "DevDoseRate" :  "1",
+	          "DevGeometry" :  "1",
+	          "JawState" :  "1",
+	          "DevCollX1" :  "1",
+	          "DevCollX2" :  "1",
+	          "DevCollY1" :  "1",
+	          "DevCollY2" :  "1",
+	          "MUSubtraction" :  "1",
+	          "AcquisitionMode" :  "AM1",
+	          "HstryUserName" :  "HUN1",
+	          "HstryTimeStamp" :  "1111-11-11 11:11:11",
+	          "HstryDateTime" :  "1111-11-11 11:11:11",
+	          "HstryTaskName" :  "1111-11-11 11:11:11",
+	          "SessionProcedureSer" :  "1",
+	          "ImageModality" :  "IM1",
+	          "RTPlanSer" :  "1"
+        }];
+
+
+  it('it should post courses, sessions and sessionProcedureParts', (done) => {
+    chai.request(server)
+        .post('/api/agent/collect/course_treatment')
+        .send({courses: courses, sessions: sessions, sessionProcedureParts: sessionProcedureParts})
+        .end((err, res) => {
+          res.should.have.status(200);
+          done();
+        });
+
+  });
+  it('it should give a error for save duplicate courses', (done) =>{
+    chai.request(server)
+        .post('/api/agent/collect/course_treatment')
+        .send({courses: courses})
+        .end((err, res) => {
+          res.should.have.status(500);
+          res.body.should.be.a('object');
+          res.body.should.have.property('error').eql('db_query_failed');
+          done();
+        });
+  });
+});
+
+describe('agent version', () => {
+
+  it('it should get version of the agent', (done) => {
+
+    const config = require('../../config_test.js');
+
+    chai.request(server)
+        .get('/api/agent/version')
+        .end((err, res) => {
+          res.should.have.status(200);
+          res.body.should.have.property('version').eql(config.agentVersion);
+          done();
+        });
+  });
+});
diff --git a/test/routes/ping.js b/test/routes/ping.js
new file mode 100644
index 0000000000000000000000000000000000000000..4c9cf2cb0b9a668115ad1c2bc95859c3b4285447
--- /dev/null
+++ b/test/routes/ping.js
@@ -0,0 +1,44 @@
+/*jshint esversion: 6*/
+
+process.env.NODE_ENV = 'test';
+let chai = require('chai');
+let chaiHttp = require('chai-http');
+const src_dir='../../src/';
+
+let should = chai.should();
+
+chai.use(chaiHttp);
+
+
+//console.log("lol");
+//console.log(server);
+describe('ping', () => {
+
+
+  it('it should pong', (done) => {
+    const server = require(src_dir + 'server.js');
+    chai.request(server)
+        .get('/api/ping')
+        .end((err, res) => {
+          res.should.have.status(200);
+          res.body.should.have.property('message').eql('Pong');
+          done();
+        });
+
+  });
+
+  it('it shouldn\'t pong', (done) =>{
+    process.argv.push("--config");
+    process.argv.push("config_test_error.js");
+
+    const server = require(src_dir + 'server.js');
+    chai.request(server)
+        .get('/api/ping')
+        .end((err, res) => {
+          res.should.have.status(200);
+          res.body.should.have.property('message').eql('db_connection_failed');
+          done();
+        });
+
+  });
+});
diff --git a/test/server.js b/test/server.js
new file mode 100644
index 0000000000000000000000000000000000000000..04d18aeb38d520b47c99d0d654702d90be8d4314
--- /dev/null
+++ b/test/server.js
@@ -0,0 +1,18 @@
+// /*jshint esversion: 6*/
+//
+// process.env.NODE_ENV = 'test';
+// let chai = require('chai');
+// let chaiHttp = require('chai-http');
+// const src_dir='../../src/';
+// const server = require(src_dir + 'server.js');
+// let should = chai.should();
+//
+// chai.use(chaiHttp);
+//
+//
+// //console.log("lol");
+// //console.log(server);
+// describe('Server', () => {
+//
+// it('it should have')
+// });