Substitui o portal Vite+Vue puro por Nuxt 3 com BFF embutido (Nitro server
routes) e fluxo de autenticação Keycloak via token-handler pattern.
Server (BFF):
- server/api/auth/{login,callback,refresh,logout,me}.ts — Keycloak PKCE
- server/api/proxy/[...path].ts — proxy autenticado pro core-api com tenant
- server/utils/{session,keycloak,pkce,redis,tenant,prefeitura}.ts
- server/middleware/csrf.ts — Origin check + header X-Requested-With
Auth (token-handler pattern):
- JWT vive só server-side em Redis; cliente recebe cookie session-id opaco
- Refresh transparente quando access_token expira
- Multi-tenant via hostname → X-Municipio/X-Dominio injetados no proxy
- Realm dedicado: modumfiscal-portal-{env}
Frontend (Nuxt):
- src/pages/** (file-based routing) substitui src/views/
- Plugins SSR: prefeitura (bootstrap pré-hidratação) + auth (hidrata user via /api/auth/me)
- Composables useAuth, useApi, useLoginModal, useFocusLoginInput
- Modal global de login quando middleware /portal/** bloqueia
- Splash overlay no boot esconde flash do preset inicial pro tema dinâmico
- DocumentoInput bloqueia campo quando user autenticado (pré-preenche em certidão/IPTU)
Removidos:
- index.html, vite.config.js, src/main.js, src/router/
- src/config/apiClient.js (substituído por \$fetch via /api/proxy)
- src/services/{auth,prefeitura}Service.js (lógica migrada pra composables/plugins)
- src/mocks/ (não mais usado)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
40 lines
1.0 KiB
JSON
40 lines
1.0 KiB
JSON
{
|
|
"name": "portal-modumfiscal-web",
|
|
"private": true,
|
|
"type": "module",
|
|
"scripts": {
|
|
"build": "nuxt build",
|
|
"dev": "nuxt dev",
|
|
"generate": "nuxt generate",
|
|
"preview": "nuxt preview",
|
|
"postinstall": "nuxt prepare",
|
|
"lint": "eslint --fix . --ext .vue,.js,.ts --ignore-path .gitignore"
|
|
},
|
|
"dependencies": {
|
|
"@pinia/nuxt": "^0.11.2",
|
|
"@primeuix/themes": "^2.0.3",
|
|
"@primevue/nuxt-module": "^4.5.5",
|
|
"axios": "^1.16.1",
|
|
"ioredis": "^5.4.1",
|
|
"jose": "^5.9.6",
|
|
"jwt-decode": "^4.0.0",
|
|
"nuxt": "^3.14.0",
|
|
"pinia": "^3.0.4",
|
|
"pinia-plugin-persistedstate": "^4.7.1",
|
|
"pkce-challenge": "^6.0.0",
|
|
"primeicons": "^7.0.0",
|
|
"primevue": "^4.5.5",
|
|
"tailwindcss-primeui": "^0.6.1",
|
|
"vue": "^3.5.34",
|
|
"zod": "^4.4.3"
|
|
},
|
|
"devDependencies": {
|
|
"@tailwindcss/vite": "^4.3.0",
|
|
"@vue/eslint-config-prettier": "^10.2.0",
|
|
"eslint-plugin-vue": "^10.9.1",
|
|
"sass": "^1.99.0",
|
|
"tailwindcss": "^4.3.0",
|
|
"typescript": "^5.6.3"
|
|
}
|
|
}
|