feat: complete contract-driven business development and MySQL integration

This commit is contained in:
2026-09-24 21:56:04 +08:00
parent f9afb8f8dd
commit f5478cdc76
108 changed files with 6557 additions and 550 deletions

View File

@@ -3,6 +3,7 @@ package apigen
import (
"encoding/json"
"fmt"
"git.yuntuo.hk/k2safe/go-omni/contract"
"net/http"
"regexp"
"sort"
@@ -119,7 +120,8 @@ func prepareMetadata(original *Spec) (*Spec, error) {
return &spec, nil
}
func decorateDocument(doc map[string]any, spec *Spec) {
func decorateDocument(doc map[string]any, spec *Spec, bindings map[string]*contract.Binder) {
doc["x-omni-contract-sources"] = sourceMetadata(spec)
if spec.DefaultResponse != "" {
doc["x-omni-default-response"] = spec.DefaultResponse
}
@@ -144,7 +146,12 @@ func decorateDocument(doc map[string]any, spec *Spec) {
}
doc["components"].(map[string]any)["securitySchemes"] = schemes
definitions := map[string]ErrorDefinition{}
registry := apierrors.MustRegistry(errorCatalog(spec, nil))
declaredRegistry := apierrors.MustRegistry(errorCatalog(spec, nil))
var documentRegistry *apierrors.Registry
if spec.DocumentCatalog != nil {
documentRegistry = apierrors.MustRegistry(*spec.DocumentCatalog)
doc["x-omni-app-error-catalog"] = documentRegistry.Catalog()
}
for _, e := range spec.Errors {
definitions[e.Name] = e
}
@@ -152,6 +159,7 @@ func decorateDocument(doc map[string]any, spec *Spec) {
doc["x-omni-errors"] = spec.Errors
}
for _, r := range spec.Routes {
registry := declaredRegistry
policy := response.MustNew(responseConfig(spec, r))
cfg := policy.Config()
parts := strings.Split(r.Path, "/")
@@ -161,7 +169,16 @@ func decorateDocument(doc map[string]any, spec *Spec) {
}
}
op := doc["paths"].(map[string]any)[strings.Join(parts, "/")].(map[string]any)[r.Method].(map[string]any)
decorateRequestOptions(op, r)
requestRoute := r
requestRoute.RequestPolicy = contract.MergePolicy(spec.RequestPolicy, r.RequestPolicy)
decorateRequestOptions(op, requestRoute)
if b := bindings[r.Request]; b != nil && b.HasMultipart() {
encoding := map[string]any{}
for _, name := range b.MultipartJSONFields() {
encoding[name] = map[string]any{"contentType": "application/json"}
}
op["requestBody"] = map[string]any{"required": true, "content": map[string]any{"multipart/form-data": map[string]any{"schema": b.MultipartSchema(), "encoding": encoding}}}
}
if r.ResponseFormat != "" {
op["x-omni-response"] = r.ResponseFormat
}
@@ -193,6 +210,13 @@ func decorateDocument(doc map[string]any, spec *Spec) {
e := definitions[name]
grouped[e.Status] = append(grouped[e.Status], e)
}
if len(r.Errors) == 0 && documentRegistry != nil {
registry = documentRegistry
op["x-omni-error-catalog-scope"] = "app"
for key, definition := range registry.Catalog().Definitions {
grouped[definition.Status] = append(grouped[definition.Status], ErrorDefinition{Name: key, Code: key, Status: definition.Status, Message: definition.Message, BusinessCode: definition.Code, Params: definition.Params})
}
}
if len(r.Errors) > 0 {
op["x-omni-errors"] = r.Errors
}