feat: proposals en registry

Añade sistema de proposals al registry: modelos (ProposalKind, ProposalStatus),
CRUD completo (Insert/Get/Update/Delete/List/Search con FTS), validación,
migración 002_proposals.sql y subcomando CLI fn proposal (add/list/show/update).
Motor de migraciones con embed.FS reemplaza schema estático.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-28 17:13:24 +01:00
parent 093367107e
commit 8d98faccd9
9 changed files with 902 additions and 109 deletions
+35
View File
@@ -126,6 +126,41 @@ func ValidateFunction(f *Function, knownFunctions, knownTypes map[string]bool) *
return nil
}
// ValidateProposal checks integrity rules for proposals.
func ValidateProposal(p *Proposal) *ValidationError {
var errs []string
if p.ID == "" {
errs = append(errs, "id is required")
}
if p.Title == "" {
errs = append(errs, "title is required")
}
switch p.Kind {
case ProposalNewFunction, ProposalNewType, ProposalImproveFunction, ProposalImproveType, ProposalNewPipeline:
case "":
errs = append(errs, "kind is required")
default:
errs = append(errs, fmt.Sprintf("invalid kind: %s", p.Kind))
}
switch p.Status {
case ProposalPending, ProposalApproved, ProposalRejected, ProposalImplemented, "":
default:
errs = append(errs, fmt.Sprintf("invalid status: %s", p.Status))
}
if (p.Kind == ProposalImproveFunction || p.Kind == ProposalImproveType) && p.TargetID == "" {
errs = append(errs, "target_id is required for improve_* proposals")
}
if len(errs) > 0 {
return &ValidationError{ID: p.ID, Errors: errs}
}
return nil
}
// ValidateType checks integrity rules for types.
func ValidateType(t *Type, knownTypes map[string]bool) *ValidationError {
var errs []string