huge refactor on web-api and web-app
This commit is contained in:
parent
1d299e52d4
commit
265e10a658
23 changed files with 1545 additions and 1233 deletions
161
apps/web-api/src/utils/validation.ts
Normal file
161
apps/web-api/src/utils/validation.ts
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
import { CreateExchangeRequest, CreateProviderMappingRequest } from '../types/exchange.types';
|
||||
|
||||
export class ValidationError extends Error {
|
||||
constructor(message: string, public field?: string) {
|
||||
super(message);
|
||||
this.name = 'ValidationError';
|
||||
}
|
||||
}
|
||||
|
||||
export function validateCreateExchange(data: any): CreateExchangeRequest {
|
||||
const { code, name, country, currency, active = true } = data;
|
||||
|
||||
if (!code || typeof code !== 'string') {
|
||||
throw new ValidationError('Exchange code is required', 'code');
|
||||
}
|
||||
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new ValidationError('Exchange name is required', 'name');
|
||||
}
|
||||
|
||||
if (!country || typeof country !== 'string') {
|
||||
throw new ValidationError('Country is required', 'country');
|
||||
}
|
||||
|
||||
if (!currency || typeof currency !== 'string') {
|
||||
throw new ValidationError('Currency is required', 'currency');
|
||||
}
|
||||
|
||||
if (code.length > 10) {
|
||||
throw new ValidationError('Exchange code must be 10 characters or less', 'code');
|
||||
}
|
||||
|
||||
if (country.length !== 2) {
|
||||
throw new ValidationError('Country must be exactly 2 characters (e.g., US, CA, GB)', 'country');
|
||||
}
|
||||
|
||||
if (currency.length !== 3) {
|
||||
throw new ValidationError('Currency must be exactly 3 characters (e.g., USD, EUR, CAD)', 'currency');
|
||||
}
|
||||
|
||||
return {
|
||||
code: code.toUpperCase().trim(),
|
||||
name: name.trim(),
|
||||
country: country.toUpperCase().trim(),
|
||||
currency: currency.toUpperCase().trim(),
|
||||
active: Boolean(active),
|
||||
};
|
||||
}
|
||||
|
||||
export function validateCreateProviderMapping(data: any): CreateProviderMappingRequest {
|
||||
const {
|
||||
provider,
|
||||
provider_exchange_code,
|
||||
provider_exchange_name,
|
||||
master_exchange_id,
|
||||
country_code,
|
||||
currency,
|
||||
confidence = 1.0,
|
||||
active = false,
|
||||
verified = false,
|
||||
} = data;
|
||||
|
||||
if (!provider || typeof provider !== 'string') {
|
||||
throw new ValidationError('Provider is required', 'provider');
|
||||
}
|
||||
|
||||
if (!provider_exchange_code || typeof provider_exchange_code !== 'string') {
|
||||
throw new ValidationError('Provider exchange code is required', 'provider_exchange_code');
|
||||
}
|
||||
|
||||
if (!master_exchange_id || typeof master_exchange_id !== 'string') {
|
||||
throw new ValidationError('Master exchange ID is required', 'master_exchange_id');
|
||||
}
|
||||
|
||||
// Validate currency is 3 characters or null
|
||||
const cleanCurrency = currency && currency.length <= 3 ? currency : null;
|
||||
|
||||
return {
|
||||
provider: provider.trim(),
|
||||
provider_exchange_code: provider_exchange_code.trim(),
|
||||
provider_exchange_name: provider_exchange_name?.trim(),
|
||||
master_exchange_id: master_exchange_id.trim(),
|
||||
country_code: country_code?.trim() || null,
|
||||
currency: cleanCurrency,
|
||||
confidence: Number(confidence),
|
||||
active: Boolean(active),
|
||||
verified: Boolean(verified),
|
||||
};
|
||||
}
|
||||
|
||||
export function validateUpdateExchange(data: any): any {
|
||||
const updates: any = {};
|
||||
|
||||
if (data.name !== undefined) {
|
||||
if (typeof data.name !== 'string') {
|
||||
throw new ValidationError('Name must be a string', 'name');
|
||||
}
|
||||
updates.name = data.name.trim();
|
||||
}
|
||||
|
||||
if (data.active !== undefined) {
|
||||
updates.active = Boolean(data.active);
|
||||
}
|
||||
|
||||
if (data.visible !== undefined) {
|
||||
updates.visible = Boolean(data.visible);
|
||||
}
|
||||
|
||||
if (data.country !== undefined) {
|
||||
if (typeof data.country !== 'string' || data.country.length !== 2) {
|
||||
throw new ValidationError('Country must be exactly 2 characters', 'country');
|
||||
}
|
||||
updates.country = data.country.toUpperCase().trim();
|
||||
}
|
||||
|
||||
if (data.currency !== undefined) {
|
||||
if (typeof data.currency !== 'string' || data.currency.length !== 3) {
|
||||
throw new ValidationError('Currency must be exactly 3 characters', 'currency');
|
||||
}
|
||||
updates.currency = data.currency.toUpperCase().trim();
|
||||
}
|
||||
|
||||
if (Object.keys(updates).length === 0) {
|
||||
throw new ValidationError('No valid fields to update');
|
||||
}
|
||||
|
||||
return updates;
|
||||
}
|
||||
|
||||
export function validateUpdateProviderMapping(data: any): any {
|
||||
const updates: any = {};
|
||||
|
||||
if (data.active !== undefined) {
|
||||
updates.active = Boolean(data.active);
|
||||
}
|
||||
|
||||
if (data.verified !== undefined) {
|
||||
updates.verified = Boolean(data.verified);
|
||||
}
|
||||
|
||||
if (data.confidence !== undefined) {
|
||||
const confidence = Number(data.confidence);
|
||||
if (isNaN(confidence) || confidence < 0 || confidence > 1) {
|
||||
throw new ValidationError('Confidence must be a number between 0 and 1', 'confidence');
|
||||
}
|
||||
updates.confidence = confidence;
|
||||
}
|
||||
|
||||
if (data.master_exchange_id !== undefined) {
|
||||
if (typeof data.master_exchange_id !== 'string') {
|
||||
throw new ValidationError('Master exchange ID must be a string', 'master_exchange_id');
|
||||
}
|
||||
updates.master_exchange_id = data.master_exchange_id.trim();
|
||||
}
|
||||
|
||||
if (Object.keys(updates).length === 0) {
|
||||
throw new ValidationError('No valid fields to update');
|
||||
}
|
||||
|
||||
return updates;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue