fix(sdk): Prevent auto-save from overwriting completed profile status
Some checks failed
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 41s
CI/CD / test-python-backend-compliance (push) Successful in 39s
CI/CD / test-python-document-crawler (push) Successful in 25s
CI/CD / test-python-dsms-gateway (push) Successful in 21s
CI/CD / deploy-hetzner (push) Failing after 1s

The auto-save timers (SDK context + backend) were firing after
completeAndSaveProfile(), resetting isComplete back to false.

Fix: skip auto-save when currentStep===99 (completed), cancel pending
timers before completing, and await backend save before updating
SDK context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-11 08:50:28 +01:00
parent 7afbcfd9f5
commit a673cb0ce4

View File

@@ -2486,6 +2486,9 @@ export default function CompanyProfilePage() {
return
}
// Don't auto-save drafts if profile is already completed (step 99)
if (currentStep === 99) return
// Debounce: sync to SDK context after 500ms of inactivity
if (autoSaveRef.current) clearTimeout(autoSaveRef.current)
autoSaveRef.current = setTimeout(() => {
@@ -2500,7 +2503,7 @@ export default function CompanyProfilePage() {
if (autoSaveRef.current) clearTimeout(autoSaveRef.current)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [formData])
}, [formData, currentStep])
// Shared payload builder for draft saves and final save (DRY)
const buildProfilePayload = (isComplete: boolean) => ({
@@ -2578,6 +2581,9 @@ export default function CompanyProfilePage() {
useEffect(() => {
if (!initialLoadDone.current) return
// Don't auto-save drafts if profile is already completed
if (currentStep === 99) return
const hasData = formData.companyName || (formData.industry && formData.industry.length > 0)
if (!hasData) return
@@ -2601,7 +2607,7 @@ export default function CompanyProfilePage() {
if (backendAutoSaveRef.current) clearTimeout(backendAutoSaveRef.current)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [formData])
}, [formData, currentStep])
const [draftSaveStatus, setDraftSaveStatus] = useState<'idle' | 'saving' | 'saved' | 'error'>('idle')
const draftSaveTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)
@@ -2646,17 +2652,17 @@ export default function CompanyProfilePage() {
}
const completeAndSaveProfile = async () => {
// Cancel any pending auto-save timers to prevent them from overwriting isComplete
if (autoSaveRef.current) clearTimeout(autoSaveRef.current)
if (backendAutoSaveRef.current) clearTimeout(backendAutoSaveRef.current)
const completeProfile: CompanyProfile = {
...formData,
isComplete: true,
completedAt: new Date(),
} as CompanyProfile
setCompanyProfile(completeProfile)
dispatch({ type: 'COMPLETE_STEP', payload: 'company-profile' })
dispatch({ type: 'SET_STATE', payload: { projectVersion: (state.projectVersion || 0) + 1 } })
// Also persist to dedicated backend endpoint
// Persist to backend FIRST (with isComplete=true)
try {
await fetch(profileApiUrl(), {
method: 'POST',
@@ -2667,6 +2673,11 @@ export default function CompanyProfilePage() {
console.error('Failed to save company profile to backend:', err)
}
// Then update SDK context (after backend is done, no race condition)
setCompanyProfile(completeProfile)
dispatch({ type: 'COMPLETE_STEP', payload: 'company-profile' })
dispatch({ type: 'SET_STATE', payload: { projectVersion: (state.projectVersion || 0) + 1 } })
setCurrentStep(99) // Show summary
}