'use strict'; /* Centralized constants for the application */ const Units = Object.freeze({ OZ: 0, GAL: 1, LB: 2, LIT: 3, KG: 4, ACRE: 5, HA: 6, HOUR: 7, GR: 8, CC: 9, PT: 10 }); // Rate Units constants for application rates const RateUnits = Object.freeze({ OZ_PER_ACRE: 0, // oz/ac - ounces per acre (fluid) GAL_PER_ACRE: 1, // gal/ac - gallons per acre LBS_PER_ACRE: 2, // lbs/ac - pounds per acre LIT_PER_HA: 3, // lit/ha - liters per hectare KG_PER_HA: 4 // kg/ha - kilograms per hectare }); // HTTP Status Codes (frozen for consistency across application) const HttpStatus = Object.freeze({ OK: 200, CREATED: 201, ACCEPTED: 202, NO_CONTENT: 204, BAD_REQUEST: 400, UNAUTHORIZED: 401, PAYMENT_REQUIRED: 402, FORBIDDEN: 403, NOT_FOUND: 404, CONFLICT: 409, GONE: 410, INTERNAL_SERVER_ERROR: 500, SERVICE_UNAVAILABLE: 503 }); const ExportType = Object.freeze({ CSV: "csv", IIF: "iif" }); const APTypes = Object.freeze( { ACTIVE: 1, CARRIER: 9 }); const RecTypes = Object.freeze({ UNKNOWN: 0, AGN_BIN_LQD: 1, AGN_BIN_DRY: 2, AGN_AMS: 3, AGN_SHP: 4, AGN_SHP_DRY: 5, SATLOG: 10 }); const UserTypes = Object.freeze({ ADMIN: "0", APP: "1", APP_ADM: "2", CLIENT: "3", OFFICER: "4", PILOT: "5", INSPECTOR: "6", DEVICE: "9", PARTNER: "20", PARTNER_SYSTEM_USER: "21" }); const AppStatus = Object.freeze({ ERROR: 0, CREATED: 1, IN_PROGRESS: 2, WAS_CANCELLED: -1, DONE: 3 }); const AppProStatus = Object.freeze({ ERROR: 0, // not fully processed (disrupted while reading or processing files) WITH_DATA: 1, NO_DATA: 2 // 10 + STATUS: If items were updated }); const AssignStatus = Object.freeze({ NEW: 0, DOWNLOADED: 1, UPLOADED: 2 // Status for jobs uploaded to partner systems }); const Fields = Object.freeze({ MARKED_DELETE: 'markedDelete' }); const DEFAULT_LANG = 'en'; const DEL_APP_IDS = "DEL_APP_IDS"; // The key name of deleted appIds cached list using REDIS const LIMIT_FILE_SIZE_ERR = "LIMIT_FILE_SIZE"; // MulterError code for file too large const DEFAULT_TRIAL_DAYS = [15, 30, 60, 90, 120, 180, 270, 365]; // Promotion mode (global promo application behavior) const PromoModes = Object.freeze({ ENABLED: 'enabled', // Promotions enabled (targeting controlled by PromoEligibility) DISABLED: 'disabled' // Kill switch: disable all automatic promos }); // Stripe coupon duration types const CouponDuration = Object.freeze({ FOREVER: 'forever', // Coupon applies indefinitely REPEATING: 'repeating', // Coupon applies for N months ONCE: 'once' // Coupon applies once (not supported in V2) }); // Stripe error types const StripeErrorTypes = Object.freeze({ CARD_ERROR: 'StripeCardError', // Card-related errors (declined, insufficient funds, etc.) INVALID_REQUEST: 'StripeInvalidRequestError', // Invalid parameters or request API_ERROR: 'StripeAPIError', // Stripe API errors CONNECTION_ERROR: 'StripeConnectionError', // Network connection errors AUTHENTICATION_ERROR: 'StripeAuthenticationError', // Authentication errors RATE_LIMIT_ERROR: 'StripeRateLimitError' // Rate limiting errors }); // Standard action labels for API mutation responses const APIActions = Object.freeze({ DISABLED: 'disabled', DELETED: 'deleted', UPDATED: 'updated' }); const TrialTypes = Object.freeze({ NONE: null, DAYS: 'days', BY_DATE: 'byDate' }); // Error constant codes mapped to tags const Errors = Object.freeze({ NOT_FOUND: 'not_found', NO_ACCESS: 'not_authorized', ACC_INACTIVE: 'acc_inactive', INVALID_ACCOUNT: 'invalid_account', WRONG_CREDENTIAL: 'wrong_credential', INVALID_TOKEN: 'invalid_token', ACTIVE_ACCOUNT: 'active_account', INVALID_EMAIL: 'invalid_email', EMAIL_ERROR: 'email_error', PARENT_NOT_EXIST: 'parent_not_exist', USER_NOT_FOUND: 'user_not_found', USER_EXIST: 'user_exist', TOKEN_EXPIRED: 'token_expired', PILOT_NOT_EXIST: 'pilot_not_exist', JOB_NOT_FOUND: 'job_not_found', NO_SPRAY_AREA: 'no_spray_area', AREAS_NOT_FOUND: 'areas_not_found', ITEMS_NOT_FOUND: 'items_not_found', NOT_KML_KMZ: 'not_kml_kmz', BLANK_KML_KMZ: 'blank_kml_kmz', JOB_NOT_ASSIGNED: 'job_not_assigned', PRJ_NOT_FOUND: 'prj_not_found', UNSUPPORTED_SHAPE_TYPE: 'unsupported_shape_type', EMPTY_SHP_FILE: 'empty_shp_file', DATA_NO_SPRAYON: 'data_no_sprayon', INVALID_REQUEST: 'invalid_request', INVALID_PARAM: 'invalid_param', INVALID_INPUT: 'invalid_input', INVALID_VAL_SCHEMA: 'invalid_val_schema', INVALID_LONGITUDE: 'invalid_longitude', INVALID_SWATH_WIDTH: 'invalid_swath_width', INVALID_DMS: 'invalid_dms', DUPLICATED_VALUE: 'duplicated_value', CORRUPTED_ZIP: 'corrupted_zip', INVALID_OBSTACLE_FILE_FORMAT: 'invalid_obstacle_file_format', NO_FILE: 'no_file', FILE_TOO_LARGE: 'file_too_large', DUPLICATED_FILE: 'duplicated_file', WRONG_JOB_FILE: 'wrong_job_file', INVALID_AREAS_FILE: 'invalid_areas_file', INVALID_JOB_FILE: 'invalid_job_file', INVALID_PAYMENT_METHOD: 'invalid_payment_method', INVALID_ADDRESS_COUNTRY: 'invalid_address_country', PAYMENT_FAILED: 'payment_failed', SUBSCRIPTION_NOT_FOUND: 'subscription_not_found', PKG_SUBSCRIPTION_NOT_FOUND: 'pkg_subscription_not_found', TRK_SUBSCRIPTION_NOT_FOUND: 'trk_subscription_not_found', PAID_INVOICES_NOT_FOUND: 'paid_invoices_not_found', REACHED_AREA_LIMIT: 'reached_area_limit', REACHED_VEHICLES_LIMIT: 'reached_vehicles_limit', PAYMENT_EXPIRED: 'payment_expired', CUST_PM_NOT_FOUND: 'cust_pm_not_found', APP_VENDOR_NOT_FOUND: 'app_vendor_not_found', LOCAL_VENDOR_NOT_FOUND: 'local_vendor_not_found', RM_LAST_DEFAULT_PM_NOT_ALLOW: 'rm_last_default_pm_not_allow', RM_ACTIVE_PM_NOT_ALLOW: 'rm_active_pm_not_allow', TRIALS_NOT_ENABLED: 'trials_not_enabled', TRIALS_EXPIRED: "trials_expired", ONLY_ONE_BILL_ADDR_ALLOWED: 'only_one_bill_address_allowed', // Promo error codes PROMO_NOT_FOUND: 'promo_not_found', PROMO_IN_USE_VALID_UNTIL_REQUIRED: 'promo_in_use_valid_until_required', PROMO_VALID_UNTIL_TOO_SOON: 'promo_valid_until_too_soon', PROMO_INVALID_VALID_UNTIL: 'promo_invalid_valid_until', PROMO_DUPLICATE_TYPE_PRICEKEY: 'promo_duplicate_type_pricekey', PROMO_DUPLICATE_COUPON: 'promo_duplicate_coupon', PROMO_OVERLAPPING_DATES: 'promo_overlapping_dates', PROMO_COUPON_NOT_FOUND: 'promo_coupon_not_found', PROMO_INVALID_COUPON: 'promo_invalid_coupon', // New email verification error codes VERIFICATION_CODE_EXPIRED: 'verification_code_expired', INVALID_VERIFICATION_CODE: 'invalid_verification_code', EMAIL_VERIFICATION_REQUIRED: 'email_verification_required', REPORT_SERVER_ERROR: 'report_server_error', HAS_REFERENCE: 'has_reference', TEMPLATE_NOT_FOUND: 'template_not_found', TO_NOT_FOUND: 'to_not_found', UNKNOWN_APP_ERROR: 'unknown_app_error', UNKNOWN_ERROR: 'unknown_error', APPLICATOR_NOT_FOUND: 'applicator_not_found', COSTING_ITEM_NOT_FOUND: 'costing_item_not_found', INVOICE_NOT_FOUND: 'invoice_not_found', INVOICE_SETTING_NOT_FOUND: 'invoice_setting_not_found', CLIENT_NOT_FOUND: 'client_not_found', JOBS_NOT_FOUND: 'jobs_not_found', CLIENTS_NOT_FOUND: 'clients_not_found', CLIENT_OVER_PAID: 'client_over_paid', INVOICE_ALREADY_PAID: 'invoice_already_paid', INVOICE_DRAFT: 'invoice_draft', INVOICE_CANCELLED: 'invoice_cancelled', INVOICE_OVERDUE: 'invoice_overdue', INVOICE_VOID: 'invoice_void', JOB_CANNOT_EDIT: 'cannot_edit_job_have_invoice_opened', STATUS_JOB_INVALID: 'status_job_invalid', COSTING_ITEM_IN_USE: 'costing_item_in_use', PARAMS_NOT_EMPTY: 'params_not_empty', INVALID_PUID: 'invalid_parent_user_id', INVALID_CREATED_BY_USER_ID: 'invalid_created_by_user_id', PARTNER_SERVICE_UNAVAILABLE: 'partner_service_unavailable', INVALID_ASSIGNMENT: 'invalid_assignment', RABBITMQ_MGMT_DISABLED: 'rabbitmq_mgmt_disabled' }); /* Applicator application types */ const ApplicationTypes = Object.freeze({ Agricultural: 'agricultural', Mosquito_Control: 'mosquito_control', Wildfire_Fighting: 'wildfire_fighting', Forestry: 'forestry', Airborne_Geophysics: 'airborne_geophysics', Animal_Control: 'animal_control', Photogrammetry: 'photogrammetry', UAV_Imaging: 'uav_imaging', Other: 'other', }); /* Applicator reference sources */ const RefSources = Object.freeze({ Web_Search: 'web_search', Online_Ads: 'online_ads', Trade_Show: 'trade_show', Magazine: 'magazine', Third_Party: '3rd_party', }); const InvCreateOption = Object.freeze({ Option1: 'option_1', Option2: 'option_2', Option3: 'option_3' }); const InvoiceStatus = Object.freeze({ Draft: 'draft', Open: 'open', Paid: 'paid', Void: 'void', Uncollectible: 'uncollectible' }); const CostingItemType = Object.freeze({ BY_ACRE: 0, BY_HA: 1, BY_AMOUNT: 2 }); const PaymentMethod = Object.freeze({ Cash: 'cash', Transfer: 'transfer', Debit: 'debit', Credit: 'credit' }); const InvoiceStatusAction = Object.freeze({ None: 'none', MARK_UNCOLLECTIBLE: 'mark_uncollectible' }); // Partner sync status constants const SyncStatus = Object.freeze({ ACTIVE: 'active', ERROR: 'error', INACTIVE: 'inactive' }); // Partner health status constants const HealthStatus = Object.freeze({ HEALTHY: 'healthy', UNHEALTHY: 'unhealthy', DEGRADED: 'degraded' }); // Partner sync operation constants const PartnerOperations = Object.freeze({ UPLOAD_JOB: 'uploadJobToPartner', HEALTH_CHECK: 'healthCheck', GET_AIRCRAFT_LIST: 'getAircraftList' }); // Partner worker task constants const PartnerTasks = Object.freeze({ PROCESS_PARTNER_LOG: 'process_partner_log', UPLOAD_PARTNER_JOB: 'upload_partner_job', PROCESS_PARTNER_DATA_FILE: 'process_partner_data_file' }); // Partner Log Tracker Status Constants const PartnerLogTrackerStatus = Object.freeze({ PENDING: 'pending', DOWNLOADING: 'downloading', DOWNLOADED: 'downloaded', PROCESSING: 'processing', PROCESSED: 'processed', FAILED: 'failed', ARCHIVED: 'archived' }); // SatLoc system type constants const SystemTypes = Object.freeze({ NONE: 'none', PLATINUM: 'platinum', TITANIUM: 'titanium', G4: 'g4', BANTAM2: 'bantam2', FALCON: 'falcon' }); // For Flow Controller Types const FCTypes = Object.freeze({ LIQUID: 1, DRY: 2 }); // Application data source types const DataTypes = Object.freeze({ SATLOC: 'satloc', AGNAV: 'agnav' }); // Material types for spray applications const MatTypes = Object.freeze({ WET: 'wet', DRY: 'dry' }); // API key service types — which service/integration a key grants access to const ApiKeyServices = Object.freeze({ DATA_EXPORT: 'data_export', // External data consumers (Power BI, ArcGIS, data warehouses) PARTNER_API: 'partner_api' // Partner system integrations }); // Export measurement unit systems const ExportUnits = Object.freeze({ METRIC: 'metric', // SI units (m/s, L/min, L/ha, m, °C) — system default US: 'us' // US customary (mph, gal/min, gal/ac, ft, °F) }); // Data export async job status lifecycle const ExportJobStatus = Object.freeze({ PENDING: 'pending', PROCESSING: 'processing', READY: 'ready', ERROR: 'error' }); // GeoJSON area feature types exposed by public data export API const ExportAreaTypes = Object.freeze({ AREA: 'area', EXCLUDED: 'xcl' }); // Partner authentication method constants const AuthMethods = Object.freeze({ API_KEY: 'api_key', USERNAME_PASSWORD: 'username_password', OAUTH: 'oauth', BEARER_TOKEN: 'bearer_token' }); // Partner codes constants const PartnerCodes = Object.freeze({ SATLOC: 'SATLOC', AGIDRONEX: 'AGIDRONEX', // Add other partner codes as needed }); // Promo eligibility constants const PromoEligibility = Object.freeze({ ALL: 'all', // Any customer can use promo NEW_ONLY: 'new_only', // Only first-time customers (no subscription history) RENEW_ONLY: 'renew_only' // Only returning customers (has subscription history) }); const PartnerFileExtensions = { '.log': PartnerCodes.SATLOC, // SatLoc binary log files // Add more partner-specific extensions here as needed // '.agx': PartnerCodes.AGIDRONEX, // '.dji': PartnerCodes.DJI, }; const jobInvoiceEditRoles = [UserTypes.APP, UserTypes.APP_ADM]; const jobInvoiceViewRoles = [...jobInvoiceEditRoles, UserTypes.CLIENT, UserTypes.OFFICER, UserTypes.INSPECTOR, UserTypes.PILOT]; const emailRegex = RegExp(/^(([^<>\(\)\[\]\\.,;:\s@"]+(\.[^<>\(\)\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i); module.exports = { APTypes, Units, RateUnits, HttpStatus, Fields, RecTypes, UserTypes, FCTypes, DataTypes, MatTypes, Errors, AppStatus, AppProStatus, AssignStatus, TrialTypes, DEFAULT_LANG, DEL_APP_IDS, DEFAULT_TRIAL_DAYS, LIMIT_FILE_SIZE_ERR, InvoiceStatus, CostingItemType, InvCreateOption, PaymentMethod, ExportType, jobInvoiceEditRoles, jobInvoiceViewRoles, InvoiceStatusAction, ApplicationTypes, RefSources, emailRegex, SyncStatus, HealthStatus, PartnerOperations, PartnerTasks, SystemTypes, AuthMethods, PartnerCodes, PartnerLogTrackerStatus, PartnerFileExtensions, PromoModes, APIActions, PromoEligibility, CouponDuration, StripeErrorTypes, ApiKeyServices, ExportUnits, ExportJobStatus, ExportAreaTypes };