Files
EpicNext-Cms/src/actions/housekeeping-preferences.ts
T

86 lines
2.6 KiB
TypeScript

"use server";
import { authorizeHousekeeping } from "@/features/housekeeping/foundation/authorization";
import {
anyCapability,
fail,
type HousekeepingResult,
ok,
} from "@/features/housekeeping/foundation/contracts";
import { createCorrelationId } from "@/features/housekeeping/foundation/correlation";
import { reconcilePreferences } from "@/features/housekeeping/foundation/preferences/reconcile";
import {
type HousekeepingPreferences,
housekeepingPreferencesSchema,
} from "@/features/housekeeping/foundation/preferences/schema";
import { createHousekeepingRegistry } from "@/features/housekeeping/foundation/registry";
import { getHousekeepingCapabilityContext } from "@/features/housekeeping/foundation/server-capability-context";
import { HOUSEKEEPING_MANIFESTS } from "@/features/housekeeping/manifests";
import { housekeepingPreferencesRepository } from "@/lib/housekeeping-preferences-repository";
import { PERMS } from "@/lib/permission-slugs";
const preferencesCapability = anyCapability(PERMS.ADMIN_DASHBOARD);
const housekeepingRegistry = createHousekeepingRegistry(HOUSEKEEPING_MANIFESTS);
export async function loadHousekeepingPreferences(): Promise<
HousekeepingResult<HousekeepingPreferences>
> {
const context = await getHousekeepingCapabilityContext();
const authorization = authorizeHousekeeping(context, preferencesCapability);
if (!authorization.ok) return authorization;
const correlationId = createCorrelationId();
try {
const stored = await housekeepingPreferencesRepository.read(
context.actor.id,
);
return ok(
reconcilePreferences(stored, housekeepingRegistry, context),
correlationId,
);
} catch {
return fail(
"INTERNAL",
"errors.housekeeping.preferences.read",
correlationId,
);
}
}
export async function saveHousekeepingPreferences(
input: unknown,
): Promise<HousekeepingResult<HousekeepingPreferences>> {
const context = await getHousekeepingCapabilityContext();
const authorization = authorizeHousekeeping(context, preferencesCapability);
if (!authorization.ok) return authorization;
const correlationId = createCorrelationId();
const parsed = housekeepingPreferencesSchema.safeParse(input);
if (!parsed.success) {
return fail(
"VALIDATION",
"errors.housekeeping.preferences.invalid",
correlationId,
);
}
const reconciled = reconcilePreferences(
parsed.data,
housekeepingRegistry,
context,
);
try {
await housekeepingPreferencesRepository.upsert(
context.actor.id,
reconciled,
);
return ok(reconciled, correlationId);
} catch {
return fail(
"INTERNAL",
"errors.housekeeping.preferences.save",
correlationId,
);
}
}