Implement persistent Line ordering for project specs and update bible

This commit is contained in:
2026-02-21 07:09:38 +03:00
parent 3c46cd7bf0
commit e5b6902c9e
22 changed files with 891 additions and 111 deletions

View File

@@ -341,7 +341,7 @@ func (l *LocalDB) GetProjectByName(ownerUsername, name string) (*LocalProject, e
func (l *LocalDB) GetProjectConfigurations(projectUUID string) ([]LocalConfiguration, error) {
var configs []LocalConfiguration
err := l.db.Where("project_uuid = ? AND is_active = ?", projectUUID, true).
Order("created_at DESC").
Order(configurationLineOrderClause()).
Find(&configs).Error
return configs, err
}
@@ -514,9 +514,54 @@ func (l *LocalDB) BackfillConfigurationProjects(defaultOwner string) error {
// SaveConfiguration saves a configuration to local SQLite
func (l *LocalDB) SaveConfiguration(config *LocalConfiguration) error {
if config != nil && config.IsActive && config.Line <= 0 {
line, err := l.NextConfigurationLine(config.ProjectUUID, config.UUID)
if err != nil {
return err
}
config.Line = line
}
return l.db.Save(config).Error
}
func (l *LocalDB) NextConfigurationLine(projectUUID *string, excludeUUID string) (int, error) {
return NextConfigurationLineTx(l.db, projectUUID, excludeUUID)
}
func NextConfigurationLineTx(tx *gorm.DB, projectUUID *string, excludeUUID string) (int, error) {
query := tx.Model(&LocalConfiguration{}).
Where("is_active = ?", true)
trimmedExclude := strings.TrimSpace(excludeUUID)
if trimmedExclude != "" {
query = query.Where("uuid <> ?", trimmedExclude)
}
if projectUUID != nil && strings.TrimSpace(*projectUUID) != "" {
query = query.Where("project_uuid = ?", strings.TrimSpace(*projectUUID))
} else {
query = query.Where("project_uuid IS NULL OR TRIM(project_uuid) = ''")
}
var maxLine int
if err := query.Select("COALESCE(MAX(line_no), 0)").Scan(&maxLine).Error; err != nil {
return 0, fmt.Errorf("read max line_no: %w", err)
}
if maxLine < 0 {
maxLine = 0
}
next := ((maxLine / 10) + 1) * 10
if next < 10 {
next = 10
}
return next, nil
}
func configurationLineOrderClause() string {
return "CASE WHEN COALESCE(local_configurations.line_no, 0) <= 0 THEN 2147483647 ELSE local_configurations.line_no END ASC, local_configurations.created_at DESC, local_configurations.id DESC"
}
// GetConfigurations returns all local configurations
func (l *LocalDB) GetConfigurations() ([]LocalConfiguration, error) {
var configs []LocalConfiguration