# Migrate existing data

Now that the migrations have run, we can upgrade the rest of the app.\
Let's start my also migrating any existing data.

Add the following code to 'internal/common/const.go':

```go
package common

const (
	// Resource Types
	Account_RT = "Account"
	Project_RT = "Project"
	Sprint_RT  = "Sprint"
	Story_RT   = "Story"

	// Account Actions
	CreateProject_A = "CreateProject"
	AddUser_A       = "AddUser"

	// Project Actions
	ReadProject_A   = "ReadProject"
	DeleteProject_A = "DeleteProject"
	CreateSprint_A  = "CreateSprint"

	// Sprint Actions
	ReadSprint_A  = "ReadSprint"
	StartSprint_A = "StartSprint"
	EndSprint_A   = "EndSprint"
	CreateStory_A = "CreateStory"

	// Story Actions
	ReadStory_A           = "ReadStory"
	EstimateStory_A       = "EstimateStory"
	ChangeStoryStatus_A   = "ChangeStoryStatus"
	ChangeStoryAssignee_A = "ChangeStoryAssignee"

	// Policies
	CanManageAccount_P = "CanManageAccount"

	// Roles
	AccountAdministrator_R = "AccountAdministrator"
)
```

This simply defines some constants we'll use later in the code.

Next, add the following code to 'cmd/api/api.go' (just before starting the webserver):

```go

// migrate existing data to cerberus

accounts, err := accountRepo.FindAll()
if err != nil {
	log.Fatal(err)
}

for _, account := range accounts {

	// admin user
	adminUser, err := userRepo.FindOneByEmail("admin")
	if err != nil {
		log.Fatal(err)
	}

	// Get token
	tokenPair, err := cerberusClient.GetUserToken(account.Id, adminUser.Id)
	if err != nil {
		log.Fatal(err)
	}
	mctx := context.WithValue(ctx, "cerberusTokenPair", tokenPair)

	err = cerberusClient.ExecuteWithCtx(mctx,
		cerberusClient.CreateAccountCmd(account.Id),
		cerberusClient.CreateSuperRoleCmd(common.AccountAdministrator_R),
		cerberusClient.CreateUserCmd(adminUser.Id, adminUser.Email, adminUser.Name),
		cerberusClient.AssignRoleCmd(common.AccountAdministrator_R, adminUser.Id),
		cerberusClient.CreateResourceCmd(account.Id, "", common.Account_RT),
		cerberusClient.CreateRolePermissionCmd(common.AccountAdministrator_R, account.Id, []string{common.CanManageAccount_P}))
	if err != nil {
		log.Fatal(err)
	}

	// all users
	users, err := userRepo.FindAll(account.Id)
	if err != nil {
		log.Fatal(err)
	}

	for _, user := range users {

		err = cerberusClient.ExecuteWithCtx(mctx,
			cerberusClient.CreateUserCmd(user.Id, user.Email, user.Name))
		if err != nil {
			log.Fatal(err)
		}
	}

	// projects
	projects, err := projectRepo.FindByAccount(account.Id)
	if err != nil {
		log.Fatal(err)
	}

	for _, project := range projects {
		err = cerberusClient.ExecuteWithCtx(mctx,
			cerberusClient.CreateResourceCmd(project.Id, account.Id, common.Project_RT))
		if err != nil {
			log.Fatal(err)
		}

		// sprints
		sprints, err := sprintRepo.FindByProject(project.Id)
		if err != nil {
			log.Fatal(err)
		}

		for _, sprint := range sprints {
			err = cerberusClient.ExecuteWithCtx(mctx,
				cerberusClient.CreateResourceCmd(sprint.Id, project.Id, common.Sprint_RT))
			if err != nil {
				log.Fatal(err)
			}

			// stories
			stories, err := storyRepo.FindBySprint(sprint.Id)
			if err != nil {
				log.Fatal(err)
			}

			for _, story := range stories {
				err = cerberusClient.ExecuteWithCtx(mctx,
					cerberusClient.CreateResourceCmd(story.Id, sprint.Id, common.Story_RT))
				if err != nil {
					log.Fatal(err)
				}
			}
		}
	}
}

```

This will migrate any existing resources and users you've created into cerberus.\
IMPORTANT!! replace the "admin" user lookup with a user of your own that you've created.

Don't worry about the details of this code. It simply loops through local data and creates corresponding users and resources in cerberus.

All commands in cerberus are idempotent, so this code can run multiple times without problems.

This type of approach is useful when you have an existing production app that you'd like to migrate to cerberus.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.a11n.io/tutorial/implementation/backend/migrate-existing-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
