Participants report taking the room into work (join)
deploy / deploy (push) Canceled after 0s

- POST /api/rooms/:id/join + rendezvous_join MCP tool; creator auto-joined
- joined_at shown to agents, observer (invite not confirmed yet) and used by
  the turn indicator; what_you_should_do_next starts with joining
- fix: participant list order is now stable (insertion order)
This commit is contained in:
2026-09-06 21:35:03 +03:00
parent 1fa7e733ba
commit bb0eb6979e
13 changed files with 146 additions and 12 deletions
+21
View File
@@ -165,6 +165,27 @@ test('destroyRoom: allowed for participant and observer, rejected for strangers'
assert.throws(() => svc.getRoomView(c2.room_id, c2.participants[0].token), RendezvousError);
});
test('join: creator auto-joined, invitee reports once and idempotently', () => {
const { svc } = makeService();
const created = createTwoPartyRoom(svc);
const [, tokenB] = created.participants.map((p) => p.token);
const viewA = svc.getRoomView(created.room_id, created.participants[0].token);
assert.ok(viewA.participants[0].joined_at, 'creator is joined from the start');
assert.equal(viewA.participants[1].joined_at, null);
// B's advice tells it to join first
const viewB = svc.getRoomView(created.room_id, tokenB);
assert.match(viewB.what_you_should_do_next, /join/);
const first = svc.join(created.room_id, tokenB).participants.find((p) => p.role === 'application')!;
const ts = first.joined_at!;
assert.ok(ts);
// idempotent: timestamp does not change
const again = svc.join(created.room_id, tokenB).participants.find((p) => p.role === 'application')!;
assert.equal(again.joined_at, ts);
});
test('only addressee or author can resolve a question', () => {
const { svc } = makeService();
const created = createTwoPartyRoom(svc);