docs & fixes
All checks were successful
Mindforge Cronjob Build and Deploy / Build Mindforge Cronjob Image (push) Successful in 4m12s
Mindforge Cronjob Build and Deploy / Deploy Mindforge Cronjob (internal) (push) Successful in 36s
Mindforge Web Build and Deploy (internal) / Build Mindforge Web Image (push) Successful in 5m30s
Mindforge Web Build and Deploy (internal) / Deploy Mindforge Web (internal) (push) Successful in 8s

This commit is contained in:
2026-06-11 15:30:09 -03:00
parent 097ba577cf
commit 82dda0395d
9 changed files with 133 additions and 348 deletions

View File

@@ -1,15 +1,18 @@
# Agents
# Agentes
Have a read in `project-context.md` file, it will be the main source of truth for the project. Always keep it up to date with the latest project specs and architecture decisions.
Leia o arquivo `project-context.md`, pois ele é a principal fonte de verdade do projeto.
## UI specs
- All UI needs to be have a glassy-look, with a not-so-dark background
- Buttons needs to appear iOS-like and modern
- All text inputs, displays and content should appear with a modern typefont
- All texts needs to be in Brazilian Portuguese
## Manutenção do project-context
- Mantenha o `project-context.md` sempre atualizado com o estado atual do projeto, sem transformá-lo em histórico de mudanças.
- Sempre que houver alteração em arquitetura, endpoints, contratos de API, variáveis de ambiente, UI/UX, fluxos de produto ou decisões técnicas, atualize o `project-context.md` na mesma entrega.
## Testing
Follow strictly the testing requirements:
- It should NOT have any form of integration testing, nor unit testing, or any kind of testing.
- The only type of testing that should be done is building the project - make sure it compiles, and it's enough.
- Don't create random tests or any kind of files that is related to testing. All testing will be done by a human later on.
## Especificações de UI
- Toda a interface precisa ter aparência de vidro, com um fundo não tão escuro.
- Os botões precisam parecer modernos, no estilo iOS.
- Todos os campos de texto, exibições e conteúdos devem ter uma tipografia moderna.
- Todos os textos precisam estar em português brasileiro.
## Testes
- Não deve haver nenhuma forma de teste de integração, nem teste unitário, nem qualquer outro tipo de teste.
- O único tipo de validação que deve ser feito é compilar o projeto - basta verificar se ele compila.
- Toda a validação será feita por um humano depois.

View File

@@ -98,7 +98,7 @@ export function SpacedReviewComponent() {
const [dashboard, setDashboard] = useState<FlashcardRagDashboardResponse | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [selectedStatuses, setSelectedStatuses] = useState<FlashcardRagStatus[]>(['Red', 'Amber']);
const [selectedStatuses, setSelectedStatuses] = useState<FlashcardRagStatus[]>(['Red', 'Amber', 'Green', 'Grey']);
const [selectedLibraryIds, setSelectedLibraryIds] = useState<number[]>([]);
const [startingSession, setStartingSession] = useState(false);
const [sessionCards, setSessionCards] = useState<FlashcardCard[]>([]);
@@ -129,6 +129,14 @@ export function SpacedReviewComponent() {
const kept = current.filter((libraryId) => available.has(libraryId));
return kept.length > 0 ? kept : allLibraryIds;
});
setSelectedStatuses((current) => {
if (current.length > 0) {
return current;
}
return ['Red', 'Amber', 'Green', 'Grey'];
});
} catch (err: any) {
setError(err?.message || 'Falha ao carregar status de revisao espacada.');
} finally {
@@ -214,7 +222,7 @@ export function SpacedReviewComponent() {
}
if (selectedRagLibraries.length === 0) {
setError('Nenhum arquivo encontrado com os filtros selecionados.');
setError('Nenhum arquivo encontrado com os filtros atuais. Ajuste os status ou os arquivos selecionados.');
return;
}
@@ -400,7 +408,7 @@ export function SpacedReviewComponent() {
</p>
<Button
variant="primary"
disabled={startingSession || selectedRagLibraries.length === 0}
disabled={startingSession || loading}
onClick={startSession}
>
{startingSession ? 'Iniciando...' : 'Iniciar Revisao Espacada'}

View File

@@ -1,3 +1,3 @@
## Mindforge Architecture
# Arquitetura do Mindforge
This is a project that will be used to aid the user in making notes and studying for hard exams and tests.
Este é um projeto que será usado para ajudar o usuário a fazer anotações e estudar para provas e testes difíceis.

11
dev.ps1
View File

@@ -1,11 +0,0 @@
# Starting Mindforge Development Environment
# Start API
Write-Host "Starting Mindforge.API..." -ForegroundColor Cyan
Start-Process powershell -ArgumentList "-NoExit", "-Command", "dotnet run --project Mindforge.API"
# Start Web
Write-Host "Starting Mindforge.Web..." -ForegroundColor Cyan
Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd Mindforge.Web; npm run dev"
Write-Host "Both projects are starting in separate windows." -ForegroundColor Green

19
dev.sh
View File

@@ -1,19 +0,0 @@
#!/bin/bash
# Function to handle script termination
cleanup() {
echo "Shutting down..."
kill $(jobs -p)
exit
}
trap cleanup SIGINT SIGTERM
echo "Starting Mindforge.API..."
(cd Mindforge.API && dotnet run) &
echo "Starting Mindforge.Web..."
(cd Mindforge.Web && npm run dev) &
echo "Both projects are running. Press Ctrl+C to stop both."
wait

View File

@@ -1,10 +1,11 @@
# Mindforge.Cronjob
The project is called Mindforge.Cronjob, it's a small part of a bigger project called **Mindforge**.
The main purpose of it is to create small summaries on `.md` documents in Brazilian Portuguese language using AI API calls.
O projeto se chama Mindforge.Cronjob e faz parte de um projeto maior chamado **Mindforge**.
## How it works
O objetivo principal dele é criar pequenos resumos de documentos `.md` em português brasileiro usando chamadas de API de IA.
This project will fetch all the changes in a Git repository from the last 7 days, and will create a summary of all the changes in a single `.md` file.
## Como funciona
It will use either Gemini or ChatGPT API to create the summary.
Este projeto busca todas as alterações em um repositório Git dos últimos 7 dias e cria um resumo de todas as mudanças em um único arquivo `.md`.
Ele usa a API do Gemini ou do ChatGPT para gerar o resumo.

View File

@@ -1,6 +1,6 @@
# Deploy
# Implantação
## Setup environment
## Configuração do ambiente
```bash
kubectl create ns mindforge
@@ -13,7 +13,7 @@ kubectl create secret generic mindforge-secrets -n mindforge \
--from-literal=SSH_PRIVATE_KEY="your_ssh_private_key"
```
## Deployment itself
## Implantação
```bash
kubectl apply -f mindforge-cronjob.yaml

View File

@@ -1,34 +1,36 @@
# Mindforge
## Visao Geral (Overview)
## Visão Geral
Mindforge e uma ferramenta de estudo para auxiliar na preparacao para concursos publicos brasileiros. O sistema permite validar e gerar materiais de estudo a partir de arquivos Markdown hospedados em repositorios Git, utilizando IA (OpenRouter/OpenAI-compatible API) para processamento.
Mindforge é uma ferramenta de estudo para auxiliar na preparação para concursos públicos brasileiros. O sistema permite validar e gerar materiais de estudo a partir de arquivos Markdown hospedados em repositórios Git, utilizando IA (API compatível com OpenRouter/OpenAI) para processamento.
A interface e em **portugues brasileiro** e possui um tema escuro com efeito vidro ("glassy-look").
A interface é em **português brasileiro** e possui um tema escuro com efeito vidro ("glassy-look").
---
## Tech Stack
## Stack Tecnológica
### Frontend (Mindforge.Web)
| Tecnologia | Versao | Finalidade |
| Tecnologia | Versão | Finalidade |
|---|---|---|
| **Preact** | ^10.29.0 | UI library (lightweight React alternative) |
| **Vite** | ^8.0.1 | Build tool e dev server |
| **TypeScript** | ~5.9.3 | Tipagem estatica |
| **marked** | ^17.0.4 | Renderizacao Markdown -> HTML |
| **Preact** | ^10.29.0 | Biblioteca de interface (alternativa leve ao React) |
| **Vite** | ^8.0.1 | Ferramenta de build e servidor de desenvolvimento |
| **TypeScript** | ~5.9.3 | Tipagem estática |
| **marked** | ^17.0.4 | Renderização Markdown -> HTML |
| **diff** | ^8.0.3 | Diff de texto (word-level) |
| **Google Fonts (Lato)** | 300/400/700 | Tipografia da interface |
### Backend API (Mindforge.API)
| Tecnologia | Versao | Finalidade |
| Tecnologia | Versão | Finalidade |
|---|---|---|
| **.NET 9** | net9.0 | ASP.NET Core Web API |
| **C#** | - | Linguagem |
| **Microsoft.AspNetCore.OpenApi** | 9.0.12 | Suporte OpenAPI/Swagger |
| **Dapper** | 2.1.66 | Acesso a dados do domínio de flashcards |
| **Npgsql** | 9.0.4 | Driver PostgreSQL para persistência de flashcards |
### Cronjob (mindforge.cronjob)
| Tecnologia | Versao | Finalidade |
| Tecnologia | Versão | Finalidade |
|---|---|---|
| **Go** | 1.22 | Linguagem |
| **godotenv** | v1.5.1 | Carregamento de arquivos .env |
@@ -41,163 +43,37 @@ A interface e em **portugues brasileiro** e possui um tema escuro com efeito vid
| **Gitea** | Git hosting + Container registry (`git.ivanch.me`) |
| **Gitea Actions** | CI/CD (build & deploy no push para main) |
| **Nginx Ingress** | K8s ingress controller |
| **OpenRouter API** | Provedor LLM (endpoint OpenAI-compatible) |
| **OpenRouter API** | Provedor LLM (endpoint compatível com OpenAI) |
---
## Arquitetura (Architecture)
## Arquitetura
O projeto e um **monorepo** com tres servicos independentes e deployaveis separadamente.
```
┌─────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ mindforge-web │ │ mindforge-api│ │ cronjob │ │
│ │ (Preact SPA) │──│ (.NET 9 API) │ │ (Go app) │ │
│ │ port 80 │ │ port 8080 │ │ (weekly) │ │
│ └──────────────┘ └──────┬───────┘ └─────┬─────┘ │
│ │ │ │ │
│ mindforge.haven api.mindforge.haven │ │
└──────────────────────────┼─────────────────┼───────┘
│ │
┌──────┴───────┐ ┌──────┴───────┐
│ OpenRouter │ │ Gitea │
│ (OpenAI API)│ │ (Git repos) │
└──────────────┘ └──────┬───────┘
┌────────┴────────┐
│ Discord │
│ Webhooks │
└─────────────────┘
```
### Servicos
#### 1. Mindforge.Web (Frontend)
- **Tipo**: Single Page Application (SPA)
- **Funcao**: Interface do usuario para validacao de arquivos e geracao de flashcards
- **Modulos**: Home, Verificador, Flashcards
- **Roteamento**: State-based manual via `useState` (nao usa react-router). Componentes sao alternados com `display: block/none`.
- **Estado**: Apenas `useState`/`useEffect` locais. Sem store global, sem Context API.
#### 2. Mindforge.API (Backend)
- **Tipo**: REST API
- **Padrao arquitetural**: Clean layered architecture
- **Controllers** -> validacao e roteamento HTTP
- **Services** -> logica de negocio (FileService, FlashcardService, AgentService, GiteaService)
- **Providers** -> abstracao de APIs externas (OpenAIApiProvider implementa ILlmApiProvider)
- **Middlewares** -> cross-cutting concerns (ExceptionHandlingMiddleware)
- **Models** -> DTOs e tipos de request/response
- **DI**: Todos servicos e providers registrados como Scoped
- **CORS**: Allow all origins
- **Auth**: Nenhuma no momento
#### 3. Mindforge.Cronjob (Background Worker)
- **Tipo**: Kubernetes CronJob
- **Schedule**: Sabados as 9:00 AM
- **Pipeline**:
1. Clona repositorio Git via SSH
2. Encontra arquivos modificados nos ultimos 7 dias (`.md`, exceto `Conteudos.md`)
3. Filtra commits de "refactor" via `git log`
4. Ranqueia por linhas alteradas, seleciona top N (default 10)
5. Gera resumo em texto com IA para cada arquivo
6. Formata resumo em Markdown
7. Envia para Discord via webhook (chunked em 1800 chars)
- **Error handling**: Reporta ao Haven Notify
### Decisoes de Arquitetura (Architecture Decisions)
1. **Sem banco de dados**: Totalmente stateless. Conteudo de estudo vive em repositorios Git, acessados via Gitea API em tempo de request.
2. **Git como content store**: Nao ha upload de arquivos - o conteudo e lido diretamente do repositorio Git.
3. **IA como engine de processamento**: Toda validacao e geracao e delegada ao LLM via OpenRouter.
4. **Provider abstraction**: `ILlmApiProvider` permite trocar o backend de IA sem alterar a logica de negocio.
5. **Monorepo com deploys independentes**: Cada servico tem seu proprio Dockerfile, manifesto K8s e pipeline CI.
6. **Roteamento manual no frontend**: Sem lib de router, toggle de visibilidade via estado.
7. **Preact em vez de React**: Bundle size menor.
O projeto é um monorepo com três serviços independentes.
- `Mindforge.Web`: SPA em Preact/Vite com navegação manual por estado e sem `react-router`.
- `Mindforge.API`: REST API em camadas com Controllers, Services, Repositories, Providers, Middlewares e Models; o domínio de flashcards é persistido em PostgreSQL (`mindforge`) via `Dapper` + `Npgsql`, com schema criado no startup.
- `mindforge.cronjob`: worker em Go executado semanalmente para resumir alterações recentes em arquivos `.md`.
- Integrações principais: OpenRouter para IA, Gitea como repositório de conteúdo e Discord via webhook para notificações.
- Deploy: cada serviço possui Dockerfile, manifesto Kubernetes e pipeline independente no Gitea Actions.
- Decisões-chave: Git como content store, revisão espaçada calculada em leitura e Preact em vez de React.
---
## Estrutura do Projeto (Project Structure)
## Estrutura do Projeto
```
mindforge/
├── AGENTS.md # Instrucoes para agentes AI
├── project-context.md # Este arquivo - fonte da verdade do projeto
├── README.md
├── mindforge.png # Logo do projeto
├── dev.ps1 / dev.sh # Scripts de inicializacao dev
├── .gitea/workflows/ # CI/CD pipelines
│ ├── mindforge-api.yaml
│ ├── mindforge-web.yaml
│ └── mindforge-cronjob.yaml
├── Mindforge.API/ # Backend .NET 9
│ ├── Program.cs # Entry point: DI, CORS, middleware
│ ├── Controllers/
│ │ ├── FileController.cs # POST /api/v1/file/check
│ │ ├── FlashcardController.cs # POST /api/v1/flashcard/generate
│ │ └── RepositoryController.cs # GET /api/v1/repository/*
│ ├── Services/ # Logica de negocio
│ │ ├── AgentService.cs
│ │ ├── FileService.cs
│ │ ├── FlashcardService.cs
│ │ ├── GiteaService.cs
│ │ └── Interfaces/
│ ├── Providers/
│ │ ├── ILlmApiProvider.cs # Interface do provedor LLM
│ │ └── OpenAIApiProvider.cs # Implementacao OpenAI/OpenRouter com retry
│ ├── Middlewares/
│ │ └── ExceptionHandlingMiddleware.cs
│ ├── Models/
│ │ ├── FileTreeNode.cs
│ │ └── Requests/ # DTOs de request
│ ├── Exceptions/
│ │ └── UserException.cs # 400 Bad Request customizado
│ └── deploy/
│ └── mindforge-api.yaml # Manifest K8s (Deployment + Service + Ingress)
├── Mindforge.Web/ # Frontend Preact + Vite
│ ├── vite.config.ts
│ ├── tsconfig.app.json # Target ES2023, JSX preact, strict mode
│ ├── .env # VITE_API_BASE_URL=http://localhost:5123
│ ├── src/
│ │ ├── main.tsx # Entry point
│ │ ├── app.tsx # Componente raiz: header, sidebar, modulos
│ │ ├── app.css # Estilos hero, animacoes
│ │ ├── index.css # CSS variables, reset, layout base
│ │ ├── services/
│ │ │ └── MindforgeApiService.ts # Cliente API (fetch, interfaces tipadas)
│ │ └── components/
│ │ ├── Button.tsx / .css # Botao reutilizavel (primary/secondary)
│ │ ├── Header.tsx / .css # Header fixo com logo + nome do repo
│ │ ├── Sidebar.tsx / .css # Navegacao lateral
│ │ ├── VerificadorComponent.tsx / .css # Validador de arquivos
│ │ ├── FlashcardComponent.tsx / .css # Gerador de flashcards
│ │ └── FileTreeComponent.tsx / .css # Arvore de arquivos do repo
│ └── deploy/
│ └── mindforge-web.yaml # Manifest K8s
└── mindforge.cronjob/ # CronJob em Go
├── cmd/mindforge.cronjob/main.go # Entry point
├── internal/
│ ├── agent/agent.go # Cria e formata resumos
│ ├── llm/ # Servico LLM
│ ├── git/git.go # Clone, diff, SSH
│ ├── errors/errors.go # Reporte de erros
│ └── message/messages.go # Notificacoes Discord
└── deploy/
└── mindforge-cronjob.yaml # Manifest K8s CronJob
```
- `mindforge/`: raiz do projeto com documentação, scripts, logo e workflows do Gitea.
- `Mindforge.API/`: backend .NET 9 com controllers, services, repositories, providers, models e deploy Kubernetes.
- `Mindforge.Web/`: frontend Preact + Vite com componentes de interface, cliente de API e deploy Kubernetes.
- `mindforge.cronjob/`: worker em Go com lógica de IA, Git, erros e mensagens do Discord, além do deploy Kubernetes.
---
## API Endpoints
## Endpoints da API
### File Controller (`/api/v1/file`)
| Metodo | Rota | Descricao |
### Controller de Arquivos (`/api/v1/file`)
| Método | Rota | Descrição |
|---|---|---|
| POST | `/api/v1/file/check` | Valida linguagem ou conteudo de um arquivo |
| POST | `/api/v1/file/check` | Valida a linguagem ou o conteúdo de um arquivo |
```json
// Request
@@ -213,64 +89,59 @@ mindforge/
}
```
### Flashcard Controller (`/api/v1/flashcard`)
| Metodo | Rota | Descricao |
### Controller de Flashcards (`/api/v1/flashcard`)
| Método | Rota | Descrição |
|---|---|---|
| POST | `/api/v1/flashcard/generate` | Gera flashcards em CSV |
| POST | `/api/v1/flashcard/generate` | Gera ou substitui bibliotecas de flashcards a partir dos arquivos selecionados |
| GET | `/api/v1/flashcard/libraries` | Lista todas as bibliotecas persistidas |
| GET | `/api/v1/flashcard/libraries/{id}` | Retorna uma biblioteca específica com seus cards |
| POST | `/api/v1/flashcard/review-session` | Inicia uma sessão de revisão com bibliotecas selecionadas |
| POST | `/api/v1/flashcard/review-answer` | Registra se a resposta do card estava correta |
| GET | `/api/v1/flashcard/rag-status` | Retorna o dashboard de revisão espaçada por matéria/submatéria |
```json
// Request
{
"fileContent": "string",
"fileName": "string",
"amount": 10,
"mode": "Basic" | "Simple" | "Detailed" | "Hyper"
}
Formas de requisição principais:
- `POST /api/v1/flashcard/generate`: `{ filePaths: string[], amount: 10-30, difficulty: "Easy" | "Hard" }`
- `POST /api/v1/flashcard/review-session`: `{ libraryIds: number[] }`
- `POST /api/v1/flashcard/review-answer`: `{ cardId: number, correct: boolean }`
// Response
{
"result": "string (CSV: Frente;Verso\nFrente;Verso\n...)"
}
```
### Repository Controller (`/api/v1/repository`)
| Metodo | Rota | Descricao |
### Controller de Repositório (`/api/v1/repository`)
| Método | Rota | Descrição |
|---|---|---|
| GET | `/api/v1/repository/info` | Nome do repositorio |
| GET | `/api/v1/repository/tree` | Arvore de arquivos do repositorio |
| GET | `/api/v1/repository/file?path=...` | Conteudo de um arquivo especifico |
| GET | `/api/v1/repository/info` | Nome do repositório |
| GET | `/api/v1/repository/tree` | Árvore de arquivos do repositório |
| GET | `/api/v1/repository/file?path=...` | Conteúdo de um arquivo específico |
---
## Convencoes de Desenvolvimento (Development Conventions)
## Convenções de Desenvolvimento
### Frontend (Preact/TypeScript)
- **Componentes**: Funcoes nomeadas exportadas com `export function Nome()`. Sem `export default`.
- **Componentes**: Funções nomeadas exportadas com `export function Nome()`. Sem `export default`.
- **Props**: Interfaces TypeScript definidas no mesmo arquivo do componente.
- **Hooks**: `useState`, `useEffect` importados de `preact/hooks`.
- **Hooks**: `useState` e `useEffect` importados de `preact/hooks`.
- **Children**: Tipados como `ComponentChildren` de `preact`.
- **CSS**: Um arquivo `.css` por componente, importado diretamente. **Sem CSS Modules.**
- **Estado**: Apenas estado local (`useState`). Sem store global, sem Context API.
- **Roteamento**: Alternancia de componentes via `display: block/none` com estado `activeModule`. Nao usa react-router.
- **API**: Chamadas via `MindforgeApiService` (objeto singleton com metodos estaticos usando `fetch`).
- **TypeScript**: Strict mode, `erasableSyntaxOnly`, `verbatimModuleSyntax`, `noUnusedLocals`, `noUnusedParameters`.
- **Roteamento**: Alternância de componentes via `display: block/none` com o estado `activeModule`. Não usa `react-router`.
- **API**: Chamadas via `MindforgeApiService` (objeto singleton com métodos estáticos usando `fetch`).
- **TypeScript**: Modo estrito, `erasableSyntaxOnly`, `verbatimModuleSyntax`, `noUnusedLocals`, `noUnusedParameters`.
- **Alias**: `react` e `react-dom` mapeados para `preact/compat/` no tsconfig.
### Backend (C#/.NET 9)
- **Namespaces**: `Mindforge.API.Controllers`, `Mindforge.API.Services`, etc.
- **Interfaces**: Prefixo `I` (ex: `IFileService`, `ILlmApiProvider`).
- **DI**: Todos servicos registrados como `Scoped` em `Program.cs`.
- **Controllers**: Atributo `[Route("api/v1/...")]`. Metodos retornam `IActionResult`.
- **Tratamento de erros**: `ExceptionHandlingMiddleware` captura `UserException` (400) e excecoes genericas (500).
- **Interfaces**: Prefixo `I` (ex.: `IFileService`, `ILlmApiProvider`).
- **DI**: Todos os serviços registrados como `Scoped` em `Program.cs`.
- **Controllers**: Atributo `[Route("api/v1/...")]`. Métodos retornam `IActionResult`.
- **Tratamento de erros**: `ExceptionHandlingMiddleware` captura `UserException` (400) e exceções genéricas (500).
### UI/UX
- **Idioma**: Todo texto em **portugues brasileiro**.
- **Idioma**: Todo texto em **português brasileiro**.
- **Tema**: Escuro com efeito vidro (glassy). `backdrop-filter: blur()`, fundos `rgba` semitransparentes.
- **Botoes**: Estilo iOS-like, modernos. Variantes `primary` (com blur) e `secondary` (transparente).
- **Botões**: Estilo iOS-like, modernos. Variantes `primary` (com blur) e `secondary` (transparente).
- **Tipografia**: Lato (Google Fonts), pesos 300/400/700.
- **Background**: `#005873` (azul petroleo escuro). Nao muito escuro.
- **Background**: `#005873` (azul petróleo escuro). Não muito escuro.
### CSS Variables (definidas em `index.css`)
### Variáveis CSS (definidas em `index.css`)
```css
--color-bg: #005873;
--color-header: #0f0f0f;
@@ -283,129 +154,49 @@ mindforge/
```
### Git
- Branches: `main` (producao)
- CI/CD: Gitea Actions dispara no push para main, build com Docker Buildx multi-arch, push para Gitea Container Registry, deploy no K8s.
- Branches: `main` (produção)
- CI/CD: Gitea Actions dispara no push para `main`, faz build com Docker Buildx multi-arch, envia para o Gitea Container Registry e faz o deploy no K8s.
---
## Configuracao & Environment Variables
## Configuração e Variáveis de Ambiente
### API (Mindforge.API)
| Variavel | Descricao |
| Variável | Descrição |
|---|---|
| `OPENAI_API_URL` | URL do endpoint OpenAI-compatible (OpenRouter) |
| `OPENAI_TOKEN` | Token de autenticacao da API |
| `OPENAI_API_URL` | URL do endpoint compatível com OpenAI (OpenRouter) |
| `OPENAI_TOKEN` | Token de autenticação da API |
| `OPENAI_MODEL` | Modelo LLM a ser usado |
| `GITEA_REPO_URL` | URL do repositorio Gitea |
| `GITEA_REPO_URL` | URL do repositório Gitea |
| `GITEA_ACCESS_TOKEN` | Token de acesso ao Gitea |
| `ConnectionStrings:MindforgeDb` | Conexão PostgreSQL usada pelo domínio de flashcards |
Fallback local/padrão para o banco de flashcards:
`Host=localhost;Port=3307;Database=mindforge;Username=root;Password=root`.
### Web (Mindforge.Web)
| Variavel | Descricao |
| Variável | Descrição |
|---|---|
| `VITE_API_BASE_URL` | URL base da API (default: `http://localhost:5123`) |
| `VITE_API_BASE_URL` | URL base da API (padrão: `http://localhost:5123`) |
### Cronjob
| Variavel | Descricao |
| Variável | Descrição |
|---|---|
| `GIT_REPOSITORY` | URL do repo Git a clonar |
| `DISCORD_WEBHOOK_URL` | Webhook do Discord para notificacoes |
| `GIT_REPOSITORY` | URL do repositório Git a clonar |
| `DISCORD_WEBHOOK_URL` | Webhook do Discord para notificações |
| `OPENAI_API_URL` | URL do endpoint OpenAI |
| `OPENAI_TOKEN` | Token de autenticacao |
| `HAVEN_NOTIFY_URL` | URL do servico de reporte de erros |
| `OPENAI_TOKEN` | Token de autenticação |
| `HAVEN_NOTIFY_URL` | URL do serviço de reporte de erros |
## Repositório base para os arquivos
A base do repositório para os arquivos de estudo (compartilhado pelo Obsidian) é https://git.ivanch.me/ivanch/concurso.
Ele segue o padrão `[base]/concurso/[Matéria]/[SubMatéria*]/[Arquivo]`, onde [base] é a URL do git, concurso é o nome da pasta dentro do git base, Matéria é o nome da matéria (ex: `Direito Constitucional`), SubMatéria é o nome da submatéria (ex. `Poder Legislativo`) - podendo ser opcional e com múltiplas submatérias -, e Arquivo é o nome do arquivo (ex: `Câmara dos Deputados.md`).
Ele segue o padrão `[base]/concurso/[Matéria]/[SubMatéria*]/[Arquivo]`, onde [base] é a URL do Git, `concurso` é o nome da pasta dentro do Git base, `Matéria` é o nome da matéria (ex.: `Direito Constitucional`), `SubMatéria` é o nome da submatéria (ex.: `Poder Legislativo`) - podendo ser opcional e com múltiplas submatérias - e `Arquivo` é o nome do arquivo (ex.: `Câmara dos Deputados.md`).
Exemplos:
- [base]/Concursos/Direito Constitucional/Poder Legislativo/Câmara dos Deputados.md
- [base]/Concursos/Direito Constitucional/Poder Legislativo/CPIs.md
- [base]/Concursos/Direito Constitucional/Ciência, Meio Ambiente e Índios.md
- [base]/Concursos/Direito Constitucional/Ciência, Meio Ambiente e Índios.md
- [base]/Concursos/TI/Analise e Engenharia de Dados/Data Lake e Data Warehouse.md
- [base]/Concursos/TI/Análise e Engenharia de Dados/Data Lake e Data Warehouse.md
- [base]/Concursos/TI/Rede/VLAN.md
- [base]/Concursos/TI/Rede/Email/IMAP e POP3.md
---
## Atualizacao - Flashcards Persistidos (2026-05-30)
### Mudancas de Arquitetura
- A API deixa de ser totalmente stateless para o dominio de flashcards.
- Flashcards agora sao persistidos em PostgreSQL (`mindforge`) via `Dapper` + `Npgsql`.
- O schema e criado de forma idempotente no startup da API.
### Tabelas de Flashcard
- `flashcard_libraries`: `id`, `file_path` (unico), `file_name`, `subject`, `difficulty`, `card_count`, `created_at`, `updated_at`.
- `flashcards`: `id`, `library_id`, `front`, `back`, `position`, `correct_count`, `incorrect_count`, `last_reviewed_at`, `created_at`.
### API de Flashcards (v1)
- `POST /api/v1/flashcard/generate`
Request: `{ filePaths: string[], amount: 10-30, difficulty: "Easy" | "Hard" }`
Comportamento: gera por arquivo selecionado, substitui biblioteca anterior do mesmo `file_path` e retorna bibliotecas com cards.
- `GET /api/v1/flashcard/libraries`
Lista todas as bibliotecas persistidas, com `subject` para agrupamento na UI.
- `GET /api/v1/flashcard/libraries/{id}`
Retorna detalhes de uma biblioteca com seus cards.
- `POST /api/v1/flashcard/review-session`
Request: `{ libraryIds: number[] }`
Retorna os cards combinados para sessao de revisao (sem repeticao espaciada nesta fase).
- `POST /api/v1/flashcard/review-answer`
Request: `{ cardId: number, correct: boolean }`
Registra no banco o resultado da revisao (`Acertei`/`Errei`) por card.
### Frontend
- Modulo `Flashcards` atualizado para:
- selecionar multiplos arquivos;
- definir quantidade fixa por arquivo (10-30);
- definir dificuldade (`Facil`/`Dificil`);
- gerar e exibir resumo das bibliotecas salvas (sem download CSV).
- Novo modulo `Revisao Flashcards`:
- lista bibliotecas agrupadas por materia (`subject`);
- permite selecionar multiplas bibliotecas;
- embaralha aleatoriamente os cards ao iniciar a sessao de revisao;
- inicia sessao estilo Anki simplificada (frente, revelar verso, acertei/errei, anterior, progresso visual).
- ao gerar novamente uma biblioteca, os contadores `correct_count` e `incorrect_count` dos cards sao resetados para zero.
### Novas Configuracoes
- `ConnectionStrings:MindforgeDb` para conexao PostgreSQL.
- Fallback local/default:
`Host=localhost;Port=3307;Database=mindforge;Username=root;Password=root`.
---
## Atualizacao - Revisao Espacada RAG (2026-06-01)
### Mudancas de Arquitetura
- O dominio de flashcards guarda `last_reviewed_at` por card.
- O status RAG da revisao espacada e calculado em tempo de leitura **por biblioteca/arquivo** (grupo de cards), nao por card.
- O agrupamento de dashboard usa `subject` + `subSubject`, onde `subSubject` vem dos segmentos do caminho apos a materia e antes do arquivo.
### Regras RAG por Arquivo (biblioteca)
- `Grey`: nenhum card da biblioteca possui `last_reviewed_at`.
- `Red`: ultima revisao da biblioteca ha 40 dias ou mais **ou** desempenho agregado `< 40%`.
- `Amber`: ultima revisao da biblioteca ha 30 dias ou mais **ou** desempenho agregado `<= 60%`.
- `Green`: ultima revisao da biblioteca abaixo de 30 dias **e** desempenho agregado `> 60%`.
- Desempenho agregado: `sum(correct_count) / (sum(correct_count) + sum(incorrect_count))`.
### Banco e Repositorio
- Tabela `flashcards` recebeu coluna `last_reviewed_at TIMESTAMPTZ NULL` (migracao idempotente no startup).
- `POST /api/v1/flashcard/review-answer` agora atualiza `correct_count`/`incorrect_count` e define `last_reviewed_at = NOW()`.
### API de Flashcards (v1)
- Novo endpoint `GET /api/v1/flashcard/rag-status`:
- Retorna dashboard de revisao espacada com grupos por materia/submateria.
- Inclui bibliotecas/arquivos com `ragStatus`, `performanceRate`, `totalAnswers` e `lastReviewedAt`.
- Inclui sumarios por materia/submateria com percentuais:
- Verde = `green / (green + amber + red)`
- Atencao = `(amber + red) / (green + amber + red)`
- Arquivos cinza ficam fora do denominador.
### Frontend
- Novo modulo `Revisao Espacada` abaixo de `Revisao Flashcards` na sidebar.
- O painel mostra:
- status agregados por materia e submateria;
- status por arquivo com destaque visual (cores e icones);
- filtros por status RAG (Vermelho, Amarelo, Verde, Cinza);
- total de arquivos selecionados para revisao.
- A sessao de revisao espacada reutiliza o fluxo de resposta (`Acertei`/`Errei`) e prioriza cards de arquivos por status (Red, Amber, Green, Grey).
- [base]/Concursos/TI/Rede/E-mail/IMAP e POP3.md

12
re-deploy.ps1 Normal file
View File

@@ -0,0 +1,12 @@
# Exit on any error
$ErrorActionPreference = "Stop"
docker login git.ivanch.me
Write-Host "Building and pushing Docker images..."
docker buildx bake --set '*.platform=linux/amd64,linux/arm64' --push
Write-Host "Build and push completed successfully."
kubectl delete -f ./deploy/deployment.yaml
kubectl apply -f ./deploy/deployment.yaml