Summary
Creating an estimate does three separate writes with no transaction, so a partial failure leaves a broken estimate or two "last used" estimates.
Where
internal/service/estimate.go Create: es.Create (the estimate row), es.ReplacePoints, and es.ClearLastUsedExcept are three independent DB calls with no wrapping transaction.
Impact
If ReplacePoints fails, an estimate persists with zero points. If lastUsed is true and ClearLastUsedExcept fails after the estimate was inserted with LastUsed: true, the project ends up with two last_used estimates.
Suggested fix
Wrap the estimate insert, point replacement, and last-used clearing in one transaction.
Summary
Creating an estimate does three separate writes with no transaction, so a partial failure leaves a broken estimate or two "last used" estimates.
Where
internal/service/estimate.goCreate:es.Create(the estimate row),es.ReplacePoints, andes.ClearLastUsedExceptare three independent DB calls with no wrapping transaction.Impact
If
ReplacePointsfails, an estimate persists with zero points. IflastUsedis true andClearLastUsedExceptfails after the estimate was inserted withLastUsed: true, the project ends up with twolast_usedestimates.Suggested fix
Wrap the estimate insert, point replacement, and last-used clearing in one transaction.