name: doccorretor-admin-role-debug
description: Debug and fix admin access in DocCorretor (documentos.rochasalesseguros.com.br) — when user has role='admin' in profiles but is still redirected to login or gets "no admin access"
tags:
- supabase
- rls
- doccorretor
- auth
- roles
DocCorretor Admin Access Debug
Trigger Conditions
- - User can login but gets redirected to login page when accessing
/admin - - User shows "Entrar com Google" even after being logged in
- - User has
role='admin'inprofilestable but still can't access admin panel - - Sets
isAdm = roles.includes('admin')based onuser_roles.role - - Queries
supabase.from('user_roles').select('role').eq('user_id', uid) - - If
user_rolesis empty or wrong,isAdmwill befalse - - Checks
role_permissionstable for section-level permissions (can_read/can_edit/can_delete) - - Skipped if
isAdm === true - - Nav items visible by default:
nav_clientes,nav_admin,nav_painel - - Redirects to
/authif user doesn't have required role - - Used as
on/adminroute - - Do NOT use anon key REST API to check
user_roles— RLS always returns[]even when data exists. Use Management API (api.supabase.com/v1/projects/.../database/query) instead. - -
profiles.roleanduser_roles.roleare independent — a user can haverole='admin'in profiles but emptyuser_roles. The frontend checksuser_roles. - - The
has_role()function checksuser_roles.rolewith exact string match for'admin'. - - OAuth login (Google) redirects to
/auth/callback— if that route returns 404, the app build may be stale. Rebuild withcd /var/www/documentos2/app && nvm use 20 && npm run build. - - Public uploads:
/var/www/documentos/uploads/public/{clientId}/{folderId}/{timestamp}-{filename} - - Upload links generated via Edge Function
client-upload-info, stored inclient_upload_linkstable - - Nginx serves
/uploads/from/var/www/documentos/uploads/ - - Never use PAT for Supabase Storage REST API — use local filesystem pattern instead
- - URL:
https://api.supabase.com/v1/projects/{ref}/database/query - - Auth: Personal Access Token from supabase.com/dashboard/account/tokens
- - Service role key does NOT work — gives "JWT failed verification"
- - URL:
https://dauftiqcvgaydddoxqhh.supabase.co/rest/v1/ - - Auth: anon key in
apikey+Authorization: Bearerheaders - - Service role key does NOT work for REST API (gives 401)
- - Anon key works for read queries; inserts need authenticated session
Architecture
DocCorretor uses TWO separate role systems that must BOTH be correct:
| Table | Column | Used For |
| ------- | -------- | ---------- |
profiles | role | Display label (admin/corretor/editor/viewer) |
user_roles | role | Actual permission check via has_role() function |
role_permissions | can_read/can_edit/can_delete | Per-section permissions per role_id |
| Aspect | Migrations say | Actual database |
| -------- | --------------- | --------------------- |
documents.category | doc_category enum | text (accepts any string) |
| Column nullability | Many NOT NULL | All nullable |
| Schema complexity | Complex with triggers | Simple |
Implication: Adding document categories requires NO database migration.
Only update TypeScript code (CATEGORY_LABELS + CATS).
Adding Document Categories
Categories are defined in THREE places (all in app/src/):
1. lib/storage-helpers.ts — CATEGORY_LABELS object (human-readable labels)
2. routes/admin.tsx — const CATS array (category dropdown in admin panel)
3. Database: documents.category — plain text, no constraint
Steps to add a category:
1. Add entry to CATEGORY_LABELS in storage-helpers.ts
2. Add key to CATS array in admin.tsx
3. Build and deploy — NO SQL migration needed
Building DocCorretor on VPS
The VPS has Node 20.20.2 at /root/.nvm/versions/node/v20.20.2/bin/node.
The nvm command may not be in PATH. Always use the full path directly:
`bash
cd /var/www/documentos/deploy-vps-nodejs/app
/root/.nvm/versions/node/v20.20.2/bin/node ./node_modules/vite/bin/vite.js build
`
Running npm run build fails because it uses system node (v18). Build output: dist/client/ + dist/server/.
Deploy: copy dist/ to the running app directory and restart:
`bash
sudo systemctl stop documentos
cp -r /var/www/documentos/deploy-vps-nodejs/app/dist /var/www/documentos2/app/dist
sudo systemctl start documentos
`
Supabase Management API vs REST API
Management API (DDL — ALTER TYPE, CREATE TABLE, etc.):
REST API (table CRUD — SELECT, INSERT, etc.):
Google Drive Migration (Jun 2026)
The Drive folder 1zVhApvpFM937qxsvsz37WCcUD-7f2zUP is organized by month/year:
documentos clientes/2023/08_2023/
Structure: top-level = year, second-level = month, third-level = client name, files inside.
gdown limitation: --folder flag cannot download folders with restricted subfolders.
If Drive folder is public, gdown may still fail on restricted content.
VPS network issues: All outbound connections (curl, wget, gdown, execute_code network)
may be blocked intermittently. If all external connections fail, use Option A:
user downloads Drive folder as .zip and uploads to VPS for local processing.