agentTriggerers method

List<String> agentTriggerers(
  1. String agentId
)

The I1 trigger set of agentId (10 5.2 and 5.3, simplified): the active people who may trigger it, in the order of people.

Targets are the channels whose operator.effective_agent_id is the agent and every channel of a space whose default operator it is; their spaces count for space grants. Triggerers are the active owners, the people with trigger in the access list of a target channel, and the active members (membership not expired) of groups and the people that hold a valid grant (not revoked, not expired) with trigger on a target channel, its space or the instance. The fake has no thread operators (10 5.2 point 2).

Implementation

List<String> agentTriggerers(String agentId) {
  final targets = [
    for (final c in channels.values)
      if ((c.json['operator'] as JsonMap?)?['effective_agent_id'] ==
              agentId ||
          spaces[c.spaceId]?['default_operator_agent_id'] == agentId)
        c,
  ];
  final targetIds = {for (final c in targets) c.id};
  final targetSpaces = {
    for (final c in targets) ?c.spaceId,
    for (final s in spaces.values)
      if (s['default_operator_agent_id'] == agentId) s['id']! as String,
  };
  final t = now();
  bool valid(Object? expiresAt) =>
      expiresAt == null || DateTime.parse(expiresAt as String).isAfter(t);
  final found = <String>{
    for (final p in people.values)
      if (p.isOwner) p.id,
    for (final c in targets)
      for (final MapEntry(:key, :value) in c.access.entries)
        if (value == 'trigger') key,
  };
  for (final g in grants.values) {
    final target = g['target_id'];
    final onTarget = switch (g['target_kind']) {
      'instance' => true,
      'space' => targetSpaces.contains(target),
      'channel' => targetIds.contains(target),
      _ => false,
    };
    if (g['revoked_at'] != null ||
        !valid(g['expires_at']) ||
        g['level'] != 'trigger' ||
        !onTarget) {
      continue;
    }
    final subject = g['subject_id']! as String;
    if (g['subject_kind'] == 'user') found.add(subject);
    if (g['subject_kind'] == 'group') {
      for (final MapEntry(:key, :value)
          in (groupMembers[subject] ?? {}).entries) {
        if (valid(value['expires_at'])) found.add(key);
      }
    }
  }
  return [
    for (final p in people.values)
      if (found.contains(p.id) && p.kind == 'user' && p.status == 'active')
        p.id,
  ];
}