Skip to content

Configuration options

Copy of sumaris-app/.agents/rules/configuration.md (rule written for AI coding agents, when creating or modifying module configuration options (.config.ts files)). Do not edit here: run npm run site:sync-rules to update it.

Each functional module declares its configuration options in a dedicated .config.ts file. These options control feature activation, naming, offline mode, and other module-specific behaviors. They are loaded from the server (POD) via ConfigService.

File structure

A .config.ts file typically exports:

  1. Feature name constants: used by services to identify the module;
  2. *_CONFIG_OPTIONS: server-side configuration options (fetched from the POD);
  3. *_LOCAL_SETTINGS_OPTIONS: client-side settings (stored locally in the browser);
  4. *_GRAPHQL_TYPE_POLICIES: Apollo cache type policies for the module's entities;
  5. *_STORAGE_TYPE_POLICIES: local storage policies for offline support;

Config options (*_CONFIG_OPTIONS)

  • Define as a frozen object (Object.freeze({...})) of FormFieldDefinition entries;
  • Each entry has:
    • key: a dot-separated string identifier (e.g. 'sumaris.trip.enable');
    • label: an i18n key for the option label;
    • type: the field type ('boolean', 'string', 'enum', 'integer', etc.);
    • defaultValue (optional): the default value;
    • values (optional): for 'enum' type, an array of { key, value } objects;
export const TRIP_CONFIG_OPTIONS = Object.freeze({
  TRIP_ENABLE: <FormFieldDefinition>{
    key: 'sumaris.trip.enable',
    label: 'TRIP.OPTIONS.ENABLE',
    type: 'boolean',
  },
  TRIP_NAME: <FormFieldDefinition>{
    key: 'sumaris.trip.name',
    label: 'TRIP.OPTIONS.NAME',
    type: 'enum',
    values: [
      { key: 'MENU.TRIPS', value: 'MENU.TRIPS' },
      { key: 'MENU.SCIENTIFIC_CRUISES', value: 'MENU.SCIENTIFIC_CRUISES' },
    ],
    defaultValue: 'MENU.TRIPS',
  },
});

Local settings options (*_LOCAL_SETTINGS_OPTIONS)

  • Same structure as config options, but for client-side preferences;
  • Registered via the APP_LOCAL_SETTINGS_OPTIONS injection token;
export const TRIP_LOCAL_SETTINGS_OPTIONS = Object.freeze({
  SAMPLE_WEIGHT_UNIT: <FormFieldDefinition>{
    key: 'sumaris.trip.samples.weightUnit',
    label: 'TRIP.SAMPLE.SETTINGS.SAMPLE_WEIGHT_UNIT',
    type: 'enum',
    values: [
      { key: UnitLabel.KG, value: UnitLabel.KG },
      { key: UnitLabel.GRAM, value: UnitLabel.GRAM },
    ],
  },
});

Registration in app.module.ts

All module config options are aggregated in app.module.ts via Angular injection tokens:

  • Server config: provided via APP_CONFIG_OPTIONS token, merged with spread operator:

    {
      provide: APP_CONFIG_OPTIONS,
      useValue: <FormFieldDefinitionMap>{
        ...CORE_CONFIG_OPTIONS,
        ...REFERENTIAL_CONFIG_OPTIONS,
        ...TRIP_CONFIG_OPTIONS,
        ...VESSEL_CONFIG_OPTIONS,
        // ... other modules
      },
    }
    

  • Local settings: provided via APP_LOCAL_SETTINGS_OPTIONS token:

    {
      provide: APP_LOCAL_SETTINGS_OPTIONS,
      useValue: [
        ...SHARED_LOCAL_SETTINGS_OPTIONS,
        ...TRIP_LOCAL_SETTINGS_OPTIONS,
        ...VESSEL_LOCAL_SETTINGS_OPTIONS,
        // ... other modules
      ],
    }
    

ConfigService

  • ConfigService (from ngx-sumaris-components) loads configuration from the server via GraphQL and merges it with the registered APP_CONFIG_OPTIONS;
  • It exposes an observable config that emits the current Configuration object;
  • Services and components can read option values from the configuration to enable/disable features at runtime;

Using config options in services

Services typically read configuration values to control behavior:

// In a service constructor or ngOnStart
this.configService.config.subscribe(config => {
  const tripEnabled = config.getPropertyAsBoolean(TRIP_CONFIG_OPTIONS.TRIP_ENABLE);
  const tripName = config.getProperty(TRIP_CONFIG_OPTIONS.TRIP_NAME);
});

GraphQL type policies (*_GRAPHQL_TYPE_POLICIES)

  • Define Apollo cache key fields for entities that need custom cache identity:
    export const TRIP_GRAPHQL_TYPE_POLICIES = <TypePolicies>{
      MeasurementVO: {
        keyFields: ['entityName', 'id'],
      },
    };
    
  • Registered via APP_GRAPHQL_TYPE_POLICIES token in app.module.ts;

Storage type policies (*_STORAGE_TYPE_POLICIES)

  • Define how entities are stored locally for offline support:
    export const TRIP_STORAGE_TYPE_POLICIES = <EntitiesStorageTypePolicies>{
      TripVO: <EntityStoreTypePolicy<Trip>>{
        mode: 'by-id',
        skipNonLocalEntities: true,
        lightFieldsExcludes: ['measurements', 'sale', 'gears'],
      },
    };
    
  • mode: storage mode ('by-id' or 'default');
  • skipNonLocalEntities: if true, only local (offline) entities are stored;
  • lightFieldsExcludes: fields excluded from the light (list) version of the entity;

Feature name constants

  • Each module defines a feature name constant used by services:
    export const TRIP_FEATURE_NAME = 'trip';
    
  • Optionally, a default program filter for strategy resolution:
    export const TRIP_FEATURE_DEFAULT_PROGRAM_FILTER: Partial<ProgramFilter> = Object.freeze({
      statusIds: [StatusIds.ENABLE, StatusIds.TEMPORARY],
      acquisitionLevelLabels: [AcquisitionLevelCodes.TRIP, AcquisitionLevelCodes.OPERATION],
    });
    

Reference examples

  • Trip module config: src/app/trip/trip.config.ts;
  • Core config options: ngx-sumaris-components/src/app/core/services/config/core.config.ts;
  • Config service: ngx-sumaris-components/src/app/core/services/config.service.ts;
  • Registration: src/app/app.module.ts (providers section);