@apowerb/apowerb-sdk 0.1.8 → 0.1.10

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/api.js +150 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apowerb/apowerb-sdk",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "JavaScript SDK for the apowerb backend: agents, tools, RAG, BI, webhooks and billing. Dependency-free, runs in the browser and in Node.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/api.js CHANGED
@@ -828,3 +828,153 @@ export const uploadBiCsv = async (file, separator = "auto", organizationId) => {
828
828
  if (!res.ok) throw new Error(`CSV upload failed (${res.status})`);
829
829
  return res.json();
830
830
  };
831
+
832
+ // ---- Control panel (admin only: users, groups, organisations, permissions)
833
+ // Published on 18/08/2026 with the panel itself: it lived in the commercial
834
+ // client while the routes lived in a private brick, and both moved together.
835
+ // Every route below is admin-only server-side -- these helpers do not guard,
836
+ // they call.
837
+ // Every route below answers 403 to a non-admin. The screen still has to
838
+ // handle that: a role can be revoked while a tab stays open.
839
+
840
+ export const listAdminUsers = () => request("/api/admin/users");
841
+
842
+ // The password is set by the administrator and travels in this one request
843
+ // body: hashed server-side, never echoed back by any response.
844
+ export const createAdminUser = ({ email, firstName, lastName, password, role }) =>
845
+ request("/api/admin/users", {
846
+ method: "POST",
847
+ body: JSON.stringify({
848
+ email,
849
+ first_name: firstName,
850
+ last_name: lastName,
851
+ password,
852
+ ...(role ? { role } : {}),
853
+ }),
854
+ });
855
+
856
+ export const changeAdminUserRole = (userId, role) =>
857
+ request(`/api/admin/users/${userId}/role`, {
858
+ method: "PATCH",
859
+ body: JSON.stringify({ role }),
860
+ });
861
+
862
+ // The catalogue of permissions this build can enforce. Never hardcode it
863
+ // here: one added server-side must show up without a front deploy.
864
+ export const listAdminPermissions = () => request("/api/admin/permissions");
865
+
866
+ export const listAdminGroups = () => request("/api/admin/groups");
867
+
868
+ export const createAdminGroup = ({ name, description }) =>
869
+ request("/api/admin/groups", {
870
+ method: "POST",
871
+ body: JSON.stringify({ name, ...(description ? { description } : {}) }),
872
+ });
873
+
874
+ export const deleteAdminGroup = (groupId) =>
875
+ request(`/api/admin/groups/${groupId}`, { method: "DELETE" });
876
+
877
+ // Replaces the whole set rather than adding to it — the screen is a list of
878
+ // checkboxes, and an add-only call would make unticking one impossible.
879
+ export const setAdminGroupPermissions = (groupId, permissions) =>
880
+ request(`/api/admin/groups/${groupId}/permissions`, {
881
+ method: "PUT",
882
+ body: JSON.stringify({ permissions }),
883
+ });
884
+
885
+ export const addAdminGroupMember = (groupId, userId) =>
886
+ request(`/api/admin/groups/${groupId}/members`, {
887
+ method: "POST",
888
+ body: JSON.stringify({ user_id: userId }),
889
+ });
890
+
891
+ export const removeAdminGroupMember = (groupId, userId) =>
892
+ request(`/api/admin/groups/${groupId}/members/${userId}`, { method: "DELETE" });
893
+
894
+ // ---- Supervision ----
895
+ // Replaces listAllSessions() for this screen: that one fans out one ADK HTTP
896
+ // call per agent to return camelCase fields the table never read. This reads
897
+ // the tables directly, and carries the opening request, the step and tool
898
+ // counts, and whether anything errored.
899
+ export const listSupervisionSessions = ({ limit = 200, offset = 0 } = {}) =>
900
+ // `/api/supervision`, not `/api/evaluations`: supervision stays in the
901
+ // core while evaluation moves to a commercial brick.
902
+ request(`/api/supervision/sessions?limit=${limit}&offset=${offset}`);
903
+
904
+ // ---- Control panel: editing, demands, organisations ----
905
+
906
+ // What this administrator may do. Without it the screen would have to infer
907
+ // the boundary from what it happens to receive, and a filtered list looks
908
+ // exactly like a small one.
909
+ export const getAdminContext = () => request("/api/admin/me");
910
+
911
+ // Platform usage over a window, scoped server-side to what this
912
+ // administrator administers — an aggregate is the easiest place for a
913
+ // boundary to vanish unnoticed.
914
+ export const getAdminMetrics = (days = 30) =>
915
+ request(`/api/admin/metrics?days=${days}`);
916
+
917
+ // The email is deliberately not editable: every ownership table joins on it.
918
+ export const editAdminUser = (userId, { firstName, lastName, plan }) =>
919
+ request(`/api/admin/users/${userId}`, {
920
+ method: "PATCH",
921
+ body: JSON.stringify({
922
+ ...(firstName ? { first_name: firstName } : {}),
923
+ ...(lastName ? { last_name: lastName } : {}),
924
+ ...(plan ? { plan } : {}),
925
+ }),
926
+ });
927
+
928
+ // Refused server-side while the account still holds anything — the response
929
+ // says what, so the screen can show it rather than a bare failure.
930
+ export const deleteAdminUser = (userId) =>
931
+ request(`/api/admin/users/${userId}`, { method: "DELETE" });
932
+
933
+ // Invalidates every token the account holds, refresh cookie included.
934
+ // Scheduled agent runs are untouched: they carry a different token type.
935
+ export const forceRelogin = (userId) =>
936
+ request(`/api/admin/users/${userId}/force-relogin`, { method: "POST" });
937
+
938
+ // Demands a second factor, or stops demanding it. Enabling MFA *for*
939
+ // someone stays impossible by construction — the secret is born when they
940
+ // scan the QR code.
941
+ export const setMfaRequired = (userId, required) =>
942
+ request(`/api/admin/users/${userId}/require-mfa`, {
943
+ method: "POST",
944
+ body: JSON.stringify({ required }),
945
+ });
946
+
947
+ // Sends the core's own reset link. No temporary password is ever minted:
948
+ // an administrator who could set one could sign in as that person.
949
+ export const demandPasswordReset = (userId) =>
950
+ request(`/api/admin/users/${userId}/password-reset`, { method: "POST" });
951
+
952
+ export const demandEmailVerification = (userId) =>
953
+ request(`/api/admin/users/${userId}/require-email-verification`, { method: "POST" });
954
+
955
+ // The locked-out case. Enabling MFA for someone else is impossible: the
956
+ // secret is created when they scan the QR code.
957
+ export const disableAdminUserMfa = (userId) =>
958
+ request(`/api/admin/users/${userId}/disable-mfa`, { method: "POST" });
959
+
960
+ // Organisations — superadmin only; these answer 403 to an org admin.
961
+ export const listAdminOrganizations = () => request("/api/admin/organizations");
962
+
963
+ export const createAdminOrganization = ({ name, description }) =>
964
+ request("/api/admin/organizations", {
965
+ method: "POST",
966
+ body: JSON.stringify({ name, ...(description ? { description } : {}) }),
967
+ });
968
+
969
+ export const renameAdminOrganization = (orgId, { name, description }) =>
970
+ request(`/api/admin/organizations/${orgId}`, {
971
+ method: "PATCH",
972
+ body: JSON.stringify({ name, ...(description ? { description } : {}) }),
973
+ });
974
+
975
+ export const deleteAdminOrganization = (orgId) =>
976
+ request(`/api/admin/organizations/${orgId}`, { method: "DELETE" });
977
+
978
+ // A user belongs to at most one organisation, so this moves rather than adds.
979
+ export const setUserOrganization = (orgId, userId) =>
980
+ request(`/api/admin/organizations/${orgId}/members/${userId}`, { method: "PUT" });