Skip to content

Core Concepts

FlagPulse's data model has five entities, each with a foreign-key chain down to the next.

users ──< projects ──< environments
                │             │
                └──< flags ──< flag_values >──┘

                └──< audit_logs >── environments / flags

Users

A user registers with a name, email, and password (hashed with bcrypt) and owns projects. Auth is a signed JWT stored in an httpOnly cookie, valid for 7 days.

Projects

A project is the top-level container — think "one FlagPulse project per application or service." Projects are owned by a single user (owner_id) and have a URL-safe slug derived from their name.

Creating a project also creates its first environment in the same request.

Environments

An environment belongs to a project and represents a deployment target (e.g. production, staging, local). Each environment has:

  • Its own SDK key (a UUID, rotatable independently of the environment itself)
  • An allowed origin URL — used to build the CORS allowlist so only that origin's SDK/SSE calls are accepted
  • An icon (for the dashboard)

Rotating an SDK key invalidates the old key immediately (removed from the Redis cache) and the new key becomes valid right away.

Flags

A flag is defined once per project with a key, name, type (boolean | string | number | json), and a default_value. Creating a flag automatically creates a flag_values row for every existing environment in the project, seeded with the default value.

Flag values

A flag value is the per-environment state of a flag:

FieldMeaning
is_enabledWhether the flag is on in this environment
rollout_percentagePercentage rollout (0–100)
targeting_attributeAttribute name to target on (e.g. userId, plan)
targeting_valueThe value of that attribute to match
targeting_return_valueThe value returned when targeting matches

This is what lets the same flag be off in staging and on at 25% in production, independently.

Audit logs

Every mutating action — project/environment/flag creation, deletion, edits, toggles, and SDK-key rotation — writes an audit_logs row with a change_summary, optional old_value/new_value, and a domain (project, environment, or flag). Logs are queryable per project and can be cleared per project.

Next: Architecture