A plataforma GVFF GRC segue uma arquitectura cliente-servidor monolítica, com separação clara entre frontend (SPA) e backend (API REST).
uploads/ e servidos por rota dedicada| Componente | Tecnologia | Versão | Propósito |
|---|---|---|---|
| Runtime | Node.js | 20.x | Ambiente de execução servidor |
| Framework | Express.js | 4.x | Framework web e API REST |
| Base de Dados | MySQL | 8.x / compatível | Armazenamento persistente de dados |
| Driver DB | mysql2/promise | 3.x | Conexão à base de dados |
| Autenticação | jsonwebtoken (JWT) | 9.x | Tokens de sessão seguros |
| Hashing | bcryptjs | 2.x | Hashing de passwords |
| Uploads | multer | 1.x | Upload de PDFs |
| Config | dotenv | 17.x | Variáveis de ambiente |
| Frontend | Vanilla JS/HTML/CSS | - | Interface de utilizador (SPA) |
gvff-grc-platform/
├── index.js # Ponto de entrada principal do servidor
├── config/
│ └── db.js # Configuração da pool MySQL
├── middleware/
│ ├── auth.js # Middleware de autenticação JWT
│ ├── rbac.js # Roles e permissões CRUD
│ ├── menuAccess.js # Controlo de acesso a módulos/menus
│ ├── countryFilter.js # Filtragem por país
│ └── passwordValidator.js # Política de passwords
├── models/
│ ├── User.js
│ ├── Entity.js
│ ├── Supplier.js
│ ├── Asset.js
│ ├── Risk.js
│ ├── Document.js
│ ├── AuditLog.js
│ ├── Iso27001Scope.js
│ ├── Nis2Scope.js
│ └── ComplianceScopeFactory.js
├── routes/
│ ├── auth.js
│ ├── users.js
│ ├── entities.js
│ ├── countries.js
│ ├── suppliers.js
│ ├── assets.js
│ ├── risks.js
│ ├── documents.js
│ ├── iso27001.js
│ ├── nis2.js
│ ├── complianceFactory.js
│ ├── framework.js
│ ├── reports.js
│ ├── audit.js
│ ├── platformModules.js
│ └── menuPermissions.js
├── seeds/
│ └── frameworkSeed.js
├── uploads/ # PDFs carregados pelos utilizadores
└── public/
├── index.html
├── app.js
├── styles.css
├── manual-utilizador.html
├── manual-tecnico.html
└── manual-exportacao.html
A plataforma utiliza MySQL como sistema de gestão de base de dados relacional. A conexão é feita com mysql2/promise através de variáveis separadas de ambiente.
DB_HOST=localhost DB_PORT=3306 DB_NAME=gvffpt_grc_gvff DB_USER=gvffpt_grcgvffusr DB_PASSWORD=******** JWT_SECRET=******** PORT=5000
Armazena os utilizadores do sistema com credenciais e roles.
| Coluna | Tipo | Descrição |
|---|---|---|
| id | INT AUTO_INCREMENT PK | Identificador único |
| VARCHAR | Email do utilizador | |
| password_hash | VARCHAR | Hash bcrypt da password |
| name | VARCHAR | Nome do utilizador |
| role | VARCHAR | platform_owner, super_admin, admin, revisor, user |
| status | VARCHAR | active / inactive |
| phone_number | VARCHAR | Telefone |
| mfa_enabled | TINYINT(1) | MFA ativo |
Países com informação de transposição NIS2 e maturidade.
| Coluna | Tipo | Descrição |
|---|---|---|
| id | INT AUTO_INCREMENT PK | Identificador |
| name, code | VARCHAR | Nome e código do país |
| region | VARCHAR | Região (EU/UE ou outra) |
| is_eu | TINYINT(1) | Indicador de UE |
| transposition_status | VARCHAR | Estado de transposição |
| implementation_phase | VARCHAR | Fase de implementação |
| nis2_compatible | VARCHAR | Compatibilidade fora da UE |
| maturity_score | INT | Pontuação de maturidade |
Entidades com classificação, contactos e scope operacional.
| Coluna | Tipo | Descrição |
|---|---|---|
| id | INT AUTO_INCREMENT PK | Identificador |
| name | VARCHAR | Nome da entidade |
| type | VARCHAR | Tipo |
| sector, subsector | VARCHAR | Sector e subsetor |
| nis2_classification | VARCHAR | Classificação NIS2 |
| country_id | INT | País associado |
| scope | VARCHAR | cp ou local |
| ip_addresses, fqdns | LONGTEXT | Dados técnicos em texto |
Fornecedores com criticidade, risco e requisitos de segurança.
| Coluna | Tipo | Descrição |
|---|---|---|
| id | INT AUTO_INCREMENT PK | Identificador |
| cod | VARCHAR | Código auto-gerado (SUP-###) |
| supplier_name | VARCHAR | Nome do fornecedor |
| supplier_type | VARCHAR | Tipo |
| criticality | VARCHAR | Critical / High / Medium / Low |
| risk_classification | VARCHAR | Classificação de risco |
| security_requirements | LONGTEXT | JSON serializado |
| country_id | INT | País |
Ativos com informação técnica e de segurança.
| Coluna | Tipo | Descrição |
|---|---|---|
| id | INT AUTO_INCREMENT PK | Identificador |
| cod | VARCHAR | Código auto-gerado (AST-###) |
| name | VARCHAR | Nome do ativo |
| asset_type | VARCHAR | Tipo de ativo |
| scope | VARCHAR | governance ou local |
| entity_id, country_id | INT | Associações |
| ip_address, mac_address, software_version | VARCHAR | Detalhes técnicos |
| mfa_enabled, encryption_* | TINYINT(1) | Controlos de segurança |
Registo de riscos com avaliação inerente e residual.
| Coluna | Tipo | Descrição |
|---|---|---|
| id | INT AUTO_INCREMENT PK | Identificador |
| entity_id | INT | Entidade associada |
| title | VARCHAR | Título do risco |
| likelihood, impact | INT | Probabilidade e impacto (1-5) |
| risk_level, risk_score | VARCHAR / INT | Nível e pontuação do risco |
| residual_likelihood, residual_impact | INT | Risco residual |
| residual_risk_level, residual_risk_score | VARCHAR / INT | Nível e pontuação residual |
Documentos com versionamento, refs e upload de PDF.
| Coluna | Tipo | Descrição |
|---|---|---|
| id | INT AUTO_INCREMENT PK | Identificador |
| code | VARCHAR | Código auto-gerado (DOC-###) |
| title | VARCHAR | Título do documento |
| doc_type | VARCHAR | Tipo |
| revision | VARCHAR | Revisão |
| status | VARCHAR | draft / review / approved / obsolete |
| framework_refs, doc_refs | LONGTEXT | JSON serializado |
| file_path, file_name | VARCHAR | Ficheiro PDF anexo |
O sistema utiliza o padrão scope/items para cada framework.
| Framework | Tabela de Scopes | Tabela de Items |
|---|---|---|
| ISO 27001 | iso27001_scopes | iso27001_items |
| NIS2 | nis2_scopes | nis2_items |
| ISO 27002 | iso27002_scopes | iso27002_items |
| ENS | ens_scopes | ens_items |
| GDPR | gdpr_scopes | gdpr_items |
| Tabela | Propósito |
|---|---|
| platform_modules | Módulos ativáveis da plataforma |
| role_menu_permissions | Permissões de menu por role |
| audit_logs | Registo de auditoria |
| framework_items | Biblioteca de referência oficial |
| user_countries | Associação utilizadores-países |
Todos os endpoints, exceto autenticação, requerem o header Authorization: Bearer <token>.
| Método | Endpoint | Descrição |
|---|---|---|
| POST | /api/auth/login | Login (retorna token JWT) |
| POST | /api/auth/register | Registo de novo utilizador |
| GET | /api/auth/me | Utilizador autenticado atual |
| Recurso | Base URL | Operações | Módulo |
|---|---|---|---|
| Utilizadores | /api/users | GET, POST, PUT, DELETE | users |
| Entidades | /api/entities | GET, POST, PUT, DELETE | entities |
| Países | /api/countries | GET, POST, PUT, DELETE | countries |
| Fornecedores | /api/suppliers | GET, POST, PUT, DELETE | suppliers |
| Ativos | /api/assets | GET, POST, PUT, DELETE | assets |
| Riscos | /api/risks | GET, POST, PUT, DELETE | risks |
| Documentos | /api/documents | GET, POST, PUT, DELETE | documents |
| Framework | Base URL | Módulo |
|---|---|---|
| ISO 27001 | /api/iso27001 | compliance_iso27001 |
| NIS2 | /api/nis2 | compliance_nis2 |
| ISO 27002 | /api/iso27002 | compliance_iso27002 |
| ENS | /api/ens | compliance_ens |
| GDPR | /api/gdpr | compliance_gdpr |
| Endpoint | Descrição |
|---|---|
/api/dashboard | Dados do dashboard principal |
/api/reports/governance | Relatório Governance |
/api/reports/country | Relatório por país |
/api/audit | Log de auditoria |
/api/platform-modules | Gestão de módulos |
/api/menu-permissions | Permissões de menu |
/api/framework | Biblioteca de referência oficial |
/health | Health check |
O sistema utiliza tokens JWT com as seguintes características:
{ id, email, role }JWT_SECRET
1. Cliente envia POST /api/auth/login { email, password }
2. Servidor valida credenciais com bcrypt.compare()
3. Se válido, gera JWT
4. Cliente armazena token no browser
5. Pedidos seguintes incluem Authorization: Bearer <token>
6. Middleware authenticate() valida e descodifica o token
7. Dados do utilizador ficam disponíveis em req.user
| Role | Nível | Descrição |
|---|---|---|
| platform_owner | Mais alto | Acesso total + gestão de módulos |
| super_admin | Elevado | Administração total da plataforma |
| admin | Operacional | Gestão de dados |
| revisor | Leitura/revisão | Sem eliminação |
| user | Básico | Acesso limitado |
Nota: platform_owner, super_admin e admin não ficam limitados por país. Os restantes podem ser filtrados pela tabela user_countries.
A plataforma possui módulos que podem ser ativados ou desativados ao nível da plataforma.
| Módulo | Chave |
|---|---|
| Dashboard Overview | overview |
| Countries | countries |
| Entities | entities |
| Suppliers | suppliers |
| Assets | assets |
| Risks | risks |
| Compliance ISO 27001 | compliance_iso27001 |
| Compliance NIS2 | compliance_nis2 |
| Compliance ISO 27002 | compliance_iso27002 |
| Compliance ENS | compliance_ens |
| Compliance GDPR | compliance_gdpr |
| Documents | documents |
| Reports | reports |
| Audit | audit |
| Users | users |
| Framework Annex A | fw_annexa |
| Framework Clauses | fw_clauses |
| Framework NIS2 | fw_nis2 |
| Framework ISO 27002 | fw_iso27002 |
| Framework ENS | fw_ens |
| Framework GDPR | fw_gdpr |
Atenção: Quando um módulo está desativado, pode desaparecer da interface e o respetivo acesso via API fica bloqueado.
? para evitar SQL injection| Variável | Descrição | Obrigatória |
|---|---|---|
DB_HOST | Host MySQL | Sim |
DB_PORT | Porta MySQL | Sim |
DB_NAME | Nome da base de dados | Sim |
DB_USER | Utilizador MySQL | Sim |
DB_PASSWORD | Password MySQL | Sim |
JWT_SECRET | Secret JWT | Sim |
PORT | Porta da aplicação | Não |
Importante: Em produção, utilize sempre um JWT_SECRET forte e não mantenha segredos hardcoded no código.
Entidade → Scope → Items Cada item tem: - item_type - item_ref - item_title - impl_status
not_implementedon_goingimplementedPercentagem = ((implemented + on_going * 0.5) / total) * 100 - implemented = 100% - on_going = 50% - not_implemented = 0%
ISO 27002, ENS e GDPR utilizam um factory genérico (ComplianceScopeFactory + complianceFactory.js) para reduzir duplicação de código.
O frontend é uma SPA em vanilla JavaScript com as seguintes características:
public/public/index.html - estrutura principal da SPApublic/app.js - lógica frontendpublic/styles.css - estilos da interfacepublic/manual-*.html - manuais estáticosnpm install.env / variáveis da app Nodenpm install# Instalar dependências npm install # Iniciar servidor npm start # Script start node index.js
Nota: Esta aplicação não requer npm run build. O backend corre diretamente com node index.js.
No arranque, a aplicação pode garantir estrutura base da plataforma, incluindo:
GVFF GRC Platform - Manual Técnico
Documento atualizado para a versão em produção