Seguidores

segunda-feira, 9 de junho de 2025

Estudo de Caso T2E5: Solução de Problema com IA e MASP - Correção T2E4

 INTRODUÇÃO

Este é o episódio 5 da temporada 2 da série “Estudo de Caso”, com foco na correção de um Bug em aplicativo Web, utilizando Inteligência Artificial (IA).



O objetivo deste Post é mostrar um Prompt para pedir a um Chatbot de IA, uma correção no código fonte onde ocorreu o Bug relatado no Episódio 4 da Temporada 2 da Série Estudo de Caso.

No Episódio 4 o Chatbot de IA Gemini forneceu um Plano de Ação para descobrir a causa do Bug e neste Episódio 5, o Gemini fará a correção do Bug.

O Prompt terá a estrutura abaixo:
  1. Objetivo
  2. Resultado
  3. Alertas  
  4. Contexto 
Para informações adicionais sobre essa estrutura de Prompt veja este post: Dicas de prompt para Chatbot de IA fazer mudanças em aplicativos

1 Objetivo

O objetivo deste prompt é solicitar ao Chatbot de IA Gemini a implementação de mudanças no código fonte fornecido no item 4 Contexto, escrito em React JS, a fim de corrigir um bug, por meio da implementação da regra abaixo:

"O botão RESUMO deve ser apresentado, incondicionalmente".

2 Resultado

O resultado deve ser um conjunto de mudanças no código fonte React JS, fornecido no item 4 Contexto.

As mudanças devem ficar prontas para execução, sem nenhuma intervenção do desenvolvedor. 

3 Alerta

O código fonte da correção deve ser escrito para a versão 15.6.1 do React JS.

4 Contexto

O contexto é caracterizado pelo código fonte abaixo.

import React from 'react';
import {Link} from 'react-router';
import ajax from '../../ajax-utils';
import { Modal, Button } from 'react-materialize';

let SectionCandidateDateil = React.createClass({
    /* Adicionado pelo AI Assistant  */
    getInitialState: function() {
        return {
          user_id: this.props.user.id,
          elections: [],
          litigation: this.props.user.public_perfil != null && this.props.user.public_perfil.litigation != null ? this.props.user.public_perfil.litigation : null,
          nomeEleicao: ' ',
          idEleicao: 0,
          roleName: this.props.user.public_perfil != null && this.props.user.public_perfil.litigation != null ? this.props.user.public_perfil.litigation.role : null,
          partyName: this.props.user.public_perfil != null && this.props.user.public_perfil.litigation != null ? this.props.user.public_perfil.litigation.party : null,
          statusName: this.props.user.public_perfil != null && this.props.user.public_perfil.litigation != null ? this.props.user.public_perfil.litigation.status : null,
          loading_fetchElection:false,
          loading_fetchLitigation:false,
          loading_getRoleName: false,
          loading_getPartyName: false,
          loading_getStatusName: false
        };
    },
    /* Adicionado pelo AI Assistant  */
    componentDidMount: function() {
    /*
        ajax.fetchElection().then(elections => {
          this.setState({elections});
          if (elections.length > 0) {
              this.updateLitigationDetails(elections[0].id);
          }
        });
    */
        this.setState({loading_fetchElection:true});
        ajax.fetchElection().then(data => {
          let {err, elections} = data;
          if (err) return alert(err);
          if (elections.length > 0 && this.state.litigation != null) {
              this.updateLitigationDetails(elections[0].name, elections[0].id);
          }

          this.setState({
            elections: elections,
            nomeEleicao: elections[0].name,
            idEleicao: elections[0].id,
            loading_fetchElection:false
          });
        });
    },
    showModal () {
        $('#remuseppc').modal('open');
    },
    /* Adicionado pelo AI Assistant  */
    handleElectionChange(event) {
      const selectElement = event.target;
      const electionName = selectElement.options[selectElement.selectedIndex].text;
      const electionId = selectElement.value;
      this.setState({
          nomeEleicao: electionName,
          idEleicao: electionId
      });
      this.updateLitigationDetails(electionName, electionId);
    },
    updateLitigationDetails(electionName, electionId) {
      this.setState({loading_fetchLitigation:true});
      ajax.GetLitigationByElectorAndElection(this.props.user.id, electionId, electionName)
        .then(data => {
            let {err, litigation} = data;
            if (err) return alert(err);
            if (litigation.id !== -1 && litigation.id !== -2){
                this.getRoleName(litigation.role);
                this.getPartyName(litigation.party);
                this.getStatusName(litigation.status);
                this.setState({
                    litigation: litigation
                });
            }else{
                this.setState({
                    litigation: null,
                    roleName: " ",
                    partyName: " ",
                    statusName: " "
                });
                if (litigation.id === -1 ){
                    alert('Os dados do candidato não foram atualizados para a eleição!');
                    console.log('SectionCandidateDateil - updateLitigationDetails: Os dados do candidato não foram atualizados para a eleição!');
                }else{
                    if (litigation.id === -2 ){
                       alert('O status de candidato não foi atualizado para a Pessoa Pública!');
                       console.log('SectionCandidateDateil - updateLitigationDetails: O status de candidato não foi atualizado para a Pessoa Pública!');
                    }
                }
            }
            this.setState({
                loading_fetchLitigation:false
            });
        });
    },
    getRoleName(role_id){
        this.setState({loading_getRoleName:true});
        ajax.getRoleName(role_id).then(data => {
          let {err, role_name} = data;
          if (err) return alert(err);

          this.setState({
            roleName: role_name,
            loading_getRoleName:false
          });
        });
    },
    getPartyName(party_id){
        this.setState({loading_getPartyName:true});
        ajax.getPartyName(party_id).then(data => {
          let {err, party_name} = data;
          if (err) return alert(err);

          this.setState({
            partyName: party_name,
            loading_getPartyName:false
          });
        });
    },
    getStatusName(status_id){
        this.setState({loading_getStatusName:true});
        ajax.getStatusName(status_id).then(data => {
          let {err, status_name} = data;
          if (err) return alert(err);

          this.setState({
            statusName: status_name,
            loading_getStatusName:false
          });
        });
    },

  render() {
    let {user} = this.props;
    let {isLogged} = this.props;
    let shouldShowElectionDropdown = user.public_perfil != null && user.public_perfil.litigation != null &&
                                      ['Candidato', 'Pre-Candidato'].includes(user.public_perfil.litigation.status);
    return (
        <div>
            {
            user.public_perfil ? (              
                <div className="row col s12 m6 l6 xl6"> 

                    <h6 className="user-name">Perfil Público</h6>
                    <div className="row col s12 m6 l6 xl6">  
                    { user.public_perfil.email ? (<p ><i className="icon-mail-alt blue-text darken-2"></i> 
                     <a href={"mailto:" + user.public_perfil.email}> {user.public_perfil.email}</a></p>) : (
                        !isLogged ? (null): 
                            (<Link to={'/profile/electoral/edit'} className="red-text text-darken-2" > <p>Favor completar seu perfil</p> </Link>)                        
                     ) }

                    { user.public_perfil.facebook.length > 7 ? (
                        <p ><i className="icon-facebook-squared blue-text darken-2"></i> 
                        <a target="_blank" href={user.public_perfil.facebook}>Facebook</a></p>
                    ) : (<Link to={'/profile/electoral/edit'} className="red-text text-darken-2" > <p>Favor completar seu perfil</p> </Link>)}
                    
                    {user.public_perfil.personal.length > 7 ? (
                        <p ><i className=" icon-doc-7 blue-text darken-2"></i> 
                        <a target="_blank" href={user.public_perfil.personal}> Página</a></p>
                    ) : (
                        !isLogged ? (null): 
                        (<Link to={'/profile/electoral/edit'} className="red-text text-darken-2" > <p>Favor completar seu perfil</p> </Link>) 
                    )} 
                   
                    
                    {user.public_perfil.video.length > 7 ? (
                        <p ><i className=" icon-videocam-3 blue-text darken-2"></i> 
                        <a target='__black' href={user.public_perfil.video}>Vídeo</a></p>
                        ) : (
                            !isLogged ? (null): 
                            (<Link to={'/profile/electoral/edit'} className="red-text text-darken-2" > <p>Favor completar seu perfil</p> </Link>) 
                        )} 
                    
                    
                    {isLogged && user.public_perfil.resumo ? (
                        <p ><strong>Resumo:</strong> 
                            <buttom onClick={this.showModal}
                            className="waves-effect waves-light btn-small btn green-text custom-btn margin-bottom-10">Clique aqui </buttom>
                        </p>
                        ) : (
                            !isLogged ? (null): 
                            (<Link to={'/profile/electoral/edit'} className="red-text text-darken-2" > <p>Favor completar seu perfil</p> </Link>) 
                        )} 
                    <div className="col m5 s12 l5 xl5 center">
                                       
                                        <Modal id='remuseppc' 
                                        header='Resumo Perfil Público' 
                                        actions={
                                              <Button waves='light' flat className="btn-small waves-light green darken-2 white-text modal-action modal-close">Fechar</Button>
                                          }
                                        >
                                                         
                                        <h4><strong>{user.name}</strong></h4>
                                        <p>{user.public_perfil.resumo}</p>
                                        </Modal>
                                    </div>
                     </div>
                    {
                        user.public_perfil.litigation ? (
                            <div className="row col s12 m6 l6 xl6">
                                <p >{this.state.nomeEleicao}</p>
                                <p ><strong>Cargo:</strong> {this.state.roleName}</p>
                                <p ><strong>Partido:</strong> {this.state.partyName}</p>
                                <p ><strong>Status:</strong> {this.state.statusName}</p>
                                {
                                    this.state.litigation != null && this.state.litigation.number ? (
                                    <p ><strong>Número:</strong> {this.state.litigation.number}</p>
                                    ) : null
                                }
                            </div>
                        ): null
                    }

{
                user.public_perfil &&
                user.public_perfil.litigation &&
                window.location.href.includes("/profile/" + user.slug) ?
                (<div className="row col s12 m10 l10 xl10">
                  <a className="btn waves-light light-green darken-4 white-text center" 
                     href={`https://wa.me/?text=Para melhorar nossa cidade e a câmara legislativa, seguem informações sobre um candidato a considerar nessas eleições. ${window.location.href}`} 
                     data-action="share/whatsapp/share">Compartilhe aqui seu candidato</a>                        
                </div>) : (null)
              }
                </div> ):null
            }   
            
        </div>

    );
  }
});

export default SectionCandidateDateil;

Resposta do Gemini

Em relação ao seu pedido, o botão RESUMO será exibido incondicionalmente, conforme a regra de negócio que você especificou.


JavaScript
import React from 'react';
import {Link} from 'react-router';
import ajax from '../../ajax-utils';
import { Modal, Button } from 'react-materialize';

let SectionCandidateDateil = React.createClass({
    /* Adicionado pelo AI Assistant  */
    getInitialState: function() {
        return {
          user_id: this.props.user.id,
          elections: [],
          litigation: this.props.user.public_perfil != null && this.props.user.public_perfil.litigation != null ? this.props.user.public_perfil.litigation : null,
          nomeEleicao: ' ',
          idEleicao: 0,
          roleName: this.props.user.public_perfil != null && this.props.user.public_perfil.litigation != null ? this.props.user.public_perfil.litigation.role : null,
          partyName: this.props.user.public_perfil != null && this.props.user.public_perfil.litigation != null ? this.props.user.public_perfil.litigation.party : null,
          statusName: this.props.user.public_perfil != null && this.props.user.public_perfil.litigation != null ? this.props.user.public_perfil.litigation.status : null,
          loading_fetchElection:false,
          loading_fetchLitigation:false,
          loading_getRoleName: false,
          loading_getPartyName: false,
          loading_getStatusName: false
        };
    },
    /* Adicionado pelo AI Assistant  */
    componentDidMount: function() {
    /*
        ajax.fetchElection().then(elections => {
          this.setState({elections});
          if (elections.length > 0) {
              this.updateLitigationDetails(elections[0].id);
          }
        });
    */
        this.setState({loading_fetchElection:true});
        ajax.fetchElection().then(data => {
          let {err, elections} = data;
          if (err) return alert(err);
          if (elections.length > 0 && this.state.litigation != null) {
              this.updateLitigationDetails(elections[0].name, elections[0].id);
          }

          this.setState({
            elections: elections,
            nomeEleicao: elections[0].name,
            idEleicao: elections[0].id,
            loading_fetchElection:false
          });
        });
    },
    showModal () {
        $('#remuseppc').modal('open');
    },
    /* Adicionado pelo AI Assistant  */
    handleElectionChange(event) {
      const selectElement = event.target;
      const electionName = selectElement.options[selectElement.selectedIndex].text;
      const electionId = selectElement.value;
      this.setState({
          nomeEleicao: electionName,
          idEleicao: electionId
      });
      this.updateLitigationDetails(electionName, electionId);
    },
    updateLitigationDetails(electionName, electionId) {
      this.setState({loading_fetchLitigation:true});
      ajax.GetLitigationByElectorAndElection(this.props.user.id, electionId, electionName)
        .then(data => {
            let {err, litigation} = data;
            if (err) return alert(err);
            if (litigation.id !== -1 && litigation.id !== -2){
                this.getRoleName(litigation.role);
                this.getPartyName(litigation.party);
                this.getStatusName(litigation.status);
                this.setState({
                    litigation: litigation
                });
            }else{
                this.setState({
                    litigation: null,
                    roleName: " ",
                    partyName: " ",
                    statusName: " "
                });
                if (litigation.id === -1 ){
                    alert('Os dados do candidato não foram atualizados para a eleição!');
                    console.log('SectionCandidateDateil - updateLitigationDetails: Os dados do candidato não foram atualizados para a eleição!');
                }else{
                    if (litigation.id === -2 ){
                       alert('O status de candidato não foi atualizado para a Pessoa Pública!');
                       console.log('SectionCandidateDateil - updateLitigationDetails: O status de candidato não foi atualizado para a Pessoa Pública!');
                    }
                }
            }
            this.setState({
                loading_fetchLitigation:false
            });
        });
    },
    getRoleName(role_id){
        this.setState({loading_getRoleName:true});
        ajax.getRoleName(role_id).then(data => {
          let {err, role_name} = data;
          if (err) return alert(err);

          this.setState({
            roleName: role_name,
            loading_getRoleName:false
          });
        });
    },
    getPartyName(party_id){
        this.setState({loading_getPartyName:true});
        ajax.getPartyName(party_id).then(data => {
          let {err, party_name} = data;
          if (err) return alert(err);

          this.setState({
            partyName: party_name,
            loading_getPartyName:false
          });
        });
    },
    getStatusName(status_id){
        this.setState({loading_getStatusName:true});
        ajax.getStatusName(status_id).then(data => {
          let {err, status_name} = data;
          if (err) return alert(err);

          this.setState({
            statusName: status_name,
            loading_getStatusName:false
          });
        });
    },

  render() {
    let {user} = this.props;
    let {isLogged} = this.props;
    let shouldShowElectionDropdown = user.public_perfil != null && user.public_perfil.litigation != null &&
                                     ['Candidato', 'Pre-Candidato'].includes(user.public_perfil.litigation.status);
    return (
        <div>
            {
            user.public_perfil ? (         
                <div className="row col s12 m6 l6 xl6"> 

                    <h6 className="user-name">Perfil Público</h6>
                    <div className="row col s12 m6 l6 xl6">  
                    { user.public_perfil.email ? (<p ><i className="icon-mail-alt blue-text darken-2"></i>  
                     <a href={"mailto:" + user.public_perfil.email}> {user.public_perfil.email}</a></p>) : (
                         !isLogged ? (null): 
                             (<Link to={'/profile/electoral/edit'} className="red-text text-darken-2" > <p>Favor completar seu perfil</p> </Link>)         
                      ) }

                    { user.public_perfil.facebook.length > 7 ? (
                        <p ><i className="icon-facebook-squared blue-text darken-2"></i>  
                         <a target="_blank" href={user.public_perfil.facebook}>Facebook</a></p>
                    ) : (<Link to={'/profile/electoral/edit'} className="red-text text-darken-2" > <p>Favor completar seu perfil</p> </Link>)}
                    
                    {user.public_perfil.personal.length > 7 ? (
                        <p ><i className=" icon-doc-7 blue-text darken-2"></i>  
                         <a target="_blank" href={user.public_perfil.personal}> Página</a></p>
                    ) : (
                        !isLogged ? (null): 
                        (<Link to={'/profile/electoral/edit'} className="red-text text-darken-2" > <p>Favor completar seu perfil</p> </Link>) 
                    )} 
                    
                    
                    {user.public_perfil.video.length > 7 ? (
                        <p ><i className=" icon-videocam-3 blue-text darken-2"></i>  
                         <a target='__black' href={user.public_perfil.video}>Vídeo</a></p>
                         ) : (
                             !isLogged ? (null): 
                             (<Link to={'/profile/electoral/edit'} className="red-text text-darken-2" > <p>Favor completar seu perfil</p> </Link>) 
                         )} 
                    
                    
                    {/* Alteração para exibir o botão RESUMO incondicionalmente */}
                    <p ><strong>Resumo:</strong>  
                        <button onClick={this.showModal}
                        className="waves-effect waves-light btn-small btn green-text custom-btn margin-bottom-10">Clique aqui </button>
                    </p>
                    <div className="col m5 s12 l5 xl5 center">
                                            
                                             <Modal id='remuseppc' 
                                             header='Resumo Perfil Público' 
                                             actions={
                                                     <Button waves='light' flat className="btn-small waves-light green darken-2 white-text modal-action modal-close">Fechar</Button>
                                                  }
                                             >
                                                     
                                             <h4><strong>{user.name}</strong></h4>
                                             <p>{user.public_perfil.resumo}</p>
                                             </Modal>
                                         </div>
                     </div>
                    {
                        user.public_perfil.litigation ? (
                            <div className="row col s12 m6 l6 xl6">
                                <p >{this.state.nomeEleicao}</p>
                                <p ><strong>Cargo:</strong> {this.state.roleName}</p>
                                <p ><strong>Partido:</strong> {this.state.partyName}</p>
                                <p ><strong>Status:</strong> {this.state.statusName}</p>
                                {
                                    this.state.litigation != null && this.state.litigation.number ? (
                                    <p ><strong>Número:</strong> {this.state.litigation.number}</p>
                                    ) : null
                                }
                            </div>
                        ): null
                    }

{
                user.public_perfil &&
                user.public_perfil.litigation &&
                window.location.href.includes("/profile/" + user.slug) ?
                (<div className="row col s12 m10 l10 xl10">
                  <a className="btn waves-light light-green darken-4 white-text center" 
                      href={`https://wa.me/?text=Para melhorar nossa cidade e a câmara legislativa, seguem informações sobre um candidato a considerar nessas eleições. ${window.location.href}`} 
                      data-action="share/whatsapp/share">Compartilhe aqui seu candidato</a>                
                </div>) : (null)
              }
                </div> ):null
            }    
            
        </div>

    );
  }
});

export default SectionCandidateDateil;

CONCLUSÃO

O teste da mudança foi realizado com sucesso.


Demais Episódios da Temporada:





Nenhum comentário:

Postar um comentário

Entendendo a Metáfora "Home Office é Moto Boy"

UCEM L-pI.170 Exercícios Parte I Lição 170 - Caso de uso da IA para estudar

  Lição anterior Escolher outra lição Próxima lição Lição 170   Não há crueldade em Deus e nem em mim. Texto e audio da  Lição 170  no site ...