Files
mindforge/project-context.md
Jose Henrique b80d28f671
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
new flashcards
2026-05-30 11:59:19 -03:00

16 KiB

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
// 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
// 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)

--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.