fix(review): Create desc gate does not require price

This commit is contained in:
grokbot_ty
2026-09-26 10:30:55 -07:00
parent 1464cac5f7
commit 076eb17db6
3 changed files with 11 additions and 19 deletions
+1 -2
View File
@@ -144,7 +144,7 @@
// Prefer slab.species_id; fall back to Capture handoff if createSlab omitted it.
$: resolvedSpeciesId = effectiveSpeciesId(slab?.species_id, capture?.speciesId ?? null);
$: canCreateTitle = canCreateTitleFromSpecies(resolvedSpeciesId, woodCatIds.length);
// Create-desc gate: recompute on every field change (no blur required). Description not required.
// Create-desc gate: recompute on every field change (no blur required). Description and price not required.
$: createDescMissing = missingCreateDescLabels({
contentLlmEnabled: canGenerateContent,
title,
@@ -156,7 +156,6 @@
figureTermIds: figureIds,
gradeTermId: gradeSel,
moistureTermId: moistureSel,
price,
});
$: canCreateDesc = createDescMissing.length === 0;
// Monotonic token: each commit captures the current value and ignores its
@@ -17,7 +17,6 @@ const full = {
figureTermIds: [328],
gradeTermId: 342,
moistureTermId: '326',
price: '184.00',
};
test('Create desc gate: full set passes; does not require description', () => {
@@ -25,7 +24,13 @@ test('Create desc gate: full set passes; does not require description', () => {
assert.deepEqual(missingCreateDesc(full), []);
});
test('Create desc gate: lists each missing field; no description key', () => {
test('Create desc gate: empty price still passes when other fields full', () => {
// Price is publish-only; Create desc must not gate on it.
assert.equal(canCreateDesc(full), true);
assert.deepEqual(missingCreateDesc(full), []);
});
test('Create desc gate: lists each missing field; no description or price key', () => {
const miss = missingCreateDesc({
...full,
contentLlmEnabled: false,
@@ -38,7 +43,6 @@ test('Create desc gate: lists each missing field; no description key', () => {
figureTermIds: [],
gradeTermId: '',
moistureTermId: '',
price: '',
});
assert.deepEqual(miss, [
'content_llm',
@@ -51,16 +55,15 @@ test('Create desc gate: lists each missing field; no description key', () => {
'figure',
'grade',
'moisture',
'price',
]);
assert.equal(miss.includes('description'), false);
assert.equal(miss.includes('price'), false);
const labels = missingCreateDescLabels({
...full,
figureTermIds: [],
price: '',
});
assert.ok(labels.includes('≥1 figure'));
assert.ok(labels.includes('price'));
assert.equal(labels.includes('price'), false);
});
test('Create desc gate: recomputes on field change (reactive-ready)', () => {
+1 -11
View File
@@ -1,7 +1,6 @@
/**
* Create-desc gate (Call 2): disable Create desc unless these are present.
* Does NOT require description (that is what Create desc writes).
* Price included for parity with publish-ready.
* Does NOT require description OR price (price stays publish-only).
*/
export type CreateDescInput = {
@@ -15,7 +14,6 @@ export type CreateDescInput = {
figureTermIds: number[];
gradeTermId: number | string | '' | null | undefined;
moistureTermId: number | string | '' | null | undefined;
price: string | number | null | undefined;
};
/** Human labels shown under Create desc when the gate fails. */
@@ -30,7 +28,6 @@ export const CREATE_DESC_LABELS: Record<string, string> = {
figure: '≥1 figure',
grade: 'grade',
moisture: 'moisture',
price: 'price',
};
function presentId(v: number | string | '' | null | undefined): boolean {
@@ -39,12 +36,6 @@ function presentId(v: number | string | '' | null | undefined): boolean {
return String(v).trim() !== '';
}
function presentPrice(v: string | number | null | undefined): boolean {
if (v === null || v === undefined || v === '') return false;
const n = typeof v === 'number' ? v : Number(v);
return Number.isFinite(n);
}
/** Return missing field keys (stable order). Empty ⇒ Create desc enabled. */
export function missingCreateDesc(input: CreateDescInput): string[] {
const missing: string[] = [];
@@ -58,7 +49,6 @@ export function missingCreateDesc(input: CreateDescInput): string[] {
if (!input.figureTermIds?.length) missing.push('figure');
if (!presentId(input.gradeTermId)) missing.push('grade');
if (!presentId(input.moistureTermId)) missing.push('moisture');
if (!presentPrice(input.price)) missing.push('price');
return missing;
}