Fix project line numbering and reorder bootstrap
This commit is contained in:
@@ -1053,7 +1053,7 @@ func (s *LocalConfigurationService) isOwner(cfg *localdb.LocalConfiguration, own
|
|||||||
|
|
||||||
func (s *LocalConfigurationService) createWithVersion(localCfg *localdb.LocalConfiguration, createdBy string) error {
|
func (s *LocalConfigurationService) createWithVersion(localCfg *localdb.LocalConfiguration, createdBy string) error {
|
||||||
return s.localDB.DB().Transaction(func(tx *gorm.DB) error {
|
return s.localDB.DB().Transaction(func(tx *gorm.DB) error {
|
||||||
if localCfg.IsActive && localCfg.Line <= 0 {
|
if localCfg.IsActive {
|
||||||
if err := s.ensureConfigurationLineTx(tx, localCfg); err != nil {
|
if err := s.ensureConfigurationLineTx(tx, localCfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -1133,7 +1133,7 @@ func (s *LocalConfigurationService) saveWithVersionAndPending(localCfg *localdb.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if localCfg.IsActive && localCfg.Line <= 0 {
|
if localCfg.IsActive {
|
||||||
if err := s.ensureConfigurationLineTx(tx, localCfg); err != nil {
|
if err := s.ensureConfigurationLineTx(tx, localCfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -1250,17 +1250,61 @@ func (s *LocalConfigurationService) loadVersionForPendingTx(tx *gorm.DB, localCf
|
|||||||
if err := tx.Where("configuration_uuid = ?", localCfg.UUID).
|
if err := tx.Where("configuration_uuid = ?", localCfg.UUID).
|
||||||
Order("version_no DESC").
|
Order("version_no DESC").
|
||||||
First(&latest).Error; err != nil {
|
First(&latest).Error; err != nil {
|
||||||
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, fmt.Errorf("load version for pending change: %w", err)
|
return nil, fmt.Errorf("load version for pending change: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Legacy/imported rows may exist without local version history.
|
||||||
|
// Bootstrap the first version so pending sync payloads can reference a version.
|
||||||
|
version, createErr := s.appendVersionTx(tx, localCfg, "bootstrap", "")
|
||||||
|
if createErr != nil {
|
||||||
|
return nil, fmt.Errorf("bootstrap version for pending change: %w", createErr)
|
||||||
|
}
|
||||||
|
if err := tx.Model(&localdb.LocalConfiguration{}).
|
||||||
|
Where("uuid = ?", localCfg.UUID).
|
||||||
|
Update("current_version_id", version.ID).Error; err != nil {
|
||||||
|
return nil, fmt.Errorf("set current version id for bootstrapped pending change: %w", err)
|
||||||
|
}
|
||||||
|
localCfg.CurrentVersionID = &version.ID
|
||||||
|
return version, nil
|
||||||
|
}
|
||||||
return &latest, nil
|
return &latest, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LocalConfigurationService) ensureConfigurationLineTx(tx *gorm.DB, localCfg *localdb.LocalConfiguration) error {
|
func (s *LocalConfigurationService) ensureConfigurationLineTx(tx *gorm.DB, localCfg *localdb.LocalConfiguration) error {
|
||||||
|
if localCfg == nil || !localCfg.IsActive {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
needsAssign := localCfg.Line <= 0
|
||||||
|
if !needsAssign {
|
||||||
|
query := tx.Model(&localdb.LocalConfiguration{}).
|
||||||
|
Where("is_active = ? AND line_no = ?", true, localCfg.Line)
|
||||||
|
|
||||||
|
if strings.TrimSpace(localCfg.UUID) != "" {
|
||||||
|
query = query.Where("uuid <> ?", strings.TrimSpace(localCfg.UUID))
|
||||||
|
}
|
||||||
|
|
||||||
|
if localCfg.ProjectUUID != nil && strings.TrimSpace(*localCfg.ProjectUUID) != "" {
|
||||||
|
query = query.Where("project_uuid = ?", strings.TrimSpace(*localCfg.ProjectUUID))
|
||||||
|
} else {
|
||||||
|
query = query.Where("project_uuid IS NULL OR TRIM(project_uuid) = ''")
|
||||||
|
}
|
||||||
|
|
||||||
|
var conflicts int64
|
||||||
|
if err := query.Count(&conflicts).Error; err != nil {
|
||||||
|
return fmt.Errorf("check line_no conflict for configuration %s: %w", localCfg.UUID, err)
|
||||||
|
}
|
||||||
|
needsAssign = conflicts > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if needsAssign {
|
||||||
line, err := localdb.NextConfigurationLineTx(tx, localCfg.ProjectUUID, localCfg.UUID)
|
line, err := localdb.NextConfigurationLineTx(tx, localCfg.ProjectUUID, localCfg.UUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("assign line_no for configuration %s: %w", localCfg.UUID, err)
|
return fmt.Errorf("assign line_no for configuration %s: %w", localCfg.UUID, err)
|
||||||
}
|
}
|
||||||
localCfg.Line = line
|
localCfg.Line = line
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -373,7 +373,7 @@ function renderConfigs(configs) {
|
|||||||
const serverCount = c.server_count || 1;
|
const serverCount = c.server_count || 1;
|
||||||
const author = c.owner_username || (c.user && c.user.username) || '—';
|
const author = c.owner_username || (c.user && c.user.username) || '—';
|
||||||
const unitPrice = serverCount > 0 ? (total / serverCount) : 0;
|
const unitPrice = serverCount > 0 ? (total / serverCount) : 0;
|
||||||
const lineValue = (typeof c.line === 'number' && c.line > 0) ? c.line : ((idx + 1) * 10);
|
const lineValue = (idx + 1) * 10;
|
||||||
const serverModel = (c.server_model || '').trim() || '—';
|
const serverModel = (c.server_model || '').trim() || '—';
|
||||||
totalSum += total;
|
totalSum += total;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user