Software projects mount only bootstrap/delivery keys and skip the medical seven-template clone. SWBOOT-10 stays a fail-closed stub. Co-authored-by: Cursor <cursoragent@cursor.com>
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
/**
|
||
* 立项确认防双击:同步 in-flight 锁 + 提交态文案。
|
||
* React state(bootstrapId / submitting)不能单独阻止并发入口。
|
||
*/
|
||
|
||
export type CreateProjectInFlightLock = { current: boolean };
|
||
|
||
export type CreateProjectSubmitPhase = 'creating' | 'syncing_members';
|
||
|
||
/** 入口立即抢锁;已在途返回 false,调用方必须直接 return。 */
|
||
export function beginCreateProjectSubmit(lock: CreateProjectInFlightLock): boolean {
|
||
if (lock.current) return false;
|
||
lock.current = true;
|
||
return true;
|
||
}
|
||
|
||
/** finally 中释放,失败后允许串行幂等重试。 */
|
||
export function endCreateProjectSubmit(lock: CreateProjectInFlightLock): void {
|
||
lock.current = false;
|
||
}
|
||
|
||
export function resolveCreateProjectSubmitPhase(
|
||
bootstrapProjectId: number | null,
|
||
): CreateProjectSubmitPhase {
|
||
return bootstrapProjectId != null && bootstrapProjectId > 0 ? 'syncing_members' : 'creating';
|
||
}
|
||
|
||
export function createProjectSubmitButtonLabel(
|
||
submitting: boolean,
|
||
phase: CreateProjectSubmitPhase | null,
|
||
): string {
|
||
if (!submitting) return '确认立项并创建会话';
|
||
if (phase === 'syncing_members') return '同步成员中';
|
||
return '立项中';
|
||
}
|
||
|
||
export function shouldBlockCreateProjectClose(submitting: boolean): boolean {
|
||
return submitting;
|
||
}
|
||
|
||
/** Software projects must not clone the medical 7-template pack. */
|
||
export function shouldCloneMedicalTemplates(productDomain: string | undefined): boolean {
|
||
return productDomain !== 'non_medical_software';
|
||
}
|