@sylphx/management 0.1.0 → 0.2.0
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/CHANGELOG.md +88 -0
- package/LICENSE +21 -0
- package/README.md +157 -101
- package/dist/admin.d.ts +141 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/admin.js +96 -0
- package/dist/adminBootstrap.d.ts +46 -0
- package/dist/adminBootstrap.d.ts.map +1 -0
- package/dist/adminBootstrap.js +33 -0
- package/dist/adminBuilds.d.ts +72 -0
- package/dist/adminBuilds.d.ts.map +1 -0
- package/dist/adminBuilds.js +29 -0
- package/dist/adminEnvServices.d.ts +41 -0
- package/dist/adminEnvServices.d.ts.map +1 -0
- package/dist/adminEnvServices.js +22 -0
- package/dist/adminRateLimits.d.ts +61 -0
- package/dist/adminRateLimits.d.ts.map +1 -0
- package/dist/adminRateLimits.js +44 -0
- package/dist/adminReconcile.d.ts +45 -0
- package/dist/adminReconcile.d.ts.map +1 -0
- package/dist/adminReconcile.js +20 -0
- package/dist/adminResources.d.ts +97 -0
- package/dist/adminResources.d.ts.map +1 -0
- package/dist/adminResources.js +40 -0
- package/dist/adminSecrets.d.ts +60 -0
- package/dist/adminSecrets.d.ts.map +1 -0
- package/dist/adminSecrets.js +43 -0
- package/dist/adminTenants.d.ts +41 -0
- package/dist/adminTenants.d.ts.map +1 -0
- package/dist/adminTenants.js +29 -0
- package/dist/ai.d.ts +148 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +29 -0
- package/dist/analytics.d.ts +49 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +23 -0
- package/dist/auth.d.ts +39 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +27 -0
- package/dist/authSettings.d.ts +71 -0
- package/dist/authSettings.d.ts.map +1 -0
- package/dist/authSettings.js +39 -0
- package/dist/backups.d.ts +66 -0
- package/dist/backups.d.ts.map +1 -0
- package/dist/backups.js +32 -0
- package/dist/billing.d.ts +105 -0
- package/dist/billing.d.ts.map +1 -0
- package/dist/billing.js +42 -0
- package/dist/billingSettings.d.ts +78 -0
- package/dist/billingSettings.d.ts.map +1 -0
- package/dist/billingSettings.js +54 -0
- package/dist/branchDatabases.d.ts +53 -0
- package/dist/branchDatabases.d.ts.map +1 -0
- package/dist/branchDatabases.js +38 -0
- package/dist/certs.d.ts +63 -0
- package/dist/certs.d.ts.map +1 -0
- package/dist/certs.js +28 -0
- package/dist/ciSettings.d.ts +77 -0
- package/dist/ciSettings.d.ts.map +1 -0
- package/dist/ciSettings.js +41 -0
- package/dist/client.d.ts +36 -38
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +32 -90
- package/dist/consent.d.ts +111 -0
- package/dist/consent.d.ts.map +1 -0
- package/dist/consent.js +35 -0
- package/dist/databases.d.ts +17 -0
- package/dist/databases.d.ts.map +1 -0
- package/dist/databases.js +32 -0
- package/dist/deployments.d.ts +22 -0
- package/dist/deployments.d.ts.map +1 -0
- package/dist/deployments.js +39 -0
- package/dist/domains.d.ts +26 -0
- package/dist/domains.d.ts.map +1 -0
- package/dist/domains.js +39 -0
- package/dist/edgeDeployments.d.ts +43 -0
- package/dist/edgeDeployments.d.ts.map +1 -0
- package/dist/edgeDeployments.js +32 -0
- package/dist/email.d.ts +45 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +21 -0
- package/dist/engagement.d.ts +100 -0
- package/dist/engagement.d.ts.map +1 -0
- package/dist/engagement.js +28 -0
- package/dist/envVars.d.ts +17 -0
- package/dist/envVars.d.ts.map +1 -0
- package/dist/envVars.js +34 -0
- package/dist/environments.d.ts +41 -0
- package/dist/environments.d.ts.map +1 -0
- package/dist/environments.js +54 -0
- package/dist/errors.d.ts +8 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +8 -2
- package/dist/experiments.d.ts +80 -0
- package/dist/experiments.d.ts.map +1 -0
- package/dist/experiments.js +23 -0
- package/dist/flags.d.ts +85 -0
- package/dist/flags.d.ts.map +1 -0
- package/dist/flags.js +25 -0
- package/dist/functions.d.ts +39 -0
- package/dist/functions.d.ts.map +1 -0
- package/dist/functions.js +40 -0
- package/dist/github.d.ts +33 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +22 -0
- package/dist/http.d.ts +28 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +71 -0
- package/dist/index.d.ts +85 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +86 -20
- package/dist/kv.d.ts +66 -0
- package/dist/kv.d.ts.map +1 -0
- package/dist/kv.js +36 -0
- package/dist/logs.d.ts +14 -0
- package/dist/logs.d.ts.map +1 -0
- package/dist/logs.js +17 -0
- package/dist/management.d.ts +55 -0
- package/dist/management.d.ts.map +1 -0
- package/dist/management.js +31 -0
- package/dist/monitoring.d.ts +65 -0
- package/dist/monitoring.d.ts.map +1 -0
- package/dist/monitoring.js +29 -0
- package/dist/newsletter.d.ts +279 -0
- package/dist/newsletter.d.ts.map +1 -0
- package/dist/newsletter.js +98 -0
- package/dist/notifications.d.ts +30 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.js +19 -0
- package/dist/oidc.d.ts +46 -0
- package/dist/oidc.d.ts.map +1 -0
- package/dist/oidc.js +25 -0
- package/dist/organizations.d.ts +24 -0
- package/dist/organizations.d.ts.map +1 -0
- package/dist/organizations.js +42 -0
- package/dist/plans.d.ts +66 -0
- package/dist/plans.d.ts.map +1 -0
- package/dist/plans.js +42 -0
- package/dist/privacy.d.ts +138 -0
- package/dist/privacy.d.ts.map +1 -0
- package/dist/privacy.js +41 -0
- package/dist/projects.d.ts +14 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +22 -0
- package/dist/realtime.d.ts +33 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +19 -0
- package/dist/referrals.d.ts +100 -0
- package/dist/referrals.d.ts.map +1 -0
- package/dist/referrals.js +33 -0
- package/dist/refresh.d.ts +44 -0
- package/dist/refresh.d.ts.map +1 -0
- package/dist/refresh.js +33 -0
- package/dist/remoteConfig.d.ts +15 -0
- package/dist/remoteConfig.d.ts.map +1 -0
- package/dist/remoteConfig.js +35 -0
- package/dist/resourceBindings.d.ts +19 -0
- package/dist/resourceBindings.d.ts.map +1 -0
- package/dist/resourceBindings.js +24 -0
- package/dist/runners.d.ts +60 -0
- package/dist/runners.d.ts.map +1 -0
- package/dist/runners.js +17 -0
- package/dist/saml.d.ts +44 -0
- package/dist/saml.d.ts.map +1 -0
- package/dist/saml.js +77 -0
- package/dist/sandboxes.d.ts +15 -0
- package/dist/sandboxes.d.ts.map +1 -0
- package/dist/sandboxes.js +18 -0
- package/dist/search.d.ts +66 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +29 -0
- package/dist/secrets.d.ts +50 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +61 -0
- package/dist/security.d.ts +58 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +49 -0
- package/dist/serviceTokenRequests.d.ts +71 -0
- package/dist/serviceTokenRequests.d.ts.map +1 -0
- package/dist/serviceTokenRequests.js +43 -0
- package/dist/serviceTokens.d.ts +65 -0
- package/dist/serviceTokens.d.ts.map +1 -0
- package/dist/serviceTokens.js +22 -0
- package/dist/services.d.ts +10 -0
- package/dist/services.d.ts.map +1 -0
- package/dist/services.js +15 -0
- package/dist/sessionReplay.d.ts +116 -0
- package/dist/sessionReplay.d.ts.map +1 -0
- package/dist/sessionReplay.js +29 -0
- package/dist/storage.d.ts +12 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +10 -0
- package/dist/tasks.d.ts +29 -0
- package/dist/tasks.d.ts.map +1 -0
- package/dist/tasks.js +29 -0
- package/dist/types.d.ts +59 -155
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +17 -3
- package/dist/user.d.ts +99 -0
- package/dist/user.d.ts.map +1 -0
- package/dist/user.js +58 -0
- package/dist/users.d.ts +9 -0
- package/dist/users.d.ts.map +1 -0
- package/dist/users.js +11 -0
- package/dist/volumes.d.ts +16 -0
- package/dist/volumes.d.ts.map +1 -0
- package/dist/volumes.js +9 -0
- package/dist/webhooks.d.ts +77 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +27 -0
- package/package.json +194 -5
- package/dist/request.d.ts +0 -5
- package/dist/request.d.ts.map +0 -1
- package/dist/request.js +0 -1
- package/dist/resources/config.d.ts +0 -30
- package/dist/resources/config.d.ts.map +0 -1
- package/dist/resources/config.js +0 -62
- package/dist/resources/databases.d.ts +0 -26
- package/dist/resources/databases.d.ts.map +0 -1
- package/dist/resources/databases.js +0 -29
- package/dist/resources/deployments.d.ts +0 -24
- package/dist/resources/deployments.d.ts.map +0 -1
- package/dist/resources/deployments.js +0 -30
- package/dist/resources/domains.d.ts +0 -30
- package/dist/resources/domains.d.ts.map +0 -1
- package/dist/resources/domains.js +0 -46
- package/dist/resources/env-vars.d.ts +0 -19
- package/dist/resources/env-vars.d.ts.map +0 -1
- package/dist/resources/env-vars.js +0 -30
- package/dist/resources/environments.d.ts +0 -16
- package/dist/resources/environments.d.ts.map +0 -1
- package/dist/resources/environments.js +0 -24
- package/dist/resources/logs.d.ts +0 -13
- package/dist/resources/logs.d.ts.map +0 -1
- package/dist/resources/logs.js +0 -20
- package/dist/resources/org.d.ts +0 -15
- package/dist/resources/org.d.ts.map +0 -1
- package/dist/resources/org.js +0 -25
- package/dist/resources/projects.d.ts +0 -19
- package/dist/resources/projects.d.ts.map +0 -1
- package/dist/resources/projects.js +0 -19
- package/dist/resources/resources.d.ts +0 -26
- package/dist/resources/resources.d.ts.map +0 -1
- package/dist/resources/resources.js +0 -32
- package/dist/resources/services.d.ts +0 -21
- package/dist/resources/services.d.ts.map +0 -1
- package/dist/resources/services.js +0 -30
- package/dist/resources/storage.d.ts +0 -21
- package/dist/resources/storage.d.ts.map +0 -1
- package/dist/resources/storage.js +0 -25
- package/dist/resources/tasks.d.ts +0 -42
- package/dist/resources/tasks.d.ts.map +0 -1
- package/dist/resources/tasks.js +0 -49
- package/dist/resources/user.d.ts +0 -9
- package/dist/resources/user.d.ts.map +0 -1
- package/dist/resources/user.js +0 -10
- package/dist/resources/volumes.d.ts +0 -20
- package/dist/resources/volumes.d.ts.map +0 -1
- package/dist/resources/volumes.js +0 -19
package/dist/admin.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-admin (superuser) surface — quotas, audit logs, invitations,
|
|
3
|
+
* JWT key rotation, plan governance. Consumed by the internal Console
|
|
4
|
+
* "Admin" sections; ordinary operators do not call these.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors `apps/api/src/server/platform/routes/admin/**`. Paths are
|
|
7
|
+
* sourced from `@sylphx/contract` admin-* endpoint modules.
|
|
8
|
+
*/
|
|
9
|
+
import { adminAuditEndpoints, adminInvitationsEndpoints, adminJwtKeysEndpoints, adminProjectsEndpoints, adminQuotasEndpoints, adminUsersEndpoints, } from '@sylphx/contract';
|
|
10
|
+
import { interpolatePath, request } from './http.js';
|
|
11
|
+
export const getProjectQuotas = (client, projectId) => {
|
|
12
|
+
const { method, path } = adminQuotasEndpoints.getProjectQuotas;
|
|
13
|
+
return request(client, method, interpolatePath(path, { projectId }));
|
|
14
|
+
};
|
|
15
|
+
export const getQuotaStats = (client, projectId) => {
|
|
16
|
+
const { method, path } = adminQuotasEndpoints.getQuotaStats;
|
|
17
|
+
return request(client, method, interpolatePath(path, { projectId }));
|
|
18
|
+
};
|
|
19
|
+
export const getQuotaAlerts = (client, projectId) => {
|
|
20
|
+
const { method, path } = adminQuotasEndpoints.getQuotaAlerts;
|
|
21
|
+
return request(client, method, interpolatePath(path, { projectId }));
|
|
22
|
+
};
|
|
23
|
+
export const updateProjectQuotas = (client, projectId, body) => {
|
|
24
|
+
const { method, path } = adminQuotasEndpoints.updateQuota;
|
|
25
|
+
return request(client, method, interpolatePath(path, { projectId }), { body });
|
|
26
|
+
};
|
|
27
|
+
export const acknowledgeQuotaAlert = (client, alertId) => {
|
|
28
|
+
const { method, path } = adminQuotasEndpoints.acknowledgeAlert;
|
|
29
|
+
return request(client, method, interpolatePath(path, { alertId }));
|
|
30
|
+
};
|
|
31
|
+
export const getAuditLogs = (client, query) => {
|
|
32
|
+
const { method, path } = adminAuditEndpoints.logs;
|
|
33
|
+
return request(client, method, path, query ? { query } : {});
|
|
34
|
+
};
|
|
35
|
+
export const getAuditActivity = (client) => {
|
|
36
|
+
const { method, path } = adminAuditEndpoints.activity;
|
|
37
|
+
return request(client, method, path);
|
|
38
|
+
};
|
|
39
|
+
export const listInvitations = (client) => {
|
|
40
|
+
const { method, path } = adminInvitationsEndpoints.list;
|
|
41
|
+
return request(client, method, path);
|
|
42
|
+
};
|
|
43
|
+
export const createInvitation = (client, body) => {
|
|
44
|
+
const { method, path } = adminInvitationsEndpoints.create;
|
|
45
|
+
return request(client, method, path, { body });
|
|
46
|
+
};
|
|
47
|
+
export const revokeInvitation = (client, id) => {
|
|
48
|
+
const { method, path } = adminInvitationsEndpoints.revoke;
|
|
49
|
+
return request(client, method, interpolatePath(path, { id }));
|
|
50
|
+
};
|
|
51
|
+
export const resendInvitation = (client, id) => {
|
|
52
|
+
const { method, path } = adminInvitationsEndpoints.resend;
|
|
53
|
+
return request(client, method, interpolatePath(path, { id }));
|
|
54
|
+
};
|
|
55
|
+
export const listJwtKeys = (client) => {
|
|
56
|
+
const { method, path } = adminJwtKeysEndpoints.list;
|
|
57
|
+
return request(client, method, path);
|
|
58
|
+
};
|
|
59
|
+
export const rotateJwtKeys = (client) => {
|
|
60
|
+
const { method, path } = adminJwtKeysEndpoints.rotate;
|
|
61
|
+
return request(client, method, path);
|
|
62
|
+
};
|
|
63
|
+
export const retireJwtKey = (client, keyId) => {
|
|
64
|
+
const { method, path } = adminJwtKeysEndpoints.forceRetire;
|
|
65
|
+
return request(client, method, interpolatePath(path, { keyId }));
|
|
66
|
+
};
|
|
67
|
+
// ─── Admin project migration (multi-region) ────────────────────────────────
|
|
68
|
+
/**
|
|
69
|
+
* Trigger a project migration between regions. Phase 4b Matrix-2 gap.
|
|
70
|
+
* Underlying endpoint on the platform API is
|
|
71
|
+
* `POST /admin/projects/:id/migrate` — the SDK wraps it directly rather
|
|
72
|
+
* than going through `adminProjectsEndpoints` because migration is its
|
|
73
|
+
* own operational concern (drain → cut-over → warm-up).
|
|
74
|
+
*/
|
|
75
|
+
export const migrateProject = (client, projectId, body) => request(client, 'POST', `/admin/projects/${encodeURIComponent(projectId)}/migrate`, { body });
|
|
76
|
+
/**
|
|
77
|
+
* Regenerate an environment's deploy / API key. Already exposed on
|
|
78
|
+
* `adminProjectsEndpoints.regenerateKey`; surfaced here under the `admin`
|
|
79
|
+
* namespace so Console wiring is one-stop.
|
|
80
|
+
*/
|
|
81
|
+
export const regenerateEnvironmentKey = (client, environmentId) => {
|
|
82
|
+
const { method, path } = adminProjectsEndpoints.regenerateSecretKey;
|
|
83
|
+
return request(client, method, interpolatePath(path, { environmentId }));
|
|
84
|
+
};
|
|
85
|
+
export const listUsers = (client) => {
|
|
86
|
+
const { method, path } = adminUsersEndpoints.search;
|
|
87
|
+
return request(client, method, path);
|
|
88
|
+
};
|
|
89
|
+
export const getUser = (client, userId) => {
|
|
90
|
+
const { method, path } = adminUsersEndpoints.get;
|
|
91
|
+
return request(client, method, interpolatePath(path, { userId }));
|
|
92
|
+
};
|
|
93
|
+
export const updateUserRole = (client, userId, body) => {
|
|
94
|
+
const { method, path } = adminUsersEndpoints.updateRole;
|
|
95
|
+
return request(client, method, interpolatePath(path, { userId }), { body });
|
|
96
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminBootstrap` — reset the Appwrite-pattern bootstrap window.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `POST /admin/reset-bootstrap-window` in
|
|
5
|
+
* `apps/api/src/server/platform/routes/admin/bootstrap.ts` (ADR-089 §2.7
|
|
6
|
+
* Phase 7 Commit B).
|
|
7
|
+
*
|
|
8
|
+
* Auth: **platform super-admin session** (cookie). Deliberately NOT a
|
|
9
|
+
* service-token surface — see the route file's header for rationale.
|
|
10
|
+
*
|
|
11
|
+
* Typical use:
|
|
12
|
+
*
|
|
13
|
+
* sylphx admin reset-bootstrap-window
|
|
14
|
+
*
|
|
15
|
+
* dispatches here via `requireAuthEffect` + `withAuthedSdk`. Once this
|
|
16
|
+
* call returns, the operator has ~10 minutes to point the new admin at
|
|
17
|
+
* `POST /v1/auth/bootstrap-signup` with the `X-Sylphx-Project-Id: platform`
|
|
18
|
+
* header; after that the window closes itself and the endpoint 404s.
|
|
19
|
+
*/
|
|
20
|
+
import type { Client } from './client.js';
|
|
21
|
+
/**
|
|
22
|
+
* Confirmation returned by {@link resetWindow}.
|
|
23
|
+
*
|
|
24
|
+
* `ttlSeconds` mirrors `BOOTSTRAP_WINDOW_TTL_SECONDS` on the server
|
|
25
|
+
* (`packages/core/src/lib/bootstrap-window.ts`). Carried on the wire so
|
|
26
|
+
* CLI output can show an accurate countdown without hard-coding the
|
|
27
|
+
* value client-side.
|
|
28
|
+
*/
|
|
29
|
+
export interface ResetBootstrapWindowResult {
|
|
30
|
+
/** Always `true` when the endpoint returns 200. */
|
|
31
|
+
readonly opened: boolean;
|
|
32
|
+
/** Seconds until the window closes again. */
|
|
33
|
+
readonly ttlSeconds: number;
|
|
34
|
+
/** Operator-facing next-step instruction. */
|
|
35
|
+
readonly message: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Re-open the bootstrap window for 10 minutes.
|
|
39
|
+
*
|
|
40
|
+
* Authenticates as the caller's platform super-admin session. The
|
|
41
|
+
* server emits an `admin_action` audit event + a
|
|
42
|
+
* `sylphx_bootstrap_window_reset_total` metric tick for every
|
|
43
|
+
* invocation, so this call is never silent.
|
|
44
|
+
*/
|
|
45
|
+
export declare const resetWindow: (client: Client) => Promise<ResetBootstrapWindowResult>;
|
|
46
|
+
//# sourceMappingURL=adminBootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adminBootstrap.d.ts","sourceRoot":"","sources":["../src/adminBootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IAC1C,mDAAmD;IACnD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACxB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,KAAG,OAAO,CAAC,0BAA0B,CAG9E,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminBootstrap` — reset the Appwrite-pattern bootstrap window.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `POST /admin/reset-bootstrap-window` in
|
|
5
|
+
* `apps/api/src/server/platform/routes/admin/bootstrap.ts` (ADR-089 §2.7
|
|
6
|
+
* Phase 7 Commit B).
|
|
7
|
+
*
|
|
8
|
+
* Auth: **platform super-admin session** (cookie). Deliberately NOT a
|
|
9
|
+
* service-token surface — see the route file's header for rationale.
|
|
10
|
+
*
|
|
11
|
+
* Typical use:
|
|
12
|
+
*
|
|
13
|
+
* sylphx admin reset-bootstrap-window
|
|
14
|
+
*
|
|
15
|
+
* dispatches here via `requireAuthEffect` + `withAuthedSdk`. Once this
|
|
16
|
+
* call returns, the operator has ~10 minutes to point the new admin at
|
|
17
|
+
* `POST /v1/auth/bootstrap-signup` with the `X-Sylphx-Project-Id: platform`
|
|
18
|
+
* header; after that the window closes itself and the endpoint 404s.
|
|
19
|
+
*/
|
|
20
|
+
import { adminBootstrapEndpoints } from '@sylphx/contract';
|
|
21
|
+
import { request } from './http.js';
|
|
22
|
+
/**
|
|
23
|
+
* Re-open the bootstrap window for 10 minutes.
|
|
24
|
+
*
|
|
25
|
+
* Authenticates as the caller's platform super-admin session. The
|
|
26
|
+
* server emits an `admin_action` audit event + a
|
|
27
|
+
* `sylphx_bootstrap_window_reset_total` metric tick for every
|
|
28
|
+
* invocation, so this call is never silent.
|
|
29
|
+
*/
|
|
30
|
+
export const resetWindow = (client) => {
|
|
31
|
+
const { method, path } = adminBootstrapEndpoints.resetWindow;
|
|
32
|
+
return request(client, method, path, { body: {} });
|
|
33
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminBuilds` — operator recovery for stuck builds.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `POST /admin/builds/reap` in
|
|
5
|
+
* `apps/api/src/server/platform/routes/admin/builds.ts`. Replaces the raw
|
|
6
|
+
* `UPDATE build_records SET status='failed' …` historically run from psql
|
|
7
|
+
* per `docs/runbooks/build-records-stuck-in-building.md`.
|
|
8
|
+
*
|
|
9
|
+
* Typical use: an on-call engineer mints a service token scoped to
|
|
10
|
+
* `platform:builds:reap`, points the CLI (`sylphx admin builds reap`) at
|
|
11
|
+
* the cluster, and the CLI calls `reap()` here. CI / cron / dashboards
|
|
12
|
+
* call this SDK directly.
|
|
13
|
+
*
|
|
14
|
+
* The API does NOT touch `build_records` rows whose `started_at IS NULL`
|
|
15
|
+
* (a different failure mode — queue starvation).
|
|
16
|
+
*/
|
|
17
|
+
import type { Client } from './client.js';
|
|
18
|
+
export interface ReapBuildsInput {
|
|
19
|
+
/**
|
|
20
|
+
* Window grammar `^[0-9]+(s|m|h|d)$`. Examples: `30m`, `2h`, `1d`. Rows
|
|
21
|
+
* whose `started_at < NOW() - olderThan` are in the candidate set.
|
|
22
|
+
*/
|
|
23
|
+
readonly olderThan: string;
|
|
24
|
+
/**
|
|
25
|
+
* When true, returns the candidate set without mutating anything.
|
|
26
|
+
* `reason` becomes optional in this mode.
|
|
27
|
+
*/
|
|
28
|
+
readonly dryRun?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Required on the write path (min 3 chars). Goes verbatim into the
|
|
31
|
+
* audit row + into each reaped row's `failure_reason` column (prefixed
|
|
32
|
+
* `admin reap: `). Surfaced to the affected customer in Console.
|
|
33
|
+
*/
|
|
34
|
+
readonly reason?: string;
|
|
35
|
+
/**
|
|
36
|
+
* OPS-7 fold-in. When provided, restricts the candidate set to rows
|
|
37
|
+
* whose `image_digest = <digest>` AND additionally NULLs the column on
|
|
38
|
+
* each reaped row. Format: `sha256:<64hex>`.
|
|
39
|
+
*/
|
|
40
|
+
readonly imageDigest?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ReapBuildsRecord {
|
|
43
|
+
/** TypeID (`bld_xxx`). */
|
|
44
|
+
readonly id: string;
|
|
45
|
+
/** TypeID (`proj_xxx`). */
|
|
46
|
+
readonly projectId: string;
|
|
47
|
+
/** TypeID (`env_xxx`). */
|
|
48
|
+
readonly envId: string;
|
|
49
|
+
/** ISO-8601. */
|
|
50
|
+
readonly startedAt: string;
|
|
51
|
+
/** Wall-clock age at reap time. Floored to whole seconds. */
|
|
52
|
+
readonly ageSeconds: number;
|
|
53
|
+
}
|
|
54
|
+
export interface ReapBuildsResult {
|
|
55
|
+
/** Echo of the request flag. */
|
|
56
|
+
readonly dryRun: boolean;
|
|
57
|
+
/** Rows transitioned (`0` on dry-run). */
|
|
58
|
+
readonly reaped: number;
|
|
59
|
+
/** Rows whose stale `image_digest` was additionally cleared. */
|
|
60
|
+
readonly digestCleared: number;
|
|
61
|
+
/** Up to 1000 rows from the candidate set / write set. */
|
|
62
|
+
readonly records: ReadonlyArray<ReapBuildsRecord>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Reap stuck `build_records` rows older than `input.olderThan`. Single
|
|
66
|
+
* UPDATE statement on the write path; SELECT only on `dryRun=true`.
|
|
67
|
+
*
|
|
68
|
+
* Idempotent: re-running with the same window flips zero rows because the
|
|
69
|
+
* first call already moved them out of `'building'`.
|
|
70
|
+
*/
|
|
71
|
+
export declare const reap: (client: Client, input: ReapBuildsInput) => Promise<ReapBuildsResult>;
|
|
72
|
+
//# sourceMappingURL=adminBuilds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adminBuilds.d.ts","sourceRoot":"","sources":["../src/adminBuilds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,MAAM,WAAW,eAAe;IAC/B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;IACzB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAChC,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,2BAA2B;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,gBAAgB;IAChB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAChC,gCAAgC;IAChC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,gEAAgE;IAChE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAA;CACjD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,GAAI,QAAQ,MAAM,EAAE,OAAO,eAAe,KAAG,OAAO,CAAC,gBAAgB,CAGrF,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminBuilds` — operator recovery for stuck builds.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `POST /admin/builds/reap` in
|
|
5
|
+
* `apps/api/src/server/platform/routes/admin/builds.ts`. Replaces the raw
|
|
6
|
+
* `UPDATE build_records SET status='failed' …` historically run from psql
|
|
7
|
+
* per `docs/runbooks/build-records-stuck-in-building.md`.
|
|
8
|
+
*
|
|
9
|
+
* Typical use: an on-call engineer mints a service token scoped to
|
|
10
|
+
* `platform:builds:reap`, points the CLI (`sylphx admin builds reap`) at
|
|
11
|
+
* the cluster, and the CLI calls `reap()` here. CI / cron / dashboards
|
|
12
|
+
* call this SDK directly.
|
|
13
|
+
*
|
|
14
|
+
* The API does NOT touch `build_records` rows whose `started_at IS NULL`
|
|
15
|
+
* (a different failure mode — queue starvation).
|
|
16
|
+
*/
|
|
17
|
+
import { adminBuildsEndpoints } from '@sylphx/contract';
|
|
18
|
+
import { request } from './http.js';
|
|
19
|
+
/**
|
|
20
|
+
* Reap stuck `build_records` rows older than `input.olderThan`. Single
|
|
21
|
+
* UPDATE statement on the write path; SELECT only on `dryRun=true`.
|
|
22
|
+
*
|
|
23
|
+
* Idempotent: re-running with the same window flips zero rows because the
|
|
24
|
+
* first call already moved them out of `'building'`.
|
|
25
|
+
*/
|
|
26
|
+
export const reap = (client, input) => {
|
|
27
|
+
const { method, path } = adminBuildsEndpoints.reap;
|
|
28
|
+
return request(client, method, path, { body: input });
|
|
29
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminEnvServices` — operator repoint of env-service
|
|
3
|
+
* desired-image pointers (OPS-4).
|
|
4
|
+
*
|
|
5
|
+
* Mirrors `POST /admin/env-services/repoint` in
|
|
6
|
+
* `apps/api/src/server/platform/routes/admin/env-services.ts`. Replaces
|
|
7
|
+
* the raw `UPDATE environment_services …` historically run from psql
|
|
8
|
+
* per `docs/how-to/customer-image-gc-outreach.md`.
|
|
9
|
+
*/
|
|
10
|
+
import type { Client } from './client.js';
|
|
11
|
+
export interface RepointEnvServiceInput {
|
|
12
|
+
/** TypeID (`env_*`) of the target environment. */
|
|
13
|
+
readonly envId: string;
|
|
14
|
+
/** Service name within the project (`project_services.name`). */
|
|
15
|
+
readonly service: string;
|
|
16
|
+
/** Image digest to repoint to. Format: `sha256:<64hex>`. */
|
|
17
|
+
readonly digest: string;
|
|
18
|
+
/** Audit narrative. Min 3 chars. */
|
|
19
|
+
readonly reason: string;
|
|
20
|
+
}
|
|
21
|
+
export interface RepointEnvServiceResult {
|
|
22
|
+
/** TypeID (`esvc_*`) of the env_service that was re-pointed. */
|
|
23
|
+
readonly envServiceId: string;
|
|
24
|
+
/** Image digest the env_service was previously pointing to (null on first repoint). */
|
|
25
|
+
readonly previousDigest: string | null;
|
|
26
|
+
/** Echo of the request `digest`. */
|
|
27
|
+
readonly newDigest: string;
|
|
28
|
+
/** TypeID (`dpl_*`) of the deployments row that carries the new pointer. */
|
|
29
|
+
readonly deploymentId: string;
|
|
30
|
+
/** `true` iff an existing deployments row was reused instead of inserted. */
|
|
31
|
+
readonly reused: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Repoint an env_service to a specific image digest. The artifact MUST
|
|
35
|
+
* already exist for `(serviceId, digest)`; the endpoint never mints
|
|
36
|
+
* artifacts. Returns 404 on any of: env not found, service name not in
|
|
37
|
+
* project, env_service not attached, artifact missing. Returns 409 if
|
|
38
|
+
* the env_service is in a terminal lifecycle state.
|
|
39
|
+
*/
|
|
40
|
+
export declare const repoint: (client: Client, input: RepointEnvServiceInput) => Promise<RepointEnvServiceResult>;
|
|
41
|
+
//# sourceMappingURL=adminEnvServices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adminEnvServices.d.ts","sourceRoot":"","sources":["../src/adminEnvServices.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,MAAM,WAAW,sBAAsB;IACtC,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,oCAAoC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,uBAAuB;IACvC,gEAAgE;IAChE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,uFAAuF;IACvF,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,oCAAoC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GACnB,QAAQ,MAAM,EACd,OAAO,sBAAsB,KAC3B,OAAO,CAAC,uBAAuB,CAGjC,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminEnvServices` — operator repoint of env-service
|
|
3
|
+
* desired-image pointers (OPS-4).
|
|
4
|
+
*
|
|
5
|
+
* Mirrors `POST /admin/env-services/repoint` in
|
|
6
|
+
* `apps/api/src/server/platform/routes/admin/env-services.ts`. Replaces
|
|
7
|
+
* the raw `UPDATE environment_services …` historically run from psql
|
|
8
|
+
* per `docs/how-to/customer-image-gc-outreach.md`.
|
|
9
|
+
*/
|
|
10
|
+
import { adminEnvServicesEndpoints } from '@sylphx/contract';
|
|
11
|
+
import { request } from './http.js';
|
|
12
|
+
/**
|
|
13
|
+
* Repoint an env_service to a specific image digest. The artifact MUST
|
|
14
|
+
* already exist for `(serviceId, digest)`; the endpoint never mints
|
|
15
|
+
* artifacts. Returns 404 on any of: env not found, service name not in
|
|
16
|
+
* project, env_service not attached, artifact missing. Returns 409 if
|
|
17
|
+
* the env_service is in a terminal lifecycle state.
|
|
18
|
+
*/
|
|
19
|
+
export const repoint = (client, input) => {
|
|
20
|
+
const { method, path } = adminEnvServicesEndpoints.repoint;
|
|
21
|
+
return request(client, method, path, { body: input });
|
|
22
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminRateLimits` — operator-driven tuning of
|
|
3
|
+
* per-credential-type rate-limit multipliers (Production-Ready audit M-3).
|
|
4
|
+
*
|
|
5
|
+
* Mirrors `/admin/rate-limits/*` in
|
|
6
|
+
* `apps/api/src/server/platform/routes/admin/rate-limits.ts`.
|
|
7
|
+
*
|
|
8
|
+
* Auth: service token + scope `platform:ratelimits:write`. Super-admin
|
|
9
|
+
* sessions also pass through `requireScopes` (their `scopes` are `null`),
|
|
10
|
+
* but the preferred path is a programmatic step in an Ops runbook.
|
|
11
|
+
*
|
|
12
|
+
* Typical use:
|
|
13
|
+
*
|
|
14
|
+
* sylphx admin rate-limits list
|
|
15
|
+
* sylphx admin rate-limits set --type public --multiplier 0.05 \
|
|
16
|
+
* --reason "credential-enumeration alert"
|
|
17
|
+
*
|
|
18
|
+
* dispatches here via `requireAuthEffect` + `withAuthedSdk`. The endpoint
|
|
19
|
+
* upserts the row + triggers `invalidateAndReload()` on the enforcement
|
|
20
|
+
* layer so the new value is live within seconds.
|
|
21
|
+
*/
|
|
22
|
+
import type { Client } from './client.js';
|
|
23
|
+
/** Credential-type literal — mirrors `AdminRateLimitCredentialType` in the contract. */
|
|
24
|
+
export type AdminRateLimitCredentialType = 'public' | 'secret' | 'service' | 'session' | 'spiffe' | 'unknown';
|
|
25
|
+
export interface AdminRateLimitMultiplierStatus {
|
|
26
|
+
readonly credentialType: AdminRateLimitCredentialType;
|
|
27
|
+
readonly multiplier: number;
|
|
28
|
+
readonly exempt: boolean;
|
|
29
|
+
readonly notes: string | null;
|
|
30
|
+
readonly lastUpdatedAt: string | null;
|
|
31
|
+
}
|
|
32
|
+
export interface ListMultipliersResult {
|
|
33
|
+
readonly multipliers: ReadonlyArray<AdminRateLimitMultiplierStatus>;
|
|
34
|
+
}
|
|
35
|
+
export interface SetMultiplierInput {
|
|
36
|
+
readonly credentialType: AdminRateLimitCredentialType;
|
|
37
|
+
readonly multiplier: number;
|
|
38
|
+
readonly exempt?: boolean;
|
|
39
|
+
readonly reason: string;
|
|
40
|
+
}
|
|
41
|
+
export interface SetMultiplierResult {
|
|
42
|
+
readonly updated: AdminRateLimitMultiplierStatus;
|
|
43
|
+
readonly auditLogId: string | null;
|
|
44
|
+
readonly message: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* List the per-credential-type multipliers currently applied to every
|
|
48
|
+
* `RateLimitPresets` base limit. Returns one row per credential type from
|
|
49
|
+
* the closed enumeration (`public`, `secret`, `service`, `session`,
|
|
50
|
+
* `spiffe`, `unknown`); rows missing in the DB fall back to the live
|
|
51
|
+
* in-memory cache so the dashboard never sees a hole.
|
|
52
|
+
*/
|
|
53
|
+
export declare const list: (client: Client) => Promise<ListMultipliersResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Upsert the multiplier (or exempt flag) for a single credential type.
|
|
56
|
+
* `reason` is required (≥3 chars) and recorded on the audit log. The
|
|
57
|
+
* server fires `invalidateAndReload()` immediately after the write so the
|
|
58
|
+
* new value is live within seconds — no 5-minute wait.
|
|
59
|
+
*/
|
|
60
|
+
export declare const set: (client: Client, body: SetMultiplierInput) => Promise<SetMultiplierResult>;
|
|
61
|
+
//# sourceMappingURL=adminRateLimits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adminRateLimits.d.ts","sourceRoot":"","sources":["../src/adminRateLimits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,wFAAwF;AACxF,MAAM,MAAM,4BAA4B,GACrC,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,SAAS,GACT,QAAQ,GACR,SAAS,CAAA;AAEZ,MAAM,WAAW,8BAA8B;IAC9C,QAAQ,CAAC,cAAc,EAAE,4BAA4B,CAAA;IACrD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CACrC;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,8BAA8B,CAAC,CAAA;CACnE;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,cAAc,EAAE,4BAA4B,CAAA;IACrD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,OAAO,EAAE,8BAA8B,CAAA;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,GAAI,QAAQ,MAAM,KAAG,OAAO,CAAC,qBAAqB,CAGlE,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,GAAG,GAAI,QAAQ,MAAM,EAAE,MAAM,kBAAkB,KAAG,OAAO,CAAC,mBAAmB,CAGzF,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminRateLimits` — operator-driven tuning of
|
|
3
|
+
* per-credential-type rate-limit multipliers (Production-Ready audit M-3).
|
|
4
|
+
*
|
|
5
|
+
* Mirrors `/admin/rate-limits/*` in
|
|
6
|
+
* `apps/api/src/server/platform/routes/admin/rate-limits.ts`.
|
|
7
|
+
*
|
|
8
|
+
* Auth: service token + scope `platform:ratelimits:write`. Super-admin
|
|
9
|
+
* sessions also pass through `requireScopes` (their `scopes` are `null`),
|
|
10
|
+
* but the preferred path is a programmatic step in an Ops runbook.
|
|
11
|
+
*
|
|
12
|
+
* Typical use:
|
|
13
|
+
*
|
|
14
|
+
* sylphx admin rate-limits list
|
|
15
|
+
* sylphx admin rate-limits set --type public --multiplier 0.05 \
|
|
16
|
+
* --reason "credential-enumeration alert"
|
|
17
|
+
*
|
|
18
|
+
* dispatches here via `requireAuthEffect` + `withAuthedSdk`. The endpoint
|
|
19
|
+
* upserts the row + triggers `invalidateAndReload()` on the enforcement
|
|
20
|
+
* layer so the new value is live within seconds.
|
|
21
|
+
*/
|
|
22
|
+
import { adminRateLimitsEndpoints } from '@sylphx/contract';
|
|
23
|
+
import { request } from './http.js';
|
|
24
|
+
/**
|
|
25
|
+
* List the per-credential-type multipliers currently applied to every
|
|
26
|
+
* `RateLimitPresets` base limit. Returns one row per credential type from
|
|
27
|
+
* the closed enumeration (`public`, `secret`, `service`, `session`,
|
|
28
|
+
* `spiffe`, `unknown`); rows missing in the DB fall back to the live
|
|
29
|
+
* in-memory cache so the dashboard never sees a hole.
|
|
30
|
+
*/
|
|
31
|
+
export const list = (client) => {
|
|
32
|
+
const { method, path } = adminRateLimitsEndpoints.listStrategies;
|
|
33
|
+
return request(client, method, path, {});
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Upsert the multiplier (or exempt flag) for a single credential type.
|
|
37
|
+
* `reason` is required (≥3 chars) and recorded on the audit log. The
|
|
38
|
+
* server fires `invalidateAndReload()` immediately after the write so the
|
|
39
|
+
* new value is live within seconds — no 5-minute wait.
|
|
40
|
+
*/
|
|
41
|
+
export const set = (client, body) => {
|
|
42
|
+
const { method, path } = adminRateLimitsEndpoints.setStrategy;
|
|
43
|
+
return request(client, method, path, { body });
|
|
44
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminReconcile` — operator reset of `reconcile_status`.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `POST /admin/reconcile/reset` in
|
|
5
|
+
* `apps/api/src/server/platform/routes/admin/reconcile.ts`. Replaces the
|
|
6
|
+
* raw `UPDATE … SET reconcile_status = 'pending'` historically run from
|
|
7
|
+
* psql per `docs/how-to/reconciler-cleanup-semantic.md`.
|
|
8
|
+
*/
|
|
9
|
+
import type { Client } from './client.js';
|
|
10
|
+
export type ReconcileKind = 'service' | 'environment';
|
|
11
|
+
export type ReconcileTarget = 'pending' | 'synced';
|
|
12
|
+
export interface ResetReconcileInput {
|
|
13
|
+
/** `service` → `environment_services` row; `environment` → `project_environments` row. */
|
|
14
|
+
readonly kind: ReconcileKind;
|
|
15
|
+
/** TypeID — `esvc_*` for `service`, `env_*` for `environment`. */
|
|
16
|
+
readonly id: string;
|
|
17
|
+
/**
|
|
18
|
+
* Target `reconcile_status`.
|
|
19
|
+
*
|
|
20
|
+
* - `pending` — re-arm the reconciler (also bumps `generation`).
|
|
21
|
+
* - `synced` — mark complete after out-of-band verification.
|
|
22
|
+
*/
|
|
23
|
+
readonly to: ReconcileTarget;
|
|
24
|
+
/** Audit narrative. Min 3 chars. */
|
|
25
|
+
readonly reason: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ResetReconcileResult {
|
|
28
|
+
readonly kind: ReconcileKind;
|
|
29
|
+
/** TypeID. */
|
|
30
|
+
readonly id: string;
|
|
31
|
+
/** `reconcile_status` value the row carried just before the UPDATE landed. */
|
|
32
|
+
readonly previousStatus: string;
|
|
33
|
+
/** Final `reconcile_status` (matches `to`). */
|
|
34
|
+
readonly newStatus: ReconcileTarget;
|
|
35
|
+
/** `true` iff the endpoint additionally incremented `generation`. */
|
|
36
|
+
readonly generationBumped: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Reset reconcile_status on a service or environment row. Refuses
|
|
40
|
+
* `terminating`/`terminated` source states (use force-delete via OPS-3
|
|
41
|
+
* instead) and refuses illegal transitions per the route file's
|
|
42
|
+
* transition table.
|
|
43
|
+
*/
|
|
44
|
+
export declare const reset: (client: Client, input: ResetReconcileInput) => Promise<ResetReconcileResult>;
|
|
45
|
+
//# sourceMappingURL=adminReconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adminReconcile.d.ts","sourceRoot":"","sources":["../src/adminReconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,aAAa,CAAA;AACrD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,QAAQ,CAAA;AAElD,MAAM,WAAW,mBAAmB;IACnC,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,eAAe,CAAA;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAC5B,cAAc;IACd,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,8EAA8E;IAC9E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAA;IACnC,qEAAqE;IACrE,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAA;CAClC;AAED;;;;;GAKG;AACH,eAAO,MAAM,KAAK,GACjB,QAAQ,MAAM,EACd,OAAO,mBAAmB,KACxB,OAAO,CAAC,oBAAoB,CAG9B,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminReconcile` — operator reset of `reconcile_status`.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `POST /admin/reconcile/reset` in
|
|
5
|
+
* `apps/api/src/server/platform/routes/admin/reconcile.ts`. Replaces the
|
|
6
|
+
* raw `UPDATE … SET reconcile_status = 'pending'` historically run from
|
|
7
|
+
* psql per `docs/how-to/reconciler-cleanup-semantic.md`.
|
|
8
|
+
*/
|
|
9
|
+
import { adminReconcileEndpoints } from '@sylphx/contract';
|
|
10
|
+
import { request } from './http.js';
|
|
11
|
+
/**
|
|
12
|
+
* Reset reconcile_status on a service or environment row. Refuses
|
|
13
|
+
* `terminating`/`terminated` source states (use force-delete via OPS-3
|
|
14
|
+
* instead) and refuses illegal transitions per the route file's
|
|
15
|
+
* transition table.
|
|
16
|
+
*/
|
|
17
|
+
export const reset = (client, input) => {
|
|
18
|
+
const { method, path } = adminReconcileEndpoints.reset;
|
|
19
|
+
return request(client, method, path, { body: input });
|
|
20
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@sylphx/management/adminResources` — operator recovery for stuck resources.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `DELETE /admin/resources/:id` in
|
|
5
|
+
* `apps/api/src/server/platform/routes/admin/resources.ts`. Replaces the
|
|
6
|
+
* raw `DELETE FROM managed_resources WHERE id=...` historically run from
|
|
7
|
+
* psql per `docs/how-to/teardown-failure.md`.
|
|
8
|
+
*
|
|
9
|
+
* Typical use: an on-call engineer mints a service token scoped to
|
|
10
|
+
* `platform:resources:forcedelete`, points the CLI
|
|
11
|
+
* (`sylphx admin resources force-delete <id>`) at the cluster, and the
|
|
12
|
+
* CLI calls `forceDelete()` here. CI / cron / dashboards call this SDK
|
|
13
|
+
* directly.
|
|
14
|
+
*/
|
|
15
|
+
import type { Client } from './client.js';
|
|
16
|
+
export interface ForceDeleteResourceInput {
|
|
17
|
+
/**
|
|
18
|
+
* Required. Goes verbatim into the audit row. Min 3 chars.
|
|
19
|
+
*/
|
|
20
|
+
readonly reason: string;
|
|
21
|
+
/**
|
|
22
|
+
* When `true`, also tears down polymorphic dependents
|
|
23
|
+
* (`project_resource_bindings` rows; the FK-cascading
|
|
24
|
+
* `project_platform_resources` row is removed automatically and
|
|
25
|
+
* counted in `dependentsDeleted`). Default `false`.
|
|
26
|
+
*/
|
|
27
|
+
readonly cascade?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Escape hatch for rows whose `reconcile_status` is NOT `terminating`.
|
|
30
|
+
* Default `false`. The endpoint refuses the row otherwise — the
|
|
31
|
+
* reconciler should drive normal teardown; only rows already in
|
|
32
|
+
* `terminating` are valid candidates.
|
|
33
|
+
*/
|
|
34
|
+
readonly reallyForce?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface ForceDeleteResourceResult {
|
|
37
|
+
/** TypeID (`res_xxx`). */
|
|
38
|
+
readonly id: string;
|
|
39
|
+
/** `reconcile_status` value the row carried just before the DELETE landed. */
|
|
40
|
+
readonly previousStatus: string;
|
|
41
|
+
/** Echo of the request flag. */
|
|
42
|
+
readonly cascade: boolean;
|
|
43
|
+
/** Echo of the request flag. */
|
|
44
|
+
readonly reallyForce: boolean;
|
|
45
|
+
/** Count of polymorphic dependents removed (always 0 when cascade=false). */
|
|
46
|
+
readonly dependentsDeleted: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Force-delete a stuck `managed_resources` row. Refuses the call when
|
|
50
|
+
* `reconcile_status !== 'terminating'` unless `reallyForce=true`. Returns
|
|
51
|
+
* 404 when the row does not exist; 409 on the wrong-status path.
|
|
52
|
+
*/
|
|
53
|
+
export declare const forceDelete: (client: Client, id: string, input: ForceDeleteResourceInput) => Promise<ForceDeleteResourceResult>;
|
|
54
|
+
export interface ResealResourcesInput {
|
|
55
|
+
/**
|
|
56
|
+
* The active KEK ID the operator believes the platform is serving with.
|
|
57
|
+
* The endpoint refuses with 409 if the live ring's `activeKeyId` does
|
|
58
|
+
* not match — protecting against split-brain rotations where two
|
|
59
|
+
* operators race.
|
|
60
|
+
*/
|
|
61
|
+
readonly keyId: string;
|
|
62
|
+
/**
|
|
63
|
+
* Reserved for future per-row scoping. Today the registry walks all
|
|
64
|
+
* rows under retired keys; the filter is logged as ignored.
|
|
65
|
+
*/
|
|
66
|
+
readonly filter?: {
|
|
67
|
+
readonly projectId?: string;
|
|
68
|
+
readonly envId?: string;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export interface ResealResourcesFieldResult {
|
|
72
|
+
readonly fieldName: string;
|
|
73
|
+
readonly rowsSeen: number;
|
|
74
|
+
readonly rowsRotated: number;
|
|
75
|
+
readonly rowsFailed: number;
|
|
76
|
+
readonly failures: ReadonlyArray<{
|
|
77
|
+
readonly id: string;
|
|
78
|
+
readonly reason: string;
|
|
79
|
+
}>;
|
|
80
|
+
}
|
|
81
|
+
export interface ResealResourcesResult {
|
|
82
|
+
/** The active KEK id the server is serving with (echo of input on success). */
|
|
83
|
+
readonly activeKeyId: string;
|
|
84
|
+
/** Total rows rewritten across all fields. */
|
|
85
|
+
readonly totalRotated: number;
|
|
86
|
+
/** Total rows that failed to rotate (per-row failures, not pass-level). */
|
|
87
|
+
readonly totalFailed: number;
|
|
88
|
+
/** Per-field rotation breakdown. Mirrors `RotationFieldResult`. */
|
|
89
|
+
readonly fields: ReadonlyArray<ResealResourcesFieldResult>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Walk the canonical rotation registry and re-encrypt every row whose
|
|
93
|
+
* envelope is not under the active KEK. Idempotent: re-running after
|
|
94
|
+
* convergence rewrites zero rows. Returns 409 on `keyId` mismatch.
|
|
95
|
+
*/
|
|
96
|
+
export declare const reseal: (client: Client, input: ResealResourcesInput) => Promise<ResealResourcesResult>;
|
|
97
|
+
//# sourceMappingURL=adminResources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adminResources.d.ts","sourceRoot":"","sources":["../src/adminResources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,MAAM,WAAW,wBAAwB;IACxC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAC9B;AAED,MAAM,WAAW,yBAAyB;IACzC,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,8EAA8E;IAC9E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,gCAAgC;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,gCAAgC;IAChC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;CAClC;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,GACvB,QAAQ,MAAM,EACd,IAAI,MAAM,EACV,OAAO,wBAAwB,KAC7B,OAAO,CAAC,yBAAyB,CAOnC,CAAA;AAID,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QACjB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;QAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KACvB,CAAA;CACD;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;QAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KACvB,CAAC,CAAA;CACF;AAED,MAAM,WAAW,qBAAqB;IACrC,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,8CAA8C;IAC9C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,0BAA0B,CAAC,CAAA;CAC1D;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAClB,QAAQ,MAAM,EACd,OAAO,oBAAoB,KACzB,OAAO,CAAC,qBAAqB,CAG/B,CAAA"}
|