Pular para conteúdo

Documento de Arquitetura

Introdução

   A finalidade deste documento é apresentar de forma geral os aspectos mais significativos da arquitetura do projeto MeasureSoftwareGram.

   Neste documento são apresentados os seguintes pontos: os serviços e as tecnologias utilizadas em cada parte do projeto, modelo de arquitetura seguido atualmente e as motivações que guiam essas escolhas.

   Através desse documento, é possível obter um melhor entendimento da arquitetura do projeto, permitindo ao leitor a compreensão do funcionamento do sistema e as abordagens utilizadas para o seu desenvolvimento.

Visão Geral

A arquitetura do projeto está documentada seguindo o modelo 4+1 de Philippe Kruchten, que organiza a descrição arquitetural em cinco perspectivas complementares:

  • Visão Lógica: Principais componentes do sistema, suas responsabilidades e como se comunicam;
  • Visão de Processo: Aspectos de concorrência, distribuição e comunicação entre processos em tempo de execução;
  • Visão de Desenvolvimento: Organização do código-fonte em módulos e pacotes;
  • Visão Física: Mapeamento dos componentes de software nos nós de infraestrutura;
  • Visão de Casos de Uso (+1): Cenários-chave que exercitam e validam as demais visões.

Além das visões arquiteturais, este documento também apresenta o modelo de dados do sistema e as metas e restrições de arquitetura.

Rich Picture

   O rich picture abaixo apresenta, de forma informal, o ecossistema do MeasureSoftGram: quem são os atores (desenvolvedores, gestores de qualidade, pipelines de CI e agentes de IA), quais sistemas eles usam e como esses sistemas se conectam. Ele complementa — sem substituir — o diagrama técnico da seção Visão Lógica, mais abaixo, que detalha componentes e protocolos.

Rich Picture - Visão Geral do MeasureSoftGram

Representação de Arquitetura

Linguagens

  • Python: Uma linguagem de programação poderosa, flexível e de fácil aprendizado, que é amplamente utilizada devido à sua legibilidade, produtividade e capacidade de integração com outros sistemas. [1]

  • JavaScript/TypeScript: Uma linguagem de programação que permite a você implementar itens complexos em páginas web, como conteúdos que se atualiza em um intervalo de tempo, mapas interativos ou gráficos 2D/3D animados, etc. É a terceira camada do bolo das tecnologias padrões da web (HTML, CSS e Javascript). TypeScript por sua vez é uma linguagem de programação fortemente tipada que se baseia em JavaScript, oferecendo melhores ferramentas em qualquer escala. [2] [3]

Tecnologias

  • React: Uma biblioteca utilizada para desenvolvimento de interfaces de usuário nativas e web. Essa ferramenta proporciona o desenvolvimento de sites com mais facilidade e rapidez em relação aos tradicionais HTML, CSS e JavaScript. [4]

  • Next.js: Um framework de código aberto criado pela Vercel que estende os recursos do React. Com essa ferramenta, é possível usufruir de recursos como geração de páginas estáticas e renderização do lado do servidor, otimizando o desenvolvimento Web. [5]

  • Django: Um framework web Python de alto nível que incentiva o desenvolvimento rápido e um design limpo e pragmático. Construído por desenvolvedores experientes, ele cuida de grande parte do incômodo do desenvolvimento da Web, para que você possa se concentrar em escrever seu aplicativo sem precisar reinventar a roda. É gratuito e de código aberto. [6]

  • Jupyter Notebook: Um aplicativo baseado na Web para a criação de documentos que combinam código (Python) ao vivo com texto narrativo, equações e visualizações. [7]

  • PyPI: O Python Package Index é um repositório para armazenar pacotes de código escritos na linguagem de programação Python. [8]

Gerenciamento de pacotes e runtime

   A partir do semestre 2026.1 o time modernizou o ferramental de runtime e pacotes do Service e do Front — as decisões abaixo estão registradas nos respectivos pull requests de modernização da stack Docker (PR #1 do Service e PR #5 do Front). As bibliotecas Python publicadas no PyPI (Core, Parser e CLI) não passaram por essa modernização: continuam em pip + requirements.txt, testadas via tox, com requires-python = ">=3.9" no pyproject.toml e sem Dockerfile/docker-compose.yml próprio — conferido contra a branch develop dos três repositórios.

  • uv: gerenciador de pacotes Python utilizado apenas no Service, em substituição ao pip e ao poetry. Core, Parser e CLI seguem em pip.
  • pnpm: gerenciador de pacotes JavaScript utilizado no Front, em substituição ao npm.
  • Python 3.12: versão fixada apenas no Service, via pyproject.toml e imagem Docker oficial. Core, Parser e CLI declaram requires-python = ">=3.9" e não fixam uma versão específica.
  • Node 20 LTS: versão fixada no Front, via .nvmrc e imagem Docker oficial.
  • Imagens Docker com tags fixas (como python:3.12-slim ou postgres:18-alpine), em vez de :latest — aplicável aos containers do Service, Front, Grafana, banco e proxy; Core, Parser e CLI não têm imagem Docker própria, por serem bibliotecas/CLI distribuídas via PyPI.
  • Docker Compose v2 com compose watch, em substituição ao docker-compose v1 — usado no Service.

Banco de dados

  • PostgreSQL 18: atualização do PG12/14 herdado para a versão estável mais recente do PostgreSQL, com tag fixada (postgres:18-alpine). Registrada no PR de modernização da stack Docker do Service (#1). [9]

Containers e imagens (estrutura evoluída)

   O Service evoluiu de um único container Django+Postgres para uma stack com cinco containers, orquestrados por dois arquivos docker compose distintos: um para desenvolvimento (raiz do repositório) e um para produção (deploy/docker-compose.prod.yml).

Container Imagem (dev) Imagem (produção) Observações
db postgres:18-alpine postgres:18-alpine volume nomeado service_postgres_data; publica 5432 só em 127.0.0.1 no dev, sem publicar porta em produção
service build local (Dockerfile multi-stage: builder com uv + runtime python:3.12-slim-bookworm) ${DOCKERHUB_USERNAME}/service:${SERVICE_IMAGE_TAG} (pull do DockerHub, buildada no CI) compose watch sincroniza ./src em dev; produção só puxa a imagem, não builda
front build local (node:20-alpine, pnpm) ${DOCKERHUB_USERNAME}/front:${FRONT_IMAGE_TAG} variáveis SERVICE_URL, GITHUB_CLIENT_ID etc. entram como build-arg no CI
grafana grafana/grafana:latest grafana/grafana:latest plugin volkovlabs-echarts-panel; volume nomeado grafana_data; provisionamento via bind mount de grafana/provisioning e grafana/dashboards
proxy — (só existe em produção) nginx:1.27-alpine único container que publica porta no host (80:80); ver seção "Nginx e Grafana" logo abaixo

   Todos os containers (exceto o proxy) ficam em uma rede bridge própria chamada msgram, isolada do host — db e service não publicam porta nenhuma em produção, só são alcançáveis pelos outros containers da mesma rede. Healthchecks (pg_isready no banco, curl no /swagger/ do Service) controlam a ordem de subida via depends_on: condition: service_healthy. Segredos (tokens, senhas de banco e do Grafana) vivem em arquivos .env dentro de deploy/env-vars/, nunca versionados no repositório.

Nginx e Grafana (integração)

   Em produção existe um proxy nginx interno à stack (container proxy, imagem nginx:1.27-alpine), que fica atrás de um proxy externo da máquina (openresty, fora do escopo deste compose) responsável por terminar o domínio e o TLS. O nginx interno publica a porta 80 do host e roteia por caminho:

Rota Destino Observação
/api/, /swagger/, /admin/, /static/ service:8080 backend Django (DRF)
/grafana/ grafana:3000 com upgrade de conexão para WebSocket (necessário para o Grafana Live)
/ front:3000 frontend Next.js

   O Grafana roda como container independente do ciclo de vida do Django, com dashboards de qualidade provisionados automaticamente a partir de arquivos JSON (grafana/dashboards/*.json) e um datasource Postgres que consulta diretamente o mesmo banco do Service — sem passar pela API REST. Para permitir a incorporação via iframe no Frontend e no Plugin VS Code, o Grafana é configurado com acesso anônimo somente-leitura (GF_AUTH_ANONYMOUS_ENABLED, papel Viewer) e GF_SECURITY_ALLOW_EMBEDDING=true.

   Como o Grafana fica aberto para leitura anônima, o controle de acesso por produto/repositório é feito no lado do Service, por um app Django dedicado, o grafana_proxy. Ele expõe dois endpoints autenticados:

  • GET /api/v1/grafana/dashboards/ — lista os dashboards disponíveis;
  • GET /api/v1/grafana/dashboard/{uid}/?product_id=...&repository_id=... — valida se o usuário tem permissão sobre aquele produto/repositório (CanAccessProduct, CanAccessDashboard) e devolve a URL pública do dashboard já filtrada, pronta para ser usada como src do iframe.

   Ou seja: o Frontend e o Plugin VS Code nunca chamam o Grafana diretamente para autorização — sempre pedem a URL ao grafana_proxy do Service, e só então carregam essa URL num iframe.

Serviços

  • CLI Abreviação de "interface de linha de comando". Este é um programa que permite aos usuários criar comandos para funções específicas passando instruções para o computador. Roda inteiramente local: usa a biblioteca msgram-parser (Parser) para interpretar os dados de entrada e a msgram_core (Core) para calcular o modelo de qualidade, sem se comunicar com o Service pela rede.

  • Frontend Web Esta é a aplicação interface web que permite aos usuários analisar e acompanhar os produtos pelo navegador. Também embute, via iframe, os dashboards do Grafana obtidos através do Service.

  • Service Este é o programa responsável por se comunicar com a aplicação Frontend Web e fornecer todos os dados necessários para a aplicação web. Importa Core (msgram_core) como biblioteca Python para calcular características, subcaracterísticas, medidas e o TSQMI dentro do próprio processo Django — não há chamada de rede entre Service e Core.

  • Core Biblioteca Python (publicada no PyPI como msgram_core) que implementa o modelo matemático de qualidade (características, subcaracterísticas, medidas e TSQMI). É consumida diretamente como dependência pelo Service e não roda como um serviço de rede próprio.

  • Parser Biblioteca Python (publicada no PyPI como msgram-parser) com a capacidade de interpretar a estrutura gramatical ou sintática dos dados de entrada, a fim de transformá-los em uma representação interna mais adequada para processamento. É consumida diretamente pela CLI, e não é uma dependência do Service.

  • Github Action Action customizada do Github que permite realizar a análise de um certo repositório. É disparada pelo evento workflow_run ao final do build de CI configurado pelo usuário, e se comunica com o Service via HTTPS para enviar os dados coletados.

  • MCP Server (AI) Servidor Python (biblioteca mcp/FastMCP) que expõe o MeasureSoftGram a clientes de inteligência artificial por meio do protocolo MCP, nos transports streamable-http (/mcp, padrão) e sse (/sse, alternativo, selecionável via MCP_TRANSPORT=sse) — ambos confirmados no código (server.py) e no guia de uso testado pela equipe (docs/manual-de-instalacao/guia-mcp.md). Fica em repositório separado (fga-eps-mds/2026.1-MeasureSoftGram-AI, publicado como imagem measuresoftgram/ai) e se comunica com o Service via HTTP/REST, autenticando-se uma única vez na subida do processo com uma conta de serviço fixa (MSGRAM_USER/MSGRAM_PASSWORD, endpoint accounts/login/) — o token obtido é reutilizado em todas as chamadas das tools, ou seja, o MCP não propaga a identidade de quem está do outro lado do agente de IA. Agentes que só suportam stdio (como o Claude Desktop) precisam de um proxy local (npx mcp-remote, ponte stdiostreamable-http) entre o agente e o servidor.

  • Plugin VS Code Extensão para o Visual Studio Code (fga-eps-mds/2026.1-MeasureSoftGram-Plugin) que leva o painel de qualidade (TSQMI e características), os dashboards do Grafana (embutidos via iframe) e a execução local do workflow da Github Action (via Docker + nektos/act) para dentro do editor. Autentica-se no Service via token (Authorization: Token <token>), guardado no Secret Storage do VS Code, e nunca chama o Grafana diretamente — sempre por meio dos endpoints de proxy do Service.

  • Grafana Ferramenta de terceiros usada para os dashboards analíticos de qualidade. Roda como container próprio, com dashboards provisionados via arquivos JSON e um datasource que consulta diretamente o mesmo PostgreSQL do Service (sem passar pela API Django). O Service expõe um app grafana_proxy que autoriza o acesso por produto/repositório e resolve as URLs dos dashboards antes de repassá-las ao Frontend Web e ao Plugin VS Code.


Visões Arquiteturais (4+1)

Visão Lógica

   A visão lógica descreve os principais componentes do sistema, suas responsabilidades e como se comunicam entre si. O diagrama abaixo apresenta os componentes do MeasureSoftGram, as tecnologias utilizadas em cada um e as relações entre eles. Core (msgram_core) é importado como biblioteca Python dentro do próprio processo do Service, e Parser (msgram-parser) é uma biblioteca consumida apenas pela CLI — nenhum dos dois roda como processo de rede próprio. A CLI, por sua vez, não chama o Service pela rede: ela calcula e grava os resultados localmente.

flowchart TB
    subgraph Cliente["Clientes"]
        FE["💻 Frontend Web<br/>(React + Next.js)"]
        VSC["🧩 Plugin VS Code<br/>(TypeScript)"]
        AI["🧠 Cliente de IA<br/>(Claude Desktop / Code)"]
    end

    subgraph Container["Ambiente containerizado (rede docker `msgram`)"]
        direction TB
        RP["🐳 nginx<br/>(reverse proxy interno)"]
        SVC["🐳 Service<br/>(Django + Core embutido como lib)"]
        DB[("🐘 PostgreSQL 18")]
        GF["🐳 Grafana<br/>(dashboards)"]
        RP -->|"/api /swagger /admin /static"| SVC
        RP -->|"/grafana"| GF
        SVC --> DB
        GF -->|"SQL direto (mesmo banco)"| DB
        SVC <-->|"grafana_proxy: HTTP<br/>(autoriza + resolve URL)"| GF
    end

    CLI["⌨️ CLI<br/>(usa lib Parser + lib Core, local)"]
    Action["🤖 GitHub Action<br/>(TypeScript, workflow_run)"]
    MCP["🔌 MCP Server / AI<br/>(Python, repo separado)"]

    FE <-->|HTTPS| RP
    VSC <-->|"HTTPS (token)"| RP
    VSC -.->|"iframe (URL resolvida pelo Service)"| GF
    FE -.->|"iframe (URL resolvida pelo Service)"| GF
    AI <-->|MCP| MCP
    MCP <-->|HTTP/REST| RP
    Action <-->|HTTPS| RP

    classDef cliente fill:#e8f8e8,stroke:#2a8c3a,stroke-dasharray:5 5
    classDef container fill:#f0e8f8,stroke:#6a3a8c,stroke-dasharray:5 5
    classDef novo fill:#fff4d6,stroke:#b07c00,stroke-width:2px
    class Cliente cliente
    class Container container
    class MCP,VSC,GF novo

Visão de Processo

   Esta visão descreve os aspectos de concorrência, distribuição e comunicação entre processos em tempo de execução. O MeasureSoftGram não usa fila de mensagens nem broker (não há Celery, Redis ou RabbitMQ na stack) — a comunicação entre os processos de rede é majoritariamente síncrona (request/response), e a única concorrência existente roda dentro do próprio processo do Service.

Processos de longa duração (sempre ativos)

Processo Natureza Comunicação
Service (gunicorn, WSGI síncrono) Múltiplos workers (GUNICORN_WORKERS, padrão 3), modelo prefork — cada worker é um processo OS separado HTTP/REST, síncrono
Grafana Container independente, ciclo de vida próprio Consulta o PostgreSQL diretamente via SQL; conversa com o Service via grafana_proxy (HTTP) só para autorização
MCP Server (AI) Container HTTP de longa duração, repositório separado Recebe chamadas MCP do agente de IA e as traduz em chamadas HTTP síncronas ao Service

Concorrência dentro do Service (in-process, sem fila)

   Existem exatamente dois mecanismos de concorrência, ambos internos ao processo Django — não há execução distribuída:

  1. Job agendado diário (APScheduler). O app releases registra, no boot de cada worker (AppConfig.ready()), um BackgroundScheduler do django-apscheduler que roda get_releases_and_create_results todo dia à meia-noite (America/Sao_Paulo), calculando as características das releases que terminam naquele dia. Como o gunicorn sobe múltiplos workers (processos separados), cada um tentaria iniciar seu próprio agendador — para evitar duplicação, o primeiro worker a conseguir um advisory lock do Postgres (pg_try_advisory_lock) vira o "líder" e é o único que efetivamente agenda o job; os demais detectam o lock ocupado e não agendam nada.
  2. Thread "fire-and-forget" na criação de repositório. Ao cadastrar um repositório pela API, o Service dispara uma threading.Thread (daemon=True) que tenta acionar o workflow de GitHub Actions do próprio usuário (via GitHub API, com o token OAuth armazenado) e, se isso falhar, gera dados de qualidade sintéticos localmente para a interface não ficar vazia. Não há fila, persistência do job nem retentativa: se o worker reiniciar no meio da execução, a thread é perdida silenciosamente.
sequenceDiagram
    participant CI as Build de CI do usuário
    participant Action as GitHub Action
    participant Nginx as nginx
    participant Svc as Service (worker gunicorn)
    participant Core as Core (lib, in-process)
    participant DB as PostgreSQL
    participant Sched as APScheduler (líder eleito)

    CI->>Action: evento workflow_run (build concluído)
    Action->>Nginx: HTTPS POST métricas coletadas
    Nginx->>Svc: proxy /api/
    Svc->>Core: calculate_characteristics() (chamada de função, mesmo processo)
    Core-->>Svc: valores calculados
    Svc->>DB: grava CollectedMetric/CalculatedMeasure/...
    Svc-->>Action: 200 OK

    Note over Sched,DB: à meia-noite (cron), independente da requisição acima
    Sched->>DB: pg_try_advisory_lock (só o worker líder segue)
    Sched->>DB: busca releases que terminam hoje
    Sched->>Core: calculate_characteristics() por repositório
    Sched->>DB: grava CalculatedCharacteristic

Processos efêmeros / orientados a evento

  • GitHub Action: cada execução é um runner novo (hospedado no GitHub ou simulado localmente via nektos/act, usado pelo Plugin VS Code), que sobe, roda e termina — disparado pelo evento workflow_run ao final do build do usuário.
  • CLI: comando único que roda até concluir e encerra; não abre conexão de rede com o Service (usa as bibliotecas Parser e Core localmente e grava o resultado em arquivo).

Visão de Desenvolvimento

   A visão de desenvolvimento apresenta a organização do código-fonte em módulos e pacotes para cada repositório do projeto.

Web

Diagrama de pacotes - Web

Core

Diagrama de pacotes - Core

CLI

Diagrama de pacotes - CLI

Parser

Diagrama de pacotes - Parser

Action

Diagrama de pacotes - Action

Plugin VS Code

   O Plugin (repositório fga-eps-mds/2026.1-MeasureSoftGram-Plugin) é dividido em dois projetos: o código do host da extensão (src/, Node/TypeScript) e uma aplicação React/Vite independente (webview-ui/) que é compilada e empacotada dentro da extensão para renderizar a interface dos painéis. Os dois só se comunicam por postMessage/acquireVsCodeApi — a webview-ui nunca chama a API do Service diretamente.

flowchart TB
    subgraph ExtHost["Extension Host (src/)"]
        EXT["extension.ts<br/>(entrypoint)"]
        ACT["activator.ts<br/>(wiring)"]
        SB["statusbar/<br/>MsgramStatusBar"]
        UTIL["utilities/"]
        subgraph Panels["panels/"]
            BASE["measureSoftGramBase.ts<br/>(settings, roteador de mensagens,<br/>chamadas ao Grafana)"]
            PANEL["measureSoftGramPanel.ts<br/>(WebviewPanel)"]
            SIDE["measureSoftGramSidebar.ts<br/>(WebviewViewProvider)"]
        end
        API["services/msgramApi.ts<br/>(cliente HTTP)"]
    end

    subgraph WebviewApp["webview-ui/ (React + Vite, projeto separado)"]
        APP["App.tsx"]
        DASH["DashboardView.tsx"]
        GRAF["GrafanaView.tsx (iframe)"]
        SET["SettingsView.tsx"]
        ACTIONV["ActionView.tsx"]
    end

    EXT --> ACT --> SB
    ACT --> PANEL
    ACT --> SIDE
    PANEL --> BASE
    SIDE --> BASE
    BASE --> UTIL
    BASE --> API
    BASE -->|"carrega build + postMessage"| APP
    APP --> DASH
    APP --> GRAF
    APP --> SET
    APP --> ACTIONV
    API -->|"HTTPS, Authorization: Token"| SVC[("Service")]
    GRAF -.->|"iframe src = grafana_url"| GF[("Grafana")]

   Ponto de atenção de manutenção: MeasureSoftGramPanel e MeasureSoftGramSidebar herdam de MeasureSoftGramBase, mas duplicam a lógica de salvar/rodar o workflow da Action (save_action/run_action) em vez de compartilhá-la.

MCP Server (AI)

   O repositório fga-eps-mds/2026.1-MeasureSoftGram-AI (pacote msgram_mcp, distribuído em src/) segue um padrão simples de registro de ferramentas: server.py monta o FastMCP e chama a função register_tools(mcp, client) de cada módulo em tools/, que por sua vez usa o MsgramClient (client.py) — um wrapper fino sobre httpx — para consultar o Service. A autenticação (auth/msgram_auth.py) roda uma única vez, na criação das Settings, e gera o token reaproveitado por todas as tools.

flowchart TB
    subgraph Server["server.py"]
        SET["Settings.from_env()"]
        CREATE["create_server()"]
    end

    AUTH["auth/msgram_auth.py<br/>(login uma vez, gera token)"]
    CLIENT["client.py<br/>MsgramClient (httpx)"]

    subgraph Tools["tools/ (register_tools(mcp, client) por módulo)"]
        T1["organizations.py"]
        T2["repositories.py"]
        T3["releases.py"]
        T4["goals.py"]
        T5["supported_characteristics.py"]
        T6["supported_measures.py"]
        T7["supported_metrics.py"]
        T8["balance_matrix.py"]
        T9["latest_values.py"]
        T10["historical_values.py"]
        T11["entity_relationship_tree.py"]
    end

    SET --> AUTH
    CREATE --> CLIENT
    CREATE --> Tools
    T1 & T2 & T3 & T4 & T5 & T6 & T7 & T8 & T9 & T10 & T11 --> CLIENT
    CLIENT -->|"HTTP/REST, Authorization: Token"| SVC[("Service")]

   Ponto de atenção: como o token é obtido uma única vez com uma conta de serviço fixa (MSGRAM_USER/MSGRAM_PASSWORD), todas as chamadas das tools ao Service acontecem com essa identidade — o MCP não tem hoje um mecanismo de repassar a identidade do usuário do agente de IA para a autorização no Service.

Grafana

   O Grafana não é um pacote de código do MeasureSoftGram — é uma ferramenta de terceiros provisionada por arquivos de configuração. Por isso, em vez de um diagrama de pacotes, documentamos a estrutura de provisionamento (dentro do repositório do Service):

grafana/
├── dashboards/                        # dashboards provisionados (JSON)
│   ├── dashboard-visao-geral.json
│   ├── dashboard-evolucao.json
│   ├── dashboard-ecg-tsqmi.json
│   └── dashboard-saude-qualidade-repositorio.json
├── provisioning/
│   ├── datasources/measuresoftgram.yml   # datasource Postgres (aponta pro mesmo banco do Service)
│   └── dashboards/provider.yml           # provider que carrega os JSONs acima automaticamente
└── seed_planejado_vs_realizado.sql       # dados de apoio para os dashboards

Visão Física

   Um diagrama de implantação especifica os construtos que podem ser usados para definir a arquitetura de execução de sistemas e a atribuição de artefatos de software aos elementos do sistema. Para descrever um site, por exemplo, um diagrama de implantação mostraria quais componentes de hardware ("nós") existem (por exemplo, um servidor web, um servidor de aplicação e um servidor de banco de dados), quais componentes de software ("artefatos") rodam em cada nó e como as diferentes peças estão conectadas.

Os nós aparecem como caixas tridimensionais, e os componentes alocados a cada nó aparecem como retângulos dentro das caixas. Os nós podem ter subnós, que aparecem como caixas aninhadas. Um único nó em um diagrama de implantação pode representar conceitualmente vários nós físicos, como um cluster de servidores de banco de dados.

Existem dois tipos de nós:

  • Nó de Dispositivo (device)
  • Nó de Ambiente de Execução (execution environment)

Os nós de dispositivo são recursos físicos de computação com memória de processamento e serviços para executar software, como computadores típicos ou telefones celulares. Um nó de ambiente de execução é um recurso de computação de software que roda dentro de um nó externo e que, por sua vez, fornece um serviço para hospedar e executar outros elementos de software executáveis.

Diagrama legado

A imagem abaixo (diagrama_implantacao.png) é anterior à stack atual e não reflete os serviços descritos nesta seção (Grafana, nginx interno, volumes nomeados). Fica mantida como registro histórico; o diagrama vigente é o Mermaid logo em seguida.

Diagrama de Implantação (legado)

   O diagrama abaixo reflete a topologia real de produção, descrita em deploy/docker-compose.prod.yml do repositório Service. Um nó de dispositivo (a máquina/VM de produção) hospeda um proxy externo (openresty, fora do escopo do MeasureSoftGram, responsável por TLS e pelo domínio) e um nó de ambiente de execução Docker com a rede msgram, dentro da qual rodam os containers da aplicação. O MCP Server (AI) e o Plugin VS Code são nós de execução independentes, fora dessa máquina.

flowchart TB
    subgraph Internet["Clientes"]
        Browser["Navegador<br/>(Frontend Web)"]
        VSCode["VS Code<br/>+ Plugin"]
        AIClient["Claude Desktop / Code"]
        CIRunner["Runner de CI<br/>(GitHub-hosted ou act)"]
    end

    subgraph Box["Nó físico de produção (VM/servidor)"]
        OpenResty["openresty<br/>(proxy externo, TLS + domínio)"]

        subgraph Docker["Docker — rede bridge `msgram`"]
            NginxC["proxy<br/>nginx:1.27-alpine<br/>publica :80"]
            ServiceC["service<br/>imagem própria (DockerHub)<br/>gunicorn, 3 workers"]
            FrontC["front<br/>imagem própria (DockerHub)"]
            GrafanaC["grafana<br/>grafana/grafana:latest"]
            DbC["db<br/>postgres:18-alpine"]
            VolPg[("volume:<br/>service_postgres_data")]
            VolGf[("volume:<br/>grafana_data")]

            NginxC --> ServiceC
            NginxC --> FrontC
            NginxC --> GrafanaC
            ServiceC --> DbC
            GrafanaC --> DbC
            ServiceC <--> GrafanaC
            DbC --- VolPg
            GrafanaC --- VolGf
        end

        OpenResty --> NginxC
    end

    subgraph AIBox["Nó de execução — MCP Server"]
        MCPC["measuresoftgram/ai<br/>(container próprio, porta 8000)"]
    end

    Browser -->|HTTPS| OpenResty
    VSCode -->|"HTTPS (token)"| OpenResty
    CIRunner -->|"HTTPS (workflow_run)"| OpenResty
    AIClient -->|MCP| MCPC
    MCPC -->|HTTP/REST| OpenResty

   Em desenvolvimento a topologia é mais simples: não há proxy nginx nem openresty — cada container publica sua porta direto no host (service:8080, grafana:5000→3000, banco só em 127.0.0.1:5432), e o código do Service é sincronizado por compose watch em vez de reconstruir a imagem a cada mudança.


Visão de Casos de Uso

   O time do MeasureSoftGram documenta requisitos como histórias de usuário (backlog em docs/produto/planejado-realizado.md, identificadas por US-XXX), não como casos de uso UML. Esta seção deriva os casos de uso a partir dessas histórias já entregues/planejadas, agrupados pelos atores que de fato aparecem no código e na documentação do produto.

Atores

Ator Descrição
Desenvolvedor / dono de repositório Configura produtos, repositórios, releases e metas; consome dados de qualidade pelo Frontend, CLI ou Plugin VS Code
Administrador de organização Administra uma Organization (campo admin), gerencia membros e tokens
Pipeline de CI (GitHub Actions) Ator de sistema — dispara a análise automaticamente ao final do build (workflow_run)
Agente de IA (via MCP) Usuário interagindo por Claude Desktop/Code, consultando dados de qualidade em linguagem natural

Diagrama de casos de uso

flowchart LR
    Dev(["👤 Desenvolvedor"])
    Admin(["👤 Admin de Organização"])
    CI(["🤖 Pipeline de CI"])
    AIAgent(["🧠 Agente de IA"])

    subgraph UC1["Autenticação e Organização"]
        uc1(("Autenticar via GitHub"))
        uc2(("Gerenciar sessão / logout"))
        uc3(("Administrar organização e membros"))
    end

    subgraph UC2["Configuração de Produto"]
        uc4(("Cadastrar produto e repositório"))
        uc5(("Definir metas de qualidade"))
        uc6(("Criar release"))
    end

    subgraph UC3["Coleta e Cálculo de Qualidade"]
        uc7(("Executar Action ao final do build"))
        uc8(("Analisar localmente via CLI"))
        uc9(("Calcular características / TSQMI"))
    end

    subgraph UC4["Visualização de Qualidade"]
        uc10(("Ver badge TSQMI do repositório"))
        uc11(("Ver dashboards Grafana"))
        uc12(("Ver painel de qualidade no VS Code"))
    end

    subgraph UC5["Consulta via IA"]
        uc13(("Consultar dados de qualidade via MCP"))
        uc14(("Analisar planejado vs. realizado via IA"))
    end

    Dev --> uc1
    Dev --> uc2
    Dev --> uc4
    Dev --> uc5
    Dev --> uc6
    Dev --> uc8
    Dev --> uc10
    Dev --> uc11
    Dev --> uc12
    Admin --> uc3
    CI --> uc7
    uc7 --> uc9
    uc8 --> uc9
    AIAgent --> uc13
    AIAgent --> uc14

Rastreabilidade com o backlog

Caso de uso História de usuário / origem
Autenticar via GitHub "Autenticação via GitHub (Front)" — Release Major 2
Gerenciar sessão / logout US006 "Gerenciar timeout de sessão"; US007 "Notificação visual ao expirar sessão" (não entregue)
Executar Action ao final do build US003 "Executar a action localmente e dockerizar o sistema"; US004 "Atualizar a publicação da Action no GitHub Marketplace"
Analisar localmente via CLI US008 "Melhorar legibilidade dos textos na CLI"
Ver badge TSQMI do repositório "Alteração do endpoint gerador da badge TSQMI" (Service); "Nova badge TSQMI nas páginas de repositório" (Front)
Ver dashboards Grafana US06 "Grafana" (docs/atas/web.md) — setup/integração e atualização automática dos gráficos
Consultar dados de qualidade via MCP "Criação do servidor MCP do MeasureSoftGram" — Release Minor 2 e Major 2
Criptografar senhas e tokens US005 "Criptografar senhas e tokens do sistema"

Modelo de Dados

Modelo Entidade-Relacionamento (MER)

   O MER textual descreve as entidades, seus atributos e os relacionamentos com cardinalidades do banco de dados do MeasureSoftGram Service. O símbolo # antes de um atributo indica que ele é opcional (nullable) — corresponde a campos declarados com null=True, blank=True no Django. Esta versão foi conferida diretamente contra os arquivos models.py do repositório Service.

Primeira versão, a ser evoluída

Este é o primeiro levantamento completo do MER textual do MeasureSoftGram — cobre o schema atual do Service, mas ainda deve evoluir em revisões futuras (novos atributos, relacionamentos e apps que forem adicionados ao sistema).

Fora do escopo deste MER

Tabelas de infraestrutura de terceiros também existem fisicamente no banco (auth_group, auth_permission, authtoken_token, tabelas do django.contrib.sites e do allauth/allauth.socialaccount, do django_apscheduler), mas não são modelos da aplicação MeasureSoftGram — por isso não são detalhadas aqui.

Entidades

CUSTOM_USER
ORGANIZATION
ORGANIZATION_MEMBERS                          [tabela de junção N:M]
PRODUCT
REPOSITORY
SUPPORTED_METRIC
COLLECTED_METRIC
SUPPORTED_MEASURE
SUPPORTED_MEASURE_METRICS                     [tabela de junção N:M]
CALCULATED_MEASURE
SUPPORTED_SUBCHARACTERISTIC
SUPPORTED_SUBCHARACTERISTIC_MEASURES          [tabela de junção N:M]
CALCULATED_SUBCHARACTERISTIC
SUPPORTED_CHARACTERISTIC
SUPPORTED_CHARACTERISTIC_SUBCHARACTERISTICS   [tabela de junção N:M]
CALCULATED_CHARACTERISTIC
BALANCE_MATRIX
TSQMI
GOAL
RELEASE
RELEASE_CONFIGURATION

   Os apps Django grafana_proxy, entity_trees e math_model estão instalados no Service mas não possuem modelos próprios (conferido em models.py de cada um) — não geram tabelas e por isso não aparecem no MER.

Atributos

CUSTOM_USER(
id [PK], username, email, # first_name, # last_name,
password, # last_login, is_superuser, is_staff, is_active, date_joined,
# github_access_token)
-- groups [M2M -> auth.Group] e user_permissions [M2M -> auth.Permission] herdados do Django, fora do escopo deste MER

ORGANIZATION(
id [PK], name, key, # description,
# admin [FK -> CUSTOM_USER],
# github_org_id, # github_org_name, # avatar_url)
-- membros da organização ficam em ORGANIZATION_MEMBERS (M2M), não em `admin`

ORGANIZATION_MEMBERS(
id [PK],
organization [FK -> ORGANIZATION],
customuser [FK -> CUSTOM_USER])

PRODUCT(
id [PK], name, key, # description,
gaugeRedLimit, gaugeYellowLimit,
organization [FK -> ORGANIZATION])

REPOSITORY(
id [PK], name, key, # url, # platform, # description, imported,
# github_repo_id, # github_full_name,
product [FK -> PRODUCT])

SUPPORTED_METRIC(
id [PK], key, name, metric_type, # description)

COLLECTED_METRIC(
id [PK], value, created_at,
# path, # qualifier, # dynamic_key,
metric [FK -> SUPPORTED_METRIC],
repository [FK -> REPOSITORY])

SUPPORTED_MEASURE(
id [PK], key, name, # description)

SUPPORTED_MEASURE_METRICS(
id [PK],
supportedmeasure [FK -> SUPPORTED_MEASURE],
supportedmetric [FK -> SUPPORTED_METRIC])

CALCULATED_MEASURE(
id [PK], value, created_at,
measure [FK -> SUPPORTED_MEASURE],
repository [FK -> REPOSITORY])

SUPPORTED_SUBCHARACTERISTIC(
id [PK], key, name, # description)

SUPPORTED_SUBCHARACTERISTIC_MEASURES(
id [PK],
supportedsubcharacteristic [FK -> SUPPORTED_SUBCHARACTERISTIC],
supportedmeasure [FK -> SUPPORTED_MEASURE])

CALCULATED_SUBCHARACTERISTIC(
id [PK], value, created_at,
subcharacteristic [FK -> SUPPORTED_SUBCHARACTERISTIC],
repository [FK -> REPOSITORY])

SUPPORTED_CHARACTERISTIC(
id [PK], key, name, # description)

SUPPORTED_CHARACTERISTIC_SUBCHARACTERISTICS(
id [PK],
supportedcharacteristic [FK -> SUPPORTED_CHARACTERISTIC],
supportedsubcharacteristic [FK -> SUPPORTED_SUBCHARACTERISTIC])

CALCULATED_CHARACTERISTIC(
id [PK], value, created_at,
characteristic [FK -> SUPPORTED_CHARACTERISTIC],
repository [FK -> REPOSITORY],
# release [FK -> RELEASE])
-- UNIQUE(repository, release, characteristic)

BALANCE_MATRIX(
id [PK], relation_type,
source_characteristic [FK -> SUPPORTED_CHARACTERISTIC],
target_characteristic [FK -> SUPPORTED_CHARACTERISTIC])
-- UNIQUE(source_characteristic, target_characteristic)

TSQMI(
id [PK], value, created_at,
repository [FK -> REPOSITORY])

GOAL(
id [PK], data, created_at,
created_by [FK -> CUSTOM_USER],
product [FK -> PRODUCT])

RELEASE(
id [PK], release_name, start_at, end_at, created_at, # description,
created_by [FK -> CUSTOM_USER],
product [FK -> PRODUCT],
goal [FK -> GOAL])
-- tabela física chamada explicitamente `releases` (Meta.db_table), não `releases_release`

RELEASE_CONFIGURATION(
id [PK], # name, data, created_at,
product [FK -> PRODUCT])

Relacionamentos

CUSTOM_USER - é_membro_de - ORGANIZATION
   - Descrição: Um usuário pode ser membro de várias organizações, e uma organização pode ter vários membros. Modelada fisicamente pela tabela ORGANIZATION_MEMBERS (campo `members`).
   - Cardinalidade: (N,M)

CUSTOM_USER - administra - ORGANIZATION
   - Descrição: Um usuário pode administrar várias organizações; o campo `admin` é opcional (uma organização pode não ter administrador definido).
   - Cardinalidade: (0,N)

ORGANIZATION - possui - PRODUCT
   - Descrição: Uma organização pode possuir vários produtos, e cada produto pertence a uma única organização.
   - Cardinalidade: (1,N)

PRODUCT - possui - REPOSITORY
   - Descrição: Um produto pode possuir vários repositórios, e cada repositório pertence a um único produto.
   - Cardinalidade: (1,N)

PRODUCT - possui - RELEASE_CONFIGURATION
   - Descrição: Um produto pode ter várias configurações de release ao longo do tempo, e cada configuração pertence a um único produto.
   - Cardinalidade: (1,N)

PRODUCT - possui - GOAL
   - Descrição: Um produto pode ter vários objetivos de qualidade definidos, e cada goal pertence a um único produto.
   - Cardinalidade: (1,N)

PRODUCT - possui - RELEASE
   - Descrição: Um produto pode ter várias releases, e cada release pertence a um único produto.
   - Cardinalidade: (1,N)

CUSTOM_USER - cria - GOAL
   - Descrição: Um usuário pode criar vários goals, e cada goal é criado por um único usuário.
   - Cardinalidade: (1,N)

CUSTOM_USER - cria - RELEASE
   - Descrição: Um usuário pode criar várias releases, e cada release é criada por um único usuário.
   - Cardinalidade: (1,N)

GOAL - referenciado_em - RELEASE
   - Descrição: Um goal pode ser referenciado por várias releases, e cada release referencia um único goal.
   - Cardinalidade: (1,N)

SUPPORTED_METRIC - compoe - SUPPORTED_MEASURE
   - Descrição: Uma métrica suportada pode compor várias medidas, e uma medida pode ser composta por várias métricas.
   - Cardinalidade: (N,M)

SUPPORTED_METRIC - origina - COLLECTED_METRIC
   - Descrição: Uma métrica suportada pode originar vários registros coletados ao longo do tempo.
   - Cardinalidade: (1,N)

REPOSITORY - armazena - COLLECTED_METRIC
   - Descrição: Um repositório pode armazenar vários registros de métricas coletadas ao longo do tempo.
   - Cardinalidade: (1,N)

SUPPORTED_MEASURE - compoe - SUPPORTED_SUBCHARACTERISTIC
   - Descrição: Uma medida suportada pode compor várias subcaracterísticas, e uma subcaracterística pode ser composta por várias medidas.
   - Cardinalidade: (N,M)

SUPPORTED_MEASURE - origina - CALCULATED_MEASURE
   - Descrição: Uma medida suportada pode originar vários registros de valores calculados ao longo do tempo.
   - Cardinalidade: (1,N)

REPOSITORY - armazena - CALCULATED_MEASURE
   - Descrição: Um repositório pode armazenar vários registros de medidas calculadas ao longo do tempo.
   - Cardinalidade: (1,N)

SUPPORTED_SUBCHARACTERISTIC - compoe - SUPPORTED_CHARACTERISTIC
   - Descrição: Uma subcaracterística suportada pode compor várias características, e uma característica pode agrupar várias subcaracterísticas.
   - Cardinalidade: (N,M)

SUPPORTED_SUBCHARACTERISTIC - origina - CALCULATED_SUBCHARACTERISTIC
   - Descrição: Uma subcaracterística suportada pode originar vários registros de valores calculados ao longo do tempo.
   - Cardinalidade: (1,N)

REPOSITORY - armazena - CALCULATED_SUBCHARACTERISTIC
   - Descrição: Um repositório pode armazenar vários registros de subcaracterísticas calculadas ao longo do tempo.
   - Cardinalidade: (1,N)

SUPPORTED_CHARACTERISTIC - origina - CALCULATED_CHARACTERISTIC
   - Descrição: Uma característica suportada pode originar vários registros de valores calculados ao longo do tempo.
   - Cardinalidade: (1,N)

REPOSITORY - armazena - CALCULATED_CHARACTERISTIC
   - Descrição: Um repositório pode armazenar vários registros de características calculadas ao longo do tempo.
   - Cardinalidade: (1,N)

RELEASE - associada_a - CALCULATED_CHARACTERISTIC
   - Descrição: Uma release pode estar associada a vários registros de características calculadas. A associação é opcional (release pode ser nula).
   - Cardinalidade: (1,N)

SUPPORTED_CHARACTERISTIC - relaciona_se_com - SUPPORTED_CHARACTERISTIC
   - Descrição: Uma característica pode se relacionar com várias outras através da BALANCE_MATRIX, e pode ser impactada por várias outras (auto-relacionamento com atributo relation_type: + positivo / - negativo).
   - Cardinalidade: (N,M)

REPOSITORY - armazena - TSQMI
   - Descrição: Um repositório pode acumular vários registros de nota TSQMI ao longo do tempo.
   - Cardinalidade: (1,N)

Diagrama Entidade-Relacionamento (DER)

   Um Diagrama Entidade-Relacionamento (DER) é uma representação gráfica que descreve as entidades, os relacionamentos e as conexões entre elas em um sistema ou domínio específico. É uma ferramenta fundamental utilizada no projeto de bancos de dados e sistemas de informação para modelar e visualizar a estrutura e interações entre os elementos essenciais de um sistema.

   Diferente do DLD (seção seguinte), que é gerado automaticamente por introspecção do código, o Diagrama Entidade-Relacionamento do projeto MeasureSoftGram foi modelado manualmente na ferramenta brModelo, em notação Peter Chen (entidades em retângulo, relacionamentos em losango, atributos em elipse, chave primária marcada com círculo preenchido). O arquivo-fonte do projeto (diagrama_entidade_relacionamento_eps.brM3) fica versionado em docs/assets/, junto com a imagem exportada abaixo.

Diagrama Entidade-Relacionamento

Diagrama Lógico de Dados (DLD)

   Diagrama gerado por introspecção real do código, com o comando python manage.py graph_models -a -g -o dld_gerado_graph_models.png (django-extensions + graphviz) rodado dentro do container service contra os models.py da branch develop (base canônica do repositório). Por ser gerado automaticamente a partir do código, não depende de transcrição manual — em contrapartida, ao usar -a (all applications), ele também traz as tabelas de infraestrutura de terceiros (django.contrib.*, allauth, django_apscheduler, rest_framework.authtoken) que o MER textual desta seção deixa propositalmente fora de escopo. O app grafana_proxy não aparece com tabelas próprias porque não define nenhum model: ele apenas repassa (proxy) chamadas para a API do Grafana, que roda como serviço externo (ver docker-compose.yml e a seção de Serviços).

Diagrama Lógico de Dados - gerado automaticamente via django-extensions

   As tabelas a seguir listam as tabelas físicas do banco (nomes reais no Postgres), colunas, tipos e chaves, extraídas diretamente dos models.py do Service. Todas as chaves primárias id são BIGINT (DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"), diferente do que normalmente se assume por padrão (INTEGER).

accounts_customuser

Coluna Tipo Nulo Chave
id BIGINT N PK
password VARCHAR(128) N
last_login TIMESTAMP S
is_superuser BOOLEAN N
username VARCHAR(150) N UNIQUE
first_name VARCHAR(150) S
last_name VARCHAR(150) S
email VARCHAR(254) N UNIQUE
is_staff BOOLEAN N
is_active BOOLEAN N
date_joined TIMESTAMP N
github_access_token VARCHAR(255) S

organizations_organization

Coluna Tipo Nulo Chave
id BIGINT N PK
name VARCHAR(128) N
key VARCHAR(128) N UNIQUE
description TEXT(512) S
admin_id BIGINT S FK → accounts_customuser
github_org_id BIGINT S UNIQUE
github_org_name VARCHAR(255) S
avatar_url VARCHAR(200) S

organizations_organization_members (M2M)

Coluna Tipo Nulo Chave
id BIGINT N PK
organization_id BIGINT N FK → organizations_organization
customuser_id BIGINT N FK → accounts_customuser

organizations_product

Coluna Tipo Nulo Chave
id BIGINT N PK
name VARCHAR(128) N
key VARCHAR(128) N UNIQUE, UNIQUE_TOGETHER(key, organization_id)
description TEXT(512) S
organization_id BIGINT N FK → organizations_organization
gaugeRedLimit NUMERIC(3,2) N default 0.33
gaugeYellowLimit NUMERIC(3,2) N default 0.66

organizations_repository

Coluna Tipo Nulo Chave
id BIGINT N PK
name VARCHAR(128) N
key VARCHAR(128) N UNIQUE_TOGETHER(key, product_id)
url VARCHAR(200) S
platform VARCHAR(128) S choices
description TEXT(512) S
product_id BIGINT N FK → organizations_product
imported BOOLEAN N default False
github_repo_id BIGINT S
github_full_name VARCHAR(255) S

metrics_supportedmetric

Coluna Tipo Nulo Chave
id BIGINT N PK
key VARCHAR(128) N UNIQUE
metric_type VARCHAR(15) N choices, default FLOAT
name VARCHAR(128) N
description TEXT(512) S

metrics_collectedmetric

Coluna Tipo Nulo Chave
id BIGINT N PK
metric_id BIGINT N FK → metrics_supportedmetric
value DOUBLE PRECISION N
path VARCHAR(255) S
qualifier VARCHAR(5) S
dynamic_key VARCHAR(128) S
created_at TIMESTAMP N default now
repository_id BIGINT N FK → organizations_repository

measures_supportedmeasure

Coluna Tipo Nulo Chave
id BIGINT N PK
key VARCHAR(128) N UNIQUE
name VARCHAR(128) N
description TEXT(512) S

measures_supportedmeasure_metrics (M2M)

Coluna Tipo Nulo Chave
id BIGINT N PK
supportedmeasure_id BIGINT N FK → measures_supportedmeasure
supportedmetric_id BIGINT N FK → metrics_supportedmetric

measures_calculatedmeasure

Coluna Tipo Nulo Chave
id BIGINT N PK
measure_id BIGINT N FK → measures_supportedmeasure
value DOUBLE PRECISION N
created_at TIMESTAMP N default now
repository_id BIGINT N FK → organizations_repository

subcharacteristics_supportedsubcharacteristic

Coluna Tipo Nulo Chave
id BIGINT N PK
name VARCHAR(128) N
key VARCHAR(128) N UNIQUE
description TEXT(512) S

subcharacteristics_supportedsubcharacteristic_measures (M2M)

Coluna Tipo Nulo Chave
id BIGINT N PK
supportedsubcharacteristic_id BIGINT N FK → subcharacteristics_supportedsubcharacteristic
supportedmeasure_id BIGINT N FK → measures_supportedmeasure

subcharacteristics_calculatedsubcharacteristic

Coluna Tipo Nulo Chave
id BIGINT N PK
subcharacteristic_id BIGINT N FK → subcharacteristics_supportedsubcharacteristic
value DOUBLE PRECISION N
created_at TIMESTAMP N default now
repository_id BIGINT N FK → organizations_repository

characteristics_supportedcharacteristic

Coluna Tipo Nulo Chave
id BIGINT N PK
name VARCHAR(128) N
key VARCHAR(128) N UNIQUE
description TEXT(512) S

characteristics_supportedcharacteristic_subcharacteristics (M2M)

Coluna Tipo Nulo Chave
id BIGINT N PK
supportedcharacteristic_id BIGINT N FK → characteristics_supportedcharacteristic
supportedsubcharacteristic_id BIGINT N FK → subcharacteristics_supportedsubcharacteristic

characteristics_balancematrix

Coluna Tipo Nulo Chave
id BIGINT N PK
source_characteristic_id BIGINT N FK → characteristics_supportedcharacteristic, UNIQUE_TOGETHER(source, target)
target_characteristic_id BIGINT N FK → characteristics_supportedcharacteristic
relation_type VARCHAR(1) N choices ('+','-')

characteristics_calculatedcharacteristic

Coluna Tipo Nulo Chave
id BIGINT N PK
characteristic_id BIGINT N FK → characteristics_supportedcharacteristic, UNIQUE_TOGETHER(repository, release, characteristic)
value DOUBLE PRECISION N
created_at TIMESTAMP N default now
repository_id BIGINT N FK → organizations_repository
release_id BIGINT S FK → releases

tsqmi_tsqmi

Coluna Tipo Nulo Chave
id BIGINT N PK
value DOUBLE PRECISION N
created_at TIMESTAMP N default now
repository_id BIGINT N FK → organizations_repository

goals_goal

Coluna Tipo Nulo Chave
id BIGINT N PK
created_at TIMESTAMP N default now
data JSONB N
created_by_id BIGINT N FK → accounts_customuser
product_id BIGINT N FK → organizations_product

releases (nome físico explícito, via Meta.db_table)

Coluna Tipo Nulo Chave
id BIGINT N PK
created_at TIMESTAMP N default now
start_at TIMESTAMP N
end_at TIMESTAMP N
release_name VARCHAR(255) N
created_by_id BIGINT N FK → accounts_customuser
product_id BIGINT N FK → organizations_product
goal_id BIGINT N FK → goals_goal
description TEXT(512) S

release_configuration_releaseconfiguration

Coluna Tipo Nulo Chave
id BIGINT N PK
created_at TIMESTAMP N default now
name VARCHAR(128) S
data JSONB N
product_id BIGINT N FK → organizations_product

Metas e Restrições de Arquitetura

Metas

Metas
Escalabilidade A aplicação deverá ser escalável
Segurança A aplicação deverá tratar de forma segura os dados sensíveis dos usuários
Deploy A aplicação deverá possuir deploy automatizado
Usabilidade A aplicação deverá ter uma boa usabilidade para o usuário

Restrições

Restrições
Conectividade Para utilização do Frontend é preciso ter conexão com a internet. Para utilizar o CLI isso será necessário apenas para extrações do GitHub, e não para o Sonarqube
Plataforma A aplicação possuirá suporte WEB e para linha de comando
Público A aplicação será desenvolvida com foco em empresas de tecnologia e desenvolvedores
Linguagem O inglês foi escolhido por conta das integrações com plataformas que já utilizam essa linguagem
Equipe A equipe possui 10 integrantes
Prazo O prazo é até o final do semestre 2026.1 da Universidade de Brasília

Referências

[1] What is Python? Executive Summary. Disponível em: < https://www.python.org/doc/essays/blurb/ > Acesso em: 4 de Outubro de 2023

[2] O que é JavaScript?. Disponível em: < https://developer.mozilla.org/pt-BR/docs/Learn/JavaScript/First_steps/What_is_JavaScript > Acesso em: 4 de Outubro de 2023

[3] TypeScript is JavaScript with syntax for types. Disponível em: < https://www.typescriptlang.org > Acesso em: 4 de Outubro de 2023

[4] React. Disponível em: < https://react.dev > Acesso em: 4 de Outubro de 2023

[5] What is Next.js?. Disponível em: < https://nextjs.org/learn/foundations/about-nextjs/what-is-nextjs > Acesso em: 4 de Outubro de 2023

[6] Django. Disponível em: < https://www.djangoproject.com > Acesso em: 4 de Outubro de 2023

[7] The Jupyter Notebook. Disponível em: < https://jupyter-notebook.readthedocs.io/en/latest/notebook.html > Acesso em: 4 de Outubro de 2023

[8] PyPI - Python Package Index. Disponível em: < https://pypi.org > Acesso em: 4 de Outubro de 2023

[9] PostgreSQL: The World's Most Advanced Open Source Relational Database. Disponível em: < https://www.postgresql.org > Acesso em: 4 de Outubro de 2023

Tudo sobre diagramas de pacotes UML. Disponível em: < https://www.lucidchart.com/pages/pt/diagrama-de-pacotes-uml > Acesso em: 4 de Outubro de 2023

Arquitetura do Sistema (MeasureSoftGram-2023-1). Disponível em: < https://fga-eps-mds.github.io/2023-1-MeasureSoftGram-Doc/documentos_de_projeto/arquitetura_do_projeto > Acesso em: 4 de Outubro de 2023

Architectural Blueprints — The "4+1" View Model of Software Architecture. Kruchten, Philippe. IEEE Software, 1995. Disponível em: < https://www.cs.ubc.ca/~gregor/teaching/papers/4+1view-architecture.pdf >


Versionamento

Data Autor Descrição Versão
01/08/2024 Gabriel Moretti Adicionando documento 1.0
13/09/2024 Christian Siqueira Atualizando o diagrama de banco de dados 1.1
13/09/2024 Christian Siqueira Adicionando diagrama de implantação 1.2
13/09/2024 Christian Siqueira Atualizando o diagrama de arquitetura 1.3
27/04/2026 Giovanni A. C. Giampauli Revisão R1 2026.1: registra decisões de stack do semestre — PostgreSQL 18, uv (Python), pnpm (JS), Python 3.12, Node 20 LTS, versões pinadas no Docker, Compose v2 com compose watch. Diagramas permanecem vigentes (sem mudança topológica). 1.4
03/05/2026 Giovanni A. C. Giampauli Adiciona MCP Server e migra diagrama arquitetural para Mermaid. 1.5
09/06/2026 Anacleto Reestrutura documento com modelo de visões 4+1 (Kruchten). Adiciona placeholders para Visão de Processo, Visão de Casos de Uso, MER e DLD. Corrige prazo para 2026.1. 1.6
09/06/2026 Anacleto Preenche seção MER com entidades, atributos e relacionamentos do Service. 1.7
05/07/2026 Anacleto Resposta às considerações do professor: adiciona rich picture na Visão Geral; documenta Grafana, nginx e a estrutura evoluída de containers/imagens; corrige a Visão Lógica (Core/Parser eram desenhados como serviços de rede, na verdade são bibliotecas); preenche Visão de Processo, Visão de Casos de Uso e Visão Física com dados reais de deploy; adiciona Plugin VS Code e MCP Server à Visão de Desenvolvimento e ao glossário de Serviços; corrige o MER contra os models.py reais do Service e adiciona o DLD. 1.8
06/07/2026 Anacleto Com acesso ao repositório 2026.1-MeasureSoftGram-AI (antes indisponível): substitui o placeholder "Pendente" do MCP Server na Visão de Desenvolvimento por um diagrama de pacotes real (server.py, client.py, auth/, tools/); corrige a descrição do MCP na seção de Serviços com base no código (autenticação via conta de serviço fixa, token único reaproveitado por todas as tools) e no guia docs/manual-de-instalacao/guia-mcp.md. 1.9
06/07/2026 Anacleto Corrige a seção "Gerenciamento de pacotes e runtime": uv, Python 3.12 fixo e Docker Compose v2 são específicos do Service, não de Core/Parser/CLI — conferido contra a branch develop desses três repositórios, que seguem em pip + tox, requires-python >= 3.9 e sem imagem Docker própria. 1.10
06/07/2026 Anacleto Adiciona o diagrama DLD_MEASURE_2026.1.png na seção do Diagrama Lógico de Dados, como complemento visual às tabelas físicas já documentadas. 1.11
06/07/2026 Anacleto Adiciona um segundo diagrama à seção do DLD, gerado automaticamente via manage.py graph_models (django-extensions) contra o código atual do Service, complementando o diagrama feito no brModelo. 1.12