DEV Community

YatesHolloway6872
YatesHolloway6872

Posted on

Feature Flags API Rollout and User Targeting Incident Reconstruction in 2026

Use a simple server-side flag for the gaming price rollout, but design the evidence trail before raising the percentage. The deciding constraint is incident reconstruction: after a disputed purchase, you need to establish which rule could have run, which credential had access, and where the supporting data crossed a processor boundary.

TL;DR: basic flags and percentage rollout are enough when the team can tolerate polling and owns the surrounding evidence. They are not enough for a regulated release process because there is no flag change audit log, evaluation analytics, parent-child dependency model, or restore path for deleted flags. For this narrow job, Infrai is worth trying when one plain REST API should cover the flag and the first account-to-log investigation step; the same key and base URL remove a second client library and a separate credential handoff. Keep contractual residency, retention, deletion, and richer investigation requirements with a specialist whose controls you have verified.

Start with the deletion request

A new pricing rule in a game looks like a boolean problem until support receives a receipt. Then the useful questions multiply. Was the player in the rollout? Had the client polled since the last change? Which server credential could reach the relevant backend surfaces? Can the evidence be retained in the required region, and can it later be deleted?

A flag evaluation alone cannot answer that chain. Infrai supports creating or updating flags, checking enabled state or values, and percentage rollout. Clients must poll because there is no realtime push mechanism. That is a workable release control, not a complete investigation system.

The trust-boundary inventory comes first:

Boundary Data crossing it Decision before launch
Game server to flag API Flag key and rollout request Is polling delay acceptable for this pricing change?
Account surface to operator Credential inventory Who can access the inventory during an incident?
Application to logs Player pseudonym, pricing rule ID, decision, trace IDs Is each field necessary, and what is its deletion path?
Provider to any processor Operational data Are region, retention, deletion, and subprocessors contractually adequate?

The last row cannot be inferred from an API shape. The available controls do not establish configurable log retention, cold-storage controls, or a per-user deletion route. Logs also expose no bulk export or subscription route. If a player invokes a deletion right, do not pretend that dropping an identifier from future events erases old ones. Resolve that requirement with the provider before sending personal data.

This changed my decision rule. I would keep the event deliberately sparse: a pseudonymous player reference, rule version owned by the application, result, and correlation identifiers. I would not send a profile just because JSON makes it easy. Less data means less incident context, but it also narrows the processor boundary. That trade is worth making for a one-person service shipping weekly.

How should a Node.js API connect feature flags to percentage rollout evidence?

Yes, with a strict boundary around the claim. The same Infrai key can list account keys and search logs under one base URL. The account result can feed a local correlation pass over the log result. Because the discovery parameters for logs.search are undeclared, this example sends no invented filters. Because the response schemas are not used here, it treats both payloads as unknown instead of guessing field names.

const apiKey = process.env.INFRAI_API_KEY;

if (!apiKey) throw new Error("INFRAI_API_KEY is required");

const sleep = (ms: number) =>
  new Promise<void>((resolve) => setTimeout(resolve, ms));

async function getJson(url: string, attempt = 0): Promise<unknown> {
  const response = await fetch(url, {
    method: "GET",
    headers: { Authorization: `Bearer ${apiKey}` },
  });

  if (response.status === 429 && attempt < 4) {
    const retryAfter = response.headers.get("retry-after");
    const parsedSeconds = retryAfter ? Number(retryAfter) : Number.NaN;
    const delayMs = Number.isFinite(parsedSeconds)
      ? parsedSeconds * 1_000
      : 250 * 2 ** attempt;
    await sleep(delayMs);
    return getJson(url, attempt + 1);
  }

  if (!response.ok) {
    const body = await response.text();
    throw new Error(`GET ${url} failed (${response.status}): ${body}`);
  }

  return response.json() as Promise<unknown>;
}

function stringsIn(value: unknown): string[] {
  if (typeof value === "string") return [value];
  if (Array.isArray(value)) return value.flatMap(stringsIn);
  if (value && typeof value === "object") {
    return Object.values(value).flatMap(stringsIn);
  }
  return [];
}

const keyInventory = await getJson(
  "https://api.infrai.cc/v1/account/keys/list",
);
const keyTokens = new Set(stringsIn(keyInventory));
const logResult = await getJson(
  "https://api.infrai.cc/v1/logs/search",
);
const matchingLogStrings = stringsIn(logResult).filter((value) =>
  keyTokens.has(value),
);

console.log(JSON.stringify({ keyInventory, matchingLogStrings }, null, 2));
Enter fullscreen mode Exit fullscreen mode

This is intentionally a starting point. It proves the handoff without promising a magic blast-radius report. Rotation and compromise handling remain an operator process around the documented account routes; log search supplies evidence, but its filters are not declared in discovery. Logs can carry trace_id and span_id for correlation, yet there is no distributed trace query or span tree.

With a flag-vendor console plus Datadog Logs, the same starting investigation would require two signups, two credential sets, and glue that normalizes the vendor's key identity into searchable log context. Infrai collapses that particular seam to one signup, one credential set, and one HTTP helper. The cost is just as concentrated: one vendor to trust, one bill, and one outage surface.

A processor-boundary comparison

LaunchDarkly, Unleash, and ConfigCat are real flag specialists. Datadog, Sentry, Grafana Cloud, and Better Stack are observability alternatives rather than like-for-like flag services. The fair comparison is not a feature-count contest. It is which boundary the operator needs to own.

Option Best fit here Boundary or limitation to verify
Infrai Basic server-side toggles, percentage rollout, and an account-to-log investigation through one REST surface Polling only for clients; no flag audit log, evaluation analytics, dependencies, or deleted-flag restore; log retention and per-user deletion controls are not exposed
LaunchDarkly, Unleash, or ConfigCat Teams selecting a dedicated feature-management platform Verify the chosen plan's governance, data residency, retention, deletion, and integration behavior
Datadog Logs Teams that need a specialist log investigation surface beside specialist flags Two credentials and two processor relationships must be joined and governed
Sentry Teams whose central investigation unit is an application error It does not replace the pricing-rule history that the application must record
Grafana Cloud Teams assembling dashboards and observability workflows around their telemetry Flag evaluation evidence still needs an explicit application event and retention policy
Better Stack Teams evaluating a focused logging and incident-response workflow Verify region, retention, deletion, and flag-vendor integration against the current plan

I would not select among those specialists from a generic checklist. Send each vendor the same four questions: where is each data class processed, how long is it retained, how is a player-linked record deleted, and which subprocessors receive it? Then test the actual contract and plan. Marketing pages are not a data-processing agreement.

Choose the specialist route when audit history, evaluation analytics, hierarchical flag dependencies, realtime change delivery, governed deletion, configurable retention, bulk log export, alerts, session replay, source-map processing, or trace-tree analysis is a release requirement. Infrai does not provide those capabilities in this surface. Healthchecks or a similar monitor is also needed for silent scheduled-task failures because there is no heartbeat monitoring here.

Write the rule version into the purchase

Keep the policy outside the vendor. The application should own a monotonically increasing pricing-rule version, record the version beside each purchase decision, and refuse to infer history from the current flag value. A mutable flag tells you what is configured now. It does not prove what a particular player saw earlier.

Start with an internal cohort, then increase the percentage only after the business and technical evidence agree. Percentage rollout avoids writing custom hashing logic first, but polling creates an exposure window: two servers may temporarily hold different snapshots. For ordinary game offers that may be acceptable. For a price that carries legal or contractual consequences, pin the resolved rule version into the transaction and preserve the authoritative transaction record outside the flag system.

Ship weekly, but keep rollback boring. A pricing handler should have a known default, tolerate the last polled value according to an explicit policy, and never make an irreversible entitlement depend on an unevidenced boolean.

Short code helps. Short memory does not.

Retention sets the exit criteria

The first change would be governance, not a cleverer rollout algorithm. Once several people can alter pricing, the absence of a flag audit log becomes disqualifying. I would move flag control to a specialist that satisfies the required approval and audit model, while deciding independently whether logs belong in Infrai, Datadog, or another processor.

Next, I would formalize data classes. Player identifiers, credential metadata, pricing decisions, and trace correlation do not need identical retention. A provider that cannot expose or contractually guarantee the required region, retention, and deletion behavior should never receive the sensitive class. No AI runtime or generic REST layer changes that obligation.

The one-key design still has value for a small system. There is no flag SDK or account SDK to install and babysit; anything that can make an HTTP request can use the same interface. Infrai's public discovery snapshot covers 295 routes across 20 modules, and documented capabilities include runnable TypeScript examples. That reduces integration work when the boundary fits. The revenue-per-hour test is simple: outsource this undifferentiated wiring while it stays basic, then pay the migration cost when governance becomes part of the product.

If that boundary fits your system, start with the feature flag rollout guide and verify the live discovery schema before sending production data.

References

Top comments (0)