╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ───────────────╮ │src/test/event/admin.zig│ ╰────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │158 │ │159 const repo_cursor = try event_id_to_repo.getCursor(hash.hashInt(repo_opts.hash, &repo_event_id)) orelse return error.NotFound; │ │160 const repo_map = try Repo.DB.HashMap(.read_only).init(repo_cursor); │ │148 - const repo_event = try evt.read(evt.Repo.Record, Repo.DB, repo_opts.hash, &arena, repo_map); │ │149 - try std.testing.expect(repo_event.removed); │ │161 + const repo_record = try evt.read(evt.Repo.Record, Repo.DB, repo_opts.hash, &arena, repo_map); │ │162 + try std.testing.expect(repo_record.removed); │ │163 │ │164 // get the repos created by the user │ │152 - const user_id_to_repo_id_set_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "user-id->repo-id-set")) orelse return error.NotFound;│ │153 - const user_id_to_repo_id_set = try Repo.DB.HashMap(.read_only).init(user_id_to_repo_id_set_cursor); │ │154 - │ │155 - const user_repos_cursor = try user_id_to_repo_id_set.getCursor(hash.hashInt(repo_opts.hash, &user_event_id)) orelse return error.NotFound; │ │165 + const user_repos_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, evt.Repo.active_id_set_key)) orelse return error.NotFound; │ │166 const user_repos = try Repo.DB.SortedSet(.read_only).init(user_repos_cursor); │ │167 │ │168 // removing the repo emptied the user's set │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │169 try std.testing.expectEqual(0, try user_repos.count()); │ │170 + try std.testing.expectEqual(null, try evt.Repo.readByName(Repo.DB, repo_opts.hash, haxy_moment, &arena, "ziglings"));│ │171 } │ │172 │ │173 // a non-null payload restores the repo and its indexes │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │163 - try evt.consume(.server, .admin, .xit, repo_opts, io, allocator, &repo, evt.events_ref, &[_]evt.EventWithId{.{ │ │164 - .id = std.fmt.bytesToHex(repo_event_id, .lower), │ │165 - .author = author, │ │166 - .event = events_to_consume[2].event, │ │167 - }}); │ │174 + try evt.consume(.server, .user, .xit, repo_opts, io, allocator, &user_repo, evt.events_ref, &.{repo_event}); │ │175 │ │176 { │ │170 - const haxy_moment = try evt.currentMoment(repo_opts, &repo); │ │177 + const haxy_moment = try evt.currentMoment(repo_opts, &user_repo); │ │178 const event_id_to_repo_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "event-id->repo")) orelse return error.NotFound;│ │179 const event_id_to_repo = try Repo.DB.HashMap(.read_only).init(event_id_to_repo_cursor); │ │180 const repo_cursor = try event_id_to_repo.getCursor(hash.hashInt(repo_opts.hash, &repo_event_id)) orelse return error.NotFound; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │181 const repo_map = try Repo.DB.HashMap(.read_only).init(repo_cursor); │ │175 - const repo_event = try evt.read(evt.Repo.Record, Repo.DB, repo_opts.hash, &arena, repo_map); │ │176 - try std.testing.expect(!repo_event.removed); │ │182 + const repo_record = try evt.read(evt.Repo.Record, Repo.DB, repo_opts.hash, &arena, repo_map); │ │183 + try std.testing.expect(!repo_record.removed); │ │184 │ │178 - const user_id_to_repo_id_set_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "user-id->repo-id-set")) orelse return error.NotFound;│ │179 - const user_id_to_repo_id_set = try Repo.DB.HashMap(.read_only).init(user_id_to_repo_id_set_cursor); │ │180 - const user_repos_cursor = try user_id_to_repo_id_set.getCursor(hash.hashInt(repo_opts.hash, &user_event_id)) orelse return error.NotFound; │ │185 + const user_repos_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, evt.Repo.active_id_set_key)) orelse return error.NotFound; │ │186 const user_repos = try Repo.DB.SortedSet(.read_only).init(user_repos_cursor); │ │187 try std.testing.expectEqual(1, try user_repos.count()); │ │188 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │213 const user_map = try Repo.DB.HashMap(.read_only).init(user_cursor); │ │214 const user_event = try evt.read(evt.User.Record, Repo.DB, repo_opts.hash, &arena, user_map); │ │215 try std.testing.expect(user_event.removed); │ │211 - │ │212 - // removing the user removes their active repos too │ │213 - const event_id_to_repo_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "event-id->repo")) orelse return error.NotFound;│ │214 - const event_id_to_repo = try Repo.DB.HashMap(.read_only).init(event_id_to_repo_cursor); │ │215 - const repo_cursor = try event_id_to_repo.getCursor(hash.hashInt(repo_opts.hash, &repo_event_id)) orelse return error.NotFound; │ │216 - const repo_map = try Repo.DB.HashMap(.read_only).init(repo_cursor); │ │217 - const repo_event = try evt.read(evt.Repo.Record, Repo.DB, repo_opts.hash, &arena, repo_map); │ │218 - try std.testing.expect(repo_event.removed); │ │216 } │ │217 } │ │218 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │227 │ │228 const repo_opts: rp.RepoOpts(.xit) = .{ .is_test = true }; │ │229 const Repo = rp.Repo(.xit, repo_opts); │ │233 - var repo = try Repo.init(io, allocator, .{ .path = temp_path }); │ │230 + const admin_path = try std.fs.path.join(allocator, &.{ temp_path, "admin" });│ │231 + defer allocator.free(admin_path); │ │232 + var admin = try Repo.init(io, allocator, .{ .path = admin_path }); │ │233 + defer admin.deinit(io, allocator); │ │234 + const user_path = try std.fs.path.join(allocator, &.{ temp_path, "user" }); │ │235 + defer allocator.free(user_path); │ │236 + var repo = try Repo.init(io, allocator, .{ .path = user_path }); │ │237 defer repo.deinit(io, allocator); │ │238 │ │239 var arena = std.heap.ArenaAllocator.init(allocator); │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │268 } │ │269 }; │ │270 │ │268 - // one user, then four repos in creation order with deliberately skewed │ │269 - // timestamps │ │271 + // one user in the admin repo, then four repos in creation order with │ │272 + // deliberately skewed timestamps in the user's repo │ │273 + try evt.consume(.server, .admin, .xit, repo_opts, io, allocator, &admin, evt.events_ref, &.{ │ │274 + .{ .id = std.fmt.bytesToHex(user_id, .lower), .author = author, .timestamp = 100, .event = .{ .user = .{ .name = "alice", .email = "alice@example.test", .password_hash = pw } } },│ │275 + }); │ │276 const events = [_]evt.EventWithId{ │ │271 - .{ .id = std.fmt.bytesToHex(user_id, .lower), .author = author, .timestamp = 100, .event = .{ .user = .{ .name = "alice", .email = "alice@example.test", .password_hash = pw } } },│ │277 .{ .id = std.fmt.bytesToHex(repo_ids[0], .lower), .author = author, .timestamp = 10_000, .event = .{ .repo = .{ .user_id = &user_id, .name = "repo0", .description = "d0" } } }, │ │278 .{ .id = std.fmt.bytesToHex(repo_ids[1], .lower), .author = author, .timestamp = 10, .event = .{ .repo = .{ .user_id = &user_id, .name = "repo1", .description = "d1" } } }, │ │279 .{ .id = std.fmt.bytesToHex(repo_ids[2], .lower), .author = author, .timestamp = 5_000, .event = .{ .repo = .{ .user_id = &user_id, .name = "repo2", .description = "d2" } } }, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │280 .{ .id = std.fmt.bytesToHex(repo_ids[3], .lower), .author = author, .timestamp = 20, .event = .{ .repo = .{ .user_id = &user_id, .name = "repo3", .description = "d3" } } },│ │281 }; │ │277 - try evt.consume(.server, .admin, .xit, repo_opts, io, allocator, &repo, evt.events_ref, &events); │ │282 + try evt.consume(.server, .user, .xit, repo_opts, io, allocator, &repo, evt.events_ref, &events); │ │283 │ │284 { │ │285 const moment = try evt.currentMoment(repo_opts, &repo); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │286 try Check.order(Repo.DB, repo_opts.hash, moment, &.{ &repo_ids[3], &repo_ids[2], &repo_ids[1], &repo_ids[0] }); │ │287 │ │288 // the single user shows up in its own ordered set │ │284 - const ucur = try moment.getCursor(hash.hashInt(repo_opts.hash, "user-id-set")) orelse return error.NotFound; │ │289 + const admin_moment = try evt.currentMoment(repo_opts, &admin); │ │290 + const ucur = try admin_moment.getCursor(hash.hashInt(repo_opts.hash, "user-id-set")) orelse return error.NotFound;│ │291 const uset = try Repo.DB.SortedSet(.read_only).init(ucur); │ │292 try std.testing.expectEqual(1, try uset.count()); │ │293 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │294 │ │295 // removing repo1 retains its place in the canonical order │ │290 - try evt.consume(.server, .admin, .xit, repo_opts, io, allocator, &repo, evt.events_ref, &[_]evt.EventWithId{ │ │296 + try evt.consume(.server, .user, .xit, repo_opts, io, allocator, &repo, evt.events_ref, &[_]evt.EventWithId{ │ │297 .{ .id = std.fmt.bytesToHex(repo_ids[1], .lower), .author = author, .timestamp = 200, .event = .{ .repo = null } },│ │298 }); │ │299 { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯