The real-group profiles stay as a test, so a change that moves a pick fails. Co-authored-by: Cursor <cursoragent@cursor.com>
88 lines
2.9 KiB
TypeScript
88 lines
2.9 KiB
TypeScript
import type { CreateFlowState } from "../../app/(app)/create/types";
|
|
import type { RequestedFacets } from "../server/validation/methodFacetsSchemas";
|
|
import {
|
|
resolveMaturityChipId,
|
|
resolveOrgChipId,
|
|
resolveScaleChipId,
|
|
resolveSizeChipId,
|
|
} from "./communityChipIds";
|
|
import type { GroupAnswers, Kind, Scale, Stage, TraitKey } from "./deckTypes";
|
|
import { KINDS, SCALES, STAGES, TRAIT_KEYS } from "./deckTypes";
|
|
|
|
function isKind(value: string): value is Kind {
|
|
return (KINDS as readonly string[]).includes(value);
|
|
}
|
|
|
|
function isScale(value: string): value is Scale {
|
|
return (SCALES as readonly string[]).includes(value);
|
|
}
|
|
|
|
function isStage(value: string): value is Stage {
|
|
return (STAGES as readonly string[]).includes(value);
|
|
}
|
|
|
|
/** Larger organization and Enterprise both score as Established. */
|
|
export function stageForScoring(value: string | null | undefined): Stage | null {
|
|
if (!value) return null;
|
|
if (value === "enterprise" || value === "larger-organization") return "established";
|
|
return isStage(value) ? value : null;
|
|
}
|
|
|
|
/**
|
|
* One size, one main kind, every ticked scale, and one maturity answer.
|
|
* Extra maturity answers stay on the draft and do not add points.
|
|
*/
|
|
export function groupAnswersFromRequestedFacets(
|
|
facets: RequestedFacets,
|
|
traits?: Partial<Record<TraitKey, boolean>>,
|
|
): GroupAnswers {
|
|
const kinds = (facets.orgType ?? []).filter(isKind);
|
|
const scales = (facets.scale ?? []).filter(isScale);
|
|
const maturity = (facets.maturity ?? [])
|
|
.map((value) => stageForScoring(value))
|
|
.filter((value): value is Stage => value !== null);
|
|
return {
|
|
size: facets.size?.[0] ?? null,
|
|
mainKind: kinds[0] ?? null,
|
|
otherKinds: kinds.slice(1),
|
|
scale: scales,
|
|
stage: maturity[0] ?? null,
|
|
traits,
|
|
};
|
|
}
|
|
|
|
function traitRecord(
|
|
raw: CreateFlowState["setupTraits"],
|
|
): Partial<Record<TraitKey, boolean>> | undefined {
|
|
if (!raw) return undefined;
|
|
const out: Partial<Record<TraitKey, boolean>> = {};
|
|
for (const key of TRAIT_KEYS) {
|
|
if (typeof raw[key] === "boolean") out[key] = raw[key];
|
|
}
|
|
return out;
|
|
}
|
|
|
|
export function groupAnswersFromCreateFlowState(
|
|
state: CreateFlowState,
|
|
): GroupAnswers {
|
|
const size = (state.selectedCommunitySizeIds ?? []).map(resolveSizeChipId)[0] ?? null;
|
|
const kinds = (state.selectedOrganizationTypeIds ?? [])
|
|
.map((id) => resolveOrgChipId(id))
|
|
.filter(isKind);
|
|
const scale = (state.selectedScaleIds ?? [])
|
|
.map(resolveScaleChipId)
|
|
.filter(isScale);
|
|
const maturity = (state.selectedMaturityIds ?? [])
|
|
.map((id) => stageForScoring(resolveMaturityChipId(id)))
|
|
.filter((value): value is Stage => value !== null);
|
|
const uniqueScale = [...new Set(scale)];
|
|
return {
|
|
size,
|
|
mainKind: kinds[0] ?? null,
|
|
otherKinds: kinds.slice(1).filter((kind, index, all) => all.indexOf(kind) === index),
|
|
scale: uniqueScale,
|
|
stage: maturity[0] ?? null,
|
|
traits: traitRecord(state.setupTraits),
|
|
};
|
|
}
|