Files
community-rule/lib/create/groupAnswers.ts
T
adilalloandCursor bcbc6f30d9 Import the remade decks on stable ids and recommend one card per job, so a saved draft still loads after a chip is renamed.
The real-group profiles stay as a test, so a change that moves a pick fails.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-04 14:22:54 -07:00

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),
};
}