Restore

For completion, let's talk about restoring a deleted fact. You do this by defining yet another successor.

class ProjectRestored {
  static Type = "Construction.Project.Restored" as const;
  type = ProjectRestored.Type;

  constructor(public deleted: ProjectDeleted) {}
}

await j.fact(new ProjectRestored(projectADeleted));

Don't forget to include the ProjectRestored type in your model:

const constructionModel = (b: ModelBuilder) => b
  .type(Project, m => m
    .predecessor("creator", User)
  )
  .type(ProjectDeleted, m => m
    .predecessor("project", Project)
  )
  .type(ProjectRestored, m => m
    .predecessor("deleted", ProjectDeleted)
  )
  ;

Again, you need to add this fact to the specification for it to have an effect.

const projectsCreatedByUser = model.given(User).match(u =>
  u.successors(Project, p => p.creator)
    .notExists(p => p.successors(ProjectDeleted, d => d.project)
      .notExists(d => d.successors(ProjectRestored, r => r.deleted)))
);

const projects = await j.query(projectsCreatedByUser, user);
%0 Gs+Fo0xO04hUAteaPwrHZDmyovTwr7asnKsBrkRf3HE3M9nYIj4Sk7ZhR8YK5uMq1SMHPrQohtQNwo9B7whK0w== Jinaga.User publicKey --- TEST USER --- PYaXGGp+ksHg101LgyF/pB/OBQsixEhWZ9RDW9wxdwX/sVFWgyhpOZROgi4Gttdz1lWJ5Un0pJPJ5MvXEk1TCQ== Construction.Project id 52eb9df8-7b1c-43d4-9... PYaXGGp+ksHg101LgyF/pB/OBQsixEhWZ9RDW9wxdwX/sVFWgyhpOZROgi4Gttdz1lWJ5Un0pJPJ5MvXEk1TCQ==->Gs+Fo0xO04hUAteaPwrHZDmyovTwr7asnKsBrkRf3HE3M9nYIj4Sk7ZhR8YK5uMq1SMHPrQohtQNwo9B7whK0w== creator JXOsjjaGesPuW0QF0qHlsoB4DN1JtH2zTz/Suq7xdg0rGawLZCUz6zsCLCWblCX5nRZBytRLx6Anbjjw7PQUoQ== Construction.Project id 967202a9-1b33-442e-8... JXOsjjaGesPuW0QF0qHlsoB4DN1JtH2zTz/Suq7xdg0rGawLZCUz6zsCLCWblCX5nRZBytRLx6Anbjjw7PQUoQ==->Gs+Fo0xO04hUAteaPwrHZDmyovTwr7asnKsBrkRf3HE3M9nYIj4Sk7ZhR8YK5uMq1SMHPrQohtQNwo9B7whK0w== creator 2WpNSOBnSkJQIM5FTovNhnTl0PSzEJKWejcdVYUdoi2Rbgl2astIMjf6WwU8/farGnt5fRU8TmdJhNkD+hE41Q== Construction.Project id 36b8402a-6993-4f89-a... 2WpNSOBnSkJQIM5FTovNhnTl0PSzEJKWejcdVYUdoi2Rbgl2astIMjf6WwU8/farGnt5fRU8TmdJhNkD+hE41Q==->Gs+Fo0xO04hUAteaPwrHZDmyovTwr7asnKsBrkRf3HE3M9nYIj4Sk7ZhR8YK5uMq1SMHPrQohtQNwo9B7whK0w== creator

And it's back!

The query logic can be broken down as follows:

  • Find all projects created by the user
  • Exclude projects that have a ProjectDeleted successor
  • Unless that deletion has a ProjectRestored successor (using nested notExists)

This creates a complete delete/restore cycle where deleted items can be brought back into the active set.

Continue With

Mutable Properties

Jinaga is a product of Jinaga LLC.

Michael L Perry, President