agmission/Development/server/docs/CONSTANTS_REFERENCE.md

11 KiB

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

PromoModes

Controls whether the promotional system is globally enabled or disabled (kill switch).

const PromoModes = Object.freeze({
  ENABLED: 'enabled',   // Promotions enabled (targeting controlled by PromoEligibility)
  DISABLED: 'disabled'  // Kill switch: disable all automatic promos
});

Usage:

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


PromoEligibility

Defines customer eligibility criteria for promotional offers.

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:

const { PromoEligibility } = require('./helpers/constants');

const promo = {
  eligibility: PromoEligibility.NEW_ONLY,  // Only for new customers
  // ...
};

Related Documentation: PROMO_ENHANCEMENTS_V2.md


CouponDuration

Stripe coupon duration types supported in the promotional system.

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:

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.

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:

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


Error Codes

Promo Error Codes

Specific error codes for promotional system operations.

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:

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:

if (duplicateTypePrice) {
  throw new AppParamError(Errors.PROMO_DUPLICATE_TYPE_PRICEKEY,
    `Active promo already exists for ${type}/${priceKey}: "${duplicate.name}"`);
}

2. Duplicate Coupon ID:

if (duplicateCoupon) {
  throw new AppParamError(Errors.PROMO_DUPLICATE_COUPON,
    `Active promo already uses coupon ${couponId}: "${duplicate.name}"`);
}

3. Overlapping Dates:

if (overlapping) {
  throw new AppParamError(Errors.PROMO_OVERLAPPING_DATES,
    `Overlapping promo period for ${type}/${priceKey}: "${overlapping.name}"`);
}

API Response Format:

{
  "error": {
    ".tag": "promo_duplicate_type_pricekey",
    "message": "Active promo already exists for package/ess_1: 'First Package Free'"
  }
}

Related Documentation: PROMO_ENHANCEMENTS_V3.md


General Error Codes

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

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

const PartnerCodes = Object.freeze({
  SATLOC: 'SATLOC',
  AGIDRONEX: 'AGIDRONEX',
  // Add other partner codes as needed
});

AuthMethods

const AuthMethods = Object.freeze({
  API_KEY: 'api_key',
  USERNAME_PASSWORD: 'username_password',
  OAUTH: 'oauth',
  BEARER_TOKEN: 'bearer_token'
});

Related Documentation: README_PARTNER_INTEGRATION.md


Other Constants

APIActions

Standard action labels for API mutation responses.

const APIActions = Object.freeze({
  DISABLED: 'disabled',
  DELETED: 'deleted',
  UPDATED: 'updated'
});

Usage:

return res.json({
  action: APIActions.DELETED,
  promo: { _id: promoId, name: promo.name }
});

HttpStatus

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):

// ❌ 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):

// ✅ 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