eletrotupi / tcc/ commit / 06314a5

api/utils: add some validations for mood, user and mood/emotion components

Pedro Lucas Porcellis porcellis@eletrotupi.com · 10 months ago 06314a5b665164bc343bc1c0a38ca4a562c53b7b Browse files
Parents f850d20
Changed files
2
Additions
+198
Deletions
0
/dev/null → api/src/utils/emotions.js
1 +
// Emotion types enum
2 +
export const Emotions = {
3 +
  JOY: 'joy',
4 +
  TRUST: 'trust',
5 +
  FEAR: 'fear',
6 +
  SURPRISE: 'surprise',
7 +
  SAD: 'sad',
8 +
  DISGUST: 'disgust',
9 +
  ANGRY: 'angry',
10 +
  ANXIETY: 'anxiety'
11 +
};
12 +

13 +
// Valid emotion values for validation
14 +
export const VALID_EMOTIONS = Object.values(Emotions);
15 +

16 +
// Validate emotion type
17 +
export function isValidEmotion(emotion) {
18 +
  return VALID_EMOTIONS.includes(emotion?.toLowerCase());
19 +
}
20 +

21 +
// Validate intensity value
22 +
export function isValidIntensity(intensity) {
23 +
  const num = Number(intensity);
24 +
  return !isNaN(num) && num >= 1 && num <= 10;
25 +
}
26 +

27 +
// Validate rating value
28 +
export function isValidRating(rating) {
29 +
  const num = Number(rating);
30 +
  return !isNaN(num) && num >= 1 && num <= 10;
31 +
}
32 +

33 +
// Validate level values (stress, anxiety, energy)
34 +
export function isValidLevel(level) {
35 +
  const num = Number(level);
36 +
  return !isNaN(num) && num >= 1 && num <= 10;
37 +
}
38 +

39 +
// Validate mood components array
40 +
export function validateMoodComponents(components) {
41 +
  if (!Array.isArray(components)) {
42 +
    return { valid: false, error: 'Components must be an array' };
43 +
  }
44 +

45 +
  const emotions = new Set();
46 +

47 +
  for (const component of components) {
48 +
    if (!Object.hasOwn(component, 'emotion') || !Object.hasOwn(component, 'intensity')) {
49 +
      return { valid: false, error: 'Each component must have emotion and intensity' };
50 +
    }
51 +

52 +
    const emotionLower = component.emotion.toLowerCase();
53 +

54 +
    if (!isValidEmotion(emotionLower)) {
55 +
      return { valid: false, error: `Invalid emotion: ${component.emotion}` };
56 +
    }
57 +

58 +
    if (!isValidIntensity(component.intensity)) {
59 +
      return { valid: false, error: `Invalid intensity for ${component.emotion}: must be 1-10` };
60 +
    }
61 +

62 +
    if (emotions.has(emotionLower)) {
63 +
      return { valid: false, error: `Duplicate emotion: ${component.emotion}` };
64 +
    }
65 +

66 +
    emotions.add(emotionLower);
67 +
  }
68 +

69 +
  return { valid: true };
70 +
}
71 +

72 +
// Get emotion statistics
73 +
export function calculateEmotionStats(moodComponents) {
74 +
  const stats = {
75 +
    dominant: null,
76 +
    average: 0,
77 +
    breakdown: {}
78 +
  };
79 +

80 +
  if (!moodComponents || moodComponents.length === 0) {
81 +
    return stats;
82 +
  }
83 +

84 +
  let maxIntensity = 0;
85 +
  let totalIntensity = 0;
86 +

87 +
  moodComponents.forEach(component => {
88 +
    const intensity = Number(component.intensity);
89 +
    totalIntensity += intensity;
90 +

91 +
    stats.breakdown[component.emotion] = intensity;
92 +

93 +
    if (intensity > maxIntensity) {
94 +
      maxIntensity = intensity;
95 +
      stats.dominant = component.emotion;
96 +
    }
97 +
  });
98 +

99 +
  stats.average = totalIntensity / moodComponents.length;
100 +

101 +
  return stats;
102 +
}
/dev/null → api/src/utils/validators.js
1 +
// Email validation
2 +
export function isValidEmail(email) {
3 +
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
4 +
  return emailRegex.test(email);
5 +
}
6 +

7 +
// Password validation (minimum 6 characters)
8 +
export function isValidPassword(password) {
9 +
  return password && password.length >= 6;
10 +
}
11 +

12 +
import { parseISO, isValid, isFuture, isAfter } from 'date-fns';
13 +

14 +
// Date validation
15 +
export function isValidDate(dateString) {
16 +
  if (!dateString) return false;
17 +
  try {
18 +
    const date = parseISO(dateString);
19 +
    return isValid(date);
20 +
  } catch {
21 +
    return false;
22 +
  }
23 +
}
24 +

25 +
// Check if date is not in the future
26 +
export function isNotFutureDate(dateString) {
27 +
  if (!dateString) return false;
28 +
  try {
29 +
    const date = parseISO(dateString);
30 +
    return isValid(date) && !isFuture(date);
31 +
  } catch {
32 +
    return false;
33 +
  }
34 +
}
35 +

36 +
// Validate date range
37 +
export function isValidDateRange(startDate, endDate) {
38 +
  if (!startDate || !endDate) return false;
39 +
  try {
40 +
    const start = parseISO(startDate);
41 +
    const end = parseISO(endDate);
42 +

43 +
    if (!isValid(start) || !isValid(end)) {
44 +
      return false;
45 +
    }
46 +

47 +
    return !isAfter(start, end);
48 +
  } catch {
49 +
    return false;
50 +
  }
51 +
}
52 +

53 +
// Sanitize string input
54 +
export function sanitizeString(str) {
55 +
  if (typeof str !== 'string') return '';
56 +
  return str.trim().slice(0, 500); // Limit to 500 chars
57 +
}
58 +

59 +
// Validate required fields
60 +
export function validateRequiredFields(data, fields) {
61 +
  const missing = [];
62 +

63 +
  for (const field of fields) {
64 +
    if (data[field] === undefined || data[field] === null || data[field] === '') {
65 +
      missing.push(field);
66 +
    }
67 +
  }
68 +

69 +
  return {
70 +
    valid: missing.length === 0,
71 +
    missing
72 +
  };
73 +
}
74 +

75 +
// Validate number in range
76 +
export function isInRange(value, min, max) {
77 +
  const num = Number(value);
78 +
  return !isNaN(num) && num >= min && num <= max;
79 +
}
80 +

81 +
// Parse and validate integer
82 +
export function parseIntOrDefault(value, defaultValue = null) {
83 +
  const parsed = parseInt(value, 10);
84 +
  return isNaN(parsed) ? defaultValue : parsed;
85 +
}
86 +

87 +
// Validate pagination parameters
88 +
export function validatePagination(page, limit) {
89 +
  const validPage = Math.max(1, parseIntOrDefault(page, 1));
90 +
  const validLimit = Math.min(100, Math.max(1, parseIntOrDefault(limit, 20)));
91 +

92 +
  return {
93 +
    page: validPage,
94 +
    limit: validLimit,
95 +
    offset: (validPage - 1) * validLimit
96 +
  };
97 +
}