5.6 KiB
OpenObserve — project rules
Build & workflow
- Build with
cargo build(debug). Never use--releaseunless explicitly asked. - Skip UI build steps (
npm run build) when working on backend tasks. .envin the project root overrides process env; check it before running the server.- Before finishing a task: run
cargo fmt --alland make the CI clippy command pass:cargo clippy --workspace --all-targets -- -W clippy::too_many_lines -W clippy::cognitive_complexity -W clippy::excessive_nesting -D warnings.
Frontend (web/)
- After every change under
web/, runnpm run format:checkfromweb/before considering the task done. If it flags a file, fix it withnpx prettier --write <file>(not a full-repo--write) and re-runformat:checkto confirm it's clean.
Rust code organization
Item order inside a file/module, top to bottom (clippy's default grouping):
mod/pub mod declarations → use imports → macros → const/static → types (struct/enum/trait/type), each immediately followed by its own impl blocks (inherent impl first, then trait impls) → functions.
-
A type and its
implblocks stay together. Do not collect all types at the top and allimplblocks below them; a reader must see a struct's methods right under its fields. Types that only serve another type (private helper structs/enums) go after the type that uses them, again followed by their own impls. No lint enforces adjacency, review does. -
Function length, cognitive complexity, and nesting depth are capped by the thresholds in clippy.toml (set just above the worst existing code). They only ratchet down — if CI flags your function, split it instead of raising the threshold.
-
Never insert a function above the file's constants or type definitions.
-
Keep
puband private functions grouped. Do not drop a private helper into the middle of the pub API block, or a pub fn into a run of private helpers. Place new functions next to related functions within the correct group. -
#[cfg(test)] mod testsis always the LAST item in a file. CI enforces this (clippyitems_after_test_moduleruns under--all-targets -- -D warnings). -
The module-level order above matches clippy's
arbitrary_source_item_orderinglint with thesource-item-ordering = ["module"]config in clippy.toml. The lint is opt-in (too much pre-existing debt to enable repo-wide); hold the code you add to this order even though nothing enforces it yet.
Comments
STRICT, and enforced in review — a comment that breaks these is deleted, not reworded:
- One line, or none. A comment is at most a single line. No multi-line comment blocks in code (the license header is the only exception). If the point needs more than one line, it does not belong in a comment.
- Only logical comments — explain WHY. The single allowed reason to write a comment is to state a non-obvious constraint, invariant, or gotcha the code itself cannot express. If a comment is not explaining logic, do not write it; no comment is better than a filler one.
- Banned outright (remove on sight): styling/visual narration (layout,
spacing,
px, "matches the header height"), change/modification notes ("now we...", "changed to...", "was X"), and narration that restates what the code plainly does. //// JSDoc doc comments on public APIs: one summary sentence, and only when the behaviour is non-obvious; never to restate the signature.
Database schema (migrations / SeaORM entities)
Applies to every NEW table and column (sqlite, MySQL and PostgreSQL alike):
- No
json/jsonbcolumns (sea-orm.json()/.json_binary()). JSON is stored in a.text()column holding the serialized string; Rust (serde_json) parses it. Never push JSON operators or extraction into SQL. - No
timestamp/datetime/datecolumns (sea-orm.timestamp(),.date_time(),.date()). A time field is a Unix timestamp in MICROSECONDS stored as.big_integer()(Rusti64), the same unit_timestampuses everywhere else. - Existing columns that break these rules are legacy; do not add new ones next to them, and do not migrate them as part of an unrelated change.
PR conventions
- CI runs on a PR only while it carries the
ready-for-cilabel and is not a draft (no label or draft = nothing runs exceptci-gate, and no red checks). Add the label when you want the run, not when you open the PR; clicking "Merge when ready" adds it automatically if it is missing. Which suites run is decided by path detection, never by a label. The merge queue only compiles and unit-tests the merged code, so the labelled PR run is the one that has to be green. - PR titles starting with
feat:requireDesign at: #xxxas the FIRST line of the description (enforced by.github/workflows/feat-design-checker.yml);fix:/chore:/test:PRs skip the check.
Enterprise-gated code
- Default features do NOT compile
#[cfg(feature = "enterprise")]code, so a green local check proves nothing about it, and--features enterprisedoes not work in this repo (the localsrc/enterprise/*stubs don't provide it). With access to the o2-enterprise repo, verify by swapping in itsCargo.toml.openobserveand runningcargo check --all-targets, then restoreCargo.toml(never commit the swap). Without access, say so in the PR. - A change needing paired PRs in openobserve and o2-enterprise must use the SAME branch name in both repos — CI checks out the paired side by branch name.
- When changing this repo's root
Cargo.toml, mirror the change intoCargo.toml.openobservein the o2-enterprise repo.