Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Douglas Motta

Gerenciamento de Aplicação Multi Instance/Tenancy em PHP

Recommended Posts

Olá, pessoal.

Desenvolvi uma aplicação em PHP para um segmento específico onde cada empresa terá essa aplicação. 

Minha dúvida é quanto ao gerencimento deste sistema, tendo em vista que cada empresa poderá personalizar a aplicação conforme suas necessidades (locais, legislação, negócio, etc.). Porém a maioria das funcionalidades será comum a todas as empresas (mas nada garante que uma funcionalidade que é comum hoje vai ser comum a todas amanhã). Por questões de segurança cada empresa terá seu banco de dados.

Estou entrando no mercado com o primeiro cliente e estou pensando no momento que tiver 30 clientes como vai ser. Utilizo o Bitbucket para controle de versão.

Qual é a melhor forma de gerenciar o codebase e o codecustom desta aplicação?  Um branch para cada cliente? Submodulos do Git? Pela própria aplicação?

Alguém que já vivenciou algo parecido que pode me ajudar?

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

No decorrer da minha experiência como dev, eu vi muitas decisões ruins, algumas delas eu mesmo sugeri. Mas, a que mais me impressionava era quanto ao projeto base e suas customizações.


Pensando apenas em code (sem entrar em banco de dados), eu utilizaria uma mescla entre o GIT e o composer.

 

Branch's e divisões

 

No GIT:

  • Dividir as branchs em 5 tipos (serão mais branchs): master, cutom-*, homologacao-*, dev-* e hotfix-*;
  • A branch master será única e exclusivamente para o código base não customizado;
  • A branch custom-*, será específica para o código homologado do projeto customizado para uma empresa (custom-empresa01, custom-empresa02, etc..);
  • A branch homologacao-* será específica para homologar a transição do código de dev para prod, aonde testes de alto nível são aplicados. Cada branch de produção (master/custom) terá sua respectiva branch de homologação (homologacao-master, homologacao-custom-empresa01, etc);
  • A branch dev-* é aonde é realizado o desenvolvimento, ela são livres, aonde o "desenvolvedor não conhece as leis" ou "o filho chora e mãe não vê", etc.. Você deve ter quantas forem necessárias, para cada implementação, cada GAP, cada moficação (dev-master-task-2784, dev-custom-empresa01-task-3500, etc...);
  • A branch de hotfix-* é aquela correção rápida, aquele conflito do merge entre uma entre o código base e uma customização ou que está implicando em parada geral do sistema (aquele bug ou erro de português que passou pela homologação/testes), que não necessariamente deve passar por todos os passos de desenvolvimento/homologação/produção. O que nós normalmente chamamos de "codificar em prod"... Sim, isso existe na realidade de todos já fizeram.

Essa é a definição da árvore do projeto. Os caminhos a serem seguidos:

  • dev-master-* <--> homologacao-master <--> master --> homologacao-custom-* <--> custom-(todas as empresas);
  • dev-custom-* <--> homologacao-custom-* <--> custom-*;
  • hotfix-* <--> para aonde for necessário.

Perceba que no fluxo, uma custom nunca deve levar o seu código para a master. Apenas a master pode levar códigos para a custom. Sempre utilizando a branch de homologação da custom.

 

Fork

 

Uma característica bem interessante dos serviços de controle de versionamento (bitbucket, github, etc...) é a possibilidade de criar um fork de um projeto. O seu projeto CORE será o repositório principal e, para cada cliente, você criará um novo fork. Logo, você terá o projeto master e os forks para cada cliente (master -> cliente-01 -> cliente-02, etc...).

 

A divisão entre branchs, deve ser a mesma exemplificada exclusiva para a master. Ou seja, 4 tipos: master, homologação, dev-* e hotfix-*). A nomenclatura das branchs (mster, homologacao, dev-* e hotfix-*) segue a mesma definição anteriormente explicada.

 

A parte de fluxo será o que está exemplificado abaixo:

  • dev-* <--> homologacao <--> master;
  • hotfix-* <--> para onde for necessário.

 

O cuidado, vem na hora de sincronizar os forks. O BitBucket, por exemplo, lhe sugere um fork automático entre as branchs masters de cada repositório. Entretanto, para um melhor controle e validação do novo código, a sincronização deve ocorrer entre a branch master, do projeto master, para a branch homologacao do projeto customizado. Ou seja:

 

  • Master:master --> Cliente-01:homologacao;

 

Dessa forma, você pode homologar, corrigir e enviar para a produção (master) da customização de clientes.

 

No BitBucket, para realizar tal feito, você pode ir no menu compare, escolha  a branch da qual está o código (parte de baixo) e a branch na qual você quer enviar o novo código (branch de cima). Compare as diferenças e, no canto direito superior, o BitBucket lhe exibirá o botão merge. Feito o merge, o processo é exatamente o mesmo que utilizando branchs.

 

Módulos

 

Aqui é que entra a questão de módulos. Caso você implemente partes do sistema como módulos, você pode usar tanto o git-submodule ou o composer. Com ambos você poderá utilizar repositórios privados para baixar as suas dependências. Para cada módulo, você deverá ter o repositório separado e, caso o repositório separado seja customizado, poderá seguir a estruturação acima mencionada.

 

Entretanto, no caso de módulos personalizados, acredito que com o git submodule não seja possível separar entre versões (branch/tags) específicas para cada projeto/branch. No caso do composer é possível, pois, cada branch/projeto, terá seu próprio composer que pode ser personalizado.

 

Banco de dados

 

Nesse caso, vai depender muito do que você irá utilizar para gerenciar o SGBD. Eu utilizei por muito tempo o MySQL WorkBench. Ele funciona perfeitamente quando o assunto é modelagem e sincronização. Entretanto, o formato de arquivo gerado por ele não é aberto e, em consequência, não pode ser versionado. Logo, quando uma tabela precisar ser diferente em algum projeto, você terá dois arquivos distintos.

 

Há, também, a possibilidade de tratar tudo na forma de SQL scripts. Mas ficaria sem uma ferramenta de apoio. Talvez alguém conheça alguma ferramenta melhor para a situação.

 

A contra-partida

 

Quando você separa pequenas partes de um projeto em módulos e os adiciona como dependências do seu projeto, você pode encontrar uma situação denominada  Dependency Hell. Esse termo também pode ser utilizado para a manutenção do código entre as branchs, pois, todas as suas customizações necessitam estarem atualizadas com a branch master. E se você almeja 30 empresas, pense que uma mudança no CORE precisa ser homologada para as 30 empresas.

 

Considerações

 

Sendo dicas como elas são, apenas dicas, você pode considerar demasiada estrutura e simplista ou exagerada demais e partir para uma abordagem meio termo ou mais robusta. Tudo dependerá de onde você está e para onde gostaria de chegar.

 

Existem outras ferramentas e abordagens que pode lhe ajudar. Uma delas seria a integração contínua, o qual incluí N outras ferramentas de auxílio.

 

Update

 

Um sistema que gerencia suas próprias customizações acaba sendo limitado a campos e novas informações. Eu, particularmente, não gosto muito da prática. Entretanto, para evitar o problema com o SGBD, pode-se utilizar tabelas de cadastros par atributo-valor para cruzar informações dinâmicas e reduzir a necessidade de criar novas colunas e tabelas. Mas, é uma questão bem limitada.

 

Update 2

 

Com a nova parte de forks (que eu não havia me lembrado anteriormente), seria a sugestão mais indicada. Pois, se você possuir uma equipe de desenvolvimento específica para cada cliente, poderá gerenciar muito melhor as permissões e acessos. O controle é bem superior a de um repositório apenas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Gabriel. Muito obrigado pela resposta.

 

Você detalhou bastante e tirou as dúvidas que eu tinha em minha cabeça com relação à esse gerenciamento. Poderia tirar uma útlima dúvida? Com relação ao projeto, a estrutura de pastas, etc. Eu uso Symfony e gostaria de saber se para cada novo cliente eu crio um projeto novo no PhpStorm e clono o Core ou eu consigo gerenciar tudo isso com apenas um projeto no PhpStorm? Tem uma estrutura de pastas para esta arquitetura?

 

Valeu mesmo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Apesar de, estruturalmente, tudo estar em um mesmo projeto. Seria necessário instalar as dependências, pelo composer, para cada projeto. Isso seria necessário sempre que mudar de uma branch de um projeto para outro.

 

Então, sim, é melhor ter um projeto separado para cada cliente.

 

Outro detalhe, que eu não comentei anteriormente é sobre o fork. Para cada cliente pode ser criado um fork do projeto (vou atualizar a resposta anterior).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Atualizei o post principal. E, nesse momento, acredito que a solução entre forks do projeto seja a mais indicada.

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, Douglas Motta disse:

Tem uma estrutura de pastas para esta arquitetura?

 

Não, apenas que exista uma estrutura definida e com coerência (e não seja uma bagunça).

 

A que um framework, como Symfony, lhe oferece estará de bom tamanho.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por violin101
      Caros amigos, saudações.
       
      Humildemente peço desculpa por postar uma dúvida que tenho.

      Preciso salvar no MySql, os seguinte Registro:

      1 - Principal
      ====> minha dúvida começa aqui
      ==========> como faço para o Sistema Contar Automaticamente o que estiver despois do 1.____?
      1.01 - Matriz
      1.01.0001 - Estoque
      1.01.0002 - Oficina
      etc

      2 - Secundário
      2.01 - Loja_1
      2.01.0001 - Caixa
      2.01.0002 - Recepção
      etc
       
      Resumindo seria como se fosse um Cadastro de PLANO de CONTAS CONTÁBEIL.

      Grato,


      Cesar









       
    • Por violin101
      Caros amigos, saudações.

      Por favor, me perdoa em recorrer a orientação dos amigos.

      Preciso fazer um Relatório onde o usuário pode Gerar uma Lista com prazo para vencimento de: 15 / 20/ 30 dias da data atual.

      Tem como montar uma SQL para o sistema fazer uma busca no MySql por período ou dias próximo ao vencimento ?

      Tentei fazer assim, mas o SQL me traz tudo:
      $query = "SELECT faturamento.*, DATE_ADD(faturamento.dataVencimento, INTERVAL 30 DAY), fornecedor.* FROM faturamento INNER JOIN fornecedor ON fornecedor.idfornecedor = faturamento.id_fornecedor WHERE faturamento.statusFatur = 1 ORDER BY faturamento.idFaturamento $ordenar ";  
      Grato,
       
      Cesar
       
       
       
       
    • Por violin101
      Caros amigos, saudações
       
      Por favor, me perdoa em recorrer a orientação dos amigos, tenho uma dúvida.
       
      Gostaria de uma rotina onde o Sistema possa acusar para o usuário antes dos 30 dias, grifar na Tabela o aviso de vencimento próximo, por exemplo:
       
      Data Atual: 15/11/2024
                                           Vencimento
      Fornecedor.....................Data.....................Valor
      Fornecedor_1...........01/12/2024..........R$ 120,00 <== grifar a linha de Laranja
      Fornecedor_1...........01/01/2025..........R$ 130,00
      Fornecedor_2...........15/12/2024..........R$ 200,00 <== grifar a linha de Amarelo
      Fornecedor_2...........15/01/2025..........R$ 230,00
      Fornecedor_3...........20/12/2024..........R$ 150,00
       
      Alguém tem alguma dica ou leitura sobre este assunto ?

      Grato,
       
      Cesar
    • Por violin101
      Caros amigos, saudações.

      Por favor, me perdoa em recorrer a ajuda dos amigos, mas preciso entender uma processo que não estou conseguindo sucesso.

      Como mencionado no Título estou escrevendo um Sistema Web para Gerenciamento de Empresa.
       
      Minha dúvida, que preciso muito entender:
      - preciso agora escrever a Rotina para Emissão de NFe e essa parte não estou conseguindo.
       
      tenho assistido alguns vídeos e leituras, mas não estou conseguindo sucesso, já fiz toda as importações das LIB da NFePhp conforme orientação.

      Preciso de ajuda.

      Algum dos amigos tem conhecimento de algum passo-a-passo explicando a criação dessa rotina ?

      tenho visto alguns vídeos com LARAVEL, mas quando tento utilizar e converter para PHP+Codeiginter, dá uma fila de erros que não entendo, mesmo informando as lib necessárias.

      Alguns do amigo tem algum vídeo, leitura explicando essa parte ?

      Grato,

      Cesar.
    • Por violin101
      Caros amigos, saudações.

      Por favor, me perdoa em recorrer ao auxílio dos amigos, mas preciso entender e resolver um problema.
       
      Tenho uma Rotina que o usuário seleciona os produtos que deseja para requerer ao setor responsável.
       
      O usuário escolhe um produto qualquer e Clicla em um button para incluir a lista.

      O problema que estou enfrentando é que após escolher o produto e teclar ENTER o Sistema já salva no BD.
       
      Gostaria de criar uma Tecla de Atalho, para quando incluir/escolher o produto na lista, o usuário tecla como exemplo:
      ALT+A  para agregar a lista
      ALT+S para salvar a lista de itens desejados.

      Assim, quando teclar enter, o sistema não dispara o GRAVAR na Base de Dados.

      Grato,

      Cesar
       
       
       
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.