@kusinta/iot-schema 0.2.0-beta.23 → 0.2.0-beta.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kusinta/iot-schema",
3
- "version": "0.2.0-beta.23",
3
+ "version": "0.2.0-beta.25",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "files": ["src"],
@@ -21,10 +21,12 @@ export declare const file_kusinta_iot_access_v1_roles: GenFile;
21
21
  * The gateway resolves the two together into DeviceAcl.allowed_actions, per device. A
22
22
  * role narrows what may appear there; it does not put anything there on its own.
23
23
  *
24
- * Carried in the app's token as webrtc.v1.AppTokenClaims.roles, as an array of proto3
25
- * canonical enum NAME strings (e.g. ["ROLE_RESIDENT", "ROLE_GATEWAY_ADMIN"]) rather than
26
- * integers, so the claim stays self-describing. A user may hold several at once and the
27
- * effective ceiling is their union.
24
+ * The building-server gateway holds each user's roles itself and authorises from what it
25
+ * holds. The one role it cannot know is the administration of whoever registered it, which
26
+ * the api-server records: that one it takes from the app's token
27
+ * (webrtc.v1.AppTokenClaims.roles). The api-server learns the rest from the gateway
28
+ * (reporting.v1.GatewayMember). A user may hold several at once and the effective ceiling is
29
+ * their union.
28
30
  *
29
31
  * UNORDERED. These are categories, not levels: a technician is not "more than" a
30
32
  * resident, and there is no >= comparison to make between them. Anything needing a graded
@@ -28,10 +28,12 @@ export const RoleSchema = /*@__PURE__*/
28
28
  * The gateway resolves the two together into DeviceAcl.allowed_actions, per device. A
29
29
  * role narrows what may appear there; it does not put anything there on its own.
30
30
  *
31
- * Carried in the app's token as webrtc.v1.AppTokenClaims.roles, as an array of proto3
32
- * canonical enum NAME strings (e.g. ["ROLE_RESIDENT", "ROLE_GATEWAY_ADMIN"]) rather than
33
- * integers, so the claim stays self-describing. A user may hold several at once and the
34
- * effective ceiling is their union.
31
+ * The building-server gateway holds each user's roles itself and authorises from what it
32
+ * holds. The one role it cannot know is the administration of whoever registered it, which
33
+ * the api-server records: that one it takes from the app's token
34
+ * (webrtc.v1.AppTokenClaims.roles). The api-server learns the rest from the gateway
35
+ * (reporting.v1.GatewayMember). A user may hold several at once and the effective ceiling is
36
+ * their union.
35
37
  *
36
38
  * UNORDERED. These are categories, not levels: a technician is not "more than" a
37
39
  * resident, and there is no >= comparison to make between them. Anything needing a graded
@@ -7,6 +7,7 @@ import type { Message } from "@bufbuild/protobuf";
7
7
  import type { ConnectorId, DeviceId, SpaceId, UserId } from "../../identity/v1/identity_pb.js";
8
8
  import type { Timestamp } from "@bufbuild/protobuf/wkt";
9
9
  import type { BackendFailureReason, SpaceType } from "../../common/v1/types_pb.js";
10
+ import type { Role } from "../../access/v1/roles_pb.js";
10
11
 
11
12
  /**
12
13
  * Describes the file kusinta/iot/reporting/v1/reporting.proto.
@@ -697,6 +698,149 @@ export declare type ReportServedSpacesResponse = Message<"kusinta.iot.reporting.
697
698
  */
698
699
  export declare const ReportServedSpacesResponseSchema: GenMessage<ReportServedSpacesResponse>;
699
700
 
701
+ /**
702
+ * One member of this gateway: a user the gateway holds a role (access.v1.Role) or a space
703
+ * membership for, either. Whom the api-server lets connect to the gateway, and in which
704
+ * capacity. A user filed somewhere with no role is a member all the same: what they may do
705
+ * there is the gateway's to decide, and they cannot connect to find out unless reported.
706
+ *
707
+ * roles carries a member's service roles alone: ROLE_TECHNICIAN, ROLE_PROPERTY_OWNER and
708
+ * ROLE_GATEWAY_ADMIN. An empty list means no service role: a resident, or someone filed with
709
+ * no role. The gateway MUST NOT
710
+ * send ROLE_RESIDENT or ROLE_UNSPECIFIED here, and the api-server keeps no role but the
711
+ * three, each once. An entry, in members or removed_user_ids, with no user id is malformed,
712
+ * and the api-server skips it.
713
+ *
714
+ * What the api-server learns of a member with no service role is that they belong to this
715
+ * gateway, and from when to when — never which home, nor anything else ServiceReach
716
+ * withholds. A member's changes are sent at once, both ways, since joining is what lets a
717
+ * person connect and leaving is what revokes them. Roles do not follow relations
718
+ * (access.v1.MembershipRelation): a relation changing alone changes nothing reported here.
719
+ *
720
+ * Who registered the gateway is the api-server's own record, not the gateway's. The
721
+ * administration that came with registering it is never taken away by this report — not by
722
+ * its absence from a snapshot, not by removed_user_ids — and ends only with a change of who
723
+ * is registered as the gateway's administrator at the api-server. Any other administrator is
724
+ * a member reported with ROLE_GATEWAY_ADMIN, whom the api-server gives what it gives the
725
+ * registering one, from administrator_since (see ServiceReach). Where the registering
726
+ * administrator is also reported so, the api-server's record governs: their administration
727
+ * counts from the earlier of its own start and administrator_since.
728
+ *
729
+ * @generated from message kusinta.iot.reporting.v1.GatewayMember
730
+ */
731
+ export declare type GatewayMember = Message<"kusinta.iot.reporting.v1.GatewayMember"> & {
732
+ /**
733
+ * As the token issuer mints it: the sub of the member's token.
734
+ *
735
+ * @generated from field: kusinta.iot.identity.v1.UserId user_id = 1;
736
+ */
737
+ userId?: UserId | undefined;
738
+
739
+ /**
740
+ * The member's service roles, each once; empty for a resident.
741
+ *
742
+ * @generated from field: repeated kusinta.iot.access.v1.Role roles = 2;
743
+ */
744
+ roles: Role[];
745
+
746
+ /**
747
+ * Set exactly when roles holds ROLE_GATEWAY_ADMIN: the quarter hour, rounded up, from
748
+ * which the member's administration of the gateway has been unbroken, as the gateway counts
749
+ * it. Given by the gateway, which saw any break, as ReachedSpace.since is. An administrator
750
+ * reported without it counts from the quarter hour, rounded up, at which the api-server
751
+ * applied the report, never earlier.
752
+ *
753
+ * @generated from field: google.protobuf.Timestamp administrator_since = 3;
754
+ */
755
+ administratorSince?: Timestamp | undefined;
756
+ };
757
+
758
+ /**
759
+ * Describes the message kusinta.iot.reporting.v1.GatewayMember.
760
+ * Use `create(GatewayMemberSchema)` to create a new message.
761
+ */
762
+ export declare const GatewayMemberSchema: GenMessage<GatewayMember>;
763
+
764
+ /**
765
+ * @generated from message kusinta.iot.reporting.v1.ReportMembersRequest
766
+ */
767
+ export declare type ReportMembersRequest = Message<"kusinta.iot.reporting.v1.ReportMembersRequest"> & {
768
+ /**
769
+ * This concern's stream; see SnapshotPart.
770
+ *
771
+ * @generated from field: string stream_id = 1;
772
+ */
773
+ streamId: string;
774
+
775
+ /**
776
+ * The streams this one replaced; see SnapshotPart. Empty on the gateway's first.
777
+ *
778
+ * @generated from field: repeated string previous_stream_ids = 2;
779
+ */
780
+ previousStreamIds: string[];
781
+
782
+ /**
783
+ * As ReportServiceReachRequest.seq, on this concern's own stream: applied in order,
784
+ * exactly once, so a late retry cannot restore a member since removed.
785
+ *
786
+ * @generated from field: uint64 seq = 3;
787
+ */
788
+ seq: bigint;
789
+
790
+ /**
791
+ * Added or changed. Each replaces what the api-server held for that member on this gateway.
792
+ *
793
+ * @generated from field: repeated kusinta.iot.reporting.v1.GatewayMember members = 4;
794
+ */
795
+ members: GatewayMember[];
796
+
797
+ /**
798
+ * No longer members of this gateway. A user named here and in members is removed.
799
+ *
800
+ * @generated from field: repeated kusinta.iot.identity.v1.UserId removed_user_ids = 5;
801
+ */
802
+ removedUserIds: UserId[];
803
+
804
+ /**
805
+ * Set when this request is part of a snapshot of every member; users absent from a whole
806
+ * snapshot are members no more.
807
+ *
808
+ * @generated from field: kusinta.iot.reporting.v1.SnapshotPart snapshot = 6;
809
+ */
810
+ snapshot?: SnapshotPart | undefined;
811
+ };
812
+
813
+ /**
814
+ * Describes the message kusinta.iot.reporting.v1.ReportMembersRequest.
815
+ * Use `create(ReportMembersRequestSchema)` to create a new message.
816
+ */
817
+ export declare const ReportMembersRequestSchema: GenMessage<ReportMembersRequest>;
818
+
819
+ /**
820
+ * @generated from message kusinta.iot.reporting.v1.ReportMembersResponse
821
+ */
822
+ export declare type ReportMembersResponse = Message<"kusinta.iot.reporting.v1.ReportMembersResponse"> & {
823
+ /**
824
+ * As ReportServiceReachResponse.applied_seq.
825
+ *
826
+ * @generated from field: uint64 applied_seq = 1;
827
+ */
828
+ appliedSeq: bigint;
829
+
830
+ /**
831
+ * As ReportServiceReachResponse.resync_required.
832
+ *
833
+ * @generated from field: bool resync_required = 2;
834
+ */
835
+ resyncRequired: boolean;
836
+ };
837
+
838
+ /**
839
+ * Describes the message kusinta.iot.reporting.v1.ReportMembersResponse.
840
+ * Use `create(ReportMembersResponseSchema)` to create a new message.
841
+ */
842
+ export declare const ReportMembersResponseSchema: GenMessage<ReportMembersResponse>;
843
+
700
844
  /**
701
845
  * What kind of problem is open. The device kinds mirror what service staff are given of a
702
846
  * device (webrtc.v1.ServiceStatus: reachability, the battery flags, the ServiceFault values);
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { enumDesc, fileDesc, messageDesc, tsEnum } from "@bufbuild/protobuf/codegenv2";
6
6
  import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
7
+ import { file_kusinta_iot_access_v1_roles } from "../../access/v1/roles_pb.js";
7
8
  import { file_kusinta_iot_common_v1_types } from "../../common/v1/types_pb.js";
8
9
  import { file_kusinta_iot_identity_v1_identity } from "../../identity/v1/identity_pb.js";
9
10
 
@@ -11,7 +12,7 @@ import { file_kusinta_iot_identity_v1_identity } from "../../identity/v1/identit
11
12
  * Describes the file kusinta/iot/reporting/v1/reporting.proto.
12
13
  */
13
14
  export const file_kusinta_iot_reporting_v1_reporting = /*@__PURE__*/
14
- fileDesc("CihrdXNpbnRhL2lvdC9yZXBvcnRpbmcvdjEvcmVwb3J0aW5nLnByb3RvEhhrdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEiPwoMU25hcHNob3RQYXJ0EhMKC3NuYXBzaG90X2lkGAEgASgJEgwKBHBhcnQYAiABKA0SDAoEbGFzdBgDIAEoCCLZAQoOUHJvYmxlbVN1YmplY3QSNgoJZGV2aWNlX2lkGAEgASgLMiEua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuRGV2aWNlSWRIABI8Cgxjb25uZWN0b3JfaWQYAiABKAsyJC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5Db25uZWN0b3JJZEgAEjMKB3Jvb21faWQYAyABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkSAASEQoHZ2F0ZXdheRgEIAEoCEgAQgkKB3N1YmplY3Qi6gIKB1Byb2JsZW0SMwoEa2luZBgCIAEoDjIlLmt1c2ludGEuaW90LnJlcG9ydGluZy52MS5Qcm9ibGVtS2luZBI5CgdzdWJqZWN0GAMgASgLMigua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLlByb2JsZW1TdWJqZWN0EjIKCHNwYWNlX2lkGAQgASgLMiAua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuU3BhY2VJZBItCglvcGVuZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhwKD2JhdHRlcnlfcGVyY2VudBgGIAEoDUgAiAEBEhQKDGRldmljZV9jb3VudBgHIAEoDRJECg9iYWNrZW5kX2ZhaWx1cmUYCCABKA4yKy5rdXNpbnRhLmlvdC5jb21tb24udjEuQmFja2VuZEZhaWx1cmVSZWFzb25CEgoQX2JhdHRlcnlfcGVyY2VudCJ3Cg5Qcm9ibGVtQ2xlYXJlZBIuCgpjbGVhcmVkX2F0GAEgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBI1CgZyZWFzb24YAiABKA4yJS5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuQ2xlYXJSZWFzb24irgEKEVByb2JsZW1UcmFuc2l0aW9uEhIKCnByb2JsZW1faWQYASABKAkSCwoDc2VxGAIgASgEEjEKBG9wZW4YAyABKAsyIS5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUHJvYmxlbUgAEjsKB2NsZWFyZWQYBCABKAsyKC5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUHJvYmxlbUNsZWFyZWRIAEIICgZjaGFuZ2Ui0AEKFVJlcG9ydFByb2JsZW1zUmVxdWVzdBIRCglzdHJlYW1faWQYAyABKAkSGwoTcHJldmlvdXNfc3RyZWFtX2lkcxgFIAMoCRILCgNzZXEYBCABKAQSQAoLdHJhbnNpdGlvbnMYASADKAsyKy5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUHJvYmxlbVRyYW5zaXRpb24SOAoIc25hcHNob3QYAiABKAsyJi5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuU25hcHNob3RQYXJ0ImUKDVRyYW5zaXRpb25BY2sSEgoKcHJvYmxlbV9pZBgBIAEoCRILCgNzZXEYAiABKAQSMwoGc3RhdHVzGAMgASgOMiMua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLkFja1N0YXR1cyJ9ChZSZXBvcnRQcm9ibGVtc1Jlc3BvbnNlEjUKBGFja3MYASADKAsyJy5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuVHJhbnNpdGlvbkFjaxITCgthcHBsaWVkX3NlcRgDIAEoBBIXCg9yZXN5bmNfcmVxdWlyZWQYAiABKAgieAoMU2VydmljZVJlYWNoEjAKB3VzZXJfaWQYASABKAsyHy5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5Vc2VySWQSNgoGc3BhY2VzGAMgAygLMiYua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLlJlYWNoZWRTcGFjZSJtCgxSZWFjaGVkU3BhY2USMgoIc3BhY2VfaWQYASABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkEikKBXNpbmNlGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCKEAgoZUmVwb3J0U2VydmljZVJlYWNoUmVxdWVzdBIRCglzdHJlYW1faWQYBSABKAkSGwoTcHJldmlvdXNfc3RyZWFtX2lkcxgGIAMoCRILCgNzZXEYASABKAQSNQoFcmVhY2gYAiADKAsyJi5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuU2VydmljZVJlYWNoEjkKEHJlbW92ZWRfdXNlcl9pZHMYAyADKAsyHy5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5Vc2VySWQSOAoIc25hcHNob3QYBCABKAsyJi5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuU25hcHNob3RQYXJ0IkoKGlJlcG9ydFNlcnZpY2VSZWFjaFJlc3BvbnNlEhMKC2FwcGxpZWRfc2VxGAEgASgEEhcKD3Jlc3luY19yZXF1aXJlZBgCIAEoCCLiAQoLU2VydmVkU3BhY2USMgoIc3BhY2VfaWQYASABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkEjQKCnNwYWNlX3R5cGUYAiABKA4yIC5rdXNpbnRhLmlvdC5jb21tb24udjEuU3BhY2VUeXBlEgwKBG5hbWUYAyABKAkSOQoPcGFyZW50X3NwYWNlX2lkGAQgASgLMiAua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuU3BhY2VJZBINCgVmbG9vchgFIAEoBRIRCgl0aW1lX3pvbmUYBiABKAkihgIKGVJlcG9ydFNlcnZlZFNwYWNlc1JlcXVlc3QSEQoJc3RyZWFtX2lkGAUgASgJEhsKE3ByZXZpb3VzX3N0cmVhbV9pZHMYBiADKAkSCwoDc2VxGAEgASgEEjUKBnNwYWNlcxgCIAMoCzIlLmt1c2ludGEuaW90LnJlcG9ydGluZy52MS5TZXJ2ZWRTcGFjZRI7ChFyZW1vdmVkX3NwYWNlX2lkcxgDIAMoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQSOAoIc25hcHNob3QYBCABKAsyJi5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuU25hcHNob3RQYXJ0IkoKGlJlcG9ydFNlcnZlZFNwYWNlc1Jlc3BvbnNlEhMKC2FwcGxpZWRfc2VxGAEgASgEEhcKD3Jlc3luY19yZXF1aXJlZBgCIAEoCCrcAgoLUHJvYmxlbUtpbmQSHAoYUFJPQkxFTV9LSU5EX1VOU1BFQ0lGSUVEEAASHwobUFJPQkxFTV9LSU5EX0RFVklDRV9PRkZMSU5FEAESHAoYUFJPQkxFTV9LSU5EX0JBVFRFUllfTE9XEAISKwonUFJPQkxFTV9LSU5EX0JBVFRFUllfUkVQTEFDRU1FTlRfTkVFREVEEAMSHQoZUFJPQkxFTV9LSU5EX0RFVklDRV9FUlJPUhAEEh4KGlBST0JMRU1fS0lORF9ERVZJQ0VfVEFNUEVSEAUSIgoeUFJPQkxFTV9LSU5EX0NPTk5FQ1RPUl9PRkZMSU5FEAYSIAocUFJPQkxFTV9LSU5EX0NPTk5FQ1RPUl9FUlJPUhAHEiAKHFBST0JMRU1fS0lORF9VTkZJTEVEX0RFVklDRVMQCBIcChhQUk9CTEVNX0tJTkRfV0lORE9XX09QRU4QCSqfAgoLQ2xlYXJSZWFzb24SHAoYQ0xFQVJfUkVBU09OX1VOU1BFQ0lGSUVEEAASGgoWQ0xFQVJfUkVBU09OX1JFQ09WRVJFRBABEhYKEkNMRUFSX1JFQVNPTl9GSUxFRBACEh8KG0NMRUFSX1JFQVNPTl9ERVZJQ0VfUkVNT1ZFRBADEjAKLENMRUFSX1JFQVNPTl9TVVBFUlNFREVEX0JZX0NPTk5FQ1RPUl9PRkZMSU5FEAQSIwofQ0xFQVJfUkVBU09OX05PX0xPTkdFUl9SRVBPUlRFRBAFEhYKEkNMRUFSX1JFQVNPTl9NT1ZFRBAGEi4KKkNMRUFSX1JFQVNPTl9TVVBFUlNFREVEX0JZX0NPTk5FQ1RPUl9FUlJPUhAHKocBCglBY2tTdGF0dXMSGgoWQUNLX1NUQVRVU19VTlNQRUNJRklFRBAAEhYKEkFDS19TVEFUVVNfQVBQTElFRBABEhgKFEFDS19TVEFUVVNfRFVQTElDQVRFEAISFwoTQUNLX1NUQVRVU19SRUpFQ1RFRBADEhMKD0FDS19TVEFUVVNfSEVMRBAEQgJIAWIGcHJvdG8z", [file_google_protobuf_timestamp, file_kusinta_iot_common_v1_types, file_kusinta_iot_identity_v1_identity]);
15
+ fileDesc("CihrdXNpbnRhL2lvdC9yZXBvcnRpbmcvdjEvcmVwb3J0aW5nLnByb3RvEhhrdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEiPwoMU25hcHNob3RQYXJ0EhMKC3NuYXBzaG90X2lkGAEgASgJEgwKBHBhcnQYAiABKA0SDAoEbGFzdBgDIAEoCCLZAQoOUHJvYmxlbVN1YmplY3QSNgoJZGV2aWNlX2lkGAEgASgLMiEua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuRGV2aWNlSWRIABI8Cgxjb25uZWN0b3JfaWQYAiABKAsyJC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5Db25uZWN0b3JJZEgAEjMKB3Jvb21faWQYAyABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkSAASEQoHZ2F0ZXdheRgEIAEoCEgAQgkKB3N1YmplY3Qi6gIKB1Byb2JsZW0SMwoEa2luZBgCIAEoDjIlLmt1c2ludGEuaW90LnJlcG9ydGluZy52MS5Qcm9ibGVtS2luZBI5CgdzdWJqZWN0GAMgASgLMigua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLlByb2JsZW1TdWJqZWN0EjIKCHNwYWNlX2lkGAQgASgLMiAua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuU3BhY2VJZBItCglvcGVuZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhwKD2JhdHRlcnlfcGVyY2VudBgGIAEoDUgAiAEBEhQKDGRldmljZV9jb3VudBgHIAEoDRJECg9iYWNrZW5kX2ZhaWx1cmUYCCABKA4yKy5rdXNpbnRhLmlvdC5jb21tb24udjEuQmFja2VuZEZhaWx1cmVSZWFzb25CEgoQX2JhdHRlcnlfcGVyY2VudCJ3Cg5Qcm9ibGVtQ2xlYXJlZBIuCgpjbGVhcmVkX2F0GAEgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBI1CgZyZWFzb24YAiABKA4yJS5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuQ2xlYXJSZWFzb24irgEKEVByb2JsZW1UcmFuc2l0aW9uEhIKCnByb2JsZW1faWQYASABKAkSCwoDc2VxGAIgASgEEjEKBG9wZW4YAyABKAsyIS5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUHJvYmxlbUgAEjsKB2NsZWFyZWQYBCABKAsyKC5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUHJvYmxlbUNsZWFyZWRIAEIICgZjaGFuZ2Ui0AEKFVJlcG9ydFByb2JsZW1zUmVxdWVzdBIRCglzdHJlYW1faWQYAyABKAkSGwoTcHJldmlvdXNfc3RyZWFtX2lkcxgFIAMoCRILCgNzZXEYBCABKAQSQAoLdHJhbnNpdGlvbnMYASADKAsyKy5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUHJvYmxlbVRyYW5zaXRpb24SOAoIc25hcHNob3QYAiABKAsyJi5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuU25hcHNob3RQYXJ0ImUKDVRyYW5zaXRpb25BY2sSEgoKcHJvYmxlbV9pZBgBIAEoCRILCgNzZXEYAiABKAQSMwoGc3RhdHVzGAMgASgOMiMua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLkFja1N0YXR1cyJ9ChZSZXBvcnRQcm9ibGVtc1Jlc3BvbnNlEjUKBGFja3MYASADKAsyJy5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuVHJhbnNpdGlvbkFjaxITCgthcHBsaWVkX3NlcRgDIAEoBBIXCg9yZXN5bmNfcmVxdWlyZWQYAiABKAgieAoMU2VydmljZVJlYWNoEjAKB3VzZXJfaWQYASABKAsyHy5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5Vc2VySWQSNgoGc3BhY2VzGAMgAygLMiYua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLlJlYWNoZWRTcGFjZSJtCgxSZWFjaGVkU3BhY2USMgoIc3BhY2VfaWQYASABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkEikKBXNpbmNlGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCKEAgoZUmVwb3J0U2VydmljZVJlYWNoUmVxdWVzdBIRCglzdHJlYW1faWQYBSABKAkSGwoTcHJldmlvdXNfc3RyZWFtX2lkcxgGIAMoCRILCgNzZXEYASABKAQSNQoFcmVhY2gYAiADKAsyJi5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuU2VydmljZVJlYWNoEjkKEHJlbW92ZWRfdXNlcl9pZHMYAyADKAsyHy5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5Vc2VySWQSOAoIc25hcHNob3QYBCABKAsyJi5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuU25hcHNob3RQYXJ0IkoKGlJlcG9ydFNlcnZpY2VSZWFjaFJlc3BvbnNlEhMKC2FwcGxpZWRfc2VxGAEgASgEEhcKD3Jlc3luY19yZXF1aXJlZBgCIAEoCCLiAQoLU2VydmVkU3BhY2USMgoIc3BhY2VfaWQYASABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkEjQKCnNwYWNlX3R5cGUYAiABKA4yIC5rdXNpbnRhLmlvdC5jb21tb24udjEuU3BhY2VUeXBlEgwKBG5hbWUYAyABKAkSOQoPcGFyZW50X3NwYWNlX2lkGAQgASgLMiAua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuU3BhY2VJZBINCgVmbG9vchgFIAEoBRIRCgl0aW1lX3pvbmUYBiABKAkihgIKGVJlcG9ydFNlcnZlZFNwYWNlc1JlcXVlc3QSEQoJc3RyZWFtX2lkGAUgASgJEhsKE3ByZXZpb3VzX3N0cmVhbV9pZHMYBiADKAkSCwoDc2VxGAEgASgEEjUKBnNwYWNlcxgCIAMoCzIlLmt1c2ludGEuaW90LnJlcG9ydGluZy52MS5TZXJ2ZWRTcGFjZRI7ChFyZW1vdmVkX3NwYWNlX2lkcxgDIAMoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQSOAoIc25hcHNob3QYBCABKAsyJi5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuU25hcHNob3RQYXJ0IkoKGlJlcG9ydFNlcnZlZFNwYWNlc1Jlc3BvbnNlEhMKC2FwcGxpZWRfc2VxGAEgASgEEhcKD3Jlc3luY19yZXF1aXJlZBgCIAEoCCKmAQoNR2F0ZXdheU1lbWJlchIwCgd1c2VyX2lkGAEgASgLMh8ua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuVXNlcklkEioKBXJvbGVzGAIgAygOMhsua3VzaW50YS5pb3QuYWNjZXNzLnYxLlJvbGUSNwoTYWRtaW5pc3RyYXRvcl9zaW5jZRgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiggIKFFJlcG9ydE1lbWJlcnNSZXF1ZXN0EhEKCXN0cmVhbV9pZBgBIAEoCRIbChNwcmV2aW91c19zdHJlYW1faWRzGAIgAygJEgsKA3NlcRgDIAEoBBI4CgdtZW1iZXJzGAQgAygLMicua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLkdhdGV3YXlNZW1iZXISOQoQcmVtb3ZlZF91c2VyX2lkcxgFIAMoCzIfLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlVzZXJJZBI4CghzbmFwc2hvdBgGIAEoCzImLmt1c2ludGEuaW90LnJlcG9ydGluZy52MS5TbmFwc2hvdFBhcnQiRQoVUmVwb3J0TWVtYmVyc1Jlc3BvbnNlEhMKC2FwcGxpZWRfc2VxGAEgASgEEhcKD3Jlc3luY19yZXF1aXJlZBgCIAEoCCrcAgoLUHJvYmxlbUtpbmQSHAoYUFJPQkxFTV9LSU5EX1VOU1BFQ0lGSUVEEAASHwobUFJPQkxFTV9LSU5EX0RFVklDRV9PRkZMSU5FEAESHAoYUFJPQkxFTV9LSU5EX0JBVFRFUllfTE9XEAISKwonUFJPQkxFTV9LSU5EX0JBVFRFUllfUkVQTEFDRU1FTlRfTkVFREVEEAMSHQoZUFJPQkxFTV9LSU5EX0RFVklDRV9FUlJPUhAEEh4KGlBST0JMRU1fS0lORF9ERVZJQ0VfVEFNUEVSEAUSIgoeUFJPQkxFTV9LSU5EX0NPTk5FQ1RPUl9PRkZMSU5FEAYSIAocUFJPQkxFTV9LSU5EX0NPTk5FQ1RPUl9FUlJPUhAHEiAKHFBST0JMRU1fS0lORF9VTkZJTEVEX0RFVklDRVMQCBIcChhQUk9CTEVNX0tJTkRfV0lORE9XX09QRU4QCSqfAgoLQ2xlYXJSZWFzb24SHAoYQ0xFQVJfUkVBU09OX1VOU1BFQ0lGSUVEEAASGgoWQ0xFQVJfUkVBU09OX1JFQ09WRVJFRBABEhYKEkNMRUFSX1JFQVNPTl9GSUxFRBACEh8KG0NMRUFSX1JFQVNPTl9ERVZJQ0VfUkVNT1ZFRBADEjAKLENMRUFSX1JFQVNPTl9TVVBFUlNFREVEX0JZX0NPTk5FQ1RPUl9PRkZMSU5FEAQSIwofQ0xFQVJfUkVBU09OX05PX0xPTkdFUl9SRVBPUlRFRBAFEhYKEkNMRUFSX1JFQVNPTl9NT1ZFRBAGEi4KKkNMRUFSX1JFQVNPTl9TVVBFUlNFREVEX0JZX0NPTk5FQ1RPUl9FUlJPUhAHKocBCglBY2tTdGF0dXMSGgoWQUNLX1NUQVRVU19VTlNQRUNJRklFRBAAEhYKEkFDS19TVEFUVVNfQVBQTElFRBABEhgKFEFDS19TVEFUVVNfRFVQTElDQVRFEAISFwoTQUNLX1NUQVRVU19SRUpFQ1RFRBADEhMKD0FDS19TVEFUVVNfSEVMRBAEQgJIAWIGcHJvdG8z", [file_google_protobuf_timestamp, file_kusinta_iot_access_v1_roles, file_kusinta_iot_common_v1_types, file_kusinta_iot_identity_v1_identity]);
15
16
 
16
17
  /**
17
18
  * Describes the message kusinta.iot.reporting.v1.SnapshotPart.
@@ -118,6 +119,27 @@ export const ReportServedSpacesRequestSchema = /*@__PURE__*/
118
119
  export const ReportServedSpacesResponseSchema = /*@__PURE__*/
119
120
  messageDesc(file_kusinta_iot_reporting_v1_reporting, 14);
120
121
 
122
+ /**
123
+ * Describes the message kusinta.iot.reporting.v1.GatewayMember.
124
+ * Use `create(GatewayMemberSchema)` to create a new message.
125
+ */
126
+ export const GatewayMemberSchema = /*@__PURE__*/
127
+ messageDesc(file_kusinta_iot_reporting_v1_reporting, 15);
128
+
129
+ /**
130
+ * Describes the message kusinta.iot.reporting.v1.ReportMembersRequest.
131
+ * Use `create(ReportMembersRequestSchema)` to create a new message.
132
+ */
133
+ export const ReportMembersRequestSchema = /*@__PURE__*/
134
+ messageDesc(file_kusinta_iot_reporting_v1_reporting, 16);
135
+
136
+ /**
137
+ * Describes the message kusinta.iot.reporting.v1.ReportMembersResponse.
138
+ * Use `create(ReportMembersResponseSchema)` to create a new message.
139
+ */
140
+ export const ReportMembersResponseSchema = /*@__PURE__*/
141
+ messageDesc(file_kusinta_iot_reporting_v1_reporting, 17);
142
+
121
143
  /**
122
144
  * Describes the enum kusinta.iot.reporting.v1.ProblemKind.
123
145
  */
@@ -3,7 +3,7 @@
3
3
  /* eslint-disable */
4
4
 
5
5
  import type { GenFile, GenService } from "@bufbuild/protobuf/codegenv2";
6
- import type { ReportProblemsRequestSchema, ReportProblemsResponseSchema, ReportServedSpacesRequestSchema, ReportServedSpacesResponseSchema, ReportServiceReachRequestSchema, ReportServiceReachResponseSchema } from "./reporting_pb.js";
6
+ import type { ReportMembersRequestSchema, ReportMembersResponseSchema, ReportProblemsRequestSchema, ReportProblemsResponseSchema, ReportServedSpacesRequestSchema, ReportServedSpacesResponseSchema, ReportServiceReachRequestSchema, ReportServiceReachResponseSchema } from "./reporting_pb.js";
7
7
 
8
8
  /**
9
9
  * Describes the file kusinta/iot/reporting/v1/reporting_service.proto.
@@ -12,8 +12,8 @@ export declare const file_kusinta_iot_reporting_v1_reporting_service: GenFile;
12
12
 
13
13
  /**
14
14
  * The building-server gateway's reports to the api-server, over the gateway's client
15
- * certificate: which gateway is reporting comes from the certificate. Three unary calls, one
16
- * per concern, each with its own stream of reports, so a slow call for one never holds back
15
+ * certificate: which gateway is reporting comes from the certificate. One unary call per
16
+ * concern, each with its own stream of reports, so a slow call for one never holds back
17
17
  * another.
18
18
  *
19
19
  * @generated from service kusinta.iot.reporting.v1.GatewayReportingService
@@ -43,5 +43,13 @@ export declare const GatewayReportingService: GenService<{
43
43
  input: typeof ReportServedSpacesRequestSchema;
44
44
  output: typeof ReportServedSpacesResponseSchema;
45
45
  },
46
+ /**
47
+ * @generated from rpc kusinta.iot.reporting.v1.GatewayReportingService.ReportMembers
48
+ */
49
+ reportMembers: {
50
+ methodKind: "unary";
51
+ input: typeof ReportMembersRequestSchema;
52
+ output: typeof ReportMembersResponseSchema;
53
+ },
46
54
  }>;
47
55
 
@@ -9,12 +9,12 @@ import { file_kusinta_iot_reporting_v1_reporting } from "./reporting_pb.js";
9
9
  * Describes the file kusinta/iot/reporting/v1/reporting_service.proto.
10
10
  */
11
11
  export const file_kusinta_iot_reporting_v1_reporting_service = /*@__PURE__*/
12
- fileDesc("CjBrdXNpbnRhL2lvdC9yZXBvcnRpbmcvdjEvcmVwb3J0aW5nX3NlcnZpY2UucHJvdG8SGGt1c2ludGEuaW90LnJlcG9ydGluZy52MTKQAwoXR2F0ZXdheVJlcG9ydGluZ1NlcnZpY2UScwoOUmVwb3J0UHJvYmxlbXMSLy5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUmVwb3J0UHJvYmxlbXNSZXF1ZXN0GjAua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLlJlcG9ydFByb2JsZW1zUmVzcG9uc2USfwoSUmVwb3J0U2VydmljZVJlYWNoEjMua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLlJlcG9ydFNlcnZpY2VSZWFjaFJlcXVlc3QaNC5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUmVwb3J0U2VydmljZVJlYWNoUmVzcG9uc2USfwoSUmVwb3J0U2VydmVkU3BhY2VzEjMua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLlJlcG9ydFNlcnZlZFNwYWNlc1JlcXVlc3QaNC5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUmVwb3J0U2VydmVkU3BhY2VzUmVzcG9uc2VCAkgBYgZwcm90bzM", [file_kusinta_iot_reporting_v1_reporting]);
12
+ fileDesc("CjBrdXNpbnRhL2lvdC9yZXBvcnRpbmcvdjEvcmVwb3J0aW5nX3NlcnZpY2UucHJvdG8SGGt1c2ludGEuaW90LnJlcG9ydGluZy52MTKCBAoXR2F0ZXdheVJlcG9ydGluZ1NlcnZpY2UScwoOUmVwb3J0UHJvYmxlbXMSLy5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUmVwb3J0UHJvYmxlbXNSZXF1ZXN0GjAua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLlJlcG9ydFByb2JsZW1zUmVzcG9uc2USfwoSUmVwb3J0U2VydmljZVJlYWNoEjMua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLlJlcG9ydFNlcnZpY2VSZWFjaFJlcXVlc3QaNC5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUmVwb3J0U2VydmljZVJlYWNoUmVzcG9uc2USfwoSUmVwb3J0U2VydmVkU3BhY2VzEjMua3VzaW50YS5pb3QucmVwb3J0aW5nLnYxLlJlcG9ydFNlcnZlZFNwYWNlc1JlcXVlc3QaNC5rdXNpbnRhLmlvdC5yZXBvcnRpbmcudjEuUmVwb3J0U2VydmVkU3BhY2VzUmVzcG9uc2UScAoNUmVwb3J0TWVtYmVycxIuLmt1c2ludGEuaW90LnJlcG9ydGluZy52MS5SZXBvcnRNZW1iZXJzUmVxdWVzdBovLmt1c2ludGEuaW90LnJlcG9ydGluZy52MS5SZXBvcnRNZW1iZXJzUmVzcG9uc2VCAkgBYgZwcm90bzM", [file_kusinta_iot_reporting_v1_reporting]);
13
13
 
14
14
  /**
15
15
  * The building-server gateway's reports to the api-server, over the gateway's client
16
- * certificate: which gateway is reporting comes from the certificate. Three unary calls, one
17
- * per concern, each with its own stream of reports, so a slow call for one never holds back
16
+ * certificate: which gateway is reporting comes from the certificate. One unary call per
17
+ * concern, each with its own stream of reports, so a slow call for one never holds back
18
18
  * another.
19
19
  *
20
20
  * @generated from service kusinta.iot.reporting.v1.GatewayReportingService
@@ -67,11 +67,23 @@ export declare type AppTokenClaims = Message<"kusinta.iot.webrtc.v1.AppTokenClai
67
67
 
68
68
  /**
69
69
  * Custom claims.
70
- * A user may hold several roles at once (e.g. resident + gateway admin), so
71
- * this is a list. Carried in the JWT as an array of enum NAME strings
72
- * (e.g. ["ROLE_RESIDENT", "ROLE_GATEWAY_ADMIN"]), matching proto3 canonical
73
- * JSON enum encoding — not integer values. This keeps the claim
74
- * self-describing and aligns with text-typed role storage on the api-server.
70
+ * The roles the api-server holds for the user on this gateway: the service
71
+ * roles the gateway reported (reporting.v1.GatewayMember) other than
72
+ * ROLE_GATEWAY_ADMIN, and ROLE_GATEWAY_ADMIN for whoever registered the
73
+ * gateway. A resident's token names none. Carried in the JWT as an array of
74
+ * enum NAME strings (e.g. ["ROLE_TECHNICIAN"]), not integer values. The
75
+ * issuer writes the claim even when it names no role ([]), and a validator
76
+ * refuses a token without it.
77
+ *
78
+ * The gateway authorises from the roles it holds itself, and takes from
79
+ * this claim ROLE_GATEWAY_ADMIN alone. So the api-server MUST set
80
+ * ROLE_GATEWAY_ADMIN here only for the administrator who registered the
81
+ * gateway, never because the gateway reported someone as one: the gateway
82
+ * holds those itself, and a copy in a token would outlive their demotion
83
+ * until the token expired. A gateway that holds roles itself must be
84
+ * deployed before an api-server issues tokens under this rule, since a
85
+ * gateway that authorised from this claim would find residents and
86
+ * reported service roles missing.
75
87
  *
76
88
  * @generated from field: repeated kusinta.iot.access.v1.Role roles = 6;
77
89
  */