feat(housekeeping): compose operations workspace
This commit is contained in:
1 parent
5574e601bb
commit
85ad0452d3
22 files changed
+1240
-87
No files matched your search
@@ -0,0 +1,97 @@
|
||||
import "server-only";
|
||||
|
||||
import { PERMS } from "@/lib/permission-slugs";
|
||||
import { authorizeHousekeeping } from "../../foundation/authorization";
|
||||
import { satisfiesCapability } from "../../foundation/capability-context";
|
||||
import {
|
||||
anyCapability,
|
||||
fail,
|
||||
type HousekeepingCapabilityContext,
|
||||
type HousekeepingInboxSource,
|
||||
ok,
|
||||
} from "../../foundation/contracts";
|
||||
|
||||
const capability = anyCapability(PERMS.ADMIN_DASHBOARD);
|
||||
|
||||
export interface OperationsAccessSummary {
|
||||
readonly accessibleDomains: number;
|
||||
}
|
||||
|
||||
export interface OperationsInboxAdapters {
|
||||
accessSummary(
|
||||
context: HousekeepingCapabilityContext,
|
||||
signal: AbortSignal,
|
||||
): Promise<OperationsAccessSummary>;
|
||||
}
|
||||
|
||||
export function createOperationsInboxSources(
|
||||
adapters: OperationsInboxAdapters,
|
||||
): readonly HousekeepingInboxSource[] {
|
||||
return [
|
||||
{
|
||||
id: "operations.access-summary",
|
||||
owner: "operations",
|
||||
capability,
|
||||
async getItems(context, signal) {
|
||||
const authorization = authorizeHousekeeping(context, capability);
|
||||
if (!authorization.ok) return authorization;
|
||||
try {
|
||||
const summary = await adapters.accessSummary(context, signal);
|
||||
const occurredAt = new Date().toISOString();
|
||||
return ok(
|
||||
{
|
||||
availability: "available" as const,
|
||||
items:
|
||||
summary.accessibleDomains === 0
|
||||
? [
|
||||
{
|
||||
sourceId: "operations.access-summary",
|
||||
itemId: "limited-access",
|
||||
deduplicationKey:
|
||||
"operations.access-summary:limited-access",
|
||||
domain: "operations" as const,
|
||||
capability,
|
||||
severity: "warning" as const,
|
||||
priority: "high" as const,
|
||||
ageMs: 0,
|
||||
state: "limited-access",
|
||||
occurredAt,
|
||||
titleKey:
|
||||
"pages.housekeeping.items.operationsLimitedAccess",
|
||||
href: "/ase" as const,
|
||||
freshness: "fresh" as const,
|
||||
actions: [],
|
||||
},
|
||||
]
|
||||
: [],
|
||||
},
|
||||
authorization.correlationId,
|
||||
);
|
||||
} catch {
|
||||
return fail(
|
||||
"DEPENDENCY_UNAVAILABLE",
|
||||
"errors.housekeeping.dependencyUnavailable",
|
||||
authorization.correlationId,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export const OPERATIONS_INBOX_SOURCES = createOperationsInboxSources({
|
||||
async accessSummary(context, signal) {
|
||||
if (signal.aborted) throw new Error("aborted operations access summary");
|
||||
const { HOUSEKEEPING_MANIFESTS } = await import("../../manifests");
|
||||
return {
|
||||
accessibleDomains: HOUSEKEEPING_MANIFESTS.filter(
|
||||
(domain) =>
|
||||
domain.id !== "operations" &&
|
||||
satisfiesCapability(context, domain.capability) &&
|
||||
domain.routes.some((route) =>
|
||||
satisfiesCapability(context, route.capability),
|
||||
),
|
||||
).length,
|
||||
};
|
||||
},
|
||||
});
|
||||
Reference in new issue
Block a user