refactor: Standardize user and organization ID properties, update Vite proxy port, and refactor data sheet file serving.

This commit is contained in:
2026-03-19 22:05:47 +00:00
parent 0b81094050
commit 37cc1b2acb
10 changed files with 50 additions and 43 deletions

View File

@@ -34,7 +34,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
const fetchTokenAndUser = async () => {
if (isAuthenticated) {
try {
const accessToken = await getAccessToken();
const accessToken = await getAccessToken(import.meta.env.VITE_LOGTO_RESOURCE || 'https://gpi.reifonas.cloud/api');
if (accessToken) {
setToken(accessToken);
setApiToken(accessToken);

View File

@@ -7,7 +7,9 @@ import type { LogtoConfig } from '@logto/react';
// Require the user to define VITE_LOGTO_APP_ID in Coolify
const config: LogtoConfig = {
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

View File

@@ -5,7 +5,7 @@ import '../middleware/roleMiddleware.js'; // Ensure type augmentation
export const createApplicationRecord = async (req: Request, res: Response) => {
try {
const organizationId = req.appUser?.organizationId;
const createdBy = req.appUser?.externalId;
const createdBy = req.appUser?.id;
const record = await appRecordService.createApplicationRecord({ ...req.body, organizationId, createdBy });
res.status(201).json(record);
} catch (error: unknown) {
@@ -29,7 +29,7 @@ export const getApplicationRecordsByProject = async (req: Request, res: Response
export const updateApplicationRecord = async (req: Request, res: Response) => {
try {
const organizationId = req.appUser?.organizationId;
const userId = req.appUser?.externalId;
const userId = req.appUser?.id;
const userRole = req.appUser?.organizationRole || req.appUser?.role;
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) => {
try {
const organizationId = req.appUser?.organizationId;
const userId = req.appUser?.externalId;
const userId = req.appUser?.id;
const userRole = req.appUser?.organizationRole || req.appUser?.role;
const isDeveloper = req.appUser?.email === 'admtracksteel@gmail.com';

View File

@@ -115,11 +115,10 @@ export const getMe = async (req: Request, res: Response): Promise<void> => {
}
res.status(200).json({
id: req.appUser._id,
id: req.appUser.id,
name: req.appUser.name,
email: req.appUser.email,
role: req.appUser.role,
externalId: req.appUser.externalId,
organizationId: req.appUser.organizationId
});
} catch (error) {

View File

@@ -267,18 +267,12 @@ export const getFile = async (req: Request, res: Response) => {
}
// Fallback to file system (legacy)
const stream = dataSheetService.getFileStream(id_or_filename);
stream.on('file', (file) => {
res.set('Content-Type', 'application/pdf');
const file = await dataSheetService.getFileStream(id_or_filename);
res.set('Content-Type', file.content_type || 'application/pdf');
res.set('Content-Disposition', `inline; filename="${file.filename}"`);
});
stream.on('error', () => {
res.status(404).json({ error: 'File not found' });
});
stream.pipe(res);
res.set('Access-Control-Allow-Origin', '*');
res.set('Cache-Control', 'public, max-age=3600');
res.send(file.data);
} catch (error: unknown) {
const message = error instanceof Error ? error.message : 'Unknown error';
console.error('Error getting file:', error);

View File

@@ -6,7 +6,7 @@ import '../middleware/roleMiddleware.js'; // Ensure type augmentation
export const createInspection = async (req: Request, res: Response) => {
try {
const organizationId = req.appUser?.organizationId;
const createdBy = req.appUser?.externalId;
const createdBy = req.appUser?.id;
const inspection = await inspectionService.createInspection({
...req.body,
organizationId,
@@ -46,7 +46,7 @@ export const getInspectionsByProject = async (req: Request, res: Response) => {
export const updateInspection = async (req: Request, res: Response) => {
try {
const organizationId = req.appUser?.organizationId;
const userId = req.appUser?.externalId;
const userId = req.appUser?.id;
const userRole = req.appUser?.organizationRole || req.appUser?.role;
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) => {
try {
const organizationId = req.appUser?.organizationId;
const userId = req.appUser?.externalId;
const userId = req.appUser?.id;
const userRole = req.appUser?.organizationRole || req.appUser?.role;
const isDeveloper = req.appUser?.email === 'admtracksteel@gmail.com';

View File

@@ -6,7 +6,7 @@ import OrganizationMember from '../models/OrganizationMember.js';
export const sendMessage = async (req: Request, res: Response) => {
try {
const { toUserId, message } = req.body;
const fromUserId = req.appUser?.externalId;
const fromUserId = req.appUser?.id;
const organizationId = req.headers['x-organization-id'] as string;
if (!organizationId) {
@@ -60,7 +60,7 @@ export const sendMessage = async (req: Request, res: Response) => {
// Get unread messages for current user
export const getUnreadMessages = async (req: Request, res: Response) => {
try {
const toUserId = req.appUser?.externalId;
const toUserId = req.appUser?.id;
const organizationId = req.headers['x-organization-id'] as string;
if (!organizationId) {
@@ -101,7 +101,7 @@ export const getUnreadMessages = async (req: Request, res: Response) => {
export const markMessageAsRead = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const userId = req.appUser?.externalId;
const userId = req.appUser?.id;
const organizationId = req.headers['x-organization-id'] as string;
if (!organizationId) {
@@ -136,7 +136,7 @@ export const markMessageAsRead = async (req: Request, res: Response) => {
// Get my pending (unread) sent messages
export const getMyPendingMessages = async (req: Request, res: Response) => {
try {
const fromUserId = req.appUser?.externalId;
const fromUserId = req.appUser?.id;
const organizationId = req.headers['x-organization-id'] as string;
if (!organizationId) {
@@ -175,7 +175,7 @@ export const getMyPendingMessages = async (req: Request, res: Response) => {
export const deleteMessage = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const userId = req.appUser?.externalId;
const userId = req.appUser?.id;
const organizationId = req.headers['x-organization-id'] as string;
if (!organizationId) {
@@ -209,7 +209,7 @@ export const deleteMessage = async (req: Request, res: Response) => {
export const archiveMessage = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const userId = req.appUser?.externalId;
const userId = req.appUser?.id;
const organizationId = req.headers['x-organization-id'] as string;
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) => {
try {
const { id } = req.params;
const userId = req.appUser?.externalId;
const userId = req.appUser?.id;
const organizationId = req.headers['x-organization-id'] as string;
const message = await Message.findOne({ _id: id, toUserId: userId, organizationId });

View File

@@ -9,7 +9,7 @@ interface AuthRequest extends Request {
export const createStockItem = async (req: AuthRequest, res: Response) => {
try {
const organizationId = req.appUser?.organization_id;
const organizationId = req.appUser?.organizationId;
const userName = req.appUser?.name || req.appUser?.email || 'Unknown User';
const {
dataSheetId,
@@ -97,7 +97,7 @@ export const createStockItem = async (req: AuthRequest, res: Response) => {
export const updateStockItem = async (req: AuthRequest, res: Response) => {
try {
const { id } = req.params;
const organizationId = req.appUser?.organization_id;
const organizationId = req.appUser?.organizationId;
const { quantity, ...otherData } = req.body;
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);
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);
} catch (error: any) {
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) => {
try {
const { id } = req.params;
const organizationId = req.appUser?.organization_id;
const organizationId = req.appUser?.organizationId;
const { quantityDelta, reason } = req.body;
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
});
await notificationService.checkLowStock(id);
await notificationService.checkLowStock(id as string);
res.json(adjustment);
} catch (error: any) {
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) => {
try {
const { id } = req.params;
const organizationId = req.appUser?.organization_id;
const organizationId = req.appUser?.organizationId;
const { quantityConsumed, requester, date } = req.body;
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}`
});
await notificationService.checkLowStock(id);
await notificationService.checkLowStock(id as string);
res.json({ message: 'Consumo registrado com sucesso.' });
} catch (error: any) {
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) => {
try {
const { id } = req.params;
const organizationId = req.appUser?.organization_id;
const organizationId = req.appUser?.organizationId;
await stockService.deleteStockItem(id as string, organizationId);
res.status(204).send();
} catch (error: any) {
@@ -188,7 +188,7 @@ export const deleteStockItem = async (req: AuthRequest, res: Response) => {
export const getStockItems = async (req: AuthRequest, res: Response) => {
try {
const organizationId = req.appUser?.organization_id;
const organizationId = req.appUser?.organizationId;
const items = await stockService.getStockItems(organizationId);
res.json(items);
} catch (error: any) {
@@ -199,7 +199,7 @@ export const getStockItems = async (req: AuthRequest, res: Response) => {
export const getStockItemById = async (req: AuthRequest, res: Response) => {
try {
const { id } = req.params;
const organizationId = req.appUser?.organization_id;
const organizationId = req.appUser?.organizationId;
const result = await query(
`SELECT si.*, tds.name as data_sheet_name
FROM stock_items si
@@ -217,8 +217,8 @@ export const getStockItemById = async (req: AuthRequest, res: Response) => {
export const getStockMovements = async (req: AuthRequest, res: Response) => {
try {
const { id } = req.params;
const organizationId = req.appUser?.organization_id;
const movements = await stockService.getMovementsByItem(id, organizationId);
const organizationId = req.appUser?.organizationId;
const movements = await stockService.getMovementsByItem(id as string, organizationId);
res.json(movements);
} catch (error: any) {
res.status(500).json({ error: error.message });

View File

@@ -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) {
try {
const check = await query('SELECT * FROM notifications WHERE id = $1', [id]);

View File

@@ -46,12 +46,12 @@ export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:3001',
target: 'http://127.0.0.1:3005',
changeOrigin: true,
secure: false,
},
'/uploads': {
target: 'http://127.0.0.1:3001',
target: 'http://127.0.0.1:3005',
changeOrigin: true,
secure: false,
},