feat(crud): tipos y generador de DDL para recursos CRUD
Anade los tipos CRUDResource, CRUDField, CRUDListParams y CRUDListResult que modelan un recurso CRUD sobre SQLite, junto con dos funciones puras: - crud_define_resource valida nombre, tabla y campos (tipos SQLite validos, nombres reservados, duplicados) antes de retornar el CRUDResource. - crud_generate_table_sql genera el DDL CREATE TABLE IF NOT EXISTS con id TEXT PRIMARY KEY, timestamps estandar y, si aplica, deleted_at para soft delete. Primera capa de 0021 — el resto (handlers + registro de rutas) se apoya sobre estas estructuras.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
package infra
|
||||
|
||||
import "fmt"
|
||||
|
||||
// CRUDDefineResource construye un CRUDResource validando que el nombre no este vacio,
|
||||
// que haya al menos un campo y que todos los tipos de los campos sean validos
|
||||
// (TEXT, INTEGER, REAL, BLOB). Es pura — solo valida y devuelve la estructura.
|
||||
func CRUDDefineResource(name string, table string, fields []CRUDField, softDelete bool) (CRUDResource, error) {
|
||||
if name == "" {
|
||||
return CRUDResource{}, fmt.Errorf("crud_define_resource: name must not be empty")
|
||||
}
|
||||
if table == "" {
|
||||
return CRUDResource{}, fmt.Errorf("crud_define_resource: table must not be empty")
|
||||
}
|
||||
if len(fields) == 0 {
|
||||
return CRUDResource{}, fmt.Errorf("crud_define_resource: must have at least one field")
|
||||
}
|
||||
seen := make(map[string]bool, len(fields))
|
||||
for _, f := range fields {
|
||||
if f.Name == "" {
|
||||
return CRUDResource{}, fmt.Errorf("crud_define_resource: field name must not be empty")
|
||||
}
|
||||
if f.Name == "id" || f.Name == "created_at" || f.Name == "updated_at" || f.Name == "deleted_at" {
|
||||
return CRUDResource{}, fmt.Errorf("crud_define_resource: field name %q is reserved", f.Name)
|
||||
}
|
||||
if seen[f.Name] {
|
||||
return CRUDResource{}, fmt.Errorf("crud_define_resource: duplicate field name %q", f.Name)
|
||||
}
|
||||
seen[f.Name] = true
|
||||
if !isValidCRUDType(f.Type) {
|
||||
return CRUDResource{}, fmt.Errorf("crud_define_resource: invalid type %q for field %q (must be TEXT, INTEGER, REAL or BLOB)", f.Type, f.Name)
|
||||
}
|
||||
}
|
||||
return CRUDResource{
|
||||
Name: name,
|
||||
Table: table,
|
||||
Fields: fields,
|
||||
SoftDelete: softDelete,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user