# How to Seed Sample Data in a Macro Local Stack: Complete CLI Guide

> Learn to seed sample data in your Macro local stack using the Seed CLI for consistent permission testing and UI prototyping. Access deterministic data with just seed scenario commands.

- Repository: [Macro/macro](https://github.com/macro-inc/macro)
- Tags: how-to-guide
- Published: 2026-08-21

---

**TLDR:** Macro provides a dedicated Seed CLI accessible via `just seed-scenario` commands that populates your local development stack with deterministic sample data defined in JSON scenario files, enabling consistent permission testing and UI prototyping across developers and CI environments.

To seed sample data in a Macro local stack, you use the **Seed CLI** to apply scenario files that define complete entity graphs—including users, teams, channels, documents, and access permissions—to your running Postgres and LocalStack services. According to the macro-inc/macro source code, this tool ensures every local environment starts with identical, reproducible data sets rather than empty databases, making it essential for end-to-end testing and frontend development workflows.

## Prerequisites for Seeding a Macro Local Stack

Before executing seed commands, you must have the local development environment running with active Postgres and LocalStack services.

### Starting the Local Development Environment

Use the helper scripts provided in the repository root. The command `just run_local` initializes the default local stack instance, or specify a named instance with `just run_local --instance <id>` for isolated testing environments.

```bash

# Start the default local stack

just run_local

# Or start a named instance for isolated testing

just run_local --instance 2508

```

## Understanding the Seed CLI Architecture

The seeding system centers on **scenario files**—declarative JSON documents that describe entire data worlds with all entities and their access relationships.

### Scenario Files and Deterministic ID Generation

Scenario files reside in `seed/scenarios/*.json`, with [`seed/scenarios/team-perms.json`](https://github.com/macro-inc/macro/blob/main/seed/scenarios/team-perms.json) serving as the reference implementation. These files define users, teams, channels, documents, tasks, chats, emails, and the access edges between them. When seeding, the CLI generates **deterministic IDs** using a `5eed` marker prefix, ensuring that seeded rows are identifiable and reproducible across runs without colliding with organic user data.

### Core Commands Overview

As documented in [`tooling/seed_cli/README.md`](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/README.md), the Seed CLI provides four primary lifecycle commands:

- **`apply`** – Deletes existing rows marked with the scenario ID, then inserts fresh data
- **`matrix`** – Computes and verifies every (user, entity) access expectation against the `entity_access` service
- **`status`** – Read-only inspection of seeded rows and FusionAuth accounts with login links
- **`reset`** – Removes only rows carrying the scenario's deterministic ID marker

## Step-by-Step Guide to Seeding Sample Data

### Applying a Scenario with `seed-scenario apply`

The `apply` command is the primary mechanism to populate your local stack. It first deletes any existing rows belonging to the scenario (identified by the `5eed` marker), then creates fresh rows derived from the scenario file. It also provisions FusionAuth accounts for each persona, allowing the signup webhook to generate base rows that the seeder adopts.

```bash

# Seed the default team-perms scenario

just seed-scenario apply --file seed/scenarios/team-perms.json

# Force drop the entire database, re-run migrations, then seed (destructive)

just seed-scenario apply --file seed/scenarios/team-perms.json --force

```

If FusionAuth is unreachable during execution, the command continues seeding database rows and reports the connectivity issue without failing.

### Verifying Permissions with `seed-scenario matrix`

After seeding, validate that your permission logic matches the intended security model using the `matrix` command. This computes every (user, entity) access expectation defined in the scenario and verifies it against the running `entity_access` service.

```bash
just seed-scenario matrix --file seed/scenarios/team-perms.json

```

### Inspecting Status and Retrieving Login Links

Use the `status` command to view present rows and obtain automated login URLs for testing. In development builds, opening links like `http://alice.localhost:3000/app/login?email=alice@seed.macro.local` automatically authenticates the persona account (the dev build auto-submits the one-time code).

```bash

# View all seeded data and login links

just seed-scenario status --file seed/scenarios/team-perms.json

# Check specific scenario file only

just seed-scenario status --file seed/scenarios/team-perms.json --file

```

For non-development builds, retrieve one-time codes from Mailpit; access the Mailpit UI address via `just status_local`.

### Resetting or Cleaning Up Seeded Data

The `reset` command removes only rows carrying the scenario's deterministic ID marker, leaving organic data intact. This is useful when you need to clean up test data without affecting manually created accounts.

```bash

# Remove only seeded rows for this scenario

just seed-scenario reset --file seed/scenarios/team-perms.json

# Remove every row in the database (cannot delete accounts created via signup webhook)

just seed-scenario reset --file seed/scenarios/team-perms.json --all

```

## Working with Multiple Local Stack Instances

When running isolated stacks using instance identifiers, you must target the specific instance during seeding operations. Pass the `--instance` flag to all Seed CLI commands to ensure data is applied to the correct environment.

```bash

# Target instance 2508 specifically

just seed-scenario --instance 2508 apply --file seed/scenarios/team-perms.json

# Verify permissions on the named instance

just seed-scenario --instance 2508 matrix --file seed/scenarios/team-perms.json

```

## Integration with End-to-End Testing

The seeding system integrates directly with the test suite. As described in [`crates/local_e2e_test_support/README.md`](https://github.com/macro-inc/macro/blob/main/crates/local_e2e_test_support/README.md), the E2E test harness loads fixtures from `tooling/seed_cli/seed` and validates against the exact permission matrices defined in your scenario files. This ensures that integration tests run against the same data structures used during local development.

## Summary

- Use `just seed-scenario apply` with JSON scenario files to populate fresh, deterministic data identified by the `5eed` marker
- Target specific stack instances with the `--instance` flag to support parallel development environments
- Reference [`tooling/seed_cli/README.md`](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/README.md) for complete command semantics and scenario file format specifications
- Verify permission implementations using `matrix` and inspect results with `status` to obtain persona login links
- Remove seeded data cleanly using `reset` without affecting organic user data, or use `--force` with `apply` for complete database reconstruction

## Frequently Asked Questions

### Where are scenario files stored in the Macro repository?

Scenario files are stored in the `seed/scenarios/` directory with the extension `.json`. The file [`seed/scenarios/team-perms.json`](https://github.com/macro-inc/macro/blob/main/seed/scenarios/team-perms.json) serves as the reference scenario used in most tutorials and defines users, teams, channels, documents, tasks, and their access edges.

### How does the Seed CLI handle user authentication when seeding?

During the `apply` command, the CLI creates FusionAuth accounts for each persona defined in the scenario. This triggers the signup webhook, which generates the base rows that the seeder subsequently adopts and extends with additional entity relationships. If FusionAuth is unreachable, the database seeding continues while reporting connectivity issues.

### Can I seed multiple isolated development stacks simultaneously?

Yes. Use `just run_local --instance <id>` to start named stack instances on separate ports, then target specific instances with `just seed-scenario --instance <id> apply`. This allows you to maintain separate data sets for different feature branches or test scenarios without conflicts.

### What is the difference between `reset` and `apply --force`?

The `reset` command deletes only rows marked with the scenario's deterministic ID (and optionally their associated email accounts), preserving any organic data created through normal application usage. In contrast, `apply --force` completely drops the entire database, re-runs all migrations from scratch, and then seeds fresh data—a destructive operation that removes all organic data alongside seeded rows.