# Constants Reference Guide ## Overview This document provides a comprehensive reference for all frozen constants defined in `helpers/constants.js`. These constants ensure type safety and consistency across the application. **Last Updated**: January 28, 2026 --- ## Table of Contents - [Promo System Constants](#promo-system-constants) - [Stripe Constants](#stripe-constants) - [Error Codes](#error-codes) - [User and Partner Constants](#user-and-partner-constants) - [Other Constants](#other-constants) --- ## Promo System Constants ### PromoModes Controls whether the promotional system is globally enabled or disabled (kill switch). ```javascript const PromoModes = Object.freeze({ ENABLED: 'enabled', // Promotions enabled (targeting controlled by PromoEligibility) DISABLED: 'disabled' // Kill switch: disable all automatic promos }); ``` **Usage**: ```javascript const { PromoModes } = require('./helpers/constants'); if (env.PROMO_MODE === PromoModes.DISABLED) { return res.json({ promos: [] }); } ``` **Environment Variable**: `PROMO_MODE=enabled` (default) **Related Documentation**: [PROMO_ENHANCEMENTS_V3.md](./PROMO_ENHANCEMENTS_V3.md) --- ### PromoEligibility Defines customer eligibility criteria for promotional offers. ```javascript 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) }); ``` **Usage**: ```javascript const { PromoEligibility } = require('./helpers/constants'); const promo = { eligibility: PromoEligibility.NEW_ONLY, // Only for new customers // ... }; ``` **Related Documentation**: [PROMO_ENHANCEMENTS_V2.md](./PROMO_ENHANCEMENTS_V2.md) --- ### CouponDuration Stripe coupon duration types supported in the promotional system. ```javascript const CouponDuration = Object.freeze({ FOREVER: 'forever', // Coupon applies indefinitely REPEATING: 'repeating', // Coupon applies for N months (uses durationInMonths) ONCE: 'once' // Coupon applies once (NOT supported in V2+) }); ``` **Usage**: ```javascript const { CouponDuration } = require('./helpers/constants'); if (stripeCoupon.duration === CouponDuration.REPEATING) { promo.durationInMonths = stripeCoupon.duration_in_months; } // Validation example if (stripeCoupon.duration === CouponDuration.ONCE) { throw new AppParamError(Errors.INVALID_PARAM, 'ONCE duration not supported'); } ``` **Files Using This Constant**: - `controllers/main.js` - Coupon validation in `addSubscriptionPromo_post()` - `controllers/subscription.js` - Promo application logic --- ## Stripe Constants ### StripeErrorTypes Stripe API error type identifiers for consistent error handling. ```javascript 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 }); ``` **Usage**: ```javascript const { StripeErrorTypes } = require('./helpers/constants'); try { const stripeCoupon = await stripe.coupons.retrieve(couponId); } catch (stripeError) { if (stripeError.type === StripeErrorTypes.INVALID_REQUEST) { throw new AppParamError(Errors.INVALID_PARAM, `Invalid coupon: ${stripeError.message}`); } if (stripeError.type === StripeErrorTypes.CARD_ERROR) { throw new AppMembershipError(Errors.PAYMENT_FAILED, `Card error: ${stripeError.message}`); } throw stripeError; // Re-throw other errors } ``` **Files Using This Constant**: - `controllers/main.js` - Coupon retrieval error handling - `controllers/subscription.js` - SetupIntent and payment error handling - `model/customer.js` - Customer deletion error handling - `tests/test_setup_intent.js` - Card validation testing **Related Documentation**: [PAYMENT_FAILURE_HANDLING.md](./PAYMENT_FAILURE_HANDLING.md) --- ## Error Codes ### Promo Error Codes Specific error codes for promotional system operations. ```javascript const Errors = Object.freeze({ // ... existing error codes ... // 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', }); ``` **Usage Examples**: **1. Invalid Coupon/Promotion Code**: ```javascript const { Errors } = require('./helpers/constants'); // Invalid or restricted coupon/promotion code if (!coupon) { throw new AppParamError(Errors.PROMO_INVALID_COUPON, `Invalid coupon or promotion code: ${code}`); } // Customer restriction if (promoCode?.customer && promoCode.customer !== customerId) { throw new AppParamError(Errors.PROMO_INVALID_COUPON, `Promotion code "${code}" is not available for this customer`); } ``` **2. Duplicate Type/PriceKey**: ```javascript if (duplicateTypePrice) { throw new AppParamError(Errors.PROMO_DUPLICATE_TYPE_PRICEKEY, `Active promo already exists for ${type}/${priceKey}: "${duplicate.name}"`); } ``` **2. Duplicate Coupon ID**: ```javascript if (duplicateCoupon) { throw new AppParamError(Errors.PROMO_DUPLICATE_COUPON, `Active promo already uses coupon ${couponId}: "${duplicate.name}"`); } ``` **3. Overlapping Dates**: ```javascript if (overlapping) { throw new AppParamError(Errors.PROMO_OVERLAPPING_DATES, `Overlapping promo period for ${type}/${priceKey}: "${overlapping.name}"`); } ``` **API Response Format**: ```json { "error": { ".tag": "promo_duplicate_type_pricekey", "message": "Active promo already exists for package/ess_1: 'First Package Free'" } } ``` **Related Documentation**: [PROMO_ENHANCEMENTS_V3.md](./PROMO_ENHANCEMENTS_V3.md) --- ### General Error Codes ```javascript const Errors = Object.freeze({ // Authentication & Authorization NOT_AUTHORIZED: 'not_authorized', INVALID_TOKEN: 'invalid_token', TOKEN_EXPIRED: 'token_expired', ACC_INACTIVE: 'acc_inactive', // Parameter & Input Validation INVALID_PARAM: 'invalid_param', INVALID_INPUT: 'invalid_input', INVALID_REQUEST: 'invalid_request', // Resource Not Found NOT_FOUND: 'not_found', USER_NOT_FOUND: 'user_not_found', JOB_NOT_FOUND: 'job_not_found', // Subscription & Payment SUBSCRIPTION_NOT_FOUND: 'subscription_not_found', PAYMENT_FAILED: 'payment_failed', PAYMENT_EXPIRED: 'payment_expired', INVALID_PAYMENT_METHOD: 'invalid_payment_method', // ... (see helpers/constants.js for complete list) }); ``` --- ## User and Partner Constants ### UserTypes ```javascript const UserTypes = Object.freeze({ ADMIN: "0", APP: "1", // Applicator APP_ADM: "2", // Applicator Admin CLIENT: "3", OFFICER: "4", PILOT: "5", INSPECTOR: "6", DEVICE: "9", PARTNER: "20", // Partner Organization PARTNER_SYSTEM_USER: "21" // Partner System User (customer credentials) }); ``` ### PartnerCodes ```javascript const PartnerCodes = Object.freeze({ SATLOC: 'SATLOC', AGIDRONEX: 'AGIDRONEX', // Add other partner codes as needed }); ``` ### AuthMethods ```javascript const AuthMethods = Object.freeze({ API_KEY: 'api_key', USERNAME_PASSWORD: 'username_password', OAUTH: 'oauth', BEARER_TOKEN: 'bearer_token' }); ``` **Related Documentation**: [README_PARTNER_INTEGRATION.md](../README_PARTNER_INTEGRATION.md) --- ## Other Constants ### APIActions Standard action labels for API mutation responses. ```javascript const APIActions = Object.freeze({ DISABLED: 'disabled', DELETED: 'deleted', UPDATED: 'updated' }); ``` **Usage**: ```javascript return res.json({ action: APIActions.DELETED, promo: { _id: promoId, name: promo.name } }); ``` ### HttpStatus ```javascript const HttpStatus = Object.freeze({ OK: 200, CREATED: 201, 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 }); ``` --- ## Migration Guide ### Using New Constants in Existing Code **Before** (String Literals): ```javascript // ❌ Old approach - string literals if (promo.mode === 'enabled') { ... } if (stripeCoupon.duration === 'forever') { ... } if (error.type === 'StripeCardError') { ... } throw new AppParamError(Errors.INVALID_PARAM, 'Duplicate promo'); ``` **After** (Frozen Constants): ```javascript // ✅ New approach - frozen constants const { PromoModes, CouponDuration, StripeErrorTypes, Errors } = require('./helpers/constants'); if (promo.mode === PromoModes.ENABLED) { ... } if (stripeCoupon.duration === CouponDuration.FOREVER) { ... } if (error.type === StripeErrorTypes.CARD_ERROR) { ... } throw new AppParamError(Errors.PROMO_DUPLICATE_TYPE_PRICEKEY, 'Duplicate promo'); ``` **Benefits**: - ✅ Type safety - catch typos at runtime - ✅ IDE autocomplete support - ✅ Easier refactoring - change once, update everywhere - ✅ Self-documenting code - ✅ Prevents accidental string modifications --- ## Best Practices 1. **Always Import Constants**: Never use string literals when a constant is available 2. **Add Comments**: Document the purpose of new constants 3. **Use Object.freeze()**: Prevent accidental modifications 4. **Export Consistently**: Add new constants to module.exports 5. **Update Documentation**: Update this file when adding new constants --- ## Files Modified (January 28, 2026) **Constants Added**: 1. `CouponDuration` - Stripe coupon duration types 2. `StripeErrorTypes` - Stripe error type identifiers 3. `PROMO_DUPLICATE_TYPE_PRICEKEY` - Duplicate type/priceKey error 4. `PROMO_DUPLICATE_COUPON` - Duplicate couponId error 5. `PROMO_OVERLAPPING_DATES` - Overlapping validUntil error **Files Updated to Use New Constants**: - `controllers/main.js` - `controllers/subscription.js` - `model/customer.js` - `tests/test_setup_intent.js` - `tests/test_duplicate_promo_validation.js` --- ## See Also - [helpers/constants.js](../helpers/constants.js) - Source file with all constants - [PROMO_ENHANCEMENTS_V3.md](./PROMO_ENHANCEMENTS_V3.md) - Promo system v3.0 changes - [PAYMENT_FAILURE_HANDLING.md](./PAYMENT_FAILURE_HANDLING.md) - Payment error handling - [README_PARTNER_INTEGRATION.md](../README_PARTNER_INTEGRATION.md) - Partner integration guide