feat: campo RETHUS con validación manual desde el admin

- Prisma schema: rethus_code y rethus_validated en tabla professionals
- Migración 0001: ALTER TABLE agrega ambas columnas
- DTO: rethus_code y rethus_validated en CreateProfessionalDto y UpdateProfessionalDto
- Service: nuevo método validateRethus, rethus_code incluido en requestProfessional
- Controller: endpoint POST /professionals/:id/validate-rethus (JWT protegido)
- Admin listado pendientes: columna RETHUS con ícono verde/amarillo y enlace al detalle
- Admin detalle profesional: card de validación RETHUS con botón consultar Minsalud y marcar como validado

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-06-27 18:23:55 -05:00
co-authored by Claude Sonnet 4.6
parent 46fcb57edf
commit c1e9dba2d1
7 changed files with 142 additions and 6 deletions
+25 -3
View File
@@ -8,6 +8,8 @@ import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { toast } from 'sonner';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import Link from 'next/link';
import { ShieldCheck, ShieldAlert } from 'lucide-react';
interface Professional {
id: string;
@@ -15,6 +17,8 @@ interface Professional {
is_active: boolean;
profession?: string;
identification?: string;
rethus_code?: string;
rethus_validated?: boolean;
rate?: number;
users?: { id: string; name: string; email?: string; phone?: string };
}
@@ -112,7 +116,7 @@ export default function ProfessionalsPage() {
<TableHead>Nombre</TableHead>
<TableHead>Email</TableHead>
<TableHead>Teléfono</TableHead>
<TableHead>Solicitud</TableHead>
<TableHead>RETHUS</TableHead>
<TableHead className="text-right">Acción</TableHead>
</TableRow>
</TableHeader>
@@ -124,11 +128,29 @@ export default function ProfessionalsPage() {
) : (
pending.map((p) => (
<TableRow key={p.id}>
<TableCell className="font-medium">{p.users?.name}</TableCell>
<TableCell className="font-medium">
<Link href={`/professionals/${p.id}`} className="hover:underline text-primary">
{p.users?.name}
</Link>
</TableCell>
<TableCell>{p.users?.email || '—'}</TableCell>
<TableCell>{p.users?.phone || '—'}</TableCell>
<TableCell>{new Date().toLocaleDateString()}</TableCell>
<TableCell>
{p.rethus_code ? (
<div className="flex items-center gap-1">
{p.rethus_validated
? <ShieldCheck className="h-4 w-4 text-green-500" />
: <ShieldAlert className="h-4 w-4 text-yellow-500" />}
<span className="font-mono text-xs">{p.rethus_code}</span>
</div>
) : (
<span className="text-muted-foreground text-xs">No aplica</span>
)}
</TableCell>
<TableCell className="text-right space-x-2">
<Link href={`/professionals/${p.id}`}>
<Button size="sm" variant="outline">Ver detalle</Button>
</Link>
<Button size="sm" onClick={() => approve(p.id)}>Aprobar</Button>
<Button size="sm" variant="destructive" onClick={() => deny(p.id)}>Rechazar</Button>
</TableCell>