Correção de erro 500 em mensagens (UUID), criação de tabela messages e tratamento defensivo no front-end para evitar crashes
This commit is contained in:
17
create_messages_table.sql
Normal file
17
create_messages_table.sql
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
-- Criar tabela de mensagens no schema gpi
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.messages (
|
||||||
|
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||||
|
organization_id uuid REFERENCES gpi.organizations(id) ON DELETE CASCADE,
|
||||||
|
from_user_id uuid REFERENCES gpi.users(id) ON DELETE SET NULL,
|
||||||
|
to_user_id uuid REFERENCES gpi.users(id) ON DELETE SET NULL,
|
||||||
|
message text NOT NULL,
|
||||||
|
is_read boolean DEFAULT false,
|
||||||
|
read_at timestamp with time zone,
|
||||||
|
is_archived boolean DEFAULT false,
|
||||||
|
is_deleted_by_recipient boolean DEFAULT false,
|
||||||
|
created_at timestamp with time zone DEFAULT now(),
|
||||||
|
updated_at timestamp with time zone DEFAULT now()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Permissões para as roles do Supabase
|
||||||
|
GRANT ALL ON gpi.messages TO postgres, anon, authenticated, service_role;
|
||||||
@@ -72,7 +72,7 @@ export const TeamPresence: React.FC = () => {
|
|||||||
|
|
||||||
// Create a map of pending messages by recipient ID
|
// Create a map of pending messages by recipient ID
|
||||||
const pendingMessagesByRecipient = new Map(
|
const pendingMessagesByRecipient = new Map(
|
||||||
pendingMessages.map(msg => [msg.toUser?.email, msg])
|
(pendingMessages || []).map(msg => [msg.toUser?.email, msg])
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleMemberClick = (member: OrganizationMember) => {
|
const handleMemberClick = (member: OrganizationMember) => {
|
||||||
@@ -102,11 +102,11 @@ export const TeamPresence: React.FC = () => {
|
|||||||
<div className="px-6 py-3">
|
<div className="px-6 py-3">
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<span className="text-[10px] font-bold text-text-muted uppercase tracking-[0.2em]">
|
<span className="text-[10px] font-bold text-text-muted uppercase tracking-[0.2em]">
|
||||||
Equipe ({activeUsers.length}/{allMembers.length} online)
|
Equipe ({(activeUsers || []).length}/{(allMembers || []).length} online)
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
{allMembers.map((member) => {
|
{(allMembers || []).map((member) => {
|
||||||
const isOnline = activeUserLogtoIds.has(member.logto_id);
|
const isOnline = activeUserLogtoIds.has(member.logto_id);
|
||||||
const isCurrentUser = member.logto_id === appUser?.logtoId;
|
const isCurrentUser = member.logto_id === appUser?.logtoId;
|
||||||
const hasPendingMessage = pendingMessagesByRecipient.has(member.email);
|
const hasPendingMessage = pendingMessagesByRecipient.has(member.email);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ interface AuthProviderProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const defaultUser: AppUser = {
|
const defaultUser: AppUser = {
|
||||||
id: 'guest-user',
|
id: '00000000-0000-0000-0000-000000000000',
|
||||||
email: 'guest@gpi.app',
|
email: 'guest@gpi.app',
|
||||||
name: 'Guest User',
|
name: 'Guest User',
|
||||||
role: 'user',
|
role: 'user',
|
||||||
@@ -18,7 +18,7 @@ const defaultUser: AppUser = {
|
|||||||
updatedAt: new Date().toISOString()
|
updatedAt: new Date().toISOString()
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_ORGANIZATION_ID = 'default-org';
|
const DEFAULT_ORGANIZATION_ID = '00000000-0000-0000-0000-000000000001';
|
||||||
const DEFAULT_ORGANIZATION_NAME = 'Organização Padrão';
|
const DEFAULT_ORGANIZATION_NAME = 'Organização Padrão';
|
||||||
|
|
||||||
export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
|
export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export const NotificationProvider: React.FC<{ children: React.ReactNode }> = ({
|
|||||||
}
|
}
|
||||||
}, [isSignedIn, fetchNotifications]);
|
}, [isSignedIn, fetchNotifications]);
|
||||||
|
|
||||||
const unreadCount = notifications.filter(n => !n.isRead).length;
|
const unreadCount = (notifications || []).filter(n => !n.isRead).length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NotificationContext.Provider value={{
|
<NotificationContext.Provider value={{
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export const getCurrentUser = async (req: AuthRequest, res: Response) => {
|
|||||||
try {
|
try {
|
||||||
if (!req.appUser) {
|
if (!req.appUser) {
|
||||||
return res.json({
|
return res.json({
|
||||||
id: 'guest-user',
|
id: '00000000-0000-0000-0000-000000000000',
|
||||||
email: 'guest@gpi.app',
|
email: 'guest@gpi.app',
|
||||||
name: 'Guest User',
|
name: 'Guest User',
|
||||||
role: 'user'
|
role: 'user'
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ declare module 'express-serve-static-core' {
|
|||||||
|
|
||||||
export const extractUser = async (req: Request, res: Response, next: NextFunction) => {
|
export const extractUser = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
req.appUser = {
|
req.appUser = {
|
||||||
id: 'guest-user',
|
id: '00000000-0000-0000-0000-000000000000',
|
||||||
logtoId: 'guest',
|
logtoId: 'guest',
|
||||||
email: 'guest@gpi.app',
|
email: 'guest@gpi.app',
|
||||||
name: 'Guest User',
|
name: 'Guest User',
|
||||||
role: 'user',
|
role: 'user',
|
||||||
organizationId: req.headers['x-organization-id'] as string || 'default-org',
|
organizationId: req.headers['x-organization-id'] as string || '00000000-0000-0000-0000-000000000001',
|
||||||
organizationRole: 'user'
|
organizationRole: 'user'
|
||||||
};
|
};
|
||||||
next();
|
next();
|
||||||
|
|||||||
Reference in New Issue
Block a user