diff --git a/susconecta/app/paciente/page.tsx b/susconecta/app/paciente/page.tsx
index 8bc6fed..e034364 100644
--- a/susconecta/app/paciente/page.tsx
+++ b/susconecta/app/paciente/page.tsx
@@ -728,14 +728,10 @@ export default function PacientePage() {
{/* Conteúdo principal */}
- {/* Banner informativo visível ao usuário/operador */}
-
-
- Observação: qualquer usuário autenticado pode acessar esta área do paciente.
-
- Importante: o perfil de paciente no backend não contém um campo `user_id` que o cliente deva manipular. A atribuição de papéis/roles e vinculação entre usuário de autenticação e perfil é feita somente pela API.
-
-
+ {/* Banner removido - mensagem relevante apenas em logs para devs/admins */}
+ {process.env.NODE_ENV === 'development' && (
+ console.log('[INFO] paciente page note: perfil de paciente não contém campo user_id; atribuição de roles e vínculo é feita pela API.')
+ )}
{/* Toasts de feedback */}
{toast && (
diff --git a/susconecta/lib/api.ts b/susconecta/lib/api.ts
index b828103..c9b271f 100644
--- a/susconecta/lib/api.ts
+++ b/susconecta/lib/api.ts
@@ -242,6 +242,13 @@ async function parse(res: Response): Promise {
// Mensagens amigáveis para erros comuns
let friendlyMessage = msg;
+ // Row-Level Security (RLS) do Postgres / Supabase -> dar mensagem amigável
+ const lowerRaw = String(rawText || '').toLowerCase();
+ const isRls = (json && (json.code === '42501' || json?.error?.code === '42501')) || lowerRaw.includes('row-level security') || String(msg).toLowerCase().includes('row-level security') || String(msg).toLowerCase().includes('violates row-level');
+ if (isRls) {
+ friendlyMessage = 'Permissão negada para gravar este registro. Verifique suas permissões ou peça para um administrador criar o registro pelo painel.';
+ }
+
// Erros de criação de usuário ou códigos conhecidos
if (res.url?.includes('create-user')) {
// organizar casos por checagens em ordem específica
@@ -1200,31 +1207,95 @@ export async function criarUsuario(input: CreateUserInput): Promise '');
+ let signupJson: any = null; try { signupJson = signupText ? JSON.parse(signupText) : null; } catch { signupJson = signupText; }
+ if (signupRes.ok) {
+ authCreated = true;
+ console.debug('[USER API] signup created auth user:', signupJson?.user ?? input.email);
+ } else {
+ // If already registered or duplicate, mark as exists and continue
+ const raw = String(signupText || '').toLowerCase();
+ if (raw.includes('already registered') || raw.includes('duplicate') || (signupJson && (signupJson.error || '').toString().toLowerCase().includes('already registered'))) {
+ authAlreadyExists = true;
+ console.debug('[USER API] signup indicates user already exists, continuing:', signupText);
+ } else {
+ console.warn('[USER API] signup failed:', signupRes.status, signupText);
+ }
+ }
+ } catch (e) {
+ console.warn('[USER API] signup request failed:', e);
}
- // Parse com captura para logar resposta bruta e final
+ // 2) Then call the Edge Function to create the app-level user record (profiles/roles)
try {
- const parsed = await parse(response);
- try { console.debug('[USER API] create-user response:', parsed); } catch (_) {}
- return parsed;
- } catch (apiErr: any) {
- // Já temos logs do parse em parse(), mas adicionamos um log contextual
- console.error('[USER API] create-user failed:', apiErr?.message || apiErr);
- throw apiErr;
+ const fnRes = await fetch(url, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ Accept: 'application/json',
+ ...baseHeaders(),
+ // Ensure requester token (admin) is sent to Edge Function for authorization
+ 'Authorization': `Bearer ${token}`,
+ },
+ body: JSON.stringify({
+ email: input.email,
+ password: passwordToUse,
+ full_name: input.full_name,
+ phone: input.phone ?? null,
+ role: input.role ?? 'user',
+ }),
+ });
+
+ const fnText = await fnRes.text();
+ let fnJson: any = null; try { fnJson = fnText ? JSON.parse(fnText) : null; } catch { fnJson = fnText; }
+
+ if (!fnRes.ok) {
+ console.warn('[USER API] Edge Function create-user failed:', fnRes.status, fnJson ?? fnText);
+ // If auth was created but app record failed, return a descriptive error
+ if (authCreated || authAlreadyExists) {
+ throw new Error('O usuário de autenticação foi criado, mas a criação do registro na API falhou. Contate o administrador.');
+ }
+ // If both failed, throw a generic error
+ throw new Error('Falha ao criar usuário na API. ' + (fnJson?.message ?? fnText ?? String(fnRes.status)));
+ }
+
+ const createdUser = fnJson?.user ?? fnJson ?? null;
+
+ const result: any = {
+ success: true,
+ user: createdUser,
+ email: input.email,
+ password: passwordToUse,
+ meta: {
+ authCreated,
+ authAlreadyExists,
+ functionResponse: fnJson ?? fnText,
+ }
+ } as unknown as CreateUserWithPasswordResponse;
+
+ return result as unknown as CreateUserResponse;
+ } catch (err) {
+ console.error('[USER API] create-user flow error:', err);
+ throw err;
}
}
diff --git a/susconecta/lib/config.ts b/susconecta/lib/config.ts
index 019ed05..261aae4 100644
--- a/susconecta/lib/config.ts
+++ b/susconecta/lib/config.ts
@@ -14,10 +14,7 @@ export const AUTH_ENDPOINTS = {
export const FUNCTIONS_ENDPOINTS = {
USER_INFO: `${ENV_CONFIG.SUPABASE_URL}/functions/v1/user-info`,
- // Use internal Next.js server route which performs privileged operations
- // with the service role key. Client should call this route instead of
- // calling the Supabase Edge Function directly.
- CREATE_USER: `/api/create-user`,
+ CREATE_USER: `${ENV_CONFIG.SUPABASE_URL}/functions/v1/create-user`,
} as const;
export const API_KEY = ENV_CONFIG.SUPABASE_ANON_KEY;