Files
openmonetis/app/(dashboard)/changelog/page.tsx
Felipe Coutinho fd817683ca feat: implementar sistema de preferências do usuário e refatorar changelog
Adiciona sistema completo de preferências de usuário:
  - Cria tabela userPreferences no schema com campos disableMagnetlines, periodMonthsBefore e periodMonthsAfter
  - Implementa página de Ajustes com abas (Preferências, Alterar nome, Senha, E-mail, Deletar conta)
  - Adiciona componente PreferencesForm para configuração de magnetlines e períodos de exibição
  - Propaga periodPreferences para todos os componentes de lançamentos e calendário

  Refatora sistema de changelog:
  - Remove implementação anterior baseada em JSON estático
  - Adiciona nova página de changelog dinâmica em app/(dashboard)/changelog
  - Adiciona componente changelog-list.tsx
  - Remove arquivos obsoletos (changelog-notification, actions, data, utils, scripts)

  Adiciona controle de saldo inicial em contas:
  - Novo campo excludeInitialBalanceFromIncome em contas
  - Permite excluir saldo inicial do cálculo de receitas
  - Atualiza queries de lançamentos para respeitar esta configuração

  Melhorias adicionais:
  - Adiciona componente ui/accordion.tsx do shadcn/ui
  - Refatora formatPeriodLabel para displayPeriod centralizado
  - Propaga estabelecimentos para componentes de lançamentos
  - Remove variável DB_PROVIDER obsoleta do .env.example e documentação
  - Adiciona 6 migrações de banco de dados (0003-0008)
2026-01-03 14:18:03 +00:00

103 lines
2.5 KiB
TypeScript

import { ChangelogList } from "@/components/changelog/changelog-list";
import { execSync } from "child_process";
type GitCommit = {
hash: string;
shortHash: string;
author: string;
date: string;
message: string;
body: string;
filesChanged: string[];
};
function getGitRemoteUrl(): string | null {
try {
const remoteUrl = execSync("git config --get remote.origin.url", {
encoding: "utf-8",
cwd: process.cwd(),
}).trim();
// Converter SSH para HTTPS se necessário
if (remoteUrl.startsWith("git@")) {
return remoteUrl
.replace("git@github.com:", "https://github.com/")
.replace("git@gitlab.com:", "https://gitlab.com/")
.replace(".git", "");
}
return remoteUrl.replace(".git", "");
} catch (error) {
console.error("Error fetching git remote URL:", error);
return null;
}
}
function getGitCommits(): GitCommit[] {
try {
// Buscar os últimos 50 commits
const commits = execSync(
'git log -50 --pretty=format:"%H|%h|%an|%ad|%s|%b" --date=iso --name-only',
{
encoding: "utf-8",
cwd: process.cwd(),
}
)
.trim()
.split("\n\n");
return commits
.map((commitBlock) => {
const lines = commitBlock.split("\n");
const [hash, shortHash, author, date, message, ...rest] =
lines[0].split("|");
// Separar body e arquivos
const bodyLines: string[] = [];
const filesChanged: string[] = [];
let isBody = true;
rest.forEach((line) => {
if (line && !line.includes("/") && !line.includes(".")) {
bodyLines.push(line);
} else {
isBody = false;
}
});
lines.slice(1).forEach((line) => {
if (line.trim()) {
filesChanged.push(line.trim());
}
});
return {
hash,
shortHash,
author,
date,
message,
body: bodyLines.join("\n").trim(),
filesChanged: filesChanged.filter(
(f) => f && !f.startsWith("git log")
),
};
})
.filter((commit) => commit.hash && commit.message);
} catch (error) {
console.error("Error fetching git commits:", error);
return [];
}
}
export default async function ChangelogPage() {
const commits = getGitCommits();
const repoUrl = getGitRemoteUrl();
return (
<main>
<ChangelogList commits={commits} repoUrl={repoUrl} />
</main>
);
}