Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,14 @@
"Read(/C:\\Users\\Marcos\\Documents\\GitHub\\aviso-projeto\\test-temporal-bridge/**)",
"Read(//c/Users/Marcos/Documents/GitHub/PROJETO-OHANA/BackEnd/src/utils/**)",
"Bash(bunx tsc:*)",
"Bash(echo:*)"
"Bash(echo:*)",
"Bash(PORT=3000 DEBUG=false bun build test-build-inlining.ts --outfile=test-output.js --minify)",
"Bash(PORT=3000 DEBUG=false node test-output.js)",
"Bash(PORT=9999 DEBUG=true node test-output.js)",
"Bash(PORT=5555 DEBUG=false TEST_NEW_VAR=hello node test-output.js)",
"Bash(bunx prettier:*)",
"Read(//c/c/Users/Marcos/Documents/GitHub/aviso-projeto/FluxStack/**)",
"Read(//c/**)"
],
"deny": []
}
Expand Down
120 changes: 115 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,17 @@
FluxStack/
├── core/ # 🔒 FRAMEWORK (read-only)
│ ├── server/ # Framework Elysia + plugins
│ ├── config/ # Sistema de configuração
│ ├── config/ # Sistema base de configuração
│ ├── utils/ # Utilitários (env.ts, config-schema.ts)
│ ├── types/ # Types do framework
│ └── build/ # Sistema de build
├── config/ # ⚙️ CONFIGURAÇÕES DA APLICAÇÃO
│ ├── app.config.ts # Configuração principal
│ ├── server.config.ts # Servidor e CORS
│ ├── logger.config.ts # Sistema de logs
│ ├── database.config.ts # Banco de dados
│ ├── system.config.ts # Informações do sistema
│ └── index.ts # Exports centralizados
├── app/ # 👨‍💻 CÓDIGO DA APLICAÇÃO
│ ├── server/ # Backend (controllers, routes)
│ │ ├── controllers/ # Lógica de negócio
Expand Down Expand Up @@ -108,10 +116,99 @@ bun run dev:clean # ✅ Output limpo (sem logs HEAD do Elysia)
- **Users CRUD**: `GET|POST|PUT|DELETE /api/users` ✅
- **Swagger Docs**: `GET /swagger` ✅

### ✅ **4. Environment Variables Dinâmicas**
- **Sistema robusto**: Precedência clara
- **Testing endpoint**: `/api/env-test`
- **Validação automática**: Environment vars
### ✅ **4. Sistema de Configuração Declarativa (Laravel-inspired)**

FluxStack usa um sistema de configuração declarativa com validação automática e inferência de tipos completa.

#### 📁 **Estrutura de Configuração**
```
config/
├── app.config.ts # Configuração da aplicação
├── server.config.ts # Configuração do servidor
├── logger.config.ts # Configuração de logs
├── database.config.ts # Configuração do banco de dados
├── system.config.ts # Informações do sistema
└── index.ts # Exports centralizados
```

#### 🎯 **Como Usar**

**1. Definir Schema de Configuração:**
```typescript
// config/app.config.ts
import { defineConfig, config } from '@/core/utils/config-schema'

const appConfigSchema = {
name: config.string('APP_NAME', 'FluxStack', true),
port: config.number('PORT', 3000, true),
env: config.enum('NODE_ENV', ['development', 'production', 'test'] as const, 'development', true),
debug: config.boolean('DEBUG', false),
} as const

export const appConfig = defineConfig(appConfigSchema)
```

**2. Usar Configuração com Type Safety:**
```typescript
import { appConfig } from '@/config/app.config'

// ✅ Type inference automática
const port = appConfig.port // number
const env = appConfig.env // "development" | "production" | "test"
const debug = appConfig.debug // boolean

// ✅ Validação em tempo de boot
if (appConfig.env === 'production') {
// TypeScript sabe que env é exatamente 'production'
}
```

**3. Validação e Transformação:**
```typescript
const schema = {
port: {
type: 'number' as const,
env: 'PORT',
default: 3000,
required: true,
validate: (value: number) => {
if (value < 1 || value > 65535) {
return 'Port must be between 1 and 65535'
}
return true
}
}
}
```

#### ⚡ **Benefícios**
- ✅ **Type Safety Total**: Inferência automática de tipos literais
- ✅ **Validação em Boot**: Falha rápida com mensagens claras
- ✅ **Zero Tipos `any`**: TypeScript infere tudo corretamente
- ✅ **Hot Reload Seguro**: Configs podem ser recarregadas em runtime
- ✅ **Documentação Automática**: Schema serve como documentação

#### 🔧 **Helpers Disponíveis**
```typescript
import { config } from '@/core/utils/config-schema'

config.string(envVar, defaultValue, required)
config.number(envVar, defaultValue, required)
config.boolean(envVar, defaultValue, required)
config.array(envVar, defaultValue, required)
config.enum(envVar, values, defaultValue, required)
```

#### 🚫 **Não Fazer**
- ❌ Usar `process.env` diretamente no código da aplicação
- ❌ Acessar variáveis de ambiente sem validação
- ❌ Criar configs sem schema

#### ✅ **Sempre Fazer**
- ✅ Usar configs declarativos de `config/`
- ✅ Definir schemas com validação
- ✅ Usar helpers `config.*` para type safety
- ✅ Adicionar `as const` nos schemas para preservar tipos literais

## 🚨 **Regras Críticas (Atualizadas)**

Expand Down Expand Up @@ -172,6 +269,19 @@ curl http://localhost:3000/api/health # ✅ Health check
- **Hot reload independente**: Backend e frontend separados
- **Build otimizado**: Sistema unificado

### **✅ Sistema de Configuração Declarativa (Janeiro 2025)**
- **Problema resolvido**: Uso direto de `process.env` sem validação
- **Solução implementada**: Sistema Laravel-inspired com schemas
- **Arquitetura**: 3 camadas (env loader → config schema → app configs)
- **Benefícios**:
- ✅ Type inference completa com tipos literais
- ✅ Validação em boot time com mensagens claras
- ✅ Zero tipos `any` em configurações
- ✅ Hot reload seguro de configs
- ✅ Pasta `config/` centralizada e organizada
- **Build**: Pasta `config/` copiada automaticamente para produção
- **CLI**: `create-fluxstack` inclui configs automaticamente

## 🎯 **Próximos Passos Sugeridos**

### **Funcionalidades Pendentes**
Expand Down
10 changes: 5 additions & 5 deletions app/server/backend-only.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Backend standalone entry point
import { startBackendOnly } from "@/core/server/standalone"
import { apiRoutes } from "./routes"
import { env } from "@/core/utils/env-runtime"
import { serverConfig } from "@/config/server.config"

// Configuração para backend standalone com env dinâmico
// Configuração para backend standalone usando config declarativo
const backendConfig = {
port: env.get('BACKEND_PORT', 3001), // Casting automático para number
apiPrefix: env.API_PREFIX // Direto! (string)
port: serverConfig.backendPort,
apiPrefix: serverConfig.apiPrefix
}

console.log(`🚀 Backend standalone: ${env.HOST}:${backendConfig.port}`)
console.log(`🚀 Backend standalone: ${serverConfig.host}:${backendConfig.port}`)

// Iniciar apenas o backend
startBackendOnly(apiRoutes, backendConfig)
96 changes: 57 additions & 39 deletions app/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,46 @@ import { FluxStackFramework, vitePlugin, swaggerPlugin, staticPlugin, liveCompon
import { isDevelopment } from "@/core/utils/helpers"
import { DEBUG } from "@/core/utils/logger"
import { apiRoutes } from "./routes"
// Import sistema de env dinâmico simplificado
import { env, helpers } from "@/core/utils/env-runtime-v2"
// Import live components registration
import { helpers } from "@/core/utils/env"
import { serverConfig } from "@/config/server.config"
import { appConfig } from "@/config/app.config"
import { loggerConfig } from "@/config/logger.config"
import "./live/register-components"

// Startup info moved to DEBUG level (set LOG_LEVEL=debug to see details)
DEBUG('🔧 Loading dynamic environment configuration...')
DEBUG(`📊 Environment: ${env.NODE_ENV}`)
DEBUG(`🚀 Port: ${env.PORT}`)
DEBUG(`🌐 Host: ${env.HOST}`)
DEBUG('🔧 Loading declarative configuration...')
DEBUG(`📊 Environment: ${appConfig.env}`)
DEBUG(`🚀 Port: ${serverConfig.port}`)
DEBUG(`🌐 Host: ${serverConfig.host}`)

// Criar aplicação com configuração dinâmica simplificada
// Criar aplicação com configuração declarativa
const app = new FluxStackFramework({
server: {
port: env.PORT, // Direto! (number)
host: env.HOST, // Direto! (string)
apiPrefix: env.API_PREFIX, // Direto! (string)
port: serverConfig.port,
host: serverConfig.host,
apiPrefix: serverConfig.apiPrefix,
cors: {
origins: env.CORS_ORIGINS, // Direto! (string[])
methods: env.get('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']),
headers: env.get('CORS_HEADERS', ['*']),
credentials: env.get('CORS_CREDENTIALS', false)
origins: serverConfig.corsOrigins,
methods: serverConfig.corsMethods,
headers: serverConfig.corsHeaders,
credentials: serverConfig.corsCredentials
},
middleware: []
},
app: {
name: env.FLUXSTACK_APP_NAME, // Direto! (string)
version: env.FLUXSTACK_APP_VERSION // Direto! (string)
name: serverConfig.appName,
version: serverConfig.appVersion
},
client: {
port: env.VITE_PORT, // Direto! (number)
port: serverConfig.clientPort,
proxy: {
target: helpers.getServerUrl() // Helper inteligente
target: helpers.getServerUrl()
},
build: {
sourceMaps: env.get('CLIENT_SOURCEMAPS', env.NODE_ENV !== 'production'),
minify: env.get('CLIENT_MINIFY', env.NODE_ENV === 'production'),
target: env.get('CLIENT_TARGET', 'es2020'),
outDir: env.get('CLIENT_OUTDIR', 'dist')
sourceMaps: serverConfig.clientSourceMaps,
minify: false,
target: serverConfig.clientTarget as any,
outDir: serverConfig.clientOutDir
}
}
})
Expand All @@ -61,30 +62,47 @@ app.use(staticFilesPlugin) // Add Static Files support
app.use(liveComponentsPlugin) // Add Live Components support


// Adicionar rota de teste para mostrar env dinâmico (antes das rotas)
// Adicionar rota de teste para mostrar config declarativo (antes das rotas)
app.getApp().get('/api/env-test', () => {
return {
message: '🔥 Environment Variables Simplificado!',
message: '⚡ Declarative Config System!',
timestamp: new Date().toISOString(),
serverConfig: {
port: serverConfig.port,
host: serverConfig.host,
apiPrefix: serverConfig.apiPrefix,
appName: serverConfig.appName,
appVersion: serverConfig.appVersion,
cors: {
origins: serverConfig.corsOrigins,
methods: serverConfig.corsMethods,
credentials: serverConfig.corsCredentials
},
client: {
port: serverConfig.clientPort,
target: serverConfig.clientTarget,
sourceMaps: serverConfig.clientSourceMaps
},
features: {
enableSwagger: serverConfig.enableSwagger,
enableMetrics: serverConfig.enableMetrics,
enableMonitoring: serverConfig.enableMonitoring
}
},
environment: {
NODE_ENV: env.NODE_ENV, // Direto!
PORT: env.PORT, // Direto!
HOST: env.HOST, // Direto!
DEBUG: env.DEBUG, // Direto!
CORS_ORIGINS: env.CORS_ORIGINS, // Direto!
ENABLE_SWAGGER: env.ENABLE_SWAGGER, // Direto!

// Vars customizadas com casting automático
CUSTOM_VAR: env.get('CUSTOM_VAR', 'not-set'),
MAX_RETRIES: env.get('MAX_RETRIES', 3), // number
ENABLE_CACHE: env.get('ENABLE_CACHE', false), // boolean
ALLOWED_IPS: env.get('ALLOWED_IPS', []) // string[]
NODE_ENV: appConfig.env,
DEBUG: appConfig.debug,
LOG_LEVEL: loggerConfig.level
},
urls: {
server: helpers.getServerUrl(), // Helper!
server: helpers.getServerUrl(),
client: helpers.getClientUrl(),
swagger: `${helpers.getServerUrl()}/swagger`
},
note: 'API simplificada com casting automático! 🚀'
system: {
version: 'declarative-config',
features: ['type-safe', 'validated', 'declarative', 'runtime-reload']
}
}
})

Expand Down
Loading
Loading