new flashcards
All checks were successful
Mindforge API Build and Deploy / Build Mindforge API Image (push) Successful in 4m4s
Mindforge Web Build and Deploy (internal) / Build Mindforge Web Image (push) Successful in 5m29s
Mindforge Web Build and Deploy (internal) / Deploy Mindforge Web (internal) (push) Successful in 9s
Mindforge API Build and Deploy / Deploy Mindforge API (internal) (push) Successful in 8s
All checks were successful
Mindforge API Build and Deploy / Build Mindforge API Image (push) Successful in 4m4s
Mindforge Web Build and Deploy (internal) / Build Mindforge Web Image (push) Successful in 5m29s
Mindforge Web Build and Deploy (internal) / Deploy Mindforge Web (internal) (push) Successful in 9s
Mindforge API Build and Deploy / Deploy Mindforge API (internal) (push) Successful in 8s
This commit is contained in:
368
project-context.md
Normal file
368
project-context.md
Normal file
@@ -0,0 +1,368 @@
|
||||
# Mindforge
|
||||
|
||||
## Visao Geral (Overview)
|
||||
|
||||
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.
|
||||
|
||||
A interface e em **portugues brasileiro** e possui um tema escuro com efeito vidro ("glassy-look").
|
||||
|
||||
---
|
||||
|
||||
## Tech Stack
|
||||
|
||||
### Frontend (Mindforge.Web)
|
||||
| Tecnologia | Versao | 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 |
|
||||
| **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 |
|
||||
|---|---|---|
|
||||
| **.NET 9** | net9.0 | ASP.NET Core Web API |
|
||||
| **C#** | - | Linguagem |
|
||||
| **Microsoft.AspNetCore.OpenApi** | 9.0.12 | Suporte OpenAPI/Swagger |
|
||||
|
||||
### Cronjob (mindforge.cronjob)
|
||||
| Tecnologia | Versao | Finalidade |
|
||||
|---|---|---|
|
||||
| **Go** | 1.22 | Linguagem |
|
||||
| **godotenv** | v1.5.1 | Carregamento de arquivos .env |
|
||||
|
||||
### Infraestrutura
|
||||
| Tecnologia | Finalidade |
|
||||
|---|---|
|
||||
| **Docker** | Imagens multi-arch (amd64, arm64) |
|
||||
| **Kubernetes** | Orquestracao (Deployments, CronJobs, Services, Ingress) |
|
||||
| **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) |
|
||||
|
||||
---
|
||||
|
||||
## Arquitetura (Architecture)
|
||||
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## Estrutura do Projeto (Project Structure)
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### File Controller (`/api/v1/file`)
|
||||
| Metodo | Rota | Descricao |
|
||||
|---|---|---|
|
||||
| POST | `/api/v1/file/check` | Valida linguagem ou conteudo de um arquivo |
|
||||
|
||||
```json
|
||||
// Request
|
||||
{
|
||||
"fileContent": "string (conteudo do arquivo)",
|
||||
"fileName": "string",
|
||||
"checkType": "language" | "content"
|
||||
}
|
||||
|
||||
// Response
|
||||
{
|
||||
"result": "string (resultado da validacao)"
|
||||
}
|
||||
```
|
||||
|
||||
### Flashcard Controller (`/api/v1/flashcard`)
|
||||
| Metodo | Rota | Descricao |
|
||||
|---|---|---|
|
||||
| POST | `/api/v1/flashcard/generate` | Gera flashcards em CSV |
|
||||
|
||||
```json
|
||||
// Request
|
||||
{
|
||||
"fileContent": "string",
|
||||
"fileName": "string",
|
||||
"amount": 10,
|
||||
"mode": "Basic" | "Simple" | "Detailed" | "Hyper"
|
||||
}
|
||||
|
||||
// Response
|
||||
{
|
||||
"result": "string (CSV: Frente;Verso\nFrente;Verso\n...)"
|
||||
}
|
||||
```
|
||||
|
||||
### Repository Controller (`/api/v1/repository`)
|
||||
| Metodo | Rota | Descricao |
|
||||
|---|---|---|
|
||||
| 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 |
|
||||
|
||||
---
|
||||
|
||||
## Convencoes de Desenvolvimento (Development Conventions)
|
||||
|
||||
### Frontend (Preact/TypeScript)
|
||||
- **Componentes**: Funcoes 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`.
|
||||
- **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`.
|
||||
- **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).
|
||||
|
||||
### UI/UX
|
||||
- **Idioma**: Todo texto em **portugues 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).
|
||||
- **Tipografia**: Lato (Google Fonts), pesos 300/400/700.
|
||||
- **Background**: `#005873` (azul petroleo escuro). Nao muito escuro.
|
||||
|
||||
### CSS Variables (definidas em `index.css`)
|
||||
```css
|
||||
--color-bg: #005873;
|
||||
--color-header: #0f0f0f;
|
||||
--color-sidebar: #013a4c;
|
||||
--color-text-creamy: #f4f5f5;
|
||||
--color-accent: #00b4d8;
|
||||
--color-accent-rgb: 0, 180, 216;
|
||||
--color-accent-hover: #0096c7;
|
||||
--font-main: 'Lato', sans-serif;
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
---
|
||||
|
||||
## Configuracao & Environment Variables
|
||||
|
||||
### API (Mindforge.API)
|
||||
| Variavel | Descricao |
|
||||
|---|---|
|
||||
| `OPENAI_API_URL` | URL do endpoint OpenAI-compatible (OpenRouter) |
|
||||
| `OPENAI_TOKEN` | Token de autenticacao da API |
|
||||
| `OPENAI_MODEL` | Modelo LLM a ser usado |
|
||||
| `GITEA_REPO_URL` | URL do repositorio Gitea |
|
||||
| `GITEA_ACCESS_TOKEN` | Token de acesso ao Gitea |
|
||||
|
||||
### Web (Mindforge.Web)
|
||||
| Variavel | Descricao |
|
||||
|---|---|
|
||||
| `VITE_API_BASE_URL` | URL base da API (default: `http://localhost:5123`) |
|
||||
|
||||
### Cronjob
|
||||
| Variavel | Descricao |
|
||||
|---|---|
|
||||
| `GIT_REPOSITORY` | URL do repo Git a clonar |
|
||||
| `DISCORD_WEBHOOK_URL` | Webhook do Discord para notificacoes |
|
||||
| `OPENAI_API_URL` | URL do endpoint OpenAI |
|
||||
| `OPENAI_TOKEN` | Token de autenticacao |
|
||||
| `HAVEN_NOTIFY_URL` | URL do servico 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`).
|
||||
|
||||
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/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`, `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).
|
||||
|
||||
### 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;
|
||||
- inicia sessao estilo Anki simplificada (frente, revelar verso, anterior/proximo, progresso visual).
|
||||
|
||||
### Novas Configuracoes
|
||||
- `ConnectionStrings:MindforgeDb` para conexao PostgreSQL.
|
||||
- Fallback local/default:
|
||||
`Host=localhost;Port=3307;Database=mindforge;Username=root;Password=root`.
|
||||
Reference in New Issue
Block a user