tRPC Routers
Esta página documenta os routers tRPC disponíveis no APAH Assistant.
User Router
Gestão de utilizadores do sistema.
Procedures
user.list
Lista utilizadores com paginação e filtros.
// Input
{
search?: string;
page?: number; // default: 1
limit?: number; // default: 10
roleId?: string;
isActive?: boolean;
}
// Output
{
items: User[];
total: number;
page: number;
totalPages: number;
}
user.getById
Obtém um utilizador por ID.
// Input
{ id: string }
// Output
User | null
user.create
Cria um novo utilizador. Requer role Admin.
// Input
{
name: string;
email: string;
password: string;
roleId: string;
}
// Output
User
user.update
Atualiza um utilizador.
// Input
{
id: string;
name?: string;
email?: string;
roleId?: string;
isActive?: boolean;
}
// Output
User
user.delete
Elimina um utilizador. Requer role Admin.
// Input
{ id: string }
// Output
{ success: boolean }
user.resetPassword
Reset de password. Requer role Admin.
// Input
{
userId: string;
newPassword: string;
}
// Output
{ success: boolean }
Chat Router
Gestão de conversas e histórico de chat.
Procedures
chat.getHistory
Obtém histórico de chats do utilizador atual.
// Input
{
limit?: number; // default: 50
}
// Output
Chat[]
chat.getById
Obtém um chat com mensagens.
// Input
{ id: string }
// Output
{
id: string;
title: string;
messages: Message[];
createdAt: Date;
updatedAt: Date;
}
chat.create
Cria um novo chat.
// Input
{
title?: string; // default: "Nova Conversa"
}
// Output
Chat
chat.updateTitle
Atualiza o título de um chat.
// Input
{
id: string;
title: string;
}
// Output
Chat
chat.delete
Elimina um chat e todas as suas mensagens.
// Input
{ id: string }
// Output
{ success: boolean }
Library Router
Gestão de documentos da biblioteca.
Procedures
library.list
Lista documentos com paginação e filtros.
// Input
{
search?: string;
page?: number; // default: 1
limit?: number; // default: 10
isActive?: boolean;
}
// Output
{
items: Document[];
total: number;
page: number;
totalPages: number;
}
library.getById
Obtém um documento por ID.
// Input
{ id: string }
// Output
Document & { chunksCount: number }
library.update
Atualiza metadados de um documento.
// Input
{
id: string;
title?: string;
description?: string;
isActive?: boolean;
}
// Output
Document
library.delete
Elimina um documento. Requer role Admin.
// Input
{ id: string }
// Output
{ success: boolean }
Feedback Router
Gestão de feedback sobre respostas do assistente.
Procedures
feedback.create
Regista feedback sobre uma mensagem.
// Input
{
messageId: string;
type: "positive" | "negative";
comment?: string;
}
// Output
Feedback
feedback.list
Lista feedbacks. Requer role Admin.
// Input
{
type?: "positive" | "negative";
page?: number;
limit?: number;
}
// Output
{
items: Feedback[];
total: number;
}
Permissões
Níveis de Acesso
| Procedure | Public | User | Editor | Admin |
|---|---|---|---|---|
user.list | ❌ | ❌ | ✅ | ✅ |
user.getById | ❌ | Próprio | ✅ | ✅ |
user.create | ❌ | ❌ | ❌ | ✅ |
user.update | ❌ | Próprio | ❌ | ✅ |
user.delete | ❌ | ❌ | ❌ | ✅ |
chat.getHistory | ❌ | ✅ | ✅ | ✅ |
chat.create | ❌ | ✅ | ✅ | ✅ |
chat.delete | ❌ | Próprio | Próprio | ✅ |
library.list | ❌ | ✅ | ✅ | ✅ |
library.update | ❌ | ❌ | ✅ | ✅ |
library.delete | ❌ | ❌ | ❌ | ✅ |
feedback.create | ❌ | ✅ | ✅ | ✅ |
feedback.list | ❌ | ❌ | ❌ | ✅ |
Exemplo de Uso Completo
"use client";
import { api } from "@/lib/trpc/client";
export function UsersPage() {
// Query com React Query
const { data, isLoading, error, refetch } = api.user.list.useQuery({
page: 1,
limit: 10,
});
// Mutations
const createMutation = api.user.create.useMutation({
onSuccess: () => {
toast.success("Utilizador criado");
refetch();
},
onError: (error) => {
toast.error(error.message);
},
});
const deleteMutation = api.user.delete.useMutation({
onSuccess: () => {
toast.success("Utilizador eliminado");
refetch();
},
});
// Handlers
const handleCreate = (data: CreateUserInput) => {
createMutation.mutate(data);
};
const handleDelete = (id: string) => {
if (confirm("Tem certeza?")) {
deleteMutation.mutate({ id });
}
};
if (isLoading) return <Loading />;
if (error) return <Error message={error.message} />;
return (
<div>
<Button onClick={() => setShowCreateModal(true)}>
Novo Utilizador
</Button>
<Table>
<TableHeader>
<TableRow>
<TableHead>Nome</TableHead>
<TableHead>Email</TableHead>
<TableHead>Role</TableHead>
<TableHead>Ações</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{data.items.map((user) => (
<TableRow key={user.id}>
<TableCell>{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>{user.roles[0]?.name}</TableCell>
<TableCell>
<Button
variant="destructive"
size="sm"
onClick={() => handleDelete(user.id)}
>
Eliminar
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<Pagination
currentPage={data.page}
totalPages={data.totalPages}
onPageChange={(page) => setPage(page)}
/>
</div>
);
}