package httpapi import ( "bytes" "context" "encoding/json" "errors" "io" "knowledge-governance/internal/qaopsorg" "net/http" ) type QAOrgStore interface { GetView(context.Context) (qaopsorg.State, error) PreviewRules(context.Context, qaopsorg.SaveRequest) (qaopsorg.State, error) SaveRules(context.Context, qaopsorg.SaveRequest, string) (qaopsorg.State, error) } func qaOrganization(w http.ResponseWriter, r *http.Request, config Config) { if !authorizeQAOps(w, r) { return } if r.URL.RawQuery != "" { writeOrgError(w, qaopsorg.ErrInvalid) return } if config.QAOrg == nil { writeOrgError(w, qaopsorg.ErrUnavailable) return } var result qaopsorg.State var err error if r.Method == http.MethodGet { result, err = config.QAOrg.GetView(r.Context()) } else { if !authorizeQAOrganizationWrite(w, r) { return } var request qaopsorg.SaveRequest raw, readErr := io.ReadAll(http.MaxBytesReader(w, r.Body, 1<<20)) check := json.NewDecoder(bytes.NewReader(raw)) var fields map[string]json.RawMessage var extra any invalidJSON := readErr != nil || json.Unmarshal(raw, &fields) != nil || fields == nil || fields["base_revision"] == nil || walkQualityJSON(check) != nil || check.Decode(&extra) != io.EOF decoder := json.NewDecoder(bytes.NewReader(raw)) decoder.DisallowUnknownFields() if invalidJSON || decoder.Decode(&request) != nil || decoder.Decode(&extra) != io.EOF || request.DirectoryID == "" || request.Rules == nil { writeOrgError(w, qaopsorg.ErrInvalid) return } if r.Method == http.MethodPost { result, err = config.QAOrg.PreviewRules(r.Context(), request) } else { identity, _ := sessionFrom(r.Context()) result, err = config.QAOrg.SaveRules(r.Context(), request, identity.Username) } } if err != nil { writeOrgError(w, err) return } writeJSON(w, 200, map[string]any{"data": result}) } func writeOrgError(w http.ResponseWriter, err error) { status, message := 503, "通讯录或区域配置存储不可用,未展示为空数据" switch { case errors.Is(err, qaopsorg.ErrInvalid): status, message = 400, "部门树或区域配置无效,请核对重复、缺失路径及区域" case errors.Is(err, qaopsorg.ErrConflict): status, message = 409, "通讯录或区域配置已变化,请重新读取后预览" case errors.Is(err, qaopsorg.ErrNoDirectory): status, message = 409, "尚无完整通讯录快照,不能保存区域配置" } writeJSON(w, status, map[string]string{"error": message}) }