Passo 8 completo. Tudo verde. Sumário do que foi feito:
Novas páginas:
app/select-operator/page.tsx — Server Component; redireciona automaticamente se já há sessão; lista operadores via prisma direto (funciona mesmo sem sessão ativa)
app/select-operator/operator-picker.tsx — Client Component; tap → signIn('credentials', { email, redirect: false }) → redireciona para /
app/sign-out-button.tsx — botão "Trocar" que chama signOut → volta ao picker
middleware.ts atualizado — redireciona para /select-operator quando não há sessão e AUTH_DEV_AUTOLOGIN=false; skip automático se já logado; o picker não faz redirect se não há sessão (deixa carregar)
app/page.tsx atualizado — mostra chip com o email do utilizador atual + botão "Trocar" (necessário para o AC "header mostra op1@demo.local")
Correções de infraestrutura descobertas:
NODE_ENV="development" removido do .env — estava a forçar o runtime de dev no next build, quebrando a geração estática
pages/_error.tsx adicionado — override mínimo que previne o erro <Html> outside _document
@repo/storage adicionado a transpilePackages e AWS SDK marcado como serverExternalPackages
app/not-found.tsx + app/error.tsx adicionados para App Router
AC verificado: build de produção passa limpo em Next.js 15.3.9 com todas as rotas correctas. O fluxo demo (/ → picker → login → / mostra email) funciona via dev server.
35 lines
1.0 KiB
TypeScript
35 lines
1.0 KiB
TypeScript
import { createEnv } from '@t3-oss/env-nextjs';
|
|
import { z } from 'zod';
|
|
|
|
/**
|
|
* Zod-validated environment. Imported eagerly from next.config.ts so that
|
|
* missing/invalid variables fail the build instead of silently leaking
|
|
* `undefined` at runtime.
|
|
*/
|
|
export const env = createEnv({
|
|
server: {
|
|
DATABASE_URL: z.string().url(),
|
|
AUTH_SECRET: z.string().min(1, 'AUTH_SECRET is required'),
|
|
AUTH_URL: z.string().url().optional(),
|
|
AUTH_DEV_AUTOLOGIN: z
|
|
.string()
|
|
.optional()
|
|
.transform((v) => v === 'true'),
|
|
LOG_LEVEL: z
|
|
.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace'])
|
|
.default('info'),
|
|
},
|
|
client: {
|
|
NEXT_PUBLIC_APP_URL: z.string().url(),
|
|
},
|
|
runtimeEnv: {
|
|
DATABASE_URL: process.env.DATABASE_URL,
|
|
AUTH_SECRET: process.env.AUTH_SECRET,
|
|
AUTH_URL: process.env.AUTH_URL,
|
|
AUTH_DEV_AUTOLOGIN: process.env.AUTH_DEV_AUTOLOGIN,
|
|
LOG_LEVEL: process.env.LOG_LEVEL,
|
|
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
|
|
},
|
|
emptyStringAsUndefined: true,
|
|
});
|