{
  "_class" : "hudson.model.FreeStyleBuild",
  "actions" : [
    {
      "_class" : "hudson.model.CauseAction",
      "causes" : [
        {
          "_class" : "hudson.triggers.TimerTrigger$TimerTriggerCause",
          "shortDescription" : "Started by timer"
        }
      ]
    },
    {
      
    },
    {
      "_class" : "hudson.plugins.git.util.BuildData",
      "buildsByBranchName" : {
        "refs/remotes/origin/main" : {
          "_class" : "hudson.plugins.git.util.Build",
          "buildNumber" : 239,
          "buildResult" : None,
          "marked" : {
            "SHA1" : "f98f983b325e5575b889ba4cde45cdf87f9f0656",
            "branch" : [
              {
                "SHA1" : "f98f983b325e5575b889ba4cde45cdf87f9f0656",
                "name" : "refs/remotes/origin/main"
              }
            ]
          },
          "revision" : {
            "SHA1" : "f98f983b325e5575b889ba4cde45cdf87f9f0656",
            "branch" : [
              {
                "SHA1" : "f98f983b325e5575b889ba4cde45cdf87f9f0656",
                "name" : "refs/remotes/origin/main"
              }
            ]
          }
        }
      },
      "lastBuiltRevision" : {
        "SHA1" : "f98f983b325e5575b889ba4cde45cdf87f9f0656",
        "branch" : [
          {
            "SHA1" : "f98f983b325e5575b889ba4cde45cdf87f9f0656",
            "name" : "refs/remotes/origin/main"
          }
        ]
      },
      "remoteUrls" : [
        "https://github.com/UstadMobile/Respect.git"
      ],
      "scmName" : ""
    },
    {
      
    },
    {
      
    },
    {
      
    },
    {
      
    },
    {
      
    },
    {
      "_class" : "org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction"
    }
  ],
  "artifacts" : [
    {
      "displayPath" : "respect-app-compose-debug.apk",
      "fileName" : "respect-app-compose-debug.apk",
      "relativePath" : "respect-app-compose/build/outputs/apk/debug/respect-app-compose-debug.apk"
    },
    {
      "displayPath" : "respect-app-compose-release.apk",
      "fileName" : "respect-app-compose-release.apk",
      "relativePath" : "respect-app-compose/build/outputs/apk/release/respect-app-compose-release.apk"
    },
    {
      "displayPath" : "respect-app-compose-debug.aab",
      "fileName" : "respect-app-compose-debug.aab",
      "relativePath" : "respect-app-compose/build/outputs/bundle/debug/respect-app-compose-debug.aab"
    },
    {
      "displayPath" : "respect-app-compose-release.aab",
      "fileName" : "respect-app-compose-release.aab",
      "relativePath" : "respect-app-compose/build/outputs/bundle/release/respect-app-compose-release.aab"
    },
    {
      "displayPath" : "mapping.txt",
      "fileName" : "mapping.txt",
      "relativePath" : "respect-app-compose/build/outputs/mapping/release/mapping.txt"
    },
    {
      "displayPath" : "respect-cli.zip",
      "fileName" : "respect-cli.zip",
      "relativePath" : "respect-cli/build/distributions/respect-cli.zip"
    },
    {
      "displayPath" : "respect-server-1.0.0.zip",
      "fileName" : "respect-server-1.0.0.zip",
      "relativePath" : "respect-server/build/distributions/respect-server-1.0.0.zip"
    },
    {
      "displayPath" : "respect-server-shadow-1.0.0.zip",
      "fileName" : "respect-server-shadow-1.0.0.zip",
      "relativePath" : "respect-server/build/distributions/respect-server-shadow-1.0.0.zip"
    }
  ],
  "building" : False,
  "description" : None,
  "displayName" : "#239",
  "duration" : 133217,
  "estimatedDuration" : 153297,
  "executor" : None,
  "fullDisplayName" : "RESPECT-Primary #239",
  "id" : "239",
  "inProgress" : False,
  "keepLog" : False,
  "number" : 239,
  "queueId" : 5066,
  "result" : "SUCCESS",
  "timestamp" : 1767618660164,
  "url" : "https://devserver3.ustadmobile.com/jenkins/view/all/job/RESPECT-Primary/239/",
  "builtOn" : "",
  "changeSet" : {
    "_class" : "hudson.plugins.git.GitChangeSetList",
    "items" : [
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer/AGENTS.md",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ext/PersonExt.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/assignment/list/AssignmentListViewModel.kt",
          "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/assignment/detail/AssignmentDetailScreen.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/apps/detail/AppsDetailViewModel.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/exceptions/UnauthorizedException.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/SchoolPermissionGrantDataSourceLocal.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/detail/PersonDetailViewModel.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/list/PersonListViewModel.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/SchoolPermissionGrantEntity.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/apps/launcher/AppLauncherViewModel.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/GetAuthenticatedPersonUseCase.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/util/ext/PersonExt.kt",
          "respect-datalayer/build.gradle.kts",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/exceptions/ForbiddenException.kt",
          "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/manageuser/accountlist/AccountListItem.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/RespectSchoolDatabase.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/adapters/SchoolPermissionGrantAdapter.kt",
          "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/clazz/detail/ClazzDetailScreen.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/SchoolPermissionGrantDao.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PermissionFlags.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/AssignmentDatasourceDb.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/LocalModelDataSource.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/ext/PersonExt.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLoadState.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/SchoolPermissionGrantDataSource.kt",
          "respect-datalayer-db/AGENTS.md",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/SchoolPermissionGrantDataSourceDb.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/changepassword/ChangePasswordViewModel.kt",
          "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/8.json",
          "respect-app-compose/src/commonMain/kotlin/world/respect/app/app/AppBar.kt",
          "AGENTS.md",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/detail/ClazzDetailViewModel.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/SchoolPermissionGrant.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/assignment/detail/AssignmentDetailViewModel.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
        ],
        "commitId" : "fb4cdd11f1d6441233f2531f788c52eb88a3e0b1",
        "timestamp" : 1761142573000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Add permission management: work in progress.\u000a",
        "date" : "2025-10-22 18:16:13 +0400",
        "id" : "fb4cdd11f1d6441233f2531f788c52eb88a3e0b1",
        "msg" : "Add permission management: work in progress.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/AGENTS.md"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/SchoolPermissionGrantEntity.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/ext/PersonExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/detail/PersonDetailViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/assignment/detail/AssignmentDetailViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/RespectSchoolDatabase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/apps/launcher/AppLauncherViewModel.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/SchoolPermissionGrantDataSource.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/AGENTS.md"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/exceptions/ForbiddenException.kt"
          },
          {
            "editType" : "delete",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/util/ext/PersonExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/changepassword/ChangePasswordViewModel.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/8.json"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/SchoolPermissionGrantDataSourceDb.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PermissionFlags.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/manageuser/accountlist/AccountListItem.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/SchoolPermissionGrantDao.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/adapters/SchoolPermissionGrantAdapter.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/clazz/detail/ClazzDetailScreen.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/GetAuthenticatedPersonUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/AssignmentDatasourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLoadState.kt"
          },
          {
            "editType" : "add",
            "file" : "AGENTS.md"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/build.gradle.kts"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/SchoolPermissionGrantDataSourceLocal.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/assignment/list/AssignmentListViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/list/PersonListViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/apps/detail/AppsDetailViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/detail/ClazzDetailViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/commonMain/kotlin/world/respect/app/app/AppBar.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/assignment/detail/AssignmentDetailScreen.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/exceptions/UnauthorizedException.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/LocalModelDataSource.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/SchoolPermissionGrant.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ext/PersonExt.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer/AGENTS.md",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/writequeue/DrainRemoteWriteQueueUseCase.kt",
          "respect-datalayer-http/src/commonMain/kotlin/world/respect/datalayer/http/school/SchoolPermissionGrantDataSourceHttp.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/SchoolPermissionGrantDataSource.kt",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/SchoolPermissionGrantDataSourceRepository.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/SchoolDataSourceDb.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/SchoolPermissionGrantDataSourceDb.kt",
          "respect-datalayer-http/AGENTS.md",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/SchoolDataSourceRepository.kt",
          "respect-datalayer-http/src/commonMain/kotlin/world/respect/datalayer/http/SchoolDataSourceHttp.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/SchoolDataSourceLocal.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/writequeue/WriteQueueItem.kt",
          "respect-datalayer-repository/AGENTS.md",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/SchoolDataSource.kt"
        ],
        "commitId" : "d63a784ce84ad38f86491b031d6bad9bdf187dd5",
        "timestamp" : 1761204786000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Add SchoolPermissionGrantDataSource implementations.\u000a",
        "date" : "2025-10-23 11:33:06 +0400",
        "id" : "d63a784ce84ad38f86491b031d6bad9bdf187dd5",
        "msg" : "Add SchoolPermissionGrantDataSource implementations.",
        "paths" : [
          {
            "editType" : "add",
            "file" : "respect-datalayer-repository/AGENTS.md"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/SchoolDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/AGENTS.md"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/SchoolPermissionGrantDataSourceRepository.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/SchoolDataSourceLocal.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/SchoolPermissionGrantDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/writequeue/DrainRemoteWriteQueueUseCase.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-http/AGENTS.md"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/SchoolDataSourceRepository.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-http/src/commonMain/kotlin/world/respect/datalayer/http/school/SchoolPermissionGrantDataSourceHttp.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/SchoolPermissionGrantDataSource.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/writequeue/WriteQueueItem.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-http/src/commonMain/kotlin/world/respect/datalayer/http/SchoolDataSourceHttp.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/SchoolDataSource.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-server/src/main/kotlin/world/respect/server/Application.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/ext/PersonExt.kt",
          "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/domain/TestCheckPersonPermissionUseCaseImpl.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/SchoolDataSourceDb.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/detail/PersonDetailViewModel.kt",
          "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/TestSchoolDb.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/domain/account/RespectAccountManager.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/ext/PersonRoleEnumExt.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/domain/CheckPersonPermissionUseCase.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/domain/AddDefaultSchoolPermissionGrantsUseCase.kt",
          "respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/SchoolPermissionGrant.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt",
          "respect-server/src/main/kotlin/world/respect/server/domain/school/add/AddSchoolUseCase.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/domain/CheckPersonPermissionUseCaseDbImpl.kt",
          "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/TestPersonStorage.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/SchoolPermissionGrantDao.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PermissionFlags.kt",
          "respect-server/src/main/kotlin/world/respect/server/routes/school/respect/SchoolPermissionGrantRoute.kt"
        ],
        "commitId" : "d087ad04fa1983803a659a5cee2339fce1be58e5",
        "timestamp" : 1761227669000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Initial implementation of using CheckPersonPermissionUseCase\u000a",
        "date" : "2025-10-23 17:54:29 +0400",
        "id" : "d087ad04fa1983803a659a5cee2339fce1be58e5",
        "msg" : "Initial implementation of using CheckPersonPermissionUseCase",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/TestPersonStorage.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/SchoolPermissionGrant.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/domain/AddDefaultSchoolPermissionGrantsUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/Application.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/ext/PersonRoleEnumExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/ext/PersonExt.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-server/src/main/kotlin/world/respect/server/routes/school/respect/SchoolPermissionGrantRoute.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/SchoolPermissionGrantDao.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/domain/CheckPersonPermissionUseCase.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/TestSchoolDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/domain/account/RespectAccountManager.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PermissionFlags.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/domain/school/add/AddSchoolUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/SchoolDataSourceDb.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/domain/CheckPersonPermissionUseCaseDbImpl.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/domain/TestCheckPersonPermissionUseCaseImpl.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/detail/PersonDetailViewModel.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-repository/src/jvmTest/kotlin/world/respect/datalayer/repository/school/PersonRepositoryIntegrationTest.kt",
          "respect-lib-test/src/jvmMain/kotlin/world/respect/lib/test/clientservertest/ClientServerDatasourceTest.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
        ],
        "commitId" : "ae01d219481d0814d5c5e323cee98ad0aea3e4ab",
        "timestamp" : 1761230727000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Fixes for PersonRepositoryIntegrationTest.kt (one test remaining)\u000a",
        "date" : "2025-10-23 18:45:27 +0400",
        "id" : "ae01d219481d0814d5c5e323cee98ad0aea3e4ab",
        "msg" : "Fixes for PersonRepositoryIntegrationTest.kt (one test remaining)",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-lib-test/src/jvmMain/kotlin/world/respect/lib/test/clientservertest/ClientServerDatasourceTest.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/jvmTest/kotlin/world/respect/datalayer/repository/school/PersonRepositoryIntegrationTest.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-repository/src/jvmTest/kotlin/world/respect/datalayer/repository/school/PersonRepositoryIntegrationTest.kt",
          "respect-server/src/main/kotlin/world/respect/server/util/ext/ApplicationCallExt.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PersonRoleEnum.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt",
          "respect-lib-test/src/jvmMain/kotlin/world/respect/lib/test/clientservertest/ClientServerDatasourceTest.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/paging/MapPagingSource.kt",
          "respect-server/src/main/kotlin/world/respect/server/domain/school/add/AddSchoolUseCase.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/paging/PermissionCheckPagingSource.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PermissionFlags.kt"
        ],
        "commitId" : "6869dd8e50b4394a92548905d11560e18966dafc",
        "timestamp" : 1762179475000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Permission enforcement work in progress\u000a\u000aa) throw ForbiddenException / return status code 403 if a request for a person is made that the user is not authorized to see. Marking the response as forbidden, rather than returning an empty json allows fail2ban/throttling implementation when someone is up to no good.\u000ab) Fix usage of add default grants in add school use case.\u000a",
        "date" : "2025-11-03 18:17:55 +0400",
        "id" : "6869dd8e50b4394a92548905d11560e18966dafc",
        "msg" : "Permission enforcement work in progress",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/jvmTest/kotlin/world/respect/datalayer/repository/school/PersonRepositoryIntegrationTest.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PermissionFlags.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/paging/PermissionCheckPagingSource.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/util/ext/ApplicationCallExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/paging/MapPagingSource.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PersonRoleEnum.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/domain/school/add/AddSchoolUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-test/src/jvmMain/kotlin/world/respect/lib/test/clientservertest/ClientServerDatasourceTest.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/8.json",
          "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/person/edit/PersonEditScreen.kt",
          "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/enrollment/list/EnrollmentListScreen.kt",
          "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/person/detail/PersonDetailScreen.kt",
          "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/domain/TestCheckPersonPermissionUseCaseImpl.kt",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/SchoolPermissionGrantDataSourceRepository.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/detail/PersonDetailViewModel.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/paging/PermissionCheckPagingSource.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/list/PersonListViewModel.kt"
        ],
        "commitId" : "bc306635b7538babc81b849bbdf473d47a802f9b",
        "timestamp" : 1764246578000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Fix compilation after merging main updates.\u000a",
        "date" : "2025-11-27 16:29:38 +0400",
        "id" : "bc306635b7538babc81b849bbdf473d47a802f9b",
        "msg" : "Fix compilation after merging main updates.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/domain/TestCheckPersonPermissionUseCaseImpl.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/enrollment/list/EnrollmentListScreen.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/person/detail/PersonDetailScreen.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/SchoolPermissionGrantDataSourceRepository.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/8.json"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/paging/PermissionCheckPagingSource.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/person/edit/PersonEditScreen.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/detail/PersonDetailViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/list/PersonListViewModel.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/Clazz.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/adapters/ClassAdapter.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/ClassEntityWithPermissions.kt",
          "respect-lib-shared/src/jvmMain/kotlin/world/respect/shared/domain/account/invite/RedeemInviteUseCaseDb.kt",
          "respect-server/src/main/kotlin/world/respect/server/account/invite/GetInviteInfoUseCaseServer.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/ClassPermissionEntity.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassPermissionEntityDao.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassEntityDao.kt",
          "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/9.json",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/RespectSchoolDatabase.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/ClassPermission.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
        ],
        "commitId" : "a15f134552b8149b5d6d43b156454a15d6f1351f",
        "timestamp" : 1764942544000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Add CLassPermission to model and datasources.\u000a",
        "date" : "2025-12-05 17:49:04 +0400",
        "id" : "a15f134552b8149b5d6d43b156454a15d6f1351f",
        "msg" : "Add CLassPermission to model and datasources.",
        "paths" : [
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/ClassPermission.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/account/invite/GetInviteInfoUseCaseServer.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/ClassPermissionEntity.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/jvmMain/kotlin/world/respect/shared/domain/account/invite/RedeemInviteUseCaseDb.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassPermissionEntityDao.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/ClassEntityWithPermissions.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/9.json"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/RespectSchoolDatabase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/Clazz.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/adapters/ClassAdapter.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassEntityDao.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/domain/account/RespectAccountManager.kt"
        ],
        "commitId" : "cc7ef41804c7789e5490b90873e49f2a85046e40",
        "timestamp" : 1765197753000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Update RespectAccountManager to use a shared hot flow to prevent lag.\u000a",
        "date" : "2025-12-08 16:42:33 +0400",
        "id" : "cc7ef41804c7789e5490b90873e49f2a85046e40",
        "msg" : "Update RespectAccountManager to use a shared hot flow to prevent lag.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/domain/account/RespectAccountManager.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/domain/AddDefaultSchoolPermissionGrantsUseCase.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassEntityDao.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/SchoolPermissionGrantDao.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PermissionFlags.kt",
          "respect-server/src/main/kotlin/world/respect/server/account/invite/GetInviteInfoUseCaseServer.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
        ],
        "commitId" : "1834bca60da831c327c95e30c4eba74544daf259",
        "timestamp" : 1765203505000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Enforce class view permissions including support for enrollment role-based permissions.\u000a",
        "date" : "2025-12-08 18:18:25 +0400",
        "id" : "1834bca60da831c327c95e30c4eba74544daf259",
        "msg" : "Enforce class view permissions including support for enrollment role-based permissions.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PermissionFlags.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/domain/AddDefaultSchoolPermissionGrantsUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/SchoolPermissionGrantDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/account/invite/GetInviteInfoUseCaseServer.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/LastModifiedAndPermission.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassEntityDao.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/WritableDataSource.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
        ],
        "commitId" : "c2aadbfda36308b406464f90d050fa95e775c294",
        "timestamp" : 1765460539000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Enforce class write permission.\u000a",
        "date" : "2025-12-11 17:42:19 +0400",
        "id" : "c2aadbfda36308b406464f90d050fa95e775c294",
        "msg" : "Enforce class write permission.",
        "paths" : [
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/LastModifiedAndPermission.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/WritableDataSource.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt"
        ],
        "commitId" : "ab1f830df858d5a9367b4500fdb738adcc22d711",
        "timestamp" : 1765461416000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Merge session changes from main.\u000a",
        "date" : "2025-12-11 17:56:56 +0400",
        "id" : "ab1f830df858d5a9367b4500fdb738adcc22d711",
        "msg" : "Merge session changes from main.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
        ],
        "commitId" : "517121263286883aee09ecd77b95e570980cc5fb",
        "timestamp" : 1765727646000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Initial implementation of read person permission checks.\u000a",
        "date" : "2025-12-14 15:54:06 +0000",
        "id" : "517121263286883aee09ecd77b95e570980cc5fb",
        "msg" : "Initial implementation of read person permission checks.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-repository/src/jvmTest/kotlin/world/respect/datalayer/repository/school/PersonRepositoryIntegrationTest.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
        ],
        "commitId" : "87132ca9c0b370017c9c8fea4ce97753b477161c",
        "timestamp" : 1765739839000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Handle permissions for parents based on class permissions of children.\u000a",
        "date" : "2025-12-14 19:17:19 +0000",
        "id" : "87132ca9c0b370017c9c8fea4ce97753b477161c",
        "msg" : "Handle permissions for parents based on class permissions of children.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/jvmTest/kotlin/world/respect/datalayer/repository/school/PersonRepositoryIntegrationTest.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/EnrollmentRoleEnum.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassEntityDao.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/EnrollmentDataSourceDb.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PermissionFlags.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/LastModifiedAndPermission.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/EnrollmentEntityDao.kt"
        ],
        "commitId" : "e49f7dd1f03c83732a47062c9b31bc4c18837b2e",
        "timestamp" : 1765884380000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Add permission enforcement/checks to enrollment entities.\u000a",
        "date" : "2025-12-16 15:26:20 +0400",
        "id" : "e49f7dd1f03c83732a47062c9b31bc4c18837b2e",
        "msg" : "Add permission enforcement/checks to enrollment entities.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/LastModifiedAndPermission.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PermissionFlags.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/EnrollmentEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/EnrollmentRoleEnum.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/EnrollmentDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassEntityDao.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/ClassPermissionEntity.kt",
          "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/9.json",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/EnrollmentEntityDao.kt"
        ],
        "commitId" : "0e6dd7db5e356d4ee99e8669bc7809eef38ba359",
        "timestamp" : 1765975040000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Fix ClassPermissionEntity to use autoincrement primary key\u000aUpdate PersonDataSource permission checks to add a CTE to get the permission personuid list (active user plus any children personuids in the case of a parent user).\u000a",
        "date" : "2025-12-17 16:37:20 +0400",
        "id" : "0e6dd7db5e356d4ee99e8669bc7809eef38ba359",
        "msg" : "Fix ClassPermissionEntity to use autoincrement primary key",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/EnrollmentEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/ClassPermissionEntity.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/9.json"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/domain/CheckPersonPermissionUseCase.kt",
          "respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/detail/PersonDetailViewModel.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/SchoolDataSourceDb.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/domain/CheckPersonPermissionUseCaseDbImpl.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
        ],
        "commitId" : "8e1628f9325ca674d471b5c23fcc5391ba7f15cb",
        "timestamp" : 1766060857000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Update CheckPersonPermissionUseCase: can be used before person is saved to db or after saved to db without needing to lookup role.\u000a",
        "date" : "2025-12-18 16:27:37 +0400",
        "id" : "8e1628f9325ca674d471b5c23fcc5391ba7f15cb",
        "msg" : "Update CheckPersonPermissionUseCase: can be used before person is saved to db or after saved to db without needing to lookup role.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/domain/CheckPersonPermissionUseCaseDbImpl.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/detail/PersonDetailViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/domain/CheckPersonPermissionUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/SchoolDataSourceDb.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/detail/PersonDetailViewModel.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
        ],
        "commitId" : "2ae2abfd160d041c9ab2d362775b8e0043f90180",
        "timestamp" : 1766066355000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Fix person entity list permission check to include viewing related persons for the authenticated user.\u000a",
        "date" : "2025-12-18 17:59:15 +0400",
        "id" : "2ae2abfd160d041c9ab2d362775b8e0043f90180",
        "msg" : "Fix person entity list permission check to include viewing related persons for the authenticated user.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/detail/PersonDetailViewModel.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/LocalModelDataSource.kt",
          "respect-server/src/main/kotlin/world/respect/server/ServerKoinModule.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/SchoolDataSourceDb.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonPasswordEntityDao.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonPasswordDataSourceDb.kt"
        ],
        "commitId" : "63f5ea635a01235f174d8e760dcadc8c30425589",
        "timestamp" : 1766144945000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Update SQL to enforce password entity permissions\u000a",
        "date" : "2025-12-19 15:49:05 +0400",
        "id" : "63f5ea635a01235f174d8e760dcadc8c30425589",
        "msg" : "Update SQL to enforce password entity permissions",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonPasswordEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/ServerKoinModule.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/LocalModelDataSource.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/SchoolDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonPasswordDataSourceDb.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/opds/daos/PersonPasskeyEntityDao.kt"
        ],
        "commitId" : "a2a843193719003af2e543ad2c191dda17806def",
        "timestamp" : 1766145521000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Remove unused PersonPasskeyEntityDao functions.\u000a",
        "date" : "2025-12-19 15:58:41 +0400",
        "id" : "a2a843193719003af2e543ad2c191dda17806def",
        "msg" : "Remove unused PersonPasskeyEntityDao functions.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/opds/daos/PersonPasskeyEntityDao.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonPasskeyDataSourceDb.kt"
        ],
        "commitId" : "f024121520d5998e74f73092cca2d9064ac1fbf6",
        "timestamp" : 1766146428000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Update PersonDataSourceDb to follow same function name pattern as other DAOs and split store/updateLocal\u000a",
        "date" : "2025-12-19 16:13:48 +0400",
        "id" : "f024121520d5998e74f73092cca2d9064ac1fbf6",
        "msg" : "Update PersonDataSourceDb to follow same function name pattern as other DAOs and split store/updateLocal",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonPasskeyDataSourceDb.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassEntityDao.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
        ],
        "commitId" : "b5d3d5ccb23cd53f30c116ce775afb033c33b034",
        "timestamp" : 1766396276000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Update class permission queries to include permissions for parents to see child's classes.\u000aUpdate use of select AuthenticatedPermissionPersonUids to use constant.\u000a",
        "date" : "2025-12-22 13:37:56 +0400",
        "id" : "b5d3d5ccb23cd53f30c116ce775afb033c33b034",
        "msg" : "Update class permission queries to include permissions for parents to see child's classes.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/ClassEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/ext/SchoolPermissionGrantExt.kt",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/SchoolPermissionGrantDataSourceRepository.kt",
          "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/domain/TestCheckPersonPermissionUseCaseImpl.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/SchoolDataSourceDb.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/list/PersonListViewModel.kt",
          "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/TestSchoolDb.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/SchoolPermissionGrantDataSourceDb.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/domain/CheckPersonPermissionUseCase.kt",
          "respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt",
          "respect-lib-test/src/jvmMain/kotlin/world/respect/lib/test/clientservertest/ClientServerDatasourceTest.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/SchoolPermissionGrantDao.kt",
          "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/TestPersonStorage.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/domain/permissions/CheckSchoolPermissionsUseCase.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
        ],
        "commitId" : "417df627dae1a87979c76f7cf53bdf84c2b70d29",
        "timestamp" : 1766408696000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Add CheckSchoolPermissionsUseCase and use it in PersonList and ClassList to control the visibility of add button.\u000aUpdate junit tests to handle permissions\u000a",
        "date" : "2025-12-22 17:04:56 +0400",
        "id" : "417df627dae1a87979c76f7cf53bdf84c2b70d29",
        "msg" : "Add CheckSchoolPermissionsUseCase and use it in PersonList and ClassList to control the visibility of add button.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/SchoolPermissionGrantDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/ClassDatasourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/SchoolDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/domain/CheckPersonPermissionUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/SchoolPermissionGrantDataSourceRepository.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-test/src/jvmMain/kotlin/world/respect/lib/test/clientservertest/ClientServerDatasourceTest.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/domain/TestCheckPersonPermissionUseCaseImpl.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/person/list/PersonListViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/TestPersonStorage.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/TestSchoolDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/SchoolPermissionGrantDataSourceDb.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/ext/SchoolPermissionGrantExt.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/domain/permissions/CheckSchoolPermissionsUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-server/src/main/kotlin/world/respect/server/util/ext/ApplicationCallExt.kt",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/EnrollmentDataSourceRepository.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/networkvalidation/entities/NetworkValidationInfoEntity.kt",
          "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/RepoWorkerConstants.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/HttpHeadersExt.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/EnrollmentEntityDao.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/writequeue/EnqueueRunPullSyncUseCase.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/PullSyncStatusEntity.kt",
          "respect-datalayer-repository/src/jvmTest/kotlin/world/respect/datalayer/repository/school/PersonRepositoryIntegrationTest.kt",
          "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/pullsync/EnqueueRunPullSyncUseCaseAndroidImpl.kt",
          "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/pullsync/RunPullSyncWorker.kt",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/PersonDataSourceRepository.kt",
          "respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/networkvalidation/NetworkValidationInfo.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/RespectSchoolDatabase.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PullSyncStatus.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/adapters/PullSyncStatusAdapter.kt",
          "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/TestPersonStorage.kt",
          "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectAppDatabase/2.json",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/PullSyncTracker.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt",
          "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/writequeue/EnqueueDrainRemoteWriteQueueUseCaseAndroidImpl.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLoadMetaInfo.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/EnrollmentDataSourceDb.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PullSyncStatusEntityDao.kt",
          "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/writequeue/DrainRemoteWriteQueueWorker.kt",
          "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/worker/WorkerExt.kt",
          "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/worker/DataBuilderExt.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/HttpClientExt.kt",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/pullsync/RunPullSyncUseCase.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/DataLoadStateExt.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt",
          "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/10.json",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/writequeue/EnqueueDrainRemoteWriteQueueUseCase.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/shared/PullSyncTrackerDbImpl.kt"
        ],
        "commitId" : "e08156910ebb699221cc9ebc660c9c728879bb6d",
        "timestamp" : 1767018672000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Implement pulling enrollment entities using a worker.\u000a\u000aRequired to ensure permissions are resolved as expected.\u000a",
        "date" : "2025-12-29 18:31:12 +0400",
        "id" : "e08156910ebb699221cc9ebc660c9c728879bb6d",
        "msg" : "Implement pulling enrollment entities using a worker.",
        "paths" : [
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PullSyncStatusEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/HttpHeadersExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/DataLoadStateExt.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/pullsync/RunPullSyncUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/HttpClientExt.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/pullsync/EnqueueRunPullSyncUseCaseAndroidImpl.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/util/ext/ApplicationCallExt.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/writequeue/EnqueueRunPullSyncUseCase.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/worker/WorkerExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/PullSyncTracker.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/jvmTest/kotlin/world/respect/datalayer/db/school/TestPersonStorage.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/10.json"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/RepoWorkerConstants.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/pullsync/RunPullSyncWorker.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/EnrollmentDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/PersonDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/RespectSchoolDatabase.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/adapters/PullSyncStatusAdapter.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/writequeue/DrainRemoteWriteQueueWorker.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/EnrollmentDataSourceRepository.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/writequeue/EnqueueDrainRemoteWriteQueueUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/networkvalidation/entities/NetworkValidationInfoEntity.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/writequeue/EnqueueDrainRemoteWriteQueueUseCaseAndroidImpl.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectAppDatabase/2.json"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/PullSyncStatusEntity.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PullSyncStatus.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/PersonDataSourceRepository.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLoadMetaInfo.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/EnrollmentEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/jvmTest/kotlin/world/respect/datalayer/repository/school/PersonRepositoryIntegrationTest.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/networkvalidation/NetworkValidationInfo.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-repository/src/androidMain/kotlin/world/respect/datalayer/repository/school/worker/DataBuilderExt.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/shared/PullSyncTrackerDbImpl.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-server/src/main/kotlin/world/respect/server/util/ext/ApplicationCallExt.kt",
          "respect-server/src/main/kotlin/world/respect/server/ServerKoinModule.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/HttpHeadersExt.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/domain/GetPermissionLastModifiedUseCase.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/domain/GetPermissionLastModifiedUseCaseDbImpl.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/EnrollmentEntityDao.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/params/GetListCommonParams.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/PullSyncStatusEntity.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/pullsync/PullSyncTracker.kt",
          "respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PullSyncStatus.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/adapters/PullSyncStatusAdapter.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLayerParams.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/PullSyncTracker.kt",
          "respect-datalayer-http/src/commonMain/kotlin/world/respect/datalayer/http/ext/ParametersBuilderExt.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLoadMetaInfo.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/params/OrderOption.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/EnrollmentDataSourceDb.kt",
          "respect-server/src/main/kotlin/world/respect/server/routes/school/respect/EnrollmentRoute.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/HttpClientExt.kt",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/pullsync/RunPullSyncUseCase.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/EnrollmentDataSource.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLayerHeaders.kt",
          "respect-datalayer-http/src/commonMain/kotlin/world/respect/datalayer/http/school/EnrollmentDataSourceHttp.kt",
          "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/10.json",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/shared/PullSyncTrackerDbImpl.kt"
        ],
        "commitId" : "75fc244fba28cda004d8274bd698f53cf9761e31",
        "timestamp" : 1767114370000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Add sinceIfPermissionsNotChangedSince parameter support.\u000a\u000aUsed to ensure that when permissions change (eg. as a result of a person joining a class) that the user does not miss out on updates being retrieved via pull sync runs.\u000a",
        "date" : "2025-12-30 21:06:10 +0400",
        "id" : "75fc244fba28cda004d8274bd698f53cf9761e31",
        "msg" : "Add sinceIfPermissionsNotChangedSince parameter support.",
        "paths" : [
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/domain/GetPermissionLastModifiedUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/pullsync/RunPullSyncUseCase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/util/ext/ApplicationCallExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLayerParams.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLoadMetaInfo.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/EnrollmentDataSource.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/params/OrderOption.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/10.json"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/pullsync/PullSyncTracker.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/adapters/PullSyncStatusAdapter.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/params/GetListCommonParams.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/EnrollmentDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/routes/school/respect/EnrollmentRoute.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/PersonEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/HttpClientExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/HttpHeadersExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/shared/PullSyncTrackerDbImpl.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/PullSyncStatusEntity.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-http/src/commonMain/kotlin/world/respect/datalayer/http/school/EnrollmentDataSourceHttp.kt"
          },
          {
            "editType" : "delete",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/PullSyncTracker.kt"
          },
          {
            "editType" : "add",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/domain/GetPermissionLastModifiedUseCaseDbImpl.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-http/src/commonMain/kotlin/world/respect/datalayer/http/ext/ParametersBuilderExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/EnrollmentEntityDao.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/PullSyncStatus.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLayerHeaders.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-server/src/main/kotlin/world/respect/server/ServerKoinModule.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/AssignmentAssigneeRefEntityDao.kt",
          "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/assignment/detail/AssignmentDetailScreen.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/Assignment.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/assignment/edit/AssignmentEditViewModel.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/RespectSchoolDatabase.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/assignment/detail/AssignmentDetailViewModel.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/AssignmentEntity.kt",
          "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/10.json",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/adapters/AssignmentAdapter.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/AssignmentDatasourceDb.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/AssignmentAssigneeRef.kt"
        ],
        "commitId" : "bddb16ab6a058c879b320758a100a856d8296176",
        "timestamp" : 1767197488000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Refactor assignment to link one assignment to one class.\u000a",
        "date" : "2025-12-31 20:11:28 +0400",
        "id" : "bddb16ab6a058c879b320758a100a856d8296176",
        "msg" : "Refactor assignment to link one assignment to one class.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-app-compose/src/commonMain/kotlin/world/respect/app/view/assignment/detail/AssignmentDetailScreen.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/assignment/detail/AssignmentDetailViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/assignment/edit/AssignmentEditViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/schemas/world.respect.datalayer.db.RespectSchoolDatabase/10.json"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/adapters/AssignmentAdapter.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/AssignmentEntity.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/AssignmentDatasourceDb.kt"
          },
          {
            "editType" : "delete",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/AssignmentAssigneeRefEntityDao.kt"
          },
          {
            "editType" : "delete",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/AssignmentAssigneeRef.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/RespectSchoolDatabase.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/Assignment.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/AssignmentEntityDao.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/AssignmentDatasourceDb.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/AssignmentAssigneeRefEntity.kt"
        ],
        "commitId" : "729a6eaf049d5d8ef25eb567613d23b4ee963184",
        "timestamp" : 1767200016000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Initial permission check for assignment read.\u000a",
        "date" : "2025-12-31 20:53:36 +0400",
        "id" : "729a6eaf049d5d8ef25eb567613d23b4ee963184",
        "msg" : "Initial permission check for assignment read.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/AssignmentDatasourceDb.kt"
          },
          {
            "editType" : "delete",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/entities/AssignmentAssigneeRefEntity.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/daos/AssignmentEntityDao.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/LocalModelDataSource.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/paging/CacheableHttpPagingSource.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLoadState.kt",
          "respect-lib-shared/src/jvmMain/kotlin/world/respect/shared/domain/account/invite/RedeemInviteUseCaseDb.kt",
          "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/EnrollmentDataSourceDb.kt",
          "respect-datalayer-http/src/commonMain/kotlin/world/respect/datalayer/http/shared/paging/OffsetLimitHttpPagingSource.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/HttpClientExt.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/EnrollmentRoleEnum.kt",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/pullsync/RunPullSyncUseCase.kt",
          "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/DataLoadStateExt.kt",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/PersonDataSourceRepository.kt",
          ".maestro/flows/001_001_invite_using_invite_code_test.yaml",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/detail/ClazzDetailViewModel.kt",
          "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/SchoolDataSourceRepository.kt"
        ],
        "commitId" : "9036fcffa2b121cab5d6ba66660b96661e8785ce",
        "timestamp" : 1767544118000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Run pull sync fixes:\u000a\u000aa) Handle not-modified http response status\u000ab) Ensure not-modified http dataloadstate preserves metadata\u000ac) Update ClazzViewModel to use only enqueue run pull sync to update enrollments.\u000a",
        "date" : "2026-01-04 20:28:38 +0400",
        "id" : "9036fcffa2b121cab5d6ba66660b96661e8785ce",
        "msg" : "Run pull sync fixes:",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/DataLoadStateExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-http/src/commonMain/kotlin/world/respect/datalayer/http/shared/paging/OffsetLimitHttpPagingSource.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/list/ClazzListViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/SchoolDataSourceRepository.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/paging/CacheableHttpPagingSource.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/PersonDataSourceRepository.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/ext/HttpClientExt.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/DataLoadState.kt"
          },
          {
            "editType" : "edit",
            "file" : ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/shared/LocalModelDataSource.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer/src/commonMain/kotlin/world/respect/datalayer/school/model/EnrollmentRoleEnum.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/jvmMain/kotlin/world/respect/shared/domain/account/invite/RedeemInviteUseCaseDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-db/src/commonMain/kotlin/world/respect/datalayer/db/school/EnrollmentDataSourceDb.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/clazz/detail/ClazzDetailViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-datalayer-repository/src/commonMain/kotlin/world/respect/datalayer/repository/school/pullsync/RunPullSyncUseCase.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/manageuser/profile/SignupViewModel.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/domain/account/child/AddChildAccountUseCaseDataSource.kt"
        ],
        "commitId" : "b7e0f98a0418c132f169f6e245a7ecc96de2ec31",
        "timestamp" : 1767545996000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Update SignupViewModel: remove unnecessary scope.launc that should not be there.\u000a",
        "date" : "2026-01-04 20:59:56 +0400",
        "id" : "b7e0f98a0418c132f169f6e245a7ecc96de2ec31",
        "msg" : "Update SignupViewModel: remove unnecessary scope.launc that should not be there.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/manageuser/profile/SignupViewModel.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/domain/account/child/AddChildAccountUseCaseDataSource.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/manageuser/profile/SignupViewModel.kt"
        ],
        "commitId" : "67c2d84be6085b3af5016c63ef358f741bc375f4",
        "timestamp" : 1767547604000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Add debugging logs to SignupViewModel.\u000aRemove signupviewmodel async launch functions setting app uistate that was not necessary.\u000a",
        "date" : "2026-01-04 21:26:44 +0400",
        "id" : "67c2d84be6085b3af5016c63ef358f741bc375f4",
        "msg" : "Add debugging logs to SignupViewModel.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/manageuser/profile/SignupViewModel.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/navigation/AppRoutes.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/manageuser/profile/SignupViewModel.kt",
          "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/manageuser/profile/ProfileType.kt"
        ],
        "commitId" : "fdb330302942df56686f26d34554ec40158a02dd",
        "timestamp" : 1767550670000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Add more debugging logs to SignupViewModel.\u000aFix ProfileType enum to use serialization as per pattern (using a string constant) to avoid potential discrepency between minified and non minified versions.\u000a",
        "date" : "2026-01-04 22:17:50 +0400",
        "id" : "fdb330302942df56686f26d34554ec40158a02dd",
        "msg" : "Add more debugging logs to SignupViewModel.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/navigation/AppRoutes.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/manageuser/profile/ProfileType.kt"
          },
          {
            "editType" : "edit",
            "file" : "respect-lib-shared/src/commonMain/kotlin/world/respect/shared/viewmodel/manageuser/profile/SignupViewModel.kt"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          ".maestro/flows/000_000_hello_world.yaml",
          ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
        ],
        "commitId" : "b7676667f0a9cf5bd27160cfb25a08e236734121",
        "timestamp" : 1767552139000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Remove hello world maestro flow\u000aTweak 001_001 to try and avoid maestro flakey tap\u000a",
        "date" : "2026-01-04 22:42:19 +0400",
        "id" : "b7676667f0a9cf5bd27160cfb25a08e236734121",
        "msg" : "Remove hello world maestro flow",
        "paths" : [
          {
            "editType" : "edit",
            "file" : ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
          },
          {
            "editType" : "delete",
            "file" : ".maestro/flows/000_000_hello_world.yaml"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
        ],
        "commitId" : "1984e6061772b1f7ee97c21753e3852c7b84b8e4",
        "timestamp" : 1767552389000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Add retryTapIfNoChange to 001_001.\u000a",
        "date" : "2026-01-04 22:46:29 +0400",
        "id" : "1984e6061772b1f7ee97c21753e3852c7b84b8e4",
        "msg" : "Add retryTapIfNoChange to 001_001.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
        ],
        "commitId" : "e0d6182b066450057da81bbd834f21746f729626",
        "timestamp" : 1767553784000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Remove action bar id parameter from 001_001\u000a",
        "date" : "2026-01-04 23:09:44 +0400",
        "id" : "e0d6182b066450057da81bbd834f21746f729626",
        "msg" : "Remove action bar id parameter from 001_001",
        "paths" : [
          {
            "editType" : "edit",
            "file" : ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          ".maestro/flows/subflows/tap_done_again.yaml",
          ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
        ],
        "commitId" : "45071e76474e3dccbea467bb5da8fb19db44369f",
        "timestamp" : 1767555668000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Add repeat loop workaround for waiting Maestro cloud error.\u000a",
        "date" : "2026-01-04 23:41:08 +0400",
        "id" : "45071e76474e3dccbea467bb5da8fb19db44369f",
        "msg" : "Add repeat loop workaround for waiting Maestro cloud error.",
        "paths" : [
          {
            "editType" : "add",
            "file" : ".maestro/flows/subflows/tap_done_again.yaml"
          },
          {
            "editType" : "edit",
            "file" : ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
          }
        ]
      },
      {
        "_class" : "hudson.plugins.git.GitChangeSet",
        "affectedPaths" : [
          ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
        ],
        "commitId" : "73c7dc12bb5b15ea41adc790e939f933c63749de",
        "timestamp" : 1767556723000,
        "author" : {
          "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
          "fullName" : "Mike Dawson"
        },
        "authorEmail" : "mike@ustadmobile.com",
        "comment" : "Another attempt for 001_001 maestro workaround.\u000a",
        "date" : "2026-01-04 23:58:43 +0400",
        "id" : "73c7dc12bb5b15ea41adc790e939f933c63749de",
        "msg" : "Another attempt for 001_001 maestro workaround.",
        "paths" : [
          {
            "editType" : "edit",
            "file" : ".maestro/flows/001_001_invite_using_invite_code_test.yaml"
          }
        ]
      }
    ],
    "kind" : "git"
  },
  "culprits" : [
    {
      "absoluteUrl" : "https://devserver3.ustadmobile.com/jenkins/user/mike",
      "fullName" : "Mike Dawson"
    }
  ]
}