Feature/224 intake notification #263

Merged
bermudalamb merged 8 commits from feature/224-intake-notification into main 2026-09-01 15:08:49 -05:00
2 changed files with 66 additions and 0 deletions
Showing only changes of commit 7522826bd0 - Show all commits
+34
View File
@@ -0,0 +1,34 @@
/**
* Where an item's price came from, and when that changes.
*
* This is the protection that used to live in the schema. Items are priced on
* arrival — the model's suggestion, or the 80.00 default — so nothing stops a
* number nobody chose from reaching the storefront except the review queue
* showing that it was never chosen.
*
* Pure and separately tested because the failure is silent. An item that sells
* at a default price looks exactly like one that sells at a chosen price;
* 80.00 was picked precisely because it reads as a decision rather than as an
* obvious sentinel the way 0.00 would.
*/
export type PriceSource = 'default' | 'ai' | 'admin';
/**
* Editing the number is the admin taking responsibility for it, and it is the
* only thing that can. Publishing without touching the field deliberately does
* NOT confirm it — that would turn "I did not look at this" into "I approved
* this", which is the exact misrecording the review queue exists to prevent.
*/
export function nextPriceSource(
current: PriceSource,
submittedCents: number,
storedCents: number
): PriceSource {
if (current === 'admin') return 'admin';
return submittedCents === storedCents ? current : 'admin';
}
/** Anything a person did not choose, which the screen marks visibly. */
export function isUnconfirmed(source: PriceSource): boolean {
return source !== 'admin';
}
+32
View File
@@ -0,0 +1,32 @@
import { nextPriceSource, isUnconfirmed } from '../../src/intake/priceSource';
describe('nextPriceSource', () => {
// Touching the number is the admin taking responsibility for it. That is the
// only event that can confirm a price.
it('becomes admin when the number changes', () => {
expect(nextPriceSource('default', 9500, 8000)).toBe('admin');
expect(nextPriceSource('ai', 4000, 4500)).toBe('admin');
});
// Publishing without touching the field must NOT silently confirm it. That
// is the whole failure this screen exists to prevent: an item selling at a
// number nobody chose, with nothing recording that.
it('leaves an untouched price unconfirmed', () => {
expect(nextPriceSource('default', 8000, 8000)).toBe('default');
expect(nextPriceSource('ai', 4500, 4500)).toBe('ai');
});
// Already confirmed stays confirmed, including when re-submitted unchanged.
it('keeps admin once set', () => {
expect(nextPriceSource('admin', 9500, 9500)).toBe('admin');
expect(nextPriceSource('admin', 7000, 9500)).toBe('admin');
});
});
describe('isUnconfirmed', () => {
it('treats anything but admin as unconfirmed', () => {
expect(isUnconfirmed('default')).toBe(true);
expect(isUnconfirmed('ai')).toBe(true);
expect(isUnconfirmed('admin')).toBe(false);
});
});