From d9c778d4c1f34e62445f2b36e75aa3ba46bfd6b0 Mon Sep 17 00:00:00 2001 From: Mateus Martinez rosa Date: Tue, 26 Aug 2025 17:56:43 -0300 Subject: [PATCH 1/2] =?UTF-8?q?feat/implementando=20tabela=20de=20=C3=BAlt?= =?UTF-8?q?ima=20atividade=20para=20usu=C3=A1rios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0055-f_insere_log_atividade.pgsql | 34 +++++++++++++++++++ .../20231228211508_session/migration.sql | 23 ------------- .../migration.sql | 22 ++++++++++++ backend/prisma/schema.prisma | 26 +++++++++++--- .../src/pessoa/entities/list-pessoa.entity.ts | 2 ++ backend/src/pessoa/pessoa.service.ts | 12 ++++++- 6 files changed, 91 insertions(+), 28 deletions(-) create mode 100644 backend/prisma/manual-copy/0055-f_insere_log_atividade.pgsql create mode 100644 backend/prisma/migrations/20250826182728_add_pessoa_ultima_atividade/migration.sql diff --git a/backend/prisma/manual-copy/0055-f_insere_log_atividade.pgsql b/backend/prisma/manual-copy/0055-f_insere_log_atividade.pgsql new file mode 100644 index 0000000000..d108e3bf30 --- /dev/null +++ b/backend/prisma/manual-copy/0055-f_insere_log_atividade.pgsql @@ -0,0 +1,34 @@ +CREATE OR REPLACE FUNCTION f_insere_log_atividade( + p_pessoa_id INTEGER, + p_ip INET, + p_pessoa_sessao_id INTEGER +) +RETURNS VOID +LANGUAGE plpgsql +AS $$ +DECLARE + v_existing_count INTEGER; +BEGIN + INSERT INTO pessoa_ultima_atividade + (pessoa_id, pessoa_sessao_id, ip, ultima_atividade_em) + VALUES + (p_pessoa_id, p_pessoa_sessao_id, p_ip, NOW()) + ON CONFLICT (pessoa_id) DO UPDATE + SET pessoa_sessao_id = EXCLUDED.pessoa_sessao_id, + ip = EXCLUDED.ip, + ultima_atividade_em = EXCLUDED.ultima_atividade_em; + + SELECT COUNT(*) + INTO v_existing_count + FROM pessoa_atividade_log + WHERE pessoa_sessao_id = p_pessoa_sessao_id + AND criado_em > (NOW() - INTERVAL '1 minute'); + + IF v_existing_count = 0 THEN + INSERT INTO pessoa_atividade_log + (pessoa_id, ip, pessoa_sessao_id, criado_em) + VALUES + (p_pessoa_id, p_ip, p_pessoa_sessao_id, NOW()); + END IF; +END; +$$; diff --git a/backend/prisma/migrations/20231228211508_session/migration.sql b/backend/prisma/migrations/20231228211508_session/migration.sql index dbf2b52596..66a6630750 100644 --- a/backend/prisma/migrations/20231228211508_session/migration.sql +++ b/backend/prisma/migrations/20231228211508_session/migration.sql @@ -44,26 +44,3 @@ ALTER TABLE "pessoa_atividade_log" ADD CONSTRAINT "pessoa_atividade_log_pessoa_i -- AddForeignKey ALTER TABLE "pessoa_atividade_log" ADD CONSTRAINT "pessoa_atividade_log_pessoa_sessao_id_fkey" FOREIGN KEY ("pessoa_sessao_id") REFERENCES "pessoa_sessao"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - - -CREATE OR REPLACE FUNCTION f_insere_log_atividade( - p_pessoa_id INTEGER, - p_ip INET, - p_pessoa_sessao_id INTEGER -) -RETURNS VOID AS $$ -DECLARE - v_existing_count INTEGER; -BEGIN - SELECT COUNT(*) - INTO v_existing_count - FROM pessoa_atividade_log - WHERE pessoa_sessao_id = p_pessoa_sessao_id - AND criado_em > (NOW() - INTERVAL '1 minute'); - - IF v_existing_count = 0 THEN - INSERT INTO pessoa_atividade_log (pessoa_id, ip, pessoa_sessao_id, criado_em) - VALUES (p_pessoa_id, p_ip, p_pessoa_sessao_id, NOW()); - END IF; -END; -$$ LANGUAGE plpgsql; diff --git a/backend/prisma/migrations/20250826182728_add_pessoa_ultima_atividade/migration.sql b/backend/prisma/migrations/20250826182728_add_pessoa_ultima_atividade/migration.sql new file mode 100644 index 0000000000..55e58dbed9 --- /dev/null +++ b/backend/prisma/migrations/20250826182728_add_pessoa_ultima_atividade/migration.sql @@ -0,0 +1,22 @@ +-- CreateTable +CREATE TABLE "pessoa_ultima_atividade" ( + "id" SERIAL NOT NULL, + "pessoa_id" INTEGER NOT NULL, + "pessoa_sessao_id" INTEGER, + "ip" INET NOT NULL, + "ultima_atividade_em" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "pessoa_ultima_atividade_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE INDEX "pessoa_ultima_atividade_ultima_atividade_em_idx" ON "pessoa_ultima_atividade"("ultima_atividade_em"); + +-- CreateIndex +CREATE UNIQUE INDEX "pessoa_ultima_atividade_pessoa_id_key" ON "pessoa_ultima_atividade"("pessoa_id"); + +-- AddForeignKey +ALTER TABLE "pessoa_ultima_atividade" ADD CONSTRAINT "pessoa_ultima_atividade_pessoa_id_fkey" FOREIGN KEY ("pessoa_id") REFERENCES "pessoa"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "pessoa_ultima_atividade" ADD CONSTRAINT "pessoa_ultima_atividade_pessoa_sessao_id_fkey" FOREIGN KEY ("pessoa_sessao_id") REFERENCES "pessoa_sessao"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 452b5278cc..c407d6a635 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -501,6 +501,8 @@ model Pessoa { AtualizacoesEmLoteCriadas AtualizacaoEmLote[] @relation("AtualizacaoEmLoteCriador") AtualizacoesEmLoteRemovidas AtualizacaoEmLote[] @relation("AtualizacaoEmLoteRemovedor") + ultimaAtividade PessoaUltimaAtividade? + @@index([email]) @@map("pessoa") } @@ -3502,7 +3504,7 @@ model Relatorio { sistema ModuloSistema @default(SMAE) - resumo_saida Json @db.Json @default("{}") + resumo_saida Json @default("{}") @db.Json // Coluna espelhada da RelatorioFilha, para facilitar a busca. processado_em DateTime? @db.Timestamptz(6) @@ -4853,9 +4855,10 @@ model PessoaSessao { removido_em DateTime? removido_ip String? @db.Inet - PessoaSessaoAtiva PessoaSessaoAtiva[] - PessoaAtividadeLog PessoaAtividadeLog[] - LogGenerico LogGenerico[] + PessoaSessaoAtiva PessoaSessaoAtiva[] + PessoaAtividadeLog PessoaAtividadeLog[] + LogGenerico LogGenerico[] + PessoaUltimaAtividade PessoaUltimaAtividade[] @@index([pessoa_id]) @@map("pessoa_sessao") @@ -7822,3 +7825,18 @@ enum ApiRequestLogControlStatus { FAILED_BACKUP FAILED_RESTORE } + +model PessoaUltimaAtividade { + id Int @id @default(autoincrement()) + pessoa_id Int + pessoa_sessao_id Int? + ip String @db.Inet + ultima_atividade_em DateTime @default(now()) @db.Timestamptz(6) + + pessoa Pessoa @relation(fields: [pessoa_id], references: [id], onDelete: Cascade) + sessao PessoaSessao? @relation(fields: [pessoa_sessao_id], references: [id], onDelete: SetNull) + + @@unique([pessoa_id]) + @@index([ultima_atividade_em]) + @@map("pessoa_ultima_atividade") +} diff --git a/backend/src/pessoa/entities/list-pessoa.entity.ts b/backend/src/pessoa/entities/list-pessoa.entity.ts index 2dd06cea2f..db4345b329 100644 --- a/backend/src/pessoa/entities/list-pessoa.entity.ts +++ b/backend/src/pessoa/entities/list-pessoa.entity.ts @@ -19,4 +19,6 @@ export class ListPessoa { cargo?: string | null; registro_funcionario?: string | null; cpf?: string | null; + + ultima_atividade_em?: Date | null; } diff --git a/backend/src/pessoa/pessoa.service.ts b/backend/src/pessoa/pessoa.service.ts index 5e39d5e0fe..7929a68da0 100644 --- a/backend/src/pessoa/pessoa.service.ts +++ b/backend/src/pessoa/pessoa.service.ts @@ -1416,6 +1416,7 @@ export class PessoaService implements OnModuleInit { perfil_acesso_id: true, }, }, + ultimaAtividade: { select: { ultima_atividade_em: true } }, }, }); @@ -1433,10 +1434,19 @@ export class PessoaService implements OnModuleInit { lotacao: p.pessoa_fisica?.lotacao ? p.pessoa_fisica.lotacao : undefined, orgao_id: p.pessoa_fisica?.orgao_id || undefined, perfil_acesso_ids: p.PessoaPerfil.map((e) => e.perfil_acesso_id).filter((e) => visiblePriv.includes(e)), + ultima_atividade_em: p.ultimaAtividade?.ultima_atividade_em ?? null, }; }); - this.logger.log(`encontrado ${listFixed.length} resultados`); + const teste = await this.prisma.pessoa.findFirst({ + where: { id: 1 }, // use o ID que vocĂȘ mostrou no print + select: { + id: true, + ultimaAtividade: { select: { ultima_atividade_em: true } }, + }, + }); + this.logger.log('teste ultimaAtividade =teste ultimaAtividade =teste ultimaAtividade =teste ultimaAtividade =teste ultimaAtividade =teste ultimaAtividade =teste ultimaAtividade =', teste); + return listFixed; } From 9922fe9ac4b319a03c758bbf0ba9539e4c89089b Mon Sep 17 00:00:00 2001 From: Mateus Martinez rosa Date: Tue, 26 Aug 2025 18:08:08 -0300 Subject: [PATCH 2/2] fix/removendo logs e testes de debug --- backend/src/pessoa/pessoa.service.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/backend/src/pessoa/pessoa.service.ts b/backend/src/pessoa/pessoa.service.ts index 7929a68da0..7d54c7a5dc 100644 --- a/backend/src/pessoa/pessoa.service.ts +++ b/backend/src/pessoa/pessoa.service.ts @@ -1438,16 +1438,6 @@ export class PessoaService implements OnModuleInit { }; }); - const teste = await this.prisma.pessoa.findFirst({ - where: { id: 1 }, // use o ID que vocĂȘ mostrou no print - select: { - id: true, - ultimaAtividade: { select: { ultima_atividade_em: true } }, - }, - }); - this.logger.log('teste ultimaAtividade =teste ultimaAtividade =teste ultimaAtividade =teste ultimaAtividade =teste ultimaAtividade =teste ultimaAtividade =teste ultimaAtividade =', teste); - - return listFixed; }