Revert "Merge pull request 'Complete Housekeeping migration and /ase cutover' (#52) from codex/housekeeping-complete into main"
CI / check (push) Successful in 27s
CI / release (push) Skipped
CI / deploy (push) Successful in 43s

This reverts commit 488b6e57c4, reversing
changes made to b506b4499a.
This commit is contained in:
Simo committed 2026-08-30 21:31:34 +02:00
1 parent 488b6e57c4
commit b1ddda66ff
802 files changed
+61370 -76659

No files matched your search

@@ -1,20 +1,9 @@
import { PERMS } from "@/lib/permission-slugs";
import { HOUSEKEEPING_DOMAIN_IDS } from "../migration/types";
import { satisfiesCapability } from "./capability-context";
import type {
CapabilityRequirement,
HousekeepingCapabilityContext,
HousekeepingDomainManifest,
HousekeepingErrorCode,
HousekeepingWidgetDefinition,
} from "./contracts";
import { ok } from "./contracts";
import { reconcilePreferences } from "./preferences/reconcile";
import type { HousekeepingPreferences } from "./preferences/schema";
import {
type HousekeepingProvider,
runProvider,
} from "./providers/run-provider";
const approvedDomainIds = new Set<string>(HOUSEKEEPING_DOMAIN_IDS);
const knownCapabilitySlugs = new Set<string>(Object.values(PERMS));
@@ -28,86 +17,13 @@ export interface HousekeepingRegistry {
domains: readonly HousekeepingDomainManifest[];
}
export const WIDGET_POLICY = Object.freeze({ timeoutMs: 2_000 } as const);
export interface HousekeepingWidgetLoadResult {
readonly widgets: readonly { readonly id: string; readonly data: unknown }[];
readonly errors: readonly {
readonly widgetId: string;
readonly code: HousekeepingErrorCode;
}[];
}
function widgetProvider(
widget: HousekeepingWidgetDefinition,
): HousekeepingProvider<unknown> {
return {
id: widget.id,
capability: widget.capability,
async run(context, signal) {
const result = await widget.load(context, signal);
return result.ok ? ok([result.data], result.correlationId) : result;
},
};
}
export async function loadHousekeepingWidgets(
registry: HousekeepingRegistry,
preferences: HousekeepingPreferences,
context: HousekeepingCapabilityContext,
timeoutMs: number = WIDGET_POLICY.timeoutMs,
): Promise<HousekeepingWidgetLoadResult> {
const reconciled = reconcilePreferences(preferences, registry, context);
const enabledOptionalIds = new Set(reconciled.enabledOptionalWidgetIds);
const selected = registry.domains
.filter((domain) => satisfiesCapability(context, domain.capability))
.flatMap((domain) => domain.widgets)
.filter(
(widget) =>
satisfiesCapability(context, widget.capability) &&
(widget.kind === "mandatory" || enabledOptionalIds.has(widget.id)),
);
const selectedById = new Map(selected.map((widget) => [widget.id, widget]));
const orderedIds = reconciled.widgetOrder.filter((id) =>
selectedById.has(id),
);
for (const widget of selected) {
if (!orderedIds.includes(widget.id)) orderedIds.push(widget.id);
}
const ordered = orderedIds.flatMap((id) => {
const widget = selectedById.get(id);
return widget ? [widget] : [];
});
const outcomes = await Promise.all(
ordered.map((widget) =>
runProvider(widgetProvider(widget), context, timeoutMs),
),
);
return {
widgets: outcomes.flatMap((outcome) =>
outcome.error === undefined
? [{ id: outcome.providerId, data: outcome.items[0] }]
: [],
),
errors: outcomes.flatMap((outcome) =>
outcome.error === undefined
? []
: [{ widgetId: outcome.providerId, code: outcome.error }],
),
};
}
export function createHousekeepingRegistry(
manifests: readonly HousekeepingDomainManifest[],
): HousekeepingRegistry {
const domainIds = new Set<string>();
const routeIds = new Set<string>();
const routeHrefs = new Set<string>();
const routeShapes = new Set<string>();
const searchProviderIds = new Set<string>();
const inboxSourceIds = new Set<string>();
const widgetIds = new Set<string>();
const registryEntryIds = new Set<string>();
for (const manifest of manifests) {
if (!approvedDomainIds.has(manifest.id)) {
@@ -118,11 +34,8 @@ export function createHousekeepingRegistry(
}
domainIds.add(manifest.id);
if (
manifest.canonicalHref !==
(manifest.id === "operations" ? "/ase" : `/ase/${manifest.id}`)
) {
throw new Error(`invalid canonical href: ${manifest.canonicalHref}`);
if (manifest.previewHref !== `/admin-next/${manifest.id}`) {
throw new Error(`invalid preview href: ${manifest.previewHref}`);
}
validateNonEmpty(manifest.labelKey, "label key");
validateNonEmpty(manifest.descriptionKey, "description key");
@@ -131,19 +44,19 @@ export function createHousekeepingRegistry(
manifest.searchProviders,
manifest.id,
"search provider",
searchProviderIds,
registryEntryIds,
);
validateOwnedRegistryEntries(
manifest.inboxSources,
manifest.id,
"inbox source",
inboxSourceIds,
registryEntryIds,
);
validateOwnedRegistryEntries(
manifest.widgets,
manifest.id,
"widget",
widgetIds,
registryEntryIds,
);
for (const widget of manifest.widgets) {
if (widget.kind !== "mandatory" && widget.kind !== "optional") {
@@ -159,20 +72,11 @@ export function createHousekeepingRegistry(
routeIds.add(route.id);
validateNonEmpty(route.href, "route href");
if (route.href !== "/ase" && !route.href.startsWith("/ase/")) {
throw new Error(`invalid canonical route href: ${route.href}`);
}
if (routeHrefs.has(route.href)) {
throw new Error(`duplicate route href: ${route.href}`);
}
routeHrefs.add(route.href);
const routeShape = dynamicRouteShape(route.href);
if (routeShape && routeShapes.has(routeShape)) {
throw new Error(`duplicate dynamic route shape: ${routeShape}`);
}
if (routeShape) routeShapes.add(routeShape);
validateNonEmpty(route.labelKey, "route label key");
validateCapability(route.capability);
}
@@ -181,20 +85,6 @@ export function createHousekeepingRegistry(
return { domains: Object.freeze([...manifests]) };
}
function dynamicRouteShape(href: string): string | null {
let hasDynamicSegment = false;
const shape = href
.split("/")
.map((segment) => {
if (!segment.startsWith(":")) return segment;
hasDynamicSegment = true;
return ":";
})
.join("/");
return hasDynamicSegment ? shape : null;
}
function validateOwnedRegistryEntries(
entries: readonly OwnedRegistryEntry[],
owner: HousekeepingDomainManifest["id"],