Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
/** Live workspace signals used to advance the checklist without relying only on localStorage. */
|
||||
export type ActivationWorkspaceEvidence = {
|
||||
hasEnabledFields?: boolean;
|
||||
hasSource?: boolean;
|
||||
hasMapping?: boolean;
|
||||
hasSyncedSample?: boolean;
|
||||
hasProcessed?: boolean;
|
||||
hasStoreConnect?: boolean;
|
||||
hasExport?: boolean;
|
||||
};
|
||||
|
||||
/** Minimal step shape for gating / workspace cursor (no i18n). */
|
||||
export type ActivationStepRef = {
|
||||
id: string;
|
||||
optional?: boolean;
|
||||
feature?: string;
|
||||
};
|
||||
|
||||
/** Steps visible for the current plan (omit feature-gated steps the plan denies). */
|
||||
export function visibleActivationSteps<T extends ActivationStepRef>(
|
||||
steps: T[],
|
||||
can: (featureKey: string) => boolean = () => true
|
||||
): T[] {
|
||||
return steps.filter((s) => !s.feature || can(s.feature));
|
||||
}
|
||||
|
||||
const evidenceForStep: Record<
|
||||
string,
|
||||
(evidence: ActivationWorkspaceEvidence) => boolean | undefined
|
||||
> = {
|
||||
"enable-fields": (e) => e.hasEnabledFields,
|
||||
"connect-source": (e) => e.hasSource,
|
||||
map: (e) => e.hasMapping,
|
||||
"sync-sample": (e) => e.hasSyncedSample,
|
||||
process: (e) => e.hasProcessed,
|
||||
"store-connect": (e) => e.hasStoreConnect,
|
||||
export: (e) => e.hasExport
|
||||
};
|
||||
|
||||
function stepEvidenceDone(step: ActivationStepRef, evidence: ActivationWorkspaceEvidence): boolean {
|
||||
const getter = evidenceForStep[step.id];
|
||||
return getter ? Boolean(getter(evidence)) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contiguous completed-step count from workspace state (stop at first incomplete).
|
||||
* Optional steps do not block later required evidence (e.g. export without a store).
|
||||
*/
|
||||
export function activationIndexFromWorkspace(
|
||||
evidence: ActivationWorkspaceEvidence | null | undefined,
|
||||
steps: ActivationStepRef[]
|
||||
): number {
|
||||
if (!evidence) return 0;
|
||||
let count = 0;
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
const step = steps[i];
|
||||
if (stepEvidenceDone(step, evidence)) {
|
||||
count += 1;
|
||||
continue;
|
||||
}
|
||||
if (step.optional) {
|
||||
const laterRequiredDone = steps
|
||||
.slice(i + 1)
|
||||
.some((s) => !s.optional && stepEvidenceDone(s, evidence));
|
||||
if (laterRequiredDone) {
|
||||
count += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return Math.min(count, steps.length);
|
||||
}
|
||||
Reference in New Issue
Block a user