feat(shared): types API, logger structuré, validation env.ts
This commit is contained in:
parent
dbc9360b36
commit
476dfeeb08
3 changed files with 63 additions and 0 deletions
22
src/shared/config/env.ts
Normal file
22
src/shared/config/env.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { z } from 'zod'
|
||||
|
||||
const envSchema = z.object({
|
||||
VITE_API_URL: z.string().url(),
|
||||
VITE_SUPABASE_URL: z.string().url(),
|
||||
VITE_SUPABASE_ANON_KEY: z.string().min(1),
|
||||
VITE_ENABLE_T2_LIVE: z.enum(['true', 'false']).optional(),
|
||||
VITE_SENTRY_DSN: z.string().url().optional(),
|
||||
})
|
||||
|
||||
const parsed = envSchema.safeParse(import.meta.env)
|
||||
|
||||
if (!parsed.success) {
|
||||
const issues = parsed.error.issues
|
||||
.map((i) => ` - ${i.path.join('.')}: ${i.message}`)
|
||||
.join('\n')
|
||||
throw new Error(
|
||||
`Variables d'environnement invalides ou manquantes :\n${issues}\n\nVérifier .env.example`,
|
||||
)
|
||||
}
|
||||
|
||||
export const env = parsed.data
|
||||
18
src/shared/lib/logger.ts
Normal file
18
src/shared/lib/logger.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
type LogLevel = 'debug' | 'info' | 'warn' | 'error'
|
||||
type LogContext = Record<string, unknown>
|
||||
|
||||
function log(level: LogLevel, message: string, context?: LogContext): void {
|
||||
if (import.meta.env.DEV) {
|
||||
console[level](`[${level.toUpperCase()}] ${message}`, context ?? '')
|
||||
return
|
||||
}
|
||||
const entry = { level, message, timestamp: new Date().toISOString(), ...context }
|
||||
console[level](JSON.stringify(entry))
|
||||
}
|
||||
|
||||
export const logger = {
|
||||
debug: (msg: string, ctx?: LogContext) => log('debug', msg, ctx),
|
||||
info: (msg: string, ctx?: LogContext) => log('info', msg, ctx),
|
||||
warn: (msg: string, ctx?: LogContext) => log('warn', msg, ctx),
|
||||
error: (msg: string, ctx?: LogContext) => log('error', msg, ctx),
|
||||
}
|
||||
23
src/shared/types/api.ts
Normal file
23
src/shared/types/api.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// SOURCE OF TRUTH: expria-backend — format réel des erreurs, confirmé par audit 2026-04-17
|
||||
// Les modifications doivent être synchronisées avec le backend.
|
||||
|
||||
export interface ApiError {
|
||||
error: true
|
||||
code: ApiErrorCode
|
||||
message: string
|
||||
status?: number
|
||||
}
|
||||
|
||||
export type ApiErrorCode =
|
||||
| 'AUTH_REQUIRED'
|
||||
| 'PLAN_INSUFFICIENT'
|
||||
| 'QUOTA_REACHED'
|
||||
| 'VALIDATION_ERROR'
|
||||
| 'INVALID_BODY'
|
||||
| 'INVALID_PLAN'
|
||||
| 'NO_ACTIVE_SUBSCRIPTION'
|
||||
| 'SIMULATION_NOT_FOUND'
|
||||
| 'STRIPE_WEBHOOK_INVALID'
|
||||
| 'INTERNAL_ERROR'
|
||||
|
||||
export type FrontendErrorCode = 'TIMEOUT' | 'NETWORK_ERROR' | 'PARSE_ERROR'
|
||||
Loading…
Add table
Add a link
Reference in a new issue