feat: architecture refactor — core layer, spreadsheet engine, envelope bidding, tests
CI / quality (push) Waiting to run
CI / quality (push) Waiting to run
- Add src/core/ (config, errors, events, http, observability, storage, query) - Add src/Spreadsheet/ engine with native POI backend and Excel bridge - Add Envelope C spreadsheet flow and tender bidding envelope modules - Consolidate components into src/components/, remove legacy Component/ and Hooks/ - Add registration state/validation, auth session guard, profile edit modules - Add unit tests across axios, redux, bidding, registration, encryption, core - Add CI workflow, docs (architecture, audit, DSC API spec), keystore example - Remove tracked keystore binary; ignore scripts.zip Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
9acec328a7
commit
1d7646d938
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Pattern configuration for the unified auction bidding screen/card.
|
||||
*
|
||||
* Forward and Reverse bidding were 90%-duplicated screens that drifted apart.
|
||||
* Every behavioral difference between them is captured HERE, explicitly, so
|
||||
* the screen and card contain zero `if (pattern === ...)` logic and a bidding
|
||||
* fix can never again land in one pattern but not the other.
|
||||
*/
|
||||
import { FORWARD_AUCTION_ITEM, REVERSE_AUCTION_ITEM } from '../../Services/ApiCall/ApiUrls';
|
||||
|
||||
export type AuctionPattern = 'Forward' | 'Reverse';
|
||||
|
||||
export type BiddingFlags = {
|
||||
oneTimeBid: boolean;
|
||||
rebid: boolean;
|
||||
};
|
||||
|
||||
export type BiddingPatternConfig = {
|
||||
pattern: AuctionPattern;
|
||||
/** Endpoint returning this pattern's auction items. */
|
||||
itemsUrl: string;
|
||||
/** Opening amount — the backend uses a different field per pattern. */
|
||||
startValue: (item: any) => number;
|
||||
/** Stepper step size. */
|
||||
step: (item: any) => number;
|
||||
stepLabel: 'Increment' | 'Decrement';
|
||||
stepPrefix: '+' | '-';
|
||||
/** Forward bids may rise without bound; reverse bids may not exceed the current bid. */
|
||||
canIncrease: (bidValue: number, item: any) => boolean;
|
||||
/** Forward bids may not drop below the current bid; reverse not below the EMD amount. */
|
||||
canDecrease: (bidValue: number, item: any) => boolean;
|
||||
/** Gate applied while typing a manual (one-time/rebid) amount. */
|
||||
acceptManualInput: (value: number, item: any) => boolean;
|
||||
/** Submit-time validation for manual bids; returns an error message or null. */
|
||||
validateManualBid: (value: number, item: any) => string | null;
|
||||
/** Reverse renders the manual input inline within the stepper row. */
|
||||
inlineManualInput: boolean;
|
||||
/** Whether the collapsible body opens at full height. */
|
||||
isBodyFull: (flags: BiddingFlags, item: any) => boolean;
|
||||
/** Whether the Confirm Bid button is rendered. */
|
||||
showSubmit: (flags: BiddingFlags, item: any) => boolean;
|
||||
};
|
||||
|
||||
const forward: BiddingPatternConfig = {
|
||||
pattern: 'Forward',
|
||||
itemsUrl: FORWARD_AUCTION_ITEM,
|
||||
startValue: item => item?.auctionStartValueFigure,
|
||||
step: item => item?.bidVariationValue,
|
||||
stepLabel: 'Increment',
|
||||
stepPrefix: '+',
|
||||
canIncrease: () => true,
|
||||
canDecrease: (bidValue, item) => bidValue > item.bidAmount,
|
||||
acceptManualInput: () => true,
|
||||
validateManualBid: (value, item) =>
|
||||
value < Number(item.bidAmount) ? 'Enter a value greater than the current bid value' : null,
|
||||
inlineManualInput: false,
|
||||
isBodyFull: (flags, item) => !flags.rebid && item.contractorId == undefined,
|
||||
showSubmit: (flags, item) => !flags.rebid && item.contractorId == undefined,
|
||||
};
|
||||
|
||||
const reverse: BiddingPatternConfig = {
|
||||
pattern: 'Reverse',
|
||||
itemsUrl: REVERSE_AUCTION_ITEM,
|
||||
startValue: item => item?.auctionStartValue,
|
||||
step: item => item?.emdAmount,
|
||||
stepLabel: 'Decrement',
|
||||
stepPrefix: '-',
|
||||
canIncrease: (bidValue, item) => bidValue < item.bidAmount,
|
||||
canDecrease: (bidValue, item) => bidValue > item.emdAmount,
|
||||
acceptManualInput: (value, item) => value >= 0 && value <= Number(item?.auctionStartValue),
|
||||
validateManualBid: () => null,
|
||||
inlineManualInput: true,
|
||||
isBodyFull: () => true,
|
||||
showSubmit: () => true,
|
||||
};
|
||||
|
||||
export const getBiddingConfig = (pattern: string | undefined): BiddingPatternConfig =>
|
||||
pattern === 'Reverse' ? reverse : forward;
|
||||
Reference in New Issue
Block a user