Files
carvalho-finances/neon-handoff/README.md
T
Mlcavalho1andClaude Sonnet 4.6 acbce4edc0 feat: multi-usuário com autenticação JWT
- Tabela `profiles` + coluna `profile_id` em todas as entidades
  (categories, transactions, recurring_expenses, accounts, player_profile,
   xp_events, player_quests, player_achievements, player_cosmetics)
- Dados existentes migrados para profile_id = 1 (Manoel)
- CLI `./api create-user --name <n> --password <p>` cria perfil com
  seed de categorias e player_profile; faz upsert de senha se já existir
- Auth substituída: cookie+APP_PASSWORD → JWT Bearer 24h (HS256)
- Middleware RequireAuth injeta profile_id no context de todas as rotas
- Todos os repositórios filtram por profile_id do context
- Endpoints: POST /api/auth/login, GET /api/auth/me,
  POST /api/auth/change-password, POST /api/logout
- Frontend: auth store usa localStorage (fc_token/fc_profile),
  api.ts envia Authorization header, LoginView usa campo name
- SettingsView reescrita com troca de senha e logout
- docker-compose.yml: remove APP_USERNAME/APP_PASSWORD, adiciona JWT_SECRET

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-27 20:04:44 -03:00

165 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Financeiro Carvalho · Handoff (Arcade Neon)
Pacote de design pronto pra ser entregue ao Claude Code / Cursor / Aider implementar.
Direção visual escolhida: **Arcade Neon**.
## O que tem aqui
```
neon-handoff/
├── STYLE_GUIDE.md ← leia primeiro
├── preview.html ← referência visual interativa (abra num servidor local)
├── tokens.css ← variáveis CSS + reset + classes utilitárias
├── components/ ← Vue 3 SFCs de referência
│ ├── NeonPanel.vue
│ ├── XPBar.vue
│ ├── HUDStat.vue
│ └── CharacterSprite.vue
├── sprites/
│ ├── sprite-data.json ← grade raw 17×24 + lista de cosméticos
│ ├── icons.json ← heart, coin, star, anchor (8×8 cada)
│ ├── manoel-default.png (e 4x)
│ ├── manoel-lv01.png (e 4x) · cabelo castanho, camisa azul, calça caqui
│ ├── manoel-lv03-bone-verolme.png · boné azul
│ ├── manoel-lv05-wingspan.png · camisa verde
│ ├── manoel-lv07-chapeu-sol.png · look "equipado" atual
│ ├── manoel-lv10-anti-vento.png · casaco roxo
│ ├── manoel-lv15-capitao.png · trajado de capitão (vermelho/preto)
│ └── manoel-sheet-4x.png · todos lado a lado pra referência
└── README.md ← este arquivo
```
## Como integrar no apps/web
1. Copie `tokens.css` para `src/styles/tokens.css`. Importe **uma vez** em `src/main.ts`:
```ts
import './styles/tokens.css'
```
2. Copie `components/*.vue` para `src/components/`. Eles já consomem `var(--fc-*)`.
3. Copie `sprites/sprite-data.json` e `sprites/icons.json` pra `src/assets/`.
Garanta que `tsconfig.json` tenha `"resolveJsonModule": true` (Vite default já tem).
4. Embrulhe o `<router-view>` em `<div class="fc-app">` — é isso que aplica o fundo + scanlines + grid.
```vue
<!-- App.vue -->
<template>
<div class="fc-app">
<AppHud />
<RouterView />
</div>
</template>
```
5. As 8 rotas do PRD (`/`, `/transacoes`, `/importar`, `/categorias`, `/recorrencias`,
`/contas`, `/personagem`, `/configuracoes`) usam o mesmo header HUD. Veja
`STYLE_GUIDE.md` §3.6 pro shape do componente.
## Sprites · uso
### Renderizar dinâmico (recomendado)
`<CharacterSprite>` lê `sprite-data.json` e aceita `theme` como prop. Cosméticos
equipados são merged no store (Pinia) e passados como `theme`.
```vue
<CharacterSprite :scale="6" :theme="gameStore.equippedTheme" :celebrate="gameStore.justLeveledUp" />
```
Exemplo de store getter:
```ts
// stores/game.ts
const equippedTheme = computed(() => {
return cosmetics.value
.filter(c => c.equipped)
.reduce((acc, c) => ({ ...acc, ...c.colors }), {} as Record<string, string>)
})
```
### Usar PNG estático
Útil pra previews em página de loja (`/personagem` → seção "cosméticos"):
```html
<img src="@/assets/sprites/manoel-lv03-bone-verolme-4x.png" alt="Boné Verolme" />
```
Sempre `image-rendering: pixelated;` no CSS pra não suavizar.
### Regenerar PNGs
`sprites/sprite-data.json` é a fonte da verdade. Se você ajustar uma cor de
cosmético lá, regenere os PNGs com um script Node:
```js
// scripts/build-sprites.mjs
import { createCanvas } from '@napi-rs/canvas' // ou node-canvas
import fs from 'node:fs/promises'
const data = JSON.parse(await fs.readFile('src/assets/sprite-data.json', 'utf8'))
// ... mesmo render do PixelSprite acima, salva PNG por cosmético
```
Ou peça pro Claude Code regenerar — o algoritmo é trivial (loop pela grade,
fillRect por célula com a cor do slot).
## Princípios para o Claude implementar
Por ordem de importância:
1. **HUD persistente em todas as rotas.** Não use sidebar — o app é um HUD de jogo.
2. **Nunca use hex direto.** Sempre `var(--fc-*)`. Se faltar token, adicione-o ao
`tokens.css` e documente no `STYLE_GUIDE.md` §1.1.
3. **Press Start 2P pra label e número. JetBrains Mono pra dado. Inter pra prosa.**
Press Start 2P sempre em maiúscula.
4. **Glow é raro.** Só nos números heroicos (47%) e no painel principal de cada
rota. Se cada card brilha, nada brilha.
5. **Verde/vermelho são binários** — meta sim / meta não. Não use vermelho pra valor
negativo (transação) — só pra alerta.
6. **Cada animação tem propósito.** Ver §6 do guia.
7. **Mobile vira bottom-nav.** Não tente espremer a HUD horizontal num iPhone.
## Telas a implementar
Conforme `STYLE_GUIDE.md` + screens visíveis em `preview.html` (Arcade · 01):
- [ ] `/` Dashboard (hero poupado, categorias, histórico, transações, recorrências, quests, patrimônio, widget personagem)
- [ ] `/transacoes` lista + CRUD
- [ ] `/importar` upload OFX/CSV + preview de deduplicação
- [ ] `/categorias` CRUD com pixel-icon picker
- [ ] `/recorrencias` lista mensal com status (paid / due / missing)
- [ ] `/contas` cards de conta + patrimônio total
- [ ] `/personagem` painel RPG completo
- [ ] `/configuracoes` formulário simples (perfil, meta %, prefs visuais)
Para qualquer tela nova: comece copiando a estrutura do dashboard,
substitua o conteúdo dos painéis, mantenha a HUD.
## Componentes adicionais que faltam
Esses não estão neste pacote — implemente seguindo os tokens já definidos:
- `AppHud.vue` (cabeçalho persistente)
- `BottomNav.vue` (mobile)
- `TransactionRow.vue`
- `QuestCard.vue`
- `CategoryBar.vue`
- `AchievementCell.vue`
- `LevelUpModal.vue` (overlay celebratório no level up)
- `MonthSwitcher.vue` ( MAIO · 2026 )
## Tom de voz
Português brasileiro, direto, com vocabulário de jogo. Não é app corporativo.
Ver `STYLE_GUIDE.md` §8.
---
Qualquer dúvida sobre **intenção visual** (não implementação), volte ao
`STYLE_GUIDE.md` ou ao `preview.html`. A página de design original do projeto
(canvas com 4 direções) também segue acessível pra comparação.