╭ changed ──╮ │src/try.zig│ ╰───────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │232 const users_dir = try std.fs.path.join(arena.allocator(), &.{ server_path, "users" }); │ │233 try evt.consume(.{ .server = .{ .users_dir = users_dir } }, .admin, .xit, evt.admin_repo_opts, io, allocator, &repo, evt.events_ref, &events_to_consume);│ │234 │ │235 - // admin co-owns every repo, so it has full privileges everywhere │ │236 - // (including undo) while the other users only own their own │ │237 - const admin_user_id_hex = std.fmt.bytesToHex(admin_user_id, .lower); │ │235 + // admin is granted ownership of every repo, so it has full privileges │ │236 + // everywhere (including undo) while the other users only own their own │ │237 var repo_events: [repo_data.len]evt.EventWithId = undefined; │ │238 + var grant_events: [repo_data.len]evt.EventWithId = undefined; │ │239 for (repo_data, 0..) |r, i| { │ │240 + const author: evt.CommitAuthor = .{ .name = user_data[r.user_index].name, .email = user_data[r.user_index].email }; │ │241 repo_events[i] = .{ │ │242 .id = std.fmt.bytesToHex(repo_event_ids[i], .lower), │ │243 .timestamp = @intCast(user_data.len + i + 1), │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │243 - .author = .{ .name = user_data[r.user_index].name, .email = user_data[r.user_index].email },│ │244 + .author = author, │ │245 .event = .{ │ │246 .repo = .{ │ │247 .user_id = &user_ids[r.user_index], │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │248 .name = r.name, │ │249 .description = r.description, │ │250 .read_access = r.read_access, │ │250 - .owner_user_ids = &admin_user_id_hex, │ │251 }, │ │252 }, │ │253 + }; │ │254 + grant_events[i] = .{ │ │255 + .id = std.fmt.bytesToHex(evt.Grant.idOf(&repo_event_ids[i], &admin_user_id), .lower), │ │256 + .timestamp = @intCast(user_data.len + i + 1), │ │257 + .author = author, │ │258 + .event = .{ .grant = .{ .target_id = &repo_event_ids[i], .user_id = &admin_user_id, .role = .owner } },│ │259 }; │ │260 } │ │261 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │256 - // each user's repo holds the repos they own │ │262 + // each user's repo holds the repos they own and the grants on them │ │263 for (user_ids, 0..) |user_id, user_index| { │ │264 const user_repo_path = try evt.userRepoPath(arena.allocator(), users_dir, &user_id);│ │265 var user_repo = try evt.initUserRepo(io, allocator, user_repo_path); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │266 defer user_repo.deinit(io, allocator); │ │267 var owned: std.ArrayList(evt.EventWithId) = .empty; │ │262 - for (repo_data, repo_events) |r, event| { │ │263 - if (r.user_index == user_index) try owned.append(arena.allocator(), event); │ │268 + for (repo_data, repo_events, grant_events) |r, repo_event, grant_event| { │ │269 + if (r.user_index != user_index) continue; │ │270 + try owned.append(arena.allocator(), repo_event); │ │271 + try owned.append(arena.allocator(), grant_event); │ │272 } │ │273 if (owned.items.len > 0) try evt.consume(.{ .server = .{ .users_dir = users_dir } }, .user, .xit, evt.user_repo_opts, io, allocator, &user_repo, evt.events_ref, owned.items);│ │274 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯