Skip to content

feat(base): add typed NDJSON workflows for professional data analysis - #2196

Merged
zgz2048 merged 20 commits into
larksuite:mainfrom
zgz2048:codex/base-record-ndjson
Aug 11, 2026
Merged

feat(base): add typed NDJSON workflows for professional data analysis#2196
zgz2048 merged 20 commits into
larksuite:mainfrom
zgz2048:codex/base-record-ndjson

Conversation

@zgz2048

@zgz2048 zgz2048 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add a typed NDJSON artifact workflow for Base record reads so agents can perform professional local analytics—joins, window and calendar calculations, multi-value expansion, attribution, and deeper insight generation—without loading hundreds of raw records into the model context.

The existing Markdown and raw JSON paths remain compatible. The new path complements Base cloud aggregation: agents use local analysis when a complete task dataset can be kept within 2,000 records per table, and fall back to the Cloud SOP when it cannot.

Why

The current Base record response is a compact matrix (fields, field_id_list, field_type_list, record_id_list, and data[][]). It is efficient on the wire, but requires every downstream agent to reconstruct rows and types before using jq, Python, or a dataframe engine. Returning the matrix inline also consumes model tokens and makes repeated analysis expensive.

This feature moves the deterministic transformation into lark-cli once:

  • AI-generated analysis code reads normal row objects keyed by field name.
  • The manifest carries the physical schema, examples, column statistics, query boundary, and table revision.
  • Raw records stay in a local file instead of the model context.
  • The same artifact can be reused for follow-up analysis without another Base download.

Changes

Typed Base record artifacts

  • Add --format ndjson to base +record-list, +record-search, and +record-get.
  • Add --output <path>.ndjson; an output path implies NDJSON unless a conflicting format was explicitly provided.
  • Write a record file and matching <path>.manifest.json, while stdout returns the manifest rather than record bodies.
  • Add --minimal-stdout for repeated workflows that only need artifact paths, records_count, and has_more.
  • Add --overwrite with actionable collision errors.
  • Keep --jq useful for NDJSON mode by applying it to the JSON manifest on stdout.

Complete local reads up to 2,000 records

  • Allow NDJSON --limit values up to 2,000 while keeping inline Markdown/JSON reads capped at 200.
  • Fetch Base pages serially in batches of at most 200 and merge them into one artifact.
  • Preserve projection, view, filter, sort, search, offset, and query context on every page.
  • Reject cross-page schema/timezone changes before publishing a mixed artifact.

Stable typed row model and manifest

  • Materialize the Base system record_id as the non-null join key; it wins over a user field with the same name.
  • Use Base field names as NDJSON keys while retaining field_id and field_type in manifest column metadata.
  • Normalize multi-value empty cells to [] and checkbox empty cells to false.
  • Normalize legacy local datetime strings to RFC3339 while preserving upstream RFC3339 offsets.
  • Keep structured cells as JSON objects and publish engine-neutral physical types, including arrays and structs for users, chats, links, attachments, and locations.
  • Include type-specific statistics and bounded real examples to guide type inference and expansion-cost decisions without rescanning the artifact.
  • Include the first record response rev when available; it is omitted for older server versions that do not return it.
  • Preserve existing content-safety scanning and use the CLI file I/O abstraction for both artifacts.

Agent analysis routing and professional Base semantics

  • Split the former single analysis SOP into Local and Cloud paths using progressive disclosure.
  • Route by local filesystem/tool availability and records_count, with predicate/projection pushdown for large tables before choosing a path.
  • Document Base-specific relational semantics: system primary key, nullable scalars, non-null arrays, Link foreign-record IDs, set operations, element expansion, array-to-table joins, and fan-out/cardinality estimation.
  • Add concise, copyable pandas and Python standard-library examples for the same representative scenarios.
  • Keep the full +data-query DSL out of context unless the Cloud path actually selects it, reducing prompt size and avoiding mixed execution plans.
  • Remove brittle tests that asserted prose inside SKILL.md; behavior is covered at the command/export boundary instead.

User and agent impact

  • Lower token usage: record bodies are written to disk; stdout can be reduced to four small fields for repeated runs.
  • Less generated glue code: agents no longer need to transpose parallel matrix arrays or rewrite schema declarations for every analysis.
  • More reliable conclusions: local analysis receives one complete, typed artifact rather than reasoning over a default page or partial stdout.
  • Stronger analytical capability: multi-table joins, windows, cohort/calendar calculations, multi-select attribution, Link traversal, and nested-array analysis become normal dataframe/relational operations.
  • Faster follow-up analysis: NDJSON and its manifest are reusable across multiple questions about the same query result.
  • Better cost decisions: column stats expose null/empty rates and array fan-out before an agent chooses set operations versus expansion.
  • Safer fallback: tasks that cannot preserve their semantic scope within the local 2,000-record bound are explicitly routed to Base cloud aggregation instead of silently sampling.
  • Backward compatible: existing Markdown and raw JSON behavior is unchanged unless NDJSON/output flags are selected.

Test Plan

  • make build
  • make unit-test (full -race unit suite across cmd, internal, shortcuts, and extension)
  • go test ./shortcuts/base/... ./shortcuts/common/... ./tests/cli_e2e/base/...
  • go vet ./...
  • gofmt -l . returned no files
  • go mod tidy produced no go.mod / go.sum changes
  • golangci-lint v2.1.6 run --new-from-rev=upstream/main returned 0 issues
  • Unit coverage includes format inference, flag conflicts, typed normalization, datetime compatibility, physical schemas, column statistics, examples/truncation, file collision/overwrite behavior, minimal stdout, jq-on-manifest, multi-page aggregation, schema changes, and pagination limits.
  • Dry-run E2E verifies NDJSON inference and first-page request capping for record list/search/get while preserving the query.
  • PRE live verification with the rebased binary:
    • +table-list: all 50 returned tables contained numeric records_count and rev.
    • +base-block-list: all 94 returned table blocks contained numeric records_count and rev.
    • +record-list, stdout manifest, and file manifest returned the same table revision (998 in the test Base).
    • A real NDJSON artifact and matching manifest were successfully written and parsed.

Related Issues

  • None

Summary by CodeRabbit

  • New Features
    • Added NDJSON export for record list, search, and get commands.
    • Supports pagination, up to 2,000 records, automatic filenames, manifests, jq filtering, normalization, and overwrite controls.
    • Added schema validation and safer file handling, including collision protection.
  • Documentation
    • Updated analysis workflows, routing, pagination, cell-value formats, date handling, and relationship-analysis examples.
  • Bug Fixes
    • Improved pagination and output-format validation, including inline search limits.
    • Enhanced dry-run details, NDJSON format inference, and ignored/read-only field explanations.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds typed NDJSON export for Base record list, search, and get commands. It adds manifests, pagination, validation, artifact handling, JQ support, CLI routing, tests, and updated Base analysis guidance.

Changes

Record export pipeline

Layer / File(s) Summary
Dataset, manifest, and NDJSON models
shortcuts/base/recordexport/*
The new package parses record matrices, normalizes values, validates schemas, generates manifests and statistics, and writes NDJSON.
Paginated export and artifact publication
shortcuts/base/record_export.go, shortcuts/base/record_export_test.go
List, search, and get exports paginate records, reject schema changes, protect output files, write paired artifacts, and support JQ and minimal output.
Shortcut flags, validation, and runtime routing
shortcuts/base/record_*.go, shortcuts/common/*, tests/cli_e2e/base/base_record_list_dryrun_test.go
Record shortcuts expose NDJSON and export flags, validate format-specific limits, preserve search parameters, and route NDJSON requests to the exporter.
Help, metadata, and regression coverage
shortcuts/base/*_test.go
Help and tests cover NDJSON limits, analysis output, structured ignored-field metadata, CellValue guidance, and format validation.
Base analysis documentation and examples
skills/lark-base/SKILL.md, skills/lark-base/references/*
The Base skill and references define NDJSON analysis routing, manifests, physical types, date handling, relationship modeling, and Python or pandas workflows.

Estimated code review effort: 5 (Critical) | ~120 minutes

Suggested reviewers: liangshuo-1

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant RecordShortcut
  participant RecordExporter
  participant RecordAPI
  participant ArtifactFiles
  CLI->>RecordShortcut: select NDJSON format and export options
  RecordShortcut->>RecordExporter: validate and start export
  RecordExporter->>RecordAPI: request paginated records
  RecordAPI-->>RecordExporter: return record matrix pages
  RecordExporter->>ArtifactFiles: write NDJSON and manifest
  ArtifactFiles-->>CLI: return export metadata
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: typed NDJSON workflows for Base data analysis.
Description check ✅ Passed The description includes all required template sections and provides detailed scope, rationale, changes, tests, and issue status.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added domain/base PR touches the base domain size/XL Architecture-level or global-impact change labels Aug 5, 2026
@zgz2048
zgz2048 force-pushed the codex/base-record-ndjson branch from 0c14a6d to 99d6a7d Compare August 5, 2026 12:16
@zgz2048
zgz2048 marked this pull request as ready for review August 7, 2026 09:39
@zgz2048
zgz2048 requested a review from liangshuo-1 as a code owner August 7, 2026 09:39
…djson

# Conflicts:
#	skills/lark-base/SKILL.md
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@ea6888f6fa49ce700c68655cb7edf62cabfef990

🧩 Skill update

npx skills add zgz2048/cli#codex/base-record-ndjson -y -g

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🧹 Nitpick comments (5)
shortcuts/base/recordexport/dataset_test.go (1)

69-69: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use the comma-ok form for these type assertions.

If a regression changes the cell shape, these assertions panic instead of producing a readable test failure. Use the comma-ok form and call t.Fatalf with the actual value.

Also applies to: 150-157

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/base/recordexport/dataset_test.go` at line 69, Update the type
assertions in the dataset test, including the assertion around first[7] and the
additional assertions at the referenced locations, to use comma-ok checks. When
an assertion fails, call t.Fatalf with the actual cell value and stop the test;
otherwise continue using the successfully asserted map value.
shortcuts/base/record_export.go (1)

193-276: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the shared pagination loop.

executeRecordListNDJSON and executeRecordSearchNDJSON contain the same loop. Only the request call differs. The row-count guard, the accumulate step, the remaining/currentOffset arithmetic, and the termination condition are duplicated. Extract a helper that takes a func(offset, limit int) (map[string]any, error) fetcher, so a future fix to the pagination arithmetic applies to both commands.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/base/record_export.go` around lines 193 - 276, Extract the
duplicated pagination logic from executeRecordListNDJSON and
executeRecordSearchNDJSON into a shared helper that accepts a func(offset, limit
int) (map[string]any, error) fetcher. Keep page parsing, row-count validation,
accumulation, offset/remaining updates, and termination behavior in the helper;
have each command provide only its request-specific fetcher and retain its
existing finalization flow.
shortcuts/base/recordexport/manifest.go (2)

336-361: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

bestExample marshals every cell of every column.

The function calls json.Marshal once per record per column to find the shortest non-empty value. For the 2000-row NDJSON limit and a wide table, this runs tens of thousands of extra marshals after the rows are already written. Stop the scan once a value is small enough, for example once the encoded length is at or below a threshold, or cap the scan at the first N records.

The name is also misleading. The function selects the shortest example, not the most representative one. Consider shortestExample.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/base/recordexport/manifest.go` around lines 336 - 361, Limit the
work performed by bestExample while preserving selection of the shortest
non-empty value: stop scanning once an encoded value meets a small-size
threshold or after a bounded number of records, using a clearly defined
constant. Rename bestExample and its callers to shortestExample to accurately
describe the behavior.

65-65: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Column order is lost in the manifest.

Columns is a map[string]ColumnManifest, so the manifest does not preserve the dataset column order. A consumer that builds a table or a DataFrame from the manifest cannot reproduce the original field order. Add an ordered column_order []string field, or change Columns to an ordered slice.

Also applies to: 121-135

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/base/recordexport/manifest.go` at line 65, Add an ordered column
sequence to the manifest model alongside Columns, such as a column_order
[]string JSON field, and populate it wherever the manifest is constructed or
serialized (including the code around lines 121-135). Preserve the existing
column definitions while ensuring consumers can reconstruct the original dataset
field order.
shortcuts/base/recordexport/dataset.go (1)

274-283: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Consider detecting rev drift across pages.

AppendPage compares the timezone and the source columns, but not Rev. recordExportAccumulator keeps the first page's Rev, so the manifest labels the whole dataset with a revision that later rows no longer match. TestRecordListNDJSONSerializesPagesAbove200 in shortcuts/base/record_export_test.go asserts this behavior with rev 100 and 101, so it looks intentional. If it is intentional, record the drift in the manifest or in a stderr warning, because row-level data changed between pages while the schema did not.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/base/recordexport/dataset.go` around lines 274 - 283, Update
Dataset.AppendPage and the manifest accumulation flow to detect when
page.Dataset.Rev differs from the dataset’s initial Rev, while preserving the
existing successful append behavior. Record the revision drift in the manifest
or emit a stderr warning so consumers are informed that row data spans multiple
revisions; retain the existing first-Rev behavior unless the surrounding
contract requires otherwise.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@shortcuts/base/base_execute_test.go`:
- Around line 2821-2829: The BaseRecordBatchUpdate test should assert the
complete ignored_fields structure rather than only checking that stdout contains
“ignored_fields” and “Formula”. Validate the ignored field’s id, name, and
reason values, matching the structured contract asserted by the corresponding
markdown test.

In `@shortcuts/base/record_export_test.go`:
- Around line 234-241: Update the collision test around runShortcut and the
jq-records table test around lines 403-414 to validate typed errors with the
existing assertInvalidArgumentValidation pattern. Assert the expected category,
subtype, and parameter, and verify cause preservation through errs.ProblemOf
instead of relying only on problem.Hint or err.Error() substring checks.

In `@shortcuts/base/record_export.go`:
- Around line 325-346: Update the error path after saveRecordManifest in the
record export flow to remove the record file created by saveRecordNDJSON before
returning the manifest-save error. Preserve the original manifest error and
ensure cleanup targets paths.recordRelative through the existing file I/O
abstraction.

In `@shortcuts/base/recordexport/dataset_test.go`:
- Around line 180-193: Update the error-path tests around
TestDatasetAppendRejectsSchemaChange and the related tests near the referenced
range to assert concrete error types with errors.As: expect *SchemaChangedError
for schema changes and *MatrixError for matrix failures. Verify the typed error
metadata, including the changed field where applicable, and preserve/assert the
underlying cause instead of checking only err != nil or message text.

In `@shortcuts/base/recordexport/dataset.go`:
- Around line 399-412: Update the ignored_fields parsing block in the record
export flow so missing id, name, or reason keys default to empty strings without
returning a MatrixError. Retain the type validation for present values,
returning the existing error when any supplied value is not a string, and
continue processing advisory warning objects without aborting valid exports.
- Around line 171-188: Validate column names while building exportColumns in the
surrounding dataset construction flow, rejecting any duplicate non-system names
with a MatrixError before returning the page; preserve the existing
RecordIDColumnName handling so the system join key continues to take precedence
over a same-named source field.

In `@skills/lark-base/references/lark-base-cell-value.md`:
- Around line 64-72: Align the datetime serialization contract across the
serializer, the artifact test, and the documentation: choose one RFC3339 output
format regarding milliseconds and apply it consistently. Update the relevant
record-export serializer and its test, then revise the datetime read-value
example in the cell-value documentation to match.
- Around line 51-60: Update the select-field examples in the complete example
and the record upsert example to use option-name arrays consistently with the
documented select write/read contract, replacing scalar "状态" values while
preserving the examples’ intended data.

In `@skills/lark-base/references/lark-base-data-analysis-sop.md`:
- Around line 168-172: 在“单表简单筛选与统计:jq”段落中,将本地分析说明里的 `js -s` 更正为 `jq -s`,保持与前文
`jq -s` 工作流及 `--jq-records` 等价命令一致。
- Around line 134-136: Update the physical-type table entries around the rows
containing inline code at lines 134–136 and 139 so every literal pipe is escaped
as \| (or replaced with an equivalent representation that contains no raw table
delimiter). Preserve the documented type and example values while keeping the
Markdown table correctly aligned.

In `@skills/lark-base/SKILL.md`:
- Around line 34-36: Clarify the workflow guidance around the Base command
section so lark-drive is used only for file import/export, while record
list/search/get operations that produce local NDJSON analysis artifacts remain
in this Base workflow. Update the related routing statements, including the
references near the high-frequency data-analysis guidance and other
Base-to-local export instructions, without changing the copy or table-copy
paths.

In `@tests/cli_e2e/base/base_record_list_dryrun_test.go`:
- Around line 118-169: Add live E2E coverage alongside the dry-run tests, using
the existing base-record test helpers and bot credential configuration to create
a temporary base/table and records, run record-list, record-search, and
record-get with NDJSON output, and verify real records plus NDJSON and manifest
publication. Make the flow self-contained with deferred cleanup of all created
resources and generated artifacts, while preserving the existing dry-run
assertions.
- Around line 147-153: Update the test assertions in the record-list dry-run
test to verify that data.output equals the requested search.ndjson destination.
Keep the existing export-format and requested-limit assertions unchanged, and
assert the output path directly so destination handling is covered.

---

Nitpick comments:
In `@shortcuts/base/record_export.go`:
- Around line 193-276: Extract the duplicated pagination logic from
executeRecordListNDJSON and executeRecordSearchNDJSON into a shared helper that
accepts a func(offset, limit int) (map[string]any, error) fetcher. Keep page
parsing, row-count validation, accumulation, offset/remaining updates, and
termination behavior in the helper; have each command provide only its
request-specific fetcher and retain its existing finalization flow.

In `@shortcuts/base/recordexport/dataset_test.go`:
- Line 69: Update the type assertions in the dataset test, including the
assertion around first[7] and the additional assertions at the referenced
locations, to use comma-ok checks. When an assertion fails, call t.Fatalf with
the actual cell value and stop the test; otherwise continue using the
successfully asserted map value.

In `@shortcuts/base/recordexport/dataset.go`:
- Around line 274-283: Update Dataset.AppendPage and the manifest accumulation
flow to detect when page.Dataset.Rev differs from the dataset’s initial Rev,
while preserving the existing successful append behavior. Record the revision
drift in the manifest or emit a stderr warning so consumers are informed that
row data spans multiple revisions; retain the existing first-Rev behavior unless
the surrounding contract requires otherwise.

In `@shortcuts/base/recordexport/manifest.go`:
- Around line 336-361: Limit the work performed by bestExample while preserving
selection of the shortest non-empty value: stop scanning once an encoded value
meets a small-size threshold or after a bounded number of records, using a
clearly defined constant. Rename bestExample and its callers to shortestExample
to accurately describe the behavior.
- Line 65: Add an ordered column sequence to the manifest model alongside
Columns, such as a column_order []string JSON field, and populate it wherever
the manifest is constructed or serialized (including the code around lines
121-135). Preserve the existing column definitions while ensuring consumers can
reconstruct the original dataset field order.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3340746b-2a55-4fc3-8b73-d5e3e945339f

📥 Commits

Reviewing files that changed from the base of the PR and between 771ff44 and ebd4a36.

📒 Files selected for processing (31)
  • shortcuts/base/base_execute_test.go
  • shortcuts/base/base_shortcuts_test.go
  • shortcuts/base/record_export.go
  • shortcuts/base/record_export_test.go
  • shortcuts/base/record_get.go
  • shortcuts/base/record_json_shorthand_test.go
  • shortcuts/base/record_list.go
  • shortcuts/base/record_markdown.go
  • shortcuts/base/record_markdown_test.go
  • shortcuts/base/record_ops.go
  • shortcuts/base/record_query.go
  • shortcuts/base/record_search.go
  • shortcuts/base/recordexport/dataset.go
  • shortcuts/base/recordexport/dataset_test.go
  • shortcuts/base/recordexport/errors.go
  • shortcuts/base/recordexport/manifest.go
  • shortcuts/base/recordexport/ndjson.go
  • shortcuts/common/runner.go
  • shortcuts/common/types.go
  • skills/lark-base/SKILL.md
  • skills/lark-base/references/lark-base-cell-value.md
  • skills/lark-base/references/lark-base-data-analysis-cloud.md
  • skills/lark-base/references/lark-base-data-analysis-pandas.md
  • skills/lark-base/references/lark-base-data-analysis-python-stdlib.md
  • skills/lark-base/references/lark-base-data-analysis-sop.md
  • skills/lark-base/references/lark-base-data-query-guide.md
  • skills/lark-base/references/lark-base-data-query.md
  • skills/lark-base/references/lark-base-field-json.md
  • skills/lark-base/references/lark-base-record-upsert.md
  • tests/cli_e2e/base/base_record_list_dryrun_test.go
  • tests/cli_e2e/base/base_skill_contract_test.go
💤 Files with no reviewable changes (1)
  • tests/cli_e2e/base/base_skill_contract_test.go

Comment thread shortcuts/base/base_execute_test.go
Comment thread shortcuts/base/record_export_test.go
Comment thread shortcuts/base/record_export.go
Comment thread shortcuts/base/recordexport/dataset_test.go
Comment thread shortcuts/base/recordexport/dataset.go
Comment thread skills/lark-base/references/lark-base-data-analysis-sop.md
Comment thread skills/lark-base/references/lark-base-data-analysis-sop.md Outdated
Comment thread skills/lark-base/SKILL.md Outdated
Comment thread tests/cli_e2e/base/base_record_list_dryrun_test.go
Comment thread tests/cli_e2e/base/base_record_list_dryrun_test.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
skills/lark-base/references/lark-base-data-analysis-sop.md (1)

39-39: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the February lower-bound example.

The > condition with ExactDate(2024-01-31 23:59:59) includes records from January 31 between 23:59:59.000 and midnight when timestamps contain milliseconds. Use February 1 at midnight as the lower bound.

Proposed fix
-    ["发生时间", ">", "ExactDate(2024-01-31 23:59:59)"], // 2024 年 2 月范围下界:闰年 2 月包含 29 日
+    ["发生时间", ">=", "ExactDate(2024-02-01 00:00:00)"], // 2024 年 2 月范围下界:闰年 2 月包含 29 日
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-base/references/lark-base-data-analysis-sop.md` at line 39,
Update the February date-range example in the SOP to use February 1, 2024 at
midnight as the lower bound, replacing the January 31 23:59:59 ExactDate value
while preserving the existing `>` condition.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@skills/lark-base/references/lark-base-data-analysis-sop.md`:
- Line 39: Update the February date-range example in the SOP to use February 1,
2024 at midnight as the lower bound, replacing the January 31 23:59:59 ExactDate
value while preserving the existing `>` condition.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 52449e61-76f6-44c0-951e-4ef5aabbb1c3

📥 Commits

Reviewing files that changed from the base of the PR and between ebd4a36 and f4e9633.

📒 Files selected for processing (10)
  • shortcuts/base/record_export.go
  • shortcuts/base/record_export_test.go
  • shortcuts/base/record_list.go
  • shortcuts/base/record_query.go
  • shortcuts/base/record_search.go
  • skills/lark-base/SKILL.md
  • skills/lark-base/references/lark-base-data-analysis-cloud.md
  • skills/lark-base/references/lark-base-data-analysis-sop.md
  • skills/lark-base/references/lark-base-data-query-guide.md
  • skills/lark-base/references/lark-base-data-query.md
🚧 Files skipped from review as they are similar to previous changes (8)
  • shortcuts/base/record_list.go
  • shortcuts/base/record_export.go
  • shortcuts/base/record_search.go
  • shortcuts/base/record_query.go
  • skills/lark-base/references/lark-base-data-query.md
  • skills/lark-base/SKILL.md
  • skills/lark-base/references/lark-base-data-analysis-cloud.md
  • shortcuts/base/record_export_test.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
skills/lark-base/references/lark-base-data-analysis-sop.md (1)

115-116: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not treat the first-page rev as a snapshot-consistency guarantee.

The exporter sends independent offset requests and stores only the first page's rev. Comparing it with the latest table rev can detect some changes, but cannot prove that all pages used the same revision. Describe this check as best effort. If stronger validation is required, retain per-page revisions and flag mismatches.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-base/references/lark-base-data-analysis-sop.md` around lines 115
- 116, 修改该 SOP 中关于 manifest.rev 与最新 table rev 比较的表述:明确首个响应页的 rev
只能用于尽力检测版本变化,不能保证所有分页请求使用同一快照。若需要更强校验,说明应保留每页 rev 并标记不一致。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skills/lark-base/references/lark-base-data-analysis-sop.md`:
- Line 48: 修正“全局结论”的完整性判定:不要仅凭 has_more=false 认定导出覆盖全表;在使用导出结果前,确认查询从预期的起始
offset 开始且未截断,或明确将完整性限定为请求窗口。同步更新该 SOP 中对 has_more=false 的表述,保留 has_more=true
时继续收敛谓词或选择 Cloud 路径的逻辑。
- Around line 39-40: Update the date-range example around the “发生时间” filters to
use only the documented ExactDate(YYYY-MM-DD HH:mm) format, avoiding seconds and
millisecond precision while preserving the intended February lower and upper
boundaries.

---

Outside diff comments:
In `@skills/lark-base/references/lark-base-data-analysis-sop.md`:
- Around line 115-116: 修改该 SOP 中关于 manifest.rev 与最新 table rev 比较的表述:明确首个响应页的 rev
只能用于尽力检测版本变化,不能保证所有分页请求使用同一快照。若需要更强校验,说明应保留每页 rev 并标记不一致。
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b047e70a-d122-41c9-9869-4b3a24f7fdb6

📥 Commits

Reviewing files that changed from the base of the PR and between 25bd566 and c8dc5ae.

📒 Files selected for processing (1)
  • skills/lark-base/references/lark-base-data-analysis-sop.md

Comment thread skills/lark-base/references/lark-base-data-analysis-sop.md
Comment thread skills/lark-base/references/lark-base-data-analysis-sop.md
@zgz2048
zgz2048 removed the request for review from liangshuo-1 August 11, 2026 12:17
@zgz2048
zgz2048 merged commit 8b824b0 into larksuite:main Aug 11, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/base PR touches the base domain size/XL Architecture-level or global-impact change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants