# How to Use the Seed CLI to Generate Realistic Team Permission Test Scenarios

> Learn how to use the Seed CLI to generate realistic team permission test scenarios. Populate your Macro instance with production-like access patterns and reproducible test data.

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

---

**The Seed CLI populates a local Macro instance with reproducible test data—including users, teams, and granular permissions—by applying JSON scenario files that mirror production-like access patterns.**

The **Seed CLI** is a dedicated command-line tool in the [macro-inc/macro](https://github.com/macro-inc/macro) repository that creates complete, deterministic test environments. By defining **team permission test scenarios** in JSON, you can spin up complex organizational structures with full access control matrices for integration testing, manual QA, or CI pipelines.

## Core Concepts of the Seed CLI

Understanding three key abstractions helps you leverage the tool effectively:

- **Scenario file** — A JSON document declaring users, roles, teams, channels, projects, documents, tasks, chats, calls, emails, and messages. The reference implementation [[`team-perms.json`](https://github.com/macro-inc/macro/blob/main/team-perms.json)](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/seed/scenarios/team-perms.json) demonstrates realistic team permission hierarchies.

- **ID marker** — All seeded rows carry the `5eed` prefix, enabling surgical cleanup without affecting production data or manually created accounts.

- **FusionAuth integration** — The CLI provisions passwordless user accounts before database insertion, generating one-time login links for each persona.

## Installing and Running the Seed CLI

The CLI is built in Rust and invoked through the repository's `just` task runner.

### Prerequisites

Start the local development stack first:

```bash
just stack up            # PostgreSQL + localstack services

just seed help           # Display available sub-commands

```

### Available Commands

| Command | Purpose |
|---------|---------|
| `apply` | Create or update a scenario (deletes existing rows first) |
| `status` | Inspect seeded entities and print login URLs |
| `matrix` | Verify actual permissions match the scenario specification |
| `reset` | Remove all rows and accounts belonging to a scenario |
| `--force` | Drop database, re-run migrations, then seed |

## Applying a Team Permission Scenario

The `apply` sub-command in [`tooling/seed_cli/src/main.rs`](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/src/main.rs) orchestrates the full seeding pipeline.

### Basic Application

```bash

# From repository root

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

```

Execution flow as implemented in [[`tooling/seed_cli/src/entity/scenario/spec.rs`](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/src/entity/scenario/spec.rs)](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/src/entity/scenario/spec.rs):

1. Derive deterministic IDs using `derive_id(scenario, kind, key)`
2. Delete existing rows matching the scenario's `scenario_marker`
3. Create FusionAuth accounts for each user
4. Insert database rows with `5eed`-prefixed identifiers

### Forcing a Clean Slate

When migrations drift or schemas change, use `--force` to rebuild from zero:

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

```

This drops the entire database, re-runs all migrations, then executes the standard seeding flow.

## Inspecting and Verifying Seeded Data

### Check Scenario Status

The `status` command reveals which entities exist and provides immediate login access:

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

```

Output includes a table of missing keys per entity type and one-time URLs like:

```

http://alice.localhost:3000/app/login?email=alice@seed.macro.local

```

### Validate Permission Matrix

The `matrix` command—implemented in [[`tooling/seed_cli/src/entity/scenario/matrix.rs`](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/src/entity/scenario/matrix.rs)](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/src/entity/scenario/matrix.rs)—computes expected access levels for every `(user, entity)` pair and validates against the live `entity_access` service:

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

```

Exit code is non-zero if any permission deviates from specification, making this ideal for CI assertions.

## Customizing Team Permission Scenarios

### Creating a New Scenario

Copy the reference and modify:

```bash
cp tooling/seed_cli/seed/scenarios/team-perms.json \
   seed/scenarios/my-custom-teams.json

```

### Scenario File Structure

Each top-level key follows a consistent pattern in [[`team-perms.json`](https://github.com/macro-inc/macro/blob/main/team-perms.json)](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/seed/scenarios/team-perms.json):

- `users` — Personas with roles and team memberships
- `teams` — Organizational units with permission inheritance
- `channels` — Communication spaces with access rules
- `projects`, `documents`, `tasks` — Work items with granular permissions
- `chats`, `calls`, `emails`, `messages` — Communications linked to users

Edit the `scenario` name field, adjust entity definitions, then run:

```bash
just seed-scenario apply --file seed/scenarios/my-custom-teams.json

```

## Cleaning Up Test Data

### Reset Single Scenario

Remove only rows created by your scenario (plus associated FusionAuth accounts):

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

```

### Reset All Seed Data

Delete across all scenarios while preserving webhook-created accounts:

```bash
just seed-scenario reset --all

```

## Source Code Reference

| Component | File Path | Description |
|-----------|-----------|-------------|
| CLI entry point | [`tooling/seed_cli/src/main.rs`](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/src/main.rs) | Command definitions and orchestration |
| Scenario parsing | [`tooling/seed_cli/src/entity/scenario/spec.rs`](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/src/entity/scenario/spec.rs) | JSON parsing, ID derivation, marker management |
| Matrix verification | [`tooling/seed_cli/src/entity/scenario/matrix.rs`](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/src/entity/scenario/matrix.rs) | Permission computation and validation |
| Reference scenario | [`tooling/seed_cli/seed/scenarios/team-perms.json`](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/seed/scenarios/team-perms.json) | Production-like team permission example |
| Task wrappers | `justfile` (lines 55-57) | Convenient `just seed-scenario` shortcuts |

## Summary

- **Seed CLI** commands `apply`, `status`, `matrix`, and `reset` manage complete test lifecycle
- **Scenario files** declare realistic team permission structures in JSON
- **Deterministic IDs** derived from `(scenario, kind, key)` ensure reproducibility
- **`5eed` marker prefix** enables safe, surgical cleanup without data loss
- **FusionAuth integration** provides passwordless login for every test persona
- **Matrix verification** validates live permissions against specification for CI reliability

## Frequently Asked Questions

### What permissions can be expressed in a scenario file?

The scenario format supports role-based access control at team, channel, project, and document levels. You define users, assign them roles within teams, and specify which entities they can read, write, or administer. The matrix verifier in [`matrix.rs`](https://github.com/macro-inc/macro/blob/main/matrix.rs) computes the transitive closure of these permissions and validates against the actual `entity_access` service.

### How does the Seed CLI prevent conflicts with production data?

Every row created by the CLI uses the `5eed` prefix in its ID, as implemented by `scenario_marker` in [`spec.rs`](https://github.com/macro-inc/macro/blob/main/spec.rs). The `reset` and `apply` commands filter on this marker, ensuring only seeded data is affected. User accounts created through normal signup webhooks lack this marker and are never touched.

### Can I run multiple scenarios simultaneously?

Yes. Each scenario has a unique name field, and IDs incorporate the scenario identifier via `derive_id`. This isolation allows parallel scenarios without collision. Use `status` with `--file` to inspect individual scenario states, or `reset --all` for global cleanup.

### Why does `apply` delete before creating?

This ensures **idempotency**. As documented in the [Seed CLI README](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/README.md), `apply` first removes existing rows for that scenario, then rebuilds from the JSON definition. You can re-run the same command after editing the scenario file without manual cleanup or ID conflicts.