diff --git a/AGENTS.md b/AGENTS.md index 84a72316c3..4055385772 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,7 +25,7 @@ Use this file as the local operating guide for the current codebase. Prefer the ## Code Layout to Expect - `cmd/ragflow_server.go`: Go entrypoint for the API, admin, ingestor, and syncer modes (`--api`, `--admin`, `--ingestor`, `--syncer`). -- `cmd/ragflow-cli.go`: Go CLI entrypoint. +- `cmd/ragflow-cli/`: Go CLI entrypoint. - `api/`, `rag/`, `deepdoc/`, and `agent/`: legacy Python implementation pending deletion. Do not add features or extend dependencies there. - `internal/`: main Go application code. Important subtrees: - `internal/agent/`: Go agent runtime, canvas execution, components, tool bindings, workflow helpers. @@ -62,6 +62,18 @@ Use this file as the local operating guide for the current codebase. Prefer the - Remove commented-out Go code instead of leaving recovery notes in place. - Keep package comments and doc comments aligned with the current runtime path, not with migration history. +## Enterprise stubs +Enterprise-only code lives in the downstream enterprise repository, never here: it is written as `*_ee.go` / `*_ee_test.go` files carrying `//go:build ee`. This tree keeps only what the open-source build needs: + +- A capability the shared code cannot implement open-source gets a `stub.go` in the same package with `//go:build !ee`, exposing exactly the surface the shared call sites use. +- A capability that is absent from this tree altogether needs no stub: the downstream repository carries that file and its build tag on its own. +- Keep stubs minimal: when shared code calls several enterprise functions in a row, collapse them into one entry point instead of stubbing each one. +- Review every stub from the caller's side: it returns a zero value or an error, and the open-source build still has to behave correctly — the call site needs the fallback that keeps normal operation intact. +- Never inline enterprise content into a shared file (a config section, an environment variable, a frontend module). The edition is selected by build tags or by an environment variable, and the enterprise repository ships the counterpart file. +- Both trees must build: this one with `bash build.sh --go`, the enterprise one with `RAGFLOW_GO_TAGS=ee bash build.sh --go`. +- New tests are Go tests run through `bash build.sh --test`, never pytest. Integration and system tests must exercise the real implementation — no mocks or stubs of the code under test. + +## GORM query traps ## GORM query traps - **Never pass a bare string ID as the second argument to `Take`/`First`** (e.g. `Take(&x, id)`). Under GORM v1.25.7 a non-numeric string is treated as a raw SQL condition and concatenated into the `WHERE` clause: `Take(&x, "88b17c7a...")` emits `WHERE 88b17c7a... LIMIT 1`, which MySQL rejects with `Error 1054 (42S22): Unknown column '...' in 'where clause'`. Only strings that parse via `strconv.Atoi` are treated as primary-key values, so this bug is invisible for integer IDs and catastrophic for UUID primary keys. Always bind explicitly: `Take(&x, "id = ?", id)` or `Where("id = ?", id).Take(&x)`. - When you change a query form across many files, verify the generated SQL with a `Session(&gorm.Session{DryRun: true})` probe before relying on it. A passing unit test with no rows and a broken `WHERE` clause look identical unless the SQL is inspected. diff --git a/build.sh b/build.sh index 2e17623097..8af9b6c1c1 100755 --- a/build.sh +++ b/build.sh @@ -825,7 +825,7 @@ build_go() { GOPROXY=${GOPROXY:-https://goproxy.cn,https://proxy.golang.org,direct} CGO_ENABLED=1 \ CGO_CFLAGS="$CGO_CFLAGS" CGO_LDFLAGS="$CGO_LDFLAGS" \ go build -tags "$GO_BUILD_TAGS" "${strip_flags[@]}" -o "$RAGFLOW_SERVER_BINARY" \ - cmd/ragflow_server.go cmd/stub.go + ./cmd set +x diff --git a/web/AGENTS.md b/web/AGENTS.md index 5f4959af1c..3813f2c2c4 100644 --- a/web/AGENTS.md +++ b/web/AGENTS.md @@ -45,6 +45,16 @@ The frontend serves only the **Go** backend. There is no runtime backend detecti Do not reintroduce backend-variant primitives or detection helpers (e.g. a `useIsGoBackend` hook, `pickByBackend`, ``, or an `/api/v1/language` probe) and do not create `go/`-vs-`python/` variant directories or files. +### Enterprise Overlays + +`src/ee/` holds the enterprise customization of shared modules at the same path it overrides. This tree ships those files empty so every shared import resolves; the enterprise repository ships the real implementation. Keep both sides in that shape: + +- `src/ee/locales/-private.ts` carries enterprise locale strings and `src/ee/utils/api-private.ts` enterprise-only API endpoints. Both stay empty objects here. +- The shared file only imports the overlay and merges it — `merge(base, private)` in `src/locales/config.ts`, `merge(apiEndpoints, apiPrivate)` in `src/utils/api.ts`. Never inline enterprise strings or endpoints into `src/locales/*.ts` or `src/utils/api.ts`, and never delete the overlay import. +- The edition is chosen by the file's content, never at runtime: no `import.meta.env` switch that selects enterprise code and no `isEnterprise` branch in shared modules. +- Adding a new overlay means adding the empty file here and the implementation downstream in the same change. + +### CSS and Layout Debugging ### CSS and Layout Debugging When fixing CSS/layout issues (especially flex truncation, ellipsis, or element sizing), **always inspect the full parent hierarchy** for `flex-shrink`, `min-width`, and `overflow` constraints before applying fixes like `min-w-0`. Do not repeatedly apply the same fix without verifying the root cause.