refactor: Standardize user and organization ID properties, update Vite proxy port, and refactor data sheet file serving.
This commit is contained in:
@@ -34,7 +34,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
|||||||
const fetchTokenAndUser = async () => {
|
const fetchTokenAndUser = async () => {
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
try {
|
try {
|
||||||
const accessToken = await getAccessToken();
|
const accessToken = await getAccessToken(import.meta.env.VITE_LOGTO_RESOURCE || 'https://gpi.reifonas.cloud/api');
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
setToken(accessToken);
|
setToken(accessToken);
|
||||||
setApiToken(accessToken);
|
setApiToken(accessToken);
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import type { LogtoConfig } from '@logto/react';
|
|||||||
// Require the user to define VITE_LOGTO_APP_ID in Coolify
|
// Require the user to define VITE_LOGTO_APP_ID in Coolify
|
||||||
const config: LogtoConfig = {
|
const config: LogtoConfig = {
|
||||||
endpoint: 'https://logto.reifonas.cloud',
|
endpoint: 'https://logto.reifonas.cloud',
|
||||||
appId: import.meta.env.VITE_LOGTO_APP_ID || '', // Replace or add via Envs!
|
appId: import.meta.env.VITE_LOGTO_APP_ID || '',
|
||||||
|
scopes: ['email', 'profile', 'organizations'],
|
||||||
|
resources: [import.meta.env.VITE_LOGTO_RESOURCE || 'https://gpi.reifonas.cloud/api'],
|
||||||
};
|
};
|
||||||
|
|
||||||
// Force service worker cache clearing because of persistent Clerk error
|
// Force service worker cache clearing because of persistent Clerk error
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import '../middleware/roleMiddleware.js'; // Ensure type augmentation
|
|||||||
export const createApplicationRecord = async (req: Request, res: Response) => {
|
export const createApplicationRecord = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const organizationId = req.appUser?.organizationId;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const createdBy = req.appUser?.externalId;
|
const createdBy = req.appUser?.id;
|
||||||
const record = await appRecordService.createApplicationRecord({ ...req.body, organizationId, createdBy });
|
const record = await appRecordService.createApplicationRecord({ ...req.body, organizationId, createdBy });
|
||||||
res.status(201).json(record);
|
res.status(201).json(record);
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
@@ -29,7 +29,7 @@ export const getApplicationRecordsByProject = async (req: Request, res: Response
|
|||||||
export const updateApplicationRecord = async (req: Request, res: Response) => {
|
export const updateApplicationRecord = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const organizationId = req.appUser?.organizationId;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const userId = req.appUser?.externalId;
|
const userId = req.appUser?.id;
|
||||||
const userRole = req.appUser?.organizationRole || req.appUser?.role;
|
const userRole = req.appUser?.organizationRole || req.appUser?.role;
|
||||||
const isDeveloper = req.appUser?.email === 'admtracksteel@gmail.com';
|
const isDeveloper = req.appUser?.email === 'admtracksteel@gmail.com';
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ export const updateApplicationRecord = async (req: Request, res: Response) => {
|
|||||||
export const deleteApplicationRecord = async (req: Request, res: Response) => {
|
export const deleteApplicationRecord = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const organizationId = req.appUser?.organizationId;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const userId = req.appUser?.externalId;
|
const userId = req.appUser?.id;
|
||||||
const userRole = req.appUser?.organizationRole || req.appUser?.role;
|
const userRole = req.appUser?.organizationRole || req.appUser?.role;
|
||||||
const isDeveloper = req.appUser?.email === 'admtracksteel@gmail.com';
|
const isDeveloper = req.appUser?.email === 'admtracksteel@gmail.com';
|
||||||
|
|
||||||
|
|||||||
@@ -115,11 +115,10 @@ export const getMe = async (req: Request, res: Response): Promise<void> => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
id: req.appUser._id,
|
id: req.appUser.id,
|
||||||
name: req.appUser.name,
|
name: req.appUser.name,
|
||||||
email: req.appUser.email,
|
email: req.appUser.email,
|
||||||
role: req.appUser.role,
|
role: req.appUser.role,
|
||||||
externalId: req.appUser.externalId,
|
|
||||||
organizationId: req.appUser.organizationId
|
organizationId: req.appUser.organizationId
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -267,18 +267,12 @@ export const getFile = async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to file system (legacy)
|
// Fallback to file system (legacy)
|
||||||
const stream = dataSheetService.getFileStream(id_or_filename);
|
const file = await dataSheetService.getFileStream(id_or_filename);
|
||||||
|
res.set('Content-Type', file.content_type || 'application/pdf');
|
||||||
stream.on('file', (file) => {
|
res.set('Content-Disposition', `inline; filename="${file.filename}"`);
|
||||||
res.set('Content-Type', 'application/pdf');
|
res.set('Access-Control-Allow-Origin', '*');
|
||||||
res.set('Content-Disposition', `inline; filename="${file.filename}"`);
|
res.set('Cache-Control', 'public, max-age=3600');
|
||||||
});
|
res.send(file.data);
|
||||||
|
|
||||||
stream.on('error', () => {
|
|
||||||
res.status(404).json({ error: 'File not found' });
|
|
||||||
});
|
|
||||||
|
|
||||||
stream.pipe(res);
|
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const message = error instanceof Error ? error.message : 'Unknown error';
|
const message = error instanceof Error ? error.message : 'Unknown error';
|
||||||
console.error('Error getting file:', error);
|
console.error('Error getting file:', error);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import '../middleware/roleMiddleware.js'; // Ensure type augmentation
|
|||||||
export const createInspection = async (req: Request, res: Response) => {
|
export const createInspection = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const organizationId = req.appUser?.organizationId;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const createdBy = req.appUser?.externalId;
|
const createdBy = req.appUser?.id;
|
||||||
const inspection = await inspectionService.createInspection({
|
const inspection = await inspectionService.createInspection({
|
||||||
...req.body,
|
...req.body,
|
||||||
organizationId,
|
organizationId,
|
||||||
@@ -46,7 +46,7 @@ export const getInspectionsByProject = async (req: Request, res: Response) => {
|
|||||||
export const updateInspection = async (req: Request, res: Response) => {
|
export const updateInspection = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const organizationId = req.appUser?.organizationId;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const userId = req.appUser?.externalId;
|
const userId = req.appUser?.id;
|
||||||
const userRole = req.appUser?.organizationRole || req.appUser?.role;
|
const userRole = req.appUser?.organizationRole || req.appUser?.role;
|
||||||
const isDeveloper = req.appUser?.email === 'admtracksteel@gmail.com';
|
const isDeveloper = req.appUser?.email === 'admtracksteel@gmail.com';
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ export const updateInspection = async (req: Request, res: Response) => {
|
|||||||
export const deleteInspection = async (req: Request, res: Response) => {
|
export const deleteInspection = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const organizationId = req.appUser?.organizationId;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const userId = req.appUser?.externalId;
|
const userId = req.appUser?.id;
|
||||||
const userRole = req.appUser?.organizationRole || req.appUser?.role;
|
const userRole = req.appUser?.organizationRole || req.appUser?.role;
|
||||||
const isDeveloper = req.appUser?.email === 'admtracksteel@gmail.com';
|
const isDeveloper = req.appUser?.email === 'admtracksteel@gmail.com';
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import OrganizationMember from '../models/OrganizationMember.js';
|
|||||||
export const sendMessage = async (req: Request, res: Response) => {
|
export const sendMessage = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { toUserId, message } = req.body;
|
const { toUserId, message } = req.body;
|
||||||
const fromUserId = req.appUser?.externalId;
|
const fromUserId = req.appUser?.id;
|
||||||
const organizationId = req.headers['x-organization-id'] as string;
|
const organizationId = req.headers['x-organization-id'] as string;
|
||||||
|
|
||||||
if (!organizationId) {
|
if (!organizationId) {
|
||||||
@@ -60,7 +60,7 @@ export const sendMessage = async (req: Request, res: Response) => {
|
|||||||
// Get unread messages for current user
|
// Get unread messages for current user
|
||||||
export const getUnreadMessages = async (req: Request, res: Response) => {
|
export const getUnreadMessages = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const toUserId = req.appUser?.externalId;
|
const toUserId = req.appUser?.id;
|
||||||
const organizationId = req.headers['x-organization-id'] as string;
|
const organizationId = req.headers['x-organization-id'] as string;
|
||||||
|
|
||||||
if (!organizationId) {
|
if (!organizationId) {
|
||||||
@@ -101,7 +101,7 @@ export const getUnreadMessages = async (req: Request, res: Response) => {
|
|||||||
export const markMessageAsRead = async (req: Request, res: Response) => {
|
export const markMessageAsRead = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const userId = req.appUser?.externalId;
|
const userId = req.appUser?.id;
|
||||||
const organizationId = req.headers['x-organization-id'] as string;
|
const organizationId = req.headers['x-organization-id'] as string;
|
||||||
|
|
||||||
if (!organizationId) {
|
if (!organizationId) {
|
||||||
@@ -136,7 +136,7 @@ export const markMessageAsRead = async (req: Request, res: Response) => {
|
|||||||
// Get my pending (unread) sent messages
|
// Get my pending (unread) sent messages
|
||||||
export const getMyPendingMessages = async (req: Request, res: Response) => {
|
export const getMyPendingMessages = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const fromUserId = req.appUser?.externalId;
|
const fromUserId = req.appUser?.id;
|
||||||
const organizationId = req.headers['x-organization-id'] as string;
|
const organizationId = req.headers['x-organization-id'] as string;
|
||||||
|
|
||||||
if (!organizationId) {
|
if (!organizationId) {
|
||||||
@@ -175,7 +175,7 @@ export const getMyPendingMessages = async (req: Request, res: Response) => {
|
|||||||
export const deleteMessage = async (req: Request, res: Response) => {
|
export const deleteMessage = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const userId = req.appUser?.externalId;
|
const userId = req.appUser?.id;
|
||||||
const organizationId = req.headers['x-organization-id'] as string;
|
const organizationId = req.headers['x-organization-id'] as string;
|
||||||
|
|
||||||
if (!organizationId) {
|
if (!organizationId) {
|
||||||
@@ -209,7 +209,7 @@ export const deleteMessage = async (req: Request, res: Response) => {
|
|||||||
export const archiveMessage = async (req: Request, res: Response) => {
|
export const archiveMessage = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const userId = req.appUser?.externalId;
|
const userId = req.appUser?.id;
|
||||||
const organizationId = req.headers['x-organization-id'] as string;
|
const organizationId = req.headers['x-organization-id'] as string;
|
||||||
|
|
||||||
const message = await Message.findOne({ _id: id, toUserId: userId, organizationId });
|
const message = await Message.findOne({ _id: id, toUserId: userId, organizationId });
|
||||||
@@ -228,7 +228,7 @@ export const archiveMessage = async (req: Request, res: Response) => {
|
|||||||
export const recipientDeleteMessage = async (req: Request, res: Response) => {
|
export const recipientDeleteMessage = async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const userId = req.appUser?.externalId;
|
const userId = req.appUser?.id;
|
||||||
const organizationId = req.headers['x-organization-id'] as string;
|
const organizationId = req.headers['x-organization-id'] as string;
|
||||||
|
|
||||||
const message = await Message.findOne({ _id: id, toUserId: userId, organizationId });
|
const message = await Message.findOne({ _id: id, toUserId: userId, organizationId });
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ interface AuthRequest extends Request {
|
|||||||
|
|
||||||
export const createStockItem = async (req: AuthRequest, res: Response) => {
|
export const createStockItem = async (req: AuthRequest, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const organizationId = req.appUser?.organization_id;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const userName = req.appUser?.name || req.appUser?.email || 'Unknown User';
|
const userName = req.appUser?.name || req.appUser?.email || 'Unknown User';
|
||||||
const {
|
const {
|
||||||
dataSheetId,
|
dataSheetId,
|
||||||
@@ -97,7 +97,7 @@ export const createStockItem = async (req: AuthRequest, res: Response) => {
|
|||||||
export const updateStockItem = async (req: AuthRequest, res: Response) => {
|
export const updateStockItem = async (req: AuthRequest, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const organizationId = req.appUser?.organization_id;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const { quantity, ...otherData } = req.body;
|
const { quantity, ...otherData } = req.body;
|
||||||
|
|
||||||
if (quantity !== undefined) {
|
if (quantity !== undefined) {
|
||||||
@@ -118,7 +118,7 @@ export const updateStockItem = async (req: AuthRequest, res: Response) => {
|
|||||||
const updated = await stockService.updateStockItem(id as string, otherData, organizationId);
|
const updated = await stockService.updateStockItem(id as string, otherData, organizationId);
|
||||||
if (!updated) return res.status(404).json({ error: 'Item não encontrado.' });
|
if (!updated) return res.status(404).json({ error: 'Item não encontrado.' });
|
||||||
|
|
||||||
await notificationService.checkLowStock(id);
|
await notificationService.checkLowStock(id as string);
|
||||||
res.json(updated);
|
res.json(updated);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
@@ -128,7 +128,7 @@ export const updateStockItem = async (req: AuthRequest, res: Response) => {
|
|||||||
export const adjustStock = async (req: AuthRequest, res: Response) => {
|
export const adjustStock = async (req: AuthRequest, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const organizationId = req.appUser?.organization_id;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const { quantityDelta, reason } = req.body;
|
const { quantityDelta, reason } = req.body;
|
||||||
|
|
||||||
if (!reason) return res.status(400).json({ error: 'Motivo é obrigatório para ajustes técnicos.' });
|
if (!reason) return res.status(400).json({ error: 'Motivo é obrigatório para ajustes técnicos.' });
|
||||||
@@ -143,7 +143,7 @@ export const adjustStock = async (req: AuthRequest, res: Response) => {
|
|||||||
reason
|
reason
|
||||||
});
|
});
|
||||||
|
|
||||||
await notificationService.checkLowStock(id);
|
await notificationService.checkLowStock(id as string);
|
||||||
res.json(adjustment);
|
res.json(adjustment);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
@@ -153,7 +153,7 @@ export const adjustStock = async (req: AuthRequest, res: Response) => {
|
|||||||
export const consumeStock = async (req: AuthRequest, res: Response) => {
|
export const consumeStock = async (req: AuthRequest, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const organizationId = req.appUser?.organization_id;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const { quantityConsumed, requester, date } = req.body;
|
const { quantityConsumed, requester, date } = req.body;
|
||||||
|
|
||||||
if (!requester) return res.status(400).json({ error: 'Solicitante é obrigatório.' });
|
if (!requester) return res.status(400).json({ error: 'Solicitante é obrigatório.' });
|
||||||
@@ -168,7 +168,7 @@ export const consumeStock = async (req: AuthRequest, res: Response) => {
|
|||||||
reason: `Consumo por ${requester}`
|
reason: `Consumo por ${requester}`
|
||||||
});
|
});
|
||||||
|
|
||||||
await notificationService.checkLowStock(id);
|
await notificationService.checkLowStock(id as string);
|
||||||
res.json({ message: 'Consumo registrado com sucesso.' });
|
res.json({ message: 'Consumo registrado com sucesso.' });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
@@ -178,7 +178,7 @@ export const consumeStock = async (req: AuthRequest, res: Response) => {
|
|||||||
export const deleteStockItem = async (req: AuthRequest, res: Response) => {
|
export const deleteStockItem = async (req: AuthRequest, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const organizationId = req.appUser?.organization_id;
|
const organizationId = req.appUser?.organizationId;
|
||||||
await stockService.deleteStockItem(id as string, organizationId);
|
await stockService.deleteStockItem(id as string, organizationId);
|
||||||
res.status(204).send();
|
res.status(204).send();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -188,7 +188,7 @@ export const deleteStockItem = async (req: AuthRequest, res: Response) => {
|
|||||||
|
|
||||||
export const getStockItems = async (req: AuthRequest, res: Response) => {
|
export const getStockItems = async (req: AuthRequest, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const organizationId = req.appUser?.organization_id;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const items = await stockService.getStockItems(organizationId);
|
const items = await stockService.getStockItems(organizationId);
|
||||||
res.json(items);
|
res.json(items);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -199,7 +199,7 @@ export const getStockItems = async (req: AuthRequest, res: Response) => {
|
|||||||
export const getStockItemById = async (req: AuthRequest, res: Response) => {
|
export const getStockItemById = async (req: AuthRequest, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const organizationId = req.appUser?.organization_id;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const result = await query(
|
const result = await query(
|
||||||
`SELECT si.*, tds.name as data_sheet_name
|
`SELECT si.*, tds.name as data_sheet_name
|
||||||
FROM stock_items si
|
FROM stock_items si
|
||||||
@@ -217,8 +217,8 @@ export const getStockItemById = async (req: AuthRequest, res: Response) => {
|
|||||||
export const getStockMovements = async (req: AuthRequest, res: Response) => {
|
export const getStockMovements = async (req: AuthRequest, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const organizationId = req.appUser?.organization_id;
|
const organizationId = req.appUser?.organizationId;
|
||||||
const movements = await stockService.getMovementsByItem(id, organizationId);
|
const movements = await stockService.getMovementsByItem(id as string, organizationId);
|
||||||
res.json(movements);
|
res.json(movements);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
|
|||||||
@@ -102,6 +102,18 @@ export const notificationService = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async clearAll(userId: string, organizationId: string) {
|
||||||
|
try {
|
||||||
|
await query(
|
||||||
|
'DELETE FROM notifications WHERE organization_id = $1 AND (user_id = $2 OR user_id IS NULL)',
|
||||||
|
[organizationId, userId]
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error clearing all notifications:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async archive(id: string, userId: string) {
|
async archive(id: string, userId: string) {
|
||||||
try {
|
try {
|
||||||
const check = await query('SELECT * FROM notifications WHERE id = $1', [id]);
|
const check = await query('SELECT * FROM notifications WHERE id = $1', [id]);
|
||||||
|
|||||||
@@ -46,12 +46,12 @@ export default defineConfig({
|
|||||||
server: {
|
server: {
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://127.0.0.1:3001',
|
target: 'http://127.0.0.1:3005',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: false,
|
secure: false,
|
||||||
},
|
},
|
||||||
'/uploads': {
|
'/uploads': {
|
||||||
target: 'http://127.0.0.1:3001',
|
target: 'http://127.0.0.1:3005',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: false,
|
secure: false,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user