Armazenamento
O AISCouncil armazena todos os dados localmente no seu navegador. Nada é enviado a nenhum servidor. O sistema de armazenamento usa dois níveis -- localStorage para leituras pequenas e síncronas necessárias no boot, e IndexedDB para dados grandes e assíncronos como perfis de bot e históricos de chat.
Arquitetura de Armazenamento de Dois Níveis
| Nível | API | Capacidade | Caso de Uso |
|---|---|---|---|
| localStorage | Síncrono | ~5-10 MB | Tema, chaves de API, configurações -- dados necessários instantaneamente no carregamento da página |
| IndexedDB | Assíncrono | ~100 MB - 1 GB+ | Perfis de bot, históricos de chat, manifests de addon -- dados grandes |
A divisão existe porque localStorage é rápido mas limitado em tamanho, enquanto IndexedDB é virtualmente ilimitado mas requer acesso assíncrono. Valores críticos de tempo de boot (tema, chaves de API, estado de login) vivem em localStorage para que o app possa renderizar imediatamente sem esperar leituras assíncronas.
Chaves do localStorage
Todas as chaves do localStorage usam o prefixo ais-:
| Chave | Tipo | Descrição |
|---|---|---|
ais-theme | string | Tema atual (light, dark ou system) |
ais-apikey-anthropic | string | Chave de API Anthropic |
ais-apikey-openai | string | Chave de API OpenAI |
ais-apikey-xai | string | Chave de API xAI |
ais-apikey-gemini | string | Chave de API Google Gemini |
ais-apikey-openrouter | string | Chave de API OpenRouter |
ais-apikey-deepseek | string | Chave de API DeepSeek |
ais-apikey-groq | string | Chave de API Groq |
ais-apikey-mistral | string | Chave de API Mistral |
ais-user | JSON | Info do usuário logado (nome, email, foto, provedor) |
ais-idb-migrated | string | Flag indicando migração localStorage-para-IndexedDB completa |
ais-ollama-endpoint | string | URL de endpoint Ollama customizado (padrão: http://localhost:11434) |
ais-custom-providers | JSON | Array de configurações de provedores customizados definidos pelo usuário |
aiscouncil-settings | JSON | Configurações globais (tema, tamanho de fonte, capacidades, etc.) |
aiscouncil-usage | JSON | Dados de rastreamento de uso (tokens, custos por provedor) |
Chaves de API em localStorage são acessíveis a qualquer JavaScript rodando na mesma origem. Isso é padrão para apps de navegador, mas significa que você não deve instalar extensões de navegador não confiáveis. Chaves nunca são incluídas em exports de URL ou backups de dados.
Chaves do IndexedDB
IndexedDB armazena dados em um object store chave-valor dentro de um banco de dados chamado ais-db (ou um banco de dados por usuário quando logado):
| Padrão de Chave | Tipo | Descrição |
|---|---|---|
ais-bots | array | Todos os metadados de sessão de bot (ID, nome, config, data de criação) |
ais-profiles | array | Todos os perfis salvos (individuais e council) |
ais-chat-{botId} | array | Histórico de mensagens de chat para uma sessão de bot específica |
ais-addon-manifests | array | Manifests de addons/plugins instalados |
ais-miniprogram-* | varia | Dados de mini-programas instalados |
Cada sessão de bot tem sua própria chave de chat (ais-chat-abc123), então históricos de chat são isolados e podem ser carregados independentemente.
Auto-Migração
No primeiro boot, AIS.Storage.init() verifica se dados existem em localStorage de uma versão mais antiga e automaticamente os migra para IndexedDB. A flag ais-idb-migrated previne re-migração em carregamentos subsequentes.
Se IndexedDB estiver indisponível (alguns navegadores de privacidade o bloqueiam), a camada de armazenamento cai para localStorage transparentemente. O app continua funcionando, mas com o limite de armazenamento de ~5-10 MB.
Camada SQLite WASM Opcional
Para casos de uso avançados envolvendo grandes dados binários (imagens, anexos), o sistema de armazenamento pode carregar um módulo SQLite WASM opcional. SQLite roda concorrentemente com IndexedDB e armazena dados no Origin Private File System (OPFS) do navegador.
SQLite é carregado sob demanda -- nunca é carregado a menos que explicitamente solicitado ou necessário para armazenamento de blobs. Para habilitá-lo, vá para Settings > General > Storage Backend e selecione SQLite.
| Funcionalidade | IndexedDB | SQLite WASM |
|---|---|---|
| Armazenamento chave-valor | Sim | Sim |
| Armazenamento de blob binário | Limitado | Otimizado |
| Queries SQL | Não | Sim |
| Persistência | Gerenciada pelo navegador | OPFS (baseado em arquivo) |
| Carregamento | Imediato | Preguiçoso (no primeiro uso) |
API AIS.Storage
O módulo AIS.Storage fornece uma API unificada que funciona independentemente do backend ativo:
Operações Principais
// Inicializa armazenamento (chamado uma vez no boot)
await AIS.Storage.init();
// Obtém um valor
const bots = await AIS.Storage.get("ais-bots");
// Define um valor
await AIS.Storage.set("ais-bots", updatedBots);
// Deleta uma chave
await AIS.Storage.delete("ais-chat-abc123");
// Lista todas as chaves
const allKeys = await AIS.Storage.keys();
// Obtém todos os pares chave-valor
const everything = await AIS.Storage.getAll();
// Limpa todos os dados
await AIS.Storage.clear();
Armazenamento de Blob (SQLite)
// Armazena um blob binário
await AIS.Storage.putBlob("image-001", arrayBuffer, "image/png");
// Recupera um blob
const blob = await AIS.Storage.getBlob("image-001");
// { data: Uint8Array, mime: 'image/png', size: 12345 }
Funções Utilitárias
// Helpers síncronos de localStorage (para leituras de tempo de boot)
const theme = AIS.Storage.loadJSON("ais-theme");
AIS.Storage.saveJSON("ais-theme", "dark");
// Fábrica de cache TTL (para cacheamento de registro)
const cache = AIS.Storage.cache("ais-models-cache", "ais-models-ts", 86400000); // TTL 24h
const data = cache.load(); // Lê dados cacheados
cache.save(newData); // Atualiza cache
const stale = cache.isStale(); // Verifica se cache expirou
Propriedades de Status
AIS.Storage.isIDB; // true se IndexedDB está ativo
AIS.Storage.hasSQLite; // true se SQLite WASM está carregado
Export e Import
Exportando Dados
Vá para Settings > Privacy > Export All Data ou use a API:
const backup = await AIS.Storage.exportData();
// Retorna: { bcz_version: "1.0.0", exported: "2026-02-19T...", data: {...} }
O export inclui todos os perfis de bot, históricos de chat, configurações e manifests de addon. Ele explicitamente exclui:
- Chaves de API (nunca exportadas)
- Chaves de API por-membro em perfis (removidas para apenas provedor/modelo)
O export é salvo como ais-backup-YYYY-MM-DD.json.
Se você tem armazenamento de blob SQLite ativo, o export também gera um arquivo separado ais-blobs-YYYY-MM-DD.db contendo o banco de dados SQLite.
Importando Dados
Vá para Settings > Privacy > Import Data ou use a API:
const count = await AIS.Storage.importData(jsonBackup);
// Retorna: número de itens importados
Import aceita:
- Arquivos
.json(formato de backup padrão) - Arquivos
.db(banco de dados SQLite)
Chaves de API nunca são importadas mesmo se presentes no arquivo.
Quotas de Armazenamento
Quotas de armazenamento do navegador variam por plataforma:
| Navegador | Quota IndexedDB | Com Armazenamento Persistente |
|---|---|---|
| Chrome/Edge | ~60% do espaço em disco | Mesmo, mas não despejado |
| Firefox | ~50% do espaço em disco | Solicita permissão do usuário |
| Safari | ~1 GB inicial, usuário pode conceder mais | Mesmo |
AISCouncil solicita armazenamento persistente no init via navigator.storage.persist(). Quando concedido, o navegador não evictará automaticamente seus dados quando o armazenamento estiver baixo.
Abra o DevTools do seu navegador, vá para Application > Storage e procure pela origem aiscouncil.net para ver uso atual de armazenamento e quota.
Privacidade
Todos os dados ficam no seu dispositivo:
- Sem uploads para servidor -- configs de bot, históricos de chat e configurações nunca são enviados a nenhum servidor
- Sem analytics -- nenhum dado de uso é transmitido para lugar nenhum
- Sem cookies -- o app usa
localStoragee IndexedDB, não cookies de rastreamento (o cookieais-authé usado apenas para detecção de auth cross-subdomain) - Sem armazenamento de terceiros -- dados são armazenados apenas sob a origem
aiscouncil.net
Limpando Dados
Para limpar todos os dados armazenados:
- Settings > Privacy > Clear All Data -- remove todos os dados IndexedDB, perfis e históricos de chat
- Browser DevTools > Application > Clear Storage -- opção nuclear, remove tudo incluindo localStorage
- Deleção individual de chat -- clique com botão direito em um bot na barra lateral e selecione Delete
Limpar todos os dados é irreversível. Exporte seus dados primeiro se quiser um backup. Chaves de API armazenadas em localStorage também são removidas ao limpar via DevTools do navegador.
Armazenamento Por-Bot para Mini-Programas
Cada mini-programa instalado obtém seu próprio namespace de armazenamento isolado. Mini-programas acessam armazenamento através da API SDK ais.storage, que mapeia para chaves prefixadas por app no IndexedDB. Um mini-programa não pode acessar dados de outro.
// Dentro de um mini-programa
await ais.storage.set("my-key", "my-value");
const val = await ais.storage.get("my-key");
const keys = await ais.storage.keys();
await ais.storage.remove("my-key");
Armazenamento para um mini-programa é deletado quando o mini-programa é desinstalado.