Comfy-Org / registry-backend

Backend API for Comfy Registry + CI Dashboard
https://registry.comfy.org
GNU General Public License v3.0
46 stars 4 forks source link

FAIL to Publish node due to license field schema updated #81

Closed snomiao closed 3 months ago

snomiao commented 4 months ago

status quo

We have updated license schema in our docs site.

License An optional field that expects a path to the license file. The path should be relative to the pyproject.toml file and should be in the format license = { file = "LICENSE.txt" }.

and in cli tools

But fails to publish in the latest schema yet.

The related schema is in here

Expected

schema from toml file standards should be:

license = { file: string } | { text: string }

ChatGPT's suggestion below, just for reference, still need refine @robinjhuang

To update the schema to make the license field accept an object with optional file and text properties, you will need to use the JSON type offered by the Ent framework. You will also need to define a custom Go type to represent this object. Here's how you can achieve this:

  1. Define a License struct in Go to represent the object.
  2. Use the NillableJSON field type provided by Ent to store this object in the database as JSON.
  3. Update the Fields method accordingly.

Here's an updated version of your schema function:

registry-backend/ent/schema /node.go

package schema

import (
    "encoding/json"

    "entgo.io/ent/schema/field"
    "entgo.io/ent/dialect"
    "github.com/google/uuid"
)

// License represents a license object with optional file and text properties.
type License struct {
    File string `json:"file,omitempty"`
    Text string `json:"text,omitempty"`
}

func (l License) MarshalJSON() ([]byte, error) {
    type Alias License
    return json.Marshal(&struct {
        Alias
    }{
        Alias: (Alias)(l),
    })
}

func (l *License) UnmarshalJSON(data []byte) error {
    type Alias License
    aux := &struct {
        *Alias
    }{
        Alias: (*Alias)(l),
    }
    return json.Unmarshal(data, &aux)
}

// Node holds the schema definition for the Node entity.
type Node struct {
    ent.Schema
}

// Fields of the Node.
func (Node) Fields() []ent.Field {
    return []ent.Field{
        field.String("id").SchemaType(map[string]string{
            dialect.Postgres: "text",
        }).Unique(),
        field.String("publisher_id").SchemaType(map[string]string{
            dialect.Postgres: "text",
        }),
        field.String("name").SchemaType(map[string]string{
            dialect.Postgres: "text",
        }),
        field.String("description").Optional().SchemaType(map[string]string{
            dialect.Postgres: "text",
        }),
        field.String("category").SchemaType(map[string]string{
            dialect.Postgres: "text",
        }).Optional(),
        field.String("author").SchemaType(map[string]string{
            dialect.Postgres: "text",
        }).Optional(),
        field.JSON("license", License{}).SchemaType(map[string]string{
            dialect.Postgres: "jsonb",
        }),
        field.String("license_deprecated").SchemaType(map[string]string{
            dialect.Postgres: "text",
        }),
        field.String("repository_url").SchemaType(map[string]string{
            dialect.Postgres: "text",
        }),
        field.String("icon_url").SchemaType(map[string]string{
            dialect.Postgres: "text",
        }).Optional(),
        field.Strings("tags").SchemaType(map[string]string{
            dialect.Postgres: "text",
        }).Default([]string{}),
        field.Int64("total_install").Default(0),
        field.Int64("total_star").Default(0),
        field.Int64("total_review").Default(0),
        field.Enum("status").
            GoType(NodeStatus("")).
            Default(string(NodeStatusActive)),
        field.String("status_detail").SchemaType(map[string]string{
            dialect.Postgres: "text",
        }).Optional(),
    }
}

In this modification:

  1. Added the License struct for representing the license object with optional file and text properties.
  2. Modified the Fields method to use field.JSON for the license field.
  3. Updated the SchemaType to use jsonb for PostgreSQL.

This allows the license field to store a JSON object while maintaining the structure in your Go code.

snomiao commented 4 months ago