Executando verificação de segurança...
4

Como lidar com cliente relutante?

Um pouco de contexto

Estou desenvolvendo um sistema de gestão para um cliente. O sistema já existe há anos no mercado, mas era server-desktop e agora estamos transformando em um sistema 100% web.

Hoje o sistema roda com um banco de dados com dezenas de tabelas, algumas com milhões de registros por empresa. Porém o sistema não parece ter sido bem desenvolvido: em uma das empresas o servidor roda em uma máquina com i7 10ª geração e 16GB de RAM e ainda assim está ficando lento. O banco atual é SQL Server e estou construindo agora com PostgreSQL.

O conflito

O cliente foi o desenvolvedor das primeiras versões do sistema e está me passando tabelas, fluxos, rotinas e processos, que eu transformo em código.

Eu gosto de desenvolver sistemas que eu não vá ter medo de mexer em 3 meses, então fiz algumas sugestões para melhorar a arquitetura:

  1. Dividir tabelas gigantes (algumas com mais de 65 campos) em tabelas semânticas.
  2. Mudar como o usuário de suporte é identificado.

Para compreender melhor o que vou dizer a seguir é importante saber que os usuários são vinculados a uma empresa, porém o usuário de suporte não deve pertencer a nenhuma empresa pois ele deve ter acesso a todas as empresas.

Atualmente, a proposta do cliente para o usuário de suporte seria:

  • Ter duas tabelas: USUÁRIOS e SUPORTE.
  • A tabela SUPORTE teria apenas um registro com nome e hash da senha.
  • Para identificar suporte, o usuário deveria informar 0 no campo Id na tela de login, logo não existe nenhum registro de usuário 0 no banco de dados.

Eu sugeri:

  • Uma tabela USUÁRIO com os dados gerais e uma flag isSupport.
  • Uma tabela intermediária (EnterpriseUser) relacionando o usuário à empresa.
  • Usuários de suporte não são linkados a nenhuma empresa e é possível ter múltiplos usuários de suporte.

Eu acho que oque sugeri é muito melhor e ainda deixa a forma como o sistema funciona muito mais clara e previsível.

Ambas as sugestões foram rejeitadas:

  • A primeira: “não faz sentido ter tabelas 1:1”.
  • A segunda: “sua solução é mais complicada”.

A pergunta

O que devo fazer?

  • Seguir o que o cliente me passou, apenas transformando o sistema em web, mesmo sabendo que é lento e menos escalável?
  • Implementar minha solução e tentar convencer novamente o cliente de que é a melhor opção, garantindo escalabilidade e facilidade de manutenção no futuro?

Também gostaria de saber se estou equivocado em pensar que minha abordagem é melhor para o futuro do sistema.

Carregando publicação patrocinada...
4

O erro não é discordar do cliente, é assumir o risco por ele

Você não deve simplesmente obedecer, porque:

daqui a 6 meses o sistema continuará lento

daqui a 1 ano o cliente vai reclamar de manutenção

daqui a 2 anos você será culpado por algo que avisou antes

Faça o seguinte:

1º Documente por escrito:

  • os problemas do modelo atual

  • os riscos de escalabilidade

  • as limitações futuras

2º Documente sua proposta com benefícios claros:

  • manutenção

  • performance

  • segurança

  • evolução

3º Apresente duas opções formais:

  • implementação conforme especificação atual, sem garantia de performance futura

  • implementação com refatoração estrutural, garantindo base sólida.

E peça uma decisão registrada.

Se o cliente escolher a solução ruim, você executa, mas:

com escopo claro

com responsabilidade técnica delimitada

sem assumir culpa futura

2

Cara, obrigado pela sugestão, gostei muito, de verdade. Gostei que assim a responsabilidade fica pra ele e não pra mim, já avisei dezenas de vezes então minha parte já fiz, agora é hora dele decidir o que vai querer pro sistema dele.

3

Show mano, clientes realmente dão muita dor de cabeça já sem ter conhecimento técnico e tendo um conhecimento técnico defasado, acredito que seja pior kkkkkk. Tenho experiência nisso, já que fazem mais de 5 anos que trabalho como freelancer e já vi de tudo!

Nesse caso, eu recomendo o contra intuitivo, seguir o que o cliente quer, mas com um contrato de levantamento de requisitos, mostrando o que ele quer segundo as palavras dele e explicando que caso ele queira alterações posteriores ela deverá ser discutida num novo levantamento de requisitos para a atualização e cobrada à parte.

Isso é bom primeiramente evitando ele dizer que o sistema não ficou bom, afinal de contas se ele soubesse do que está querendo/fazendo ele mesmo faria e não contrataria alguém, como ele não sabe ele vai pagar pelo sistema "ruim" e depois pelo bom e esse documento te ajuda a se resguardar. Em segundo lugar, vai te resguardar do re-trabalho programadores não são pagos por hora ou linhas de código, são pagos por solucionar problemas, se o cliente não quer tua solução, tu cobra a solução dele e a tua e aí ele aprende a dar valor a sua solução fazendo com que esse problema não se repita.

Tem um vídeo muito show que fala sobre isso, sempre que vejo alguém com dúvida em preço/processo eu passo ele. O vídeo é esse, caso interesse:

https://www.youtube.com/watch?v=EkAOLjjImUc&t=1158s

A playlist toda é muito boa! Super recomendo!

2

Opa, valeu mesmo! Muito bom ouvir de alguém com mais experiência nisso. Vou seguir nessa linha do que você me aconselhou, até melhor porque ajuda a evitar possíveis conflitos. Como já deixo tudo documentado vai ser tranquilo.
Cara, esse vídeo vai ajudar bastante, não sou dos melhores com contratos kkkkk.

1

Sim! Eu também sou bem ruim com isso kkkkkkk Mas o conteúdo do cara é monstro, tanto esse quando o do levantamento de requisitos! Certeza que você não vai se arrepender! Muito sucesso na sua carreira

1

O banco atual é SQL Server e estou construindo agora com PostgreSQL.

Mudar de banco não vai ter diferença nenhuma. Você tem que aplicar práticas inteligentes de otimização de querys e indices.

milhões de registros por empresa

Milhões de registros não é nenhum problema para bancos bem configurados.

O limite teórico do PostgreSQL por tabela é 1 bilhão de registros. É a partir desse numero que otimizar é mais custoso que dividir.

A única coisa que na minha opinião vai resolver o problema é um bom DBA.

PostgreSQL vs SQLServer

Os dois vão ter um desempenho péssimo para querys mal estruturadas e mal indexadas

Os dois vão ter um desempenho semelhante para querys bem estruturadas e indexadas.

A diferença aqui só vai começar aparecer no bilhão.

1

Eu faria uma outra abordagem:
Uma tabela users_roles poderia ter papéis vinculados ou não a empresas.
Ex.:

o usuário pode ser gerente na empresa 1
o dono pode ter permissão admin nas empresas 1, 2 e 3.
o suporte teria permissão de suporte em todas as empresas. poderia ser null no lugar da empresa.

Users
id: uuid
name: string

Roles
id: uuid
name: string
requires_business_id: boolean

Business
id: uuid
name: string

users_roles
id: uuid
user_id: uuid
role_id: uuid
business_id: uuid <-- não obrigatório
is_active: boolean

Dessa forma, você permitiria que o mesmo usuário tivesse n papéis em cada empresa. Inclusive, se um dia quiserem colocar um suporte que seja específico somente de 2 empresas, ou um gerente que possa visualizar 3 empresas, é possível com essa modelagem. Poderia deixar o business_id não obrigatório para que seja considerado como "todos". Quando o roles tiver o requires_business_id, então aquele perfil exige que seja informado uma empresa.

Essa modelagem é usada nos meus sistemas seguindo a mesma ideia, onde o mesmo usuário pode ser gerente de uma loja e atendente da outra, por exemplo. E os papéis de dev, admin e suporte são de toodos, então não precisaria informar uma loja.

1

Entendi seu modelo, ficou bom, mas os usuários comuns pertencem a uma única empresa e não existe hoje cenário de usuário com múltiplos papéis em empresas diferentes no sistema saca?
Minha proposta é pra resolver o problema real de agora com a menor complexidade possível, mantendo espaço para evolução futura. Se nem a separação ele tá querendo aceitar, imagina se eu mostrar esse modelo pra ele kkkkkkk.
Mas valeu cara, só tô vendo ainda mais que o modelo que ele quer não escala nunca.

1

Mas os exemplos de múltiplos papéis em empresas diferentes foram apenas exemplos. Não necessariamente você precisa usar. A questão é que você precisa definir de alguma forma quais usuários se ligam a que.
E o relacionamento n:n é a melhor escolha. Gambiarra zero e escalável. Ainda que sua interface não reflita isso, é interessante que você deixe uma base pra não mexer nos dados futuramente.
Como no exemplo: digamos que uma empresa com múltiplas filiais contrate o sistema amanhã. Ou uma empresa de empresas. O cara pode querer que um funcionário possa visualizar várias.
A chance de deixar os dados escaláveis é agora, mesmo que a sua interface não mostre a opção .
Com a modelagem correta, tu só meteria um select no topo e tava resolvido. Sem isso, você teria que mudar dados, migrations etc.

Eu, particularmente, mesmo não resolvendo coisas que não fui contratado, sempre deixo ganchos preparados para uma escala. Ainda que a interface não mostre.

Mas enfim..