Skip to content

Feature Flags

Applies to: All subscriptions

Purpose

Document every per-GSTIN switch: what it does, its default, the reasoning behind that default, and the consequence of changing it. Three of these flags change what the system does without a person present, and those deserve a decision rather than a default.

Audience

System administrators and implementation consultants. The three off-by-default flags also concern the customer's finance control owner.

Prerequisites

Reference

How flags resolve

Every GSTIN starts from a platform default so a newly provisioned registration works immediately. An explicit per-GSTIN setting, where present, always wins.

Flags are per GSTIN, never per company and never per user. A group can therefore enable a module on one registration while the rest continue unchanged — which is the right way to pilot anything with legal consequence.

Values are cached briefly for performance. A change takes effect within about a minute, or immediately on re-authentication. This is why "I changed it and nothing happened" is usually impatience rather than a fault.

The flags

Flag Default What it controls
EINVOICE_ENABLED On e-Invoice module: IRN generation, cancellation, printing
EWAYBILL_ENABLED On e-Way Bill module: generation, Part-B, extension, consolidated bills
RECONCILIATION_ENABLED On Reconciliation and matching screens
SOD_ENFORCED On Segregation of duties. See below
AUTO_IRN_ENABLED Off Fires IRN generation automatically on ingest
INVOICING_ENABLED Off Invoice Generation Module
ERP_WRITEBACK_ENABLED Off Sends compliance outcomes back to the ERP
IGM_CREDIT_RULE WARN Credit management. ALLOW switches it off — limits are recorded but never checked at post time; the interface labels this value OFF. WARN flags a breach and posts anyway; BLOCK refuses the post until a checker overrides it
IGM_APPROVAL_VALUE_THRESHOLD 0 (off) Invoice value above which approval is required
IGM_APPROVAL_DISCOUNT_PCT 0 (off) Discount percentage above which approval is required
IGM_DISCOUNT_OVER_MAX_ACTION BLOCK When a line discount exceeds the item's maximum: BLOCK outright, or APPROVE (allowed, but requires approval)
IGM_APPROVAL_ENGINE Off Multi-level approval workflow, rather than the simpler threshold gate

The three that default to off, and why

These share a property: enabling one changes what the system does without a person present, or sends data outward. Neither is a convenience, so neither is inherited.

AUTO_IRN_ENABLED. Fires IRN generation the moment a document is ingested. It is an automation, not a module unlock — and registering an invoice is a legal act that consumes a billed call and permanently consumes a document number. The default is off so that generation stays a decision until someone deliberately chooses otherwise. Enable it only when validation quality is proven; automating generation over a poor-quality feed produces rejections at volume.

INVOICING_ENABLED. Unlocks the Invoice Generation Module, which raises invoices inside Complifly. A module unlock with legal consequence.

ERP_WRITEBACK_ENABLED. Sends compliance outcomes to the ERP. Two properties matter operationally:

  • It is enforced at emission, not at delivery. A tenant with this off stores not one outbound event — so there is nothing to purge, index, back up or explain.
  • It does not backfill. Emission starts from the moment it is enabled. Seeding an ERP with existing compliance state is a separate, explicit exercise.

Segregation of duties, and what relaxing it means

SOD_ENFORCED defaults to on: the person who prepares a document is not the person who commits it. Preparation and commitment sit with different roles.

Turning it off collapses maker permissions into checker permissions. A user who could previously only prepare can then also approve, issue and cancel. This is a legitimate configuration for a small business where the same person genuinely performs both functions and no separation is possible — but it is a control decision belonging to the customer's finance control owner, not a convenience for an implementation team frustrated by an approval step.

Record the decision in writing. It is exactly the kind of setting an auditor asks about, and "it was easier during testing" is not an answer.

Invoice Generation Module rules

The IGM_* flags encode business rules the customer chooses, not statutory constraints:

Setting Decision it encodes
Credit rule Whether exceeding a customer's credit limit warns or blocks
Approval value threshold The value above which a second pair of eyes is required
Approval discount percentage The discount above which approval is required
Discount over maximum Whether an excessive line discount is refused or routed for approval
Approval engine Whether a multi-level workflow replaces the simple threshold gate

A threshold of 0 means the rule is off, not that everything requires approval.

All twelve are on one screen

Every flag on this page has a control on Admin & Logs > Operational Controls, one column per flag and one row per registration. That is enforced by a test (__tests__/admin/operationalMatrix.test.js) which reads the flag list from the code and the columns from the component, so a flag cannot be added to the product without a control appearing — or a control left behind for a flag that was removed.

Before 2026-08-30 the matrix was short one column, and it was the one that mattered most: INVOICING_ENABLED, the master switch for Invoice Generation. Every one of its sub-settings was present and the switch itself was not.

The table scrolls horizontally. With twelve controls it is wider than most screens; the registration column stays fixed while you scroll so a checkbox on the right is always attributable to a row.

Two modules have no flag

TDS and DPDP are licensed modules with no per-GSTIN switch, and their routes carry no feature gate — only authentication. There is therefore nothing to put on the matrix for them, and nothing that would enforce it if there were.

Verify: Adding TDS_ENABLED and DPDP_ENABLED to the matrix would require the corresponding requireFeature gates on those routers first. A switch that writes a value nothing reads is worse than no switch: it reports success and changes nothing. H2

Validation

After changing a flag:

Check Method Pass condition
Set against the right GSTIN Open the permissions matrix The flag shows against every intended registration — check all of them, not only the one you are signed in to
Change has propagated Wait about a minute, or re-authenticate Behaviour reflects the new value
Module screens appear Navigate to the module Entry present and it opens
Role can actually use it Sign in as a real user of that module Controls are enabled, not greyed out. Module visibility and permission are separate gates
Automation behaves as intended With auto-generation on, ingest one document It generates without intervention. With it off, it waits
Segregation change is understood With enforcement off, sign in as a preparer They can now approve and issue. Confirm this is intended and recorded
Write-back is emitting With write-back on, process a new document An outbound event appears. Older documents produce nothing — by design
Approval thresholds fire Create a document above and below the threshold Above requires approval; below does not
Decision recorded Change log Who decided, when, and why — especially for segregation of duties

Troubleshooting

Symptom Cause Action
Module enabled but no screen Set against the wrong GSTIN, or cache not yet expired Confirm the registration; wait a minute or re-authenticate
Screen present, everything greyed out The user's role lacks the permissions Fix the role, not the flag. See Roles and Permissions
Automation not firing after enabling the module Automation is a separate flag from the module unlock Enable the automation deliberately
Automation firing on poor-quality documents Auto-generation enabled before validation quality was proven Turn it off, fix the feed, then re-enable
Write-back on but the ERP has nothing for older documents Emission is not retrospective Expected. Plan a separate seeding exercise
Approvals unexpectedly required A threshold set to a low value, or the approval engine enabled Review the IGM_* settings
Approvals never required Thresholds left at 0, which means off Set a real value
A preparer can suddenly approve Segregation of duties was relaxed Confirm this was a recorded decision. If not, re-enable it
One registration behaves differently from the rest Per-GSTIN settings have diverged Compare across all registrations. Usually intended, occasionally an oversight
An auditor asks who authorised relaxing segregation No record kept Record every control-relevant flag change at the time it is made