Skip to content

Commit e357e44

Browse files
committed
ajustes na lógica da Ada
1 parent a1bf249 commit e357e44

2 files changed

Lines changed: 78 additions & 78 deletions

File tree

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
/**
2-
* @file useAdaContext.js
2+
* @file useSyntaxContext.js
33
* @description Hook que carrega estatísticas do sistema em tempo real para injetar
4-
* no system prompt do Gemini (AdaBot). Garante que o agente tenha consciência do
5-
* estado atual do usuário: matérias, flashcards, revisoes pendentes, streak etc.
4+
* no system prompt do Syntax (assistente de engenharia de software). Garante que o
5+
* agente tenha consciência do estado atual do usuário: projetos, snippets,
6+
* tarefas pendentes, atividade recente etc.
67
*
78
* @dependencies
89
* - Firebase Firestore (getDocs com queries filtradas por uid)
9-
* - streakService.getStreakStats — dados de ofensiva diária
10-
* - sm2.isDueForReview — filtro de flashcards pendentes de revisão
10+
* - streakService.getStreakStats — dados de atividade diária
1111
*
1212
* @sideEffects
13-
* - Realiza múltiplas leituras no Firestore a cada chamada (matérias, resumos, flashcards)
14-
* - Re-executa quando eventos 'cinesia:*' são disparados (via CustomEvent)
13+
* - Realiza múltiplas leituras no Firestore a cada chamada (projetos, snippets, tarefas)
14+
* - Re-executa quando eventos 'syntax:*' são disparados (via CustomEvent)
1515
*
1616
* @notes
17-
* - Os custom events permitem que o AdaBot tenha dados atualizados após executar ações
17+
* - Os custom events permitem que o Syntax tenha dados atualizados após executar ações
1818
* - Não usa onSnapshot (tempo real do Firestore) para economizar leituras — usa polling por evento
1919
* - PERF: limit(500) em cada query — usuários com muito conteúdo podem ter dados truncados
2020
*/
@@ -28,23 +28,23 @@ import {
2828
limit,
2929
} from 'firebase/firestore';
3030
import { db } from '../config/firebase-config';
31-
import { isDueForReview } from '../utils/sm2';
3231
import { getStreakStats } from '../services/streakService';
3332

3433
/**
3534
* @param {string|null} uid - UID do usuário logado
36-
* @returns {{ dadosSistema: object, materiasLista: Array, isLoadingContext: boolean }}
35+
* @returns {{ dadosSistema: object, projetosLista: Array, isLoadingContext: boolean }}
3736
*/
38-
const useAdaContext = (uid) => {
37+
const useSyntaxContext = (uid) => {
3938
const [dadosSistema, setDadosSistema] = useState({
40-
materias: [],
41-
totalFlashcards: 0,
42-
totalResumos: 0,
43-
cardsParaRevisarHoje: 0,
39+
projetos: [],
40+
totalSnippets: 0,
41+
totalTarefas: 0,
42+
tarefasPendentes: 0,
43+
ultimoProjeto: null,
4444
streakAtual: 0,
4545
longestStreak: 0,
4646
});
47-
const [materiasLista, setMateriasLista] = useState([]);
47+
const [projetosLista, setProjetosLista] = useState([]);
4848
const [isLoadingContext, setIsLoadingContext] = useState(true);
4949

5050
useEffect(() => {
@@ -58,35 +58,41 @@ const useAdaContext = (uid) => {
5858
const fetchContext = async () => {
5959
try {
6060
// Buscar tudo em paralelo
61-
const [materiasSnap, resumosSnap, flashcardsSnap, streakStats] = await Promise.all([
62-
getDocs(query(collection(db, 'materias'), where('uid', '==', uid), limit(500))),
63-
getDocs(query(collection(db, 'resumos'), where('uid', '==', uid), limit(500))),
64-
getDocs(query(collection(db, 'flashcards'), where('uid', '==', uid), limit(500))),
61+
const [projetosSnap, snippetsSnap, tarefasSnap, streakStats] = await Promise.all([
62+
getDocs(query(collection(db, 'projetos'), where('uid', '==', uid), limit(500))),
63+
getDocs(query(collection(db, 'snippets'), where('uid', '==', uid), limit(500))),
64+
getDocs(query(collection(db, 'tarefas'), where('uid', '==', uid), limit(500))),
6565
getStreakStats(uid).catch(() => ({ currentStreak: 0, longestStreak: 0 })),
6666
]);
6767

6868
if (cancelled) return;
6969

70-
const materias = materiasSnap.docs.map((d) => ({ id: d.id, ...d.data() }));
71-
const flashcards = flashcardsSnap.docs.map((d) => ({ id: d.id, ...d.data() }));
70+
const projetos = projetosSnap.docs.map((d) => ({ id: d.id, ...d.data() }));
71+
const tarefas = tarefasSnap.docs.map((d) => ({ id: d.id, ...d.data() }));
7272

73-
// Contar flashcards pendentes de revisão SM-2
74-
const cardsParaRevisarHoje = flashcards.filter((fc) => isDueForReview(fc)).length;
73+
// Contar tarefas ainda não concluídas
74+
const tarefasPendentes = tarefas.filter((t) => !t.concluida).length;
7575

76-
setMateriasLista(materias);
76+
// Último projeto acessado/atualizado
77+
const ultimoProjeto = projetos
78+
.sort((a, b) => new Date(b.ultimaAtualizacao || 0) - new Date(a.ultimaAtualizacao || 0))
79+
.at(0)?.nome || null;
80+
81+
setProjetosLista(projetos);
7782
setDadosSistema({
78-
materias,
79-
totalFlashcards: flashcardsSnap.size,
80-
totalResumos: resumosSnap.size,
81-
cardsParaRevisarHoje,
83+
projetos,
84+
totalSnippets: snippetsSnap.size,
85+
totalTarefas: tarefasSnap.size,
86+
tarefasPendentes,
87+
ultimoProjeto,
8288
streakAtual: streakStats?.currentStreak || 0,
8389
longestStreak: streakStats?.longestStreak || 0,
8490
});
8591
} catch (err) {
8692
if (err?.message?.includes('INTERNAL ASSERTION FAILED')) {
87-
console.warn('[useKakabotContext] Firestore temporariamente indisponível');
93+
console.warn('[useSyntaxContext] Firestore temporariamente indisponível');
8894
} else {
89-
console.warn('[useKakabotContext] Erro ao carregar contexto:', err?.message);
95+
console.warn('[useSyntaxContext] Erro ao carregar contexto:', err?.message);
9096
}
9197
} finally {
9298
if (!cancelled) setIsLoadingContext(false);
@@ -97,10 +103,9 @@ const useAdaContext = (uid) => {
97103

98104
// Listener para atualizar quando dados mudam
99105
const handlers = [
100-
'cinesia:resumo:alterado',
101-
'cinesia:flashcard:alterado',
102-
'cinesia:materia:alterada',
103-
'cinesia:evento:alterado',
106+
'syntax:projeto:alterado',
107+
'syntax:snippet:alterado',
108+
'syntax:tarefa:alterada',
104109
];
105110
const refresh = () => fetchContext();
106111
handlers.forEach((evt) => window.addEventListener(evt, refresh));
@@ -111,7 +116,7 @@ const useAdaContext = (uid) => {
111116
};
112117
}, [uid]);
113118

114-
return { dadosSistema, materiasLista, isLoadingContext };
119+
return { dadosSistema, projetosLista, isLoadingContext };
115120
};
116121

117-
export default useAdaContext;
122+
export default useSyntaxContext;

frontend/src/hooks/useAdaSessoes.js

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/**
2-
* @file useAdaSessoes.js
3-
* @description Gerencia criação, carregamento e persistência de sessões do AdaBot.
4-
* Cada sessão é um documento em users/{uid}/ada_sessoes/{sessaoId}.
2+
* @file useSyntaxSessoes.js
3+
* @description Gerencia criação, carregamento e persistência de sessões do Syntax,
4+
* assistente de engenharia de software e programação.
5+
* Cada sessão é um documento em users/{uid}/syntax_sessoes/{sessaoId}.
56
* Suporta carregamento paginado (MENSAGENS_INICIAIS + "carregar mais") para não
67
* sobrecarregar o chat com histórico extenso.
78
*
@@ -10,7 +11,7 @@
1011
* - firebase-config.js — instância db
1112
*
1213
* @sideEffects
13-
* - Lê e escreve em users/{uid}/ada_sessoes/{sessaoId}
14+
* - Lê e escreve em users/{uid}/syntax_sessoes/{sessaoId}
1415
* - Nenhum efeito externo além do Firestore
1516
*
1617
* @notes
@@ -43,18 +44,18 @@ const MENSAGENS_POR_PAGINA = 10;
4344
const MENSAGEM_BOAS_VINDAS_PADRAO = {
4445
role: 'assistant',
4546
content:
46-
'\ud83d\udc4b Olá! Sou o **Kaka**, seu parceiro de estudos em Fisioterapia!\n\nPosso te ajudar com dúvidas clínicas, criar flashcards, resumos, organizar matérias e agendar revisões. Por onde quer começar?',
47+
'👋 Olá! Sou o **Syntax**, seu assistente de engenharia de software.\n\nPosso te ajudar com revisão de código, debugging, arquitetura de sistemas, boas práticas, documentação e muito mais. Por onde quer começar?',
4748
};
4849

4950
/**
50-
* Hook para gerenciar sessões de conversa do KakaBot.
51+
* Hook para gerenciar sessões de conversa do Syntax.
5152
*
5253
* @param {string|null} uid - UID do usuário autenticado
5354
* @returns {{ sessaoAtual, mensagensVisiveis, totalMensagens, temMais, carregando,
5455
* novaSessao, carregarSessao, carregarMais, adicionarMensagem,
55-
* listarSessoes, setMensagensVisiveis }}
56+
* adicionarMensagemSemUI, listarSessoes, setMensagensVisiveis }}
5657
*/
57-
const useKakabotSessoes = (uid) => {
58+
const useSyntaxSessoes = (uid) => {
5859
const [sessaoAtual, setSessaoAtual] = useState(null);
5960
const [mensagensVisiveis, setMensagensVisiveis] = useState([]);
6061
const [totalMensagens, setTotalMensagens] = useState(0);
@@ -79,8 +80,8 @@ const useKakabotSessoes = (uid) => {
7980
* Aceita opcionalmente memória e dados do sistema para gerar mensagem contextual.
8081
* NOTE: não apaga sessões anteriores — ficam disponíveis no painel de histórico.
8182
*
82-
* @param {object} [memoria] - Estado memoriaUsuario (para mensagem contextual)
83-
* @param {object} [dadosSistema] - Dados do useKakabotContext (para mensagem contextual)
83+
* @param {object} [memoria] - Estado memoriausuario (para mensagem contextual)
84+
* @param {object} [dadosSistema] - Dados do useSyntaxContext (para mensagem contextual)
8485
* @returns {Promise<object|null>} Dados da sessão criada
8586
*/
8687
const novaSessao = useCallback(async (memoria, dadosSistema) => {
@@ -89,8 +90,8 @@ const useKakabotSessoes = (uid) => {
8990
const sessaoId = `sessao_${Date.now()}`;
9091
const agora = new Date();
9192

92-
// Gerar mensagem de abertura contextual se dados disponíveis
9393
let conteudoBoasVindas = MENSAGEM_BOAS_VINDAS_PADRAO.content;
94+
9495
if (memoria && dadosSistema) {
9596
try {
9697
const hora = agora.getHours();
@@ -99,27 +100,25 @@ const useKakabotSessoes = (uid) => {
99100
const stats = memoria?.estatisticasUso || {};
100101
const nome = pref.nomePreferido ? `, ${pref.nomePreferido}` : '';
101102
const totalMsgs = stats.totalMensagens || 0;
102-
const streakAtual = dadosSistema?.streakAtual || 0;
103-
const cardsHoje = dadosSistema?.cardsParaRevisarHoje || 0;
103+
const linguagemFavorita = pref.linguagemFavorita || null;
104+
const ultimoProjeto = dadosSistema?.ultimoProjeto || null;
104105

105106
if (totalMsgs === 0) {
106-
conteudoBoasVindas = `${saudacao}! Sou o Kaka, seu parceiro de estudos aqui no Cinesia. Pode me perguntar qualquer coisa sobre fisioterapia, pedir pra criar flashcards, resumos — o que precisar. Por onde quer começar?`;
107-
} else if (cardsHoje > 5) {
108-
conteudoBoasVindas = `${saudacao}${nome}. Você tem ${cardsHoje} cards esperando revisão hoje — quer resolver isso primeiro ou tinha algo em mente?`;
109-
} else if (streakAtual >= 7 && streakAtual % 7 === 0) {
110-
conteudoBoasVindas = `${saudacao}${nome}! ${streakAtual} dias seguidos — isso é consistência de verdade. O que vamos estudar hoje?`;
111-
} else if (streakAtual === 0 && totalMsgs > 0) {
112-
conteudoBoasVindas = `${saudacao}${nome}. Que bom que voltou! Às vezes a gente precisa de uma pausa mesmo. Quer retomar de onde parou?`;
107+
conteudoBoasVindas = `${saudacao}! Sou o Syntax, seu assistente de engenharia de software. Pode me mandar código pra revisar, tirar dúvidas sobre arquitetura, pedir ajuda com debugging — o que precisar. Por onde quer começar?`;
108+
} else if (ultimoProjeto) {
109+
conteudoBoasVindas = `${saudacao}${nome}. Continuando com **${ultimoProjeto}**? É só mandar o código ou me contar onde travou.`;
110+
} else if (linguagemFavorita) {
111+
conteudoBoasVindas = `${saudacao}${nome}. Mais um dia de código. Trabalhando com ${linguagemFavorita} hoje?`;
113112
} else {
114113
const aberturasGenericas = [
115-
`${saudacao}${nome}. O que tá rolando hoje?`,
116-
`${saudacao}${nome}. Pronto pra estudar?`,
117-
`${saudacao}${nome}. Tem ${cardsHoje} cards pra revisar. Quer começar por eles?`,
114+
`${saudacao}${nome}. Qual o problema de hoje?`,
115+
`${saudacao}${nome}. Pronto pra codar?`,
116+
`${saudacao}${nome}. Me manda o código ou descreve o que precisa.`,
118117
];
119118
conteudoBoasVindas = aberturasGenericas[Math.floor(Math.random() * aberturasGenericas.length)];
120119
}
121120
} catch (err) {
122-
console.warn('[useKakabotSessoes] Erro ao gerar mensagem contextual:', err?.message);
121+
console.warn('[useSyntaxSessoes] Erro ao gerar mensagem contextual:', err?.message);
123122
}
124123
}
125124

@@ -140,9 +139,9 @@ const useKakabotSessoes = (uid) => {
140139
};
141140

142141
try {
143-
await setDoc(doc(db, 'users', uid, 'kakabot_sessoes', sessaoId), novaSessaoData);
142+
await setDoc(doc(db, 'users', uid, 'syntax_sessoes', sessaoId), novaSessaoData);
144143
} catch (err) {
145-
console.warn('[useKakabotSessoes] Erro ao criar sessão:', err?.message);
144+
console.warn('[useSyntaxSessoes] Erro ao criar sessão:', err?.message);
146145
}
147146

148147
setSessaoAtual(novaSessaoData);
@@ -164,7 +163,7 @@ const useKakabotSessoes = (uid) => {
164163
if (!uid) return;
165164
setCarregando(true);
166165
try {
167-
const docRef = doc(db, 'users', uid, 'kakabot_sessoes', sessaoId);
166+
const docRef = doc(db, 'users', uid, 'syntax_sessoes', sessaoId);
168167
const snap = await getDoc(docRef);
169168
if (!snap.exists()) return;
170169

@@ -179,7 +178,7 @@ const useKakabotSessoes = (uid) => {
179178
setOffset(novoOffset);
180179
setTemMais(novoOffset > 0);
181180
} catch (err) {
182-
console.warn('[useKakabotSessoes] Erro ao carregar sessão:', err?.message);
181+
console.warn('[useSyntaxSessoes] Erro ao carregar sessão:', err?.message);
183182
} finally {
184183
setCarregando(false);
185184
}
@@ -188,7 +187,7 @@ const useKakabotSessoes = (uid) => {
188187
/**
189188
* Carrega o bloco anterior de mensagens ao clicar em "Carregar mensagens anteriores".
190189
* Insere no início do array visível sem perder a posição do scroll (responsabilidade
191-
* do componente — ver carregarMaisComScroll em KakaBot.jsx).
190+
* do componente — ver carregarMaisComScroll em Syntax.jsx).
192191
*/
193192
const carregarMais = useCallback(() => {
194193
if (!sessaoAtual || !temMais) return;
@@ -222,7 +221,7 @@ const useKakabotSessoes = (uid) => {
222221

223222
// GUARD: sessão deve existir antes de adicionar mensagens
224223
if (!uid || !sessaoAtual?.id) {
225-
console.error('[KakaBot] Tentativa de salvar mensagem sem sessão ativa');
224+
console.error('[Syntax] Tentativa de salvar mensagem sem sessão ativa');
226225
return;
227226
}
228227

@@ -244,14 +243,12 @@ const useKakabotSessoes = (uid) => {
244243

245244
try {
246245
await setDoc(
247-
doc(db, 'users', uid, 'kakabot_sessoes', sessaoAtual.id),
246+
doc(db, 'users', uid, 'syntax_sessoes', sessaoAtual.id),
248247
sessaoAtualizada,
249248
{ merge: true }
250249
);
251-
// TODO: remover log após confirmar que está salvando corretamente
252-
console.warn('[KakaBot] Sessão salva:', sessaoAtual.id, '| Total:', sessaoAtualizada.totalMensagens);
253250
} catch (err) {
254-
console.error('[KakaBot] Erro ao salvar sessão:', err);
251+
console.error('[Syntax] Erro ao salvar sessão:', err);
255252
}
256253

257254
setSessaoAtual(sessaoAtualizada);
@@ -285,13 +282,12 @@ const useKakabotSessoes = (uid) => {
285282

286283
try {
287284
await setDoc(
288-
doc(db, 'users', uid, 'kakabot_sessoes', sessaoAtual.id),
285+
doc(db, 'users', uid, 'syntax_sessoes', sessaoAtual.id),
289286
sessaoAtualizada,
290287
{ merge: true }
291288
);
292-
console.warn('[KakaBot] Sessão salva (sem UI):', sessaoAtual.id, '| Total:', sessaoAtualizada.totalMensagens);
293289
} catch (err) {
294-
console.error('[KakaBot] Erro ao salvar sessão:', err);
290+
console.error('[Syntax] Erro ao salvar sessão:', err);
295291
}
296292

297293
setSessaoAtual(sessaoAtualizada);
@@ -307,12 +303,12 @@ const useKakabotSessoes = (uid) => {
307303
const listarSessoes = useCallback(async () => {
308304
if (!uid) return [];
309305
try {
310-
const ref = collection(db, 'users', uid, 'kakabot_sessoes');
306+
const ref = collection(db, 'users', uid, 'syntax_sessoes');
311307
const q = query(ref, orderBy('ultimaAtualizacao', 'desc'), limit(15));
312308
const snap = await getDocs(q);
313309
return snap.docs.map((d) => d.data());
314310
} catch (err) {
315-
console.warn('[useKakabotSessoes] Erro ao listar sessões:', err?.message);
311+
console.warn('[useSyntaxSessoes] Erro ao listar sessões:', err?.message);
316312
return [];
317313
}
318314
}, [uid]);
@@ -329,9 +325,8 @@ const useKakabotSessoes = (uid) => {
329325
adicionarMensagem,
330326
adicionarMensagemSemUI,
331327
listarSessoes,
332-
// Exposto para addSystemMessage poder adicionar msgs transientes sem Firestore
333328
setMensagensVisiveis,
334329
};
335330
};
336331

337-
export default useKakabotSessoes;
332+
export default useSyntaxSessoes;

0 commit comments

Comments
 (0)