Skip to content

feat(common): backfill resource URL when create APIs omit it#680

Merged
fangshuyu-768 merged 1 commit intomainfrom
feat/url
Apr 28, 2026
Merged

feat(common): backfill resource URL when create APIs omit it#680
fangshuyu-768 merged 1 commit intomainfrom
feat/url

Conversation

@caojie0621
Copy link
Copy Markdown
Collaborator

@caojie0621 caojie0621 commented Apr 27, 2026

Summary

  • Add common.BuildResourceURL(brand, kind, token) helper that returns brand-standard URLs (www.feishu.cn / www.larksuite.com) for known resource kinds (docx / doc / sheet / wiki / file / folder). The standard host transparently redirects to the tenant domain.
  • Wire it into the create paths so the output always carries a usable url field even when the backend response omits one — e.g. degraded MCP responses where ExtractMCPResult collapses
    multi-content into a plain string, the drive upload API which never returns a URL, or wiki node create which only returns tokens.
  • The fallback is non-invasive: it only fills url when the backend value is empty, so tenant-specific URLs returned by the API are preserved.

Affected entries

Path Behavior change
docs +create --api-version v1 doc_url falls back to /docx/<doc_id> when MCP omits it
docs +create --api-version v2 data.document.url falls back to /docx/<document_id>
sheets +create out.url falls back to /sheets/<token> (also fixes a pre-existing bug where missing url produced a literal null field)
drive +create-folder url falls back to /drive/folder/<token>
drive +import url falls back to /<docx|sheets|base>/<token> based on resolved resultType
drive +upload newly exposes url, only when parent_type=explorer (wiki-hosted files have no standalone URL)
wiki +node-create newly exposes url = /wiki/<node_token>

drive +create-shortcut is intentionally not covered: shortcut URL form depends on the underlying file kind, which the create payload does not carry — better to omit than to guess wrong.

Test plan

  • go test ./shortcuts/common/ ./shortcuts/doc/ ./shortcuts/sheets/ ./shortcuts/drive/ ./shortcuts/wiki/ — all green
  • New BuildResourceURL helper has 16 table-driven cases covering brand/kind/token edge cases
  • wiki_node_create_test.go extended to assert the new url field on output

Summary by CodeRabbit

  • New Features

    • Creation, import, and upload operations now populate brand-standard resource URLs (Feishu/Lark) for docs, sheets, wikis, folders, files, mindnotes and slides when upstream responses omit them; tenant-provided URLs are preserved.
  • Bug Fixes

    • Avoided missing or invalid URL outputs by trimming tokens and normalizing kinds; wiki-parent uploads intentionally omit fragile fallbacks to prevent broken links.
  • Tests

    • Added extensive tests covering URL fallbacks, token trimming, kind normalization (case-insensitive), and preservation behavior.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

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

Adds an exported BuildResourceURL helper and uses it across shortcuts (docs, sheets, drive, wiki) to populate output URL fields from tokens when backend responses omit tenant-provided links; includes unit and integration tests validating fallback and preservation behavior.

Changes

Cohort / File(s) Summary
Core URL Builder
shortcuts/common/resource_url.go, shortcuts/common/resource_url_test.go
New exported BuildResourceURL(core.LarkBrand, kind, token) string that normalizes inputs and returns brand-specific resource URLs for supported kinds; comprehensive table-driven tests for brands, kinds, trimming, case-insensitivity, and edge cases.
Doc Shortcuts
shortcuts/doc/docs_create.go, shortcuts/doc/docs_create_v2.go, shortcuts/doc/docs_create_test.go
Add unexported fallbacks to populate doc_url / document.url from doc_id when backend omits URL; ensure existing backend-provided URLs are preserved; tests added for both v1 and v2 flows.
Drive Shortcuts
shortcuts/drive/drive_create_folder.go, shortcuts/drive/drive_import.go, shortcuts/drive/drive_upload.go, shortcuts/drive/drive_create_folder_test.go, shortcuts/drive/drive_import_test.go, shortcuts/drive/drive_io_test.go
Trim API url fields, populate out["url"] from token via BuildResourceURL when API url is absent/blank (except wiki-parent uploads), and normalize import type to canonical kinds; extensive tests for fallback, preservation, and parent-specific behavior.
Sheet Shortcuts
shortcuts/sheets/sheet_create.go, shortcuts/sheets/sheet_create_test.go
Only use API-provided spreadsheet.url if non-blank after trim; otherwise build brand-standard sheet URL from token and set out["url"] if non-empty; tests cover both cases.
Wiki Shortcuts
shortcuts/wiki/wiki_node_create.go, shortcuts/wiki/wiki_node_create_test.go
Populate url for created wiki nodes via BuildResourceURL when backend omits it; test updated to assert derived URL presence.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as CLI Shortcut
    participant API as Backend API
    participant Builder as BuildResourceURL
    CLI->>API: Create resource (doc/sheet/folder/wiki/upload/import)
    API-->>CLI: Response { token, url? }
    alt url present and non-empty
        CLI->>CLI: Preserve API-provided url in output
    else url missing or blank
        CLI->>Builder: BuildResourceURL(brand, kind, token)
        Builder-->>CLI: url (or "")
        alt url returned
            CLI->>CLI: Emit derived url in output envelope
        else no url
            CLI->>CLI: Leave url unset
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • fangshuyu-768
  • liujinkun2025
  • zhaoleibd

Poem

🐰
I stitched a link from token bright,
Brand and kind to guide its light.
When APIs forget to show,
I hop and build the paths they owe.
Carrot-coded URLs — delight! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.73% 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 'feat(common): backfill resource URL when create APIs omit it' clearly and concisely summarizes the main change—adding a helper to populate missing resource URLs in API responses.
Description check ✅ Passed The PR description comprehensively covers the summary, specific changes across affected commands, and test validation, exceeding the template requirements with a detailed affected entries table.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/url

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 and usage tips.

@github-actions github-actions Bot added domain/base PR touches the base domain domain/ccm PR touches the ccm domain size/L Large or sensitive change across domains or core paths labels Apr 27, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 27, 2026

Codecov Report

❌ Patch coverage is 91.66667% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.25%. Comparing base (78d92de) to head (6a1c400).
⚠️ Report is 12 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/doc/docs_create_v2.go 66.66% 2 Missing and 2 partials ⚠️
shortcuts/doc/docs_create.go 77.77% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #680      +/-   ##
==========================================
+ Coverage   63.04%   63.25%   +0.21%     
==========================================
  Files         437      492      +55     
  Lines       38847    42305    +3458     
==========================================
+ Hits        24491    26761    +2270     
- Misses      12184    13210    +1026     
- Partials     2172     2334     +162     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

coderabbitai[bot]

This comment was marked as outdated.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 27, 2026

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#feat/url -y -g

@github-actions github-actions Bot removed the domain/base PR touches the base domain label Apr 28, 2026
Copy link
Copy Markdown
Collaborator

@fangshuyu-768 fangshuyu-768 left a comment

Choose a reason for hiding this comment

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

Nice helper and clean fallback strategy — the create paths definitely benefit from a stable url field. A few inline comments below; one is a real inconsistency with how the rest of the repo parses legacy doc URLs, and the others are about hardening the contract and shoring up test coverage.

Comment thread shortcuts/common/resource_url.go Outdated
Comment thread shortcuts/common/resource_url.go
Comment thread shortcuts/drive/drive_import.go Outdated
Comment thread shortcuts/doc/docs_create_v2.go
Comment thread shortcuts/sheets/sheet_create.go
Comment thread shortcuts/drive/drive_upload.go
@caojie0621 caojie0621 force-pushed the feat/url branch 2 times, most recently from 02d1c88 to 3fa4cbc Compare April 28, 2026 09:27
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shortcuts/drive/drive_create_folder.go`:
- Around line 95-99: The current check uses common.GetString(data, "url") != ""
which treats whitespace-only strings as non-empty; change the logic where url is
assigned (variable url in the block using common.GetString and
common.BuildResourceURL) to treat whitespace-only values as empty by trimming
whitespace (e.g., use strings.TrimSpace on the result of common.GetString)
before deciding to set out["url"], and fall back to
common.BuildResourceURL(runtime.Config.Brand, "folder", folderToken) when the
trimmed url is empty.

In `@shortcuts/drive/drive_import.go`:
- Around line 122-127: The code currently checks status.URL != "" which treats
whitespace-only URLs as present and prevents fallback; update the check to trim
whitespace first (e.g., use strings.TrimSpace) and only use status.URL when the
trimmed value is non-empty, otherwise fall back to building the resource URL
from status.Token via common.BuildResourceURL (reference symbols: status.URL,
status.Token, common.BuildResourceURL, normalizeDriveImportKindForURL,
resultType, spec.DocType, out map).
🪄 Autofix (Beta)

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

Run ID: 43ca52ae-817a-44a5-b94b-f99805a0b9af

📥 Commits

Reviewing files that changed from the base of the PR and between 02d1c88 and 3fa4cbc.

⛔ Files ignored due to path filters (1)
  • span.log is excluded by !**/*.log
📒 Files selected for processing (15)
  • shortcuts/common/resource_url.go
  • shortcuts/common/resource_url_test.go
  • shortcuts/doc/docs_create.go
  • shortcuts/doc/docs_create_test.go
  • shortcuts/doc/docs_create_v2.go
  • shortcuts/drive/drive_create_folder.go
  • shortcuts/drive/drive_create_folder_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/drive/drive_upload.go
  • shortcuts/sheets/sheet_create.go
  • shortcuts/sheets/sheet_create_test.go
  • shortcuts/wiki/wiki_node_create.go
  • shortcuts/wiki/wiki_node_create_test.go
✅ Files skipped from review due to trivial changes (1)
  • shortcuts/wiki/wiki_node_create_test.go
🚧 Files skipped from review as they are similar to previous changes (9)
  • shortcuts/wiki/wiki_node_create.go
  • shortcuts/drive/drive_upload.go
  • shortcuts/doc/docs_create_v2.go
  • shortcuts/drive/drive_create_folder_test.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/sheets/sheet_create_test.go
  • shortcuts/doc/docs_create_test.go
  • shortcuts/common/resource_url.go
  • shortcuts/drive/drive_import_test.go

Comment thread shortcuts/drive/drive_create_folder.go Outdated
Comment thread shortcuts/drive/drive_import.go Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shortcuts/drive/drive_import_test.go`:
- Around line 400-406: The tests always use driveImportTestConfig which
hardcodes BrandFeishu, so they never hit BuildResourceURL's larksuite.com
branch; update or add a variant of driveImportTestConfig to accept/return
core.BrandLark (or core.BrandLarkSuite) and modify the four tests
(TestDriveImportFallbackURLWhenBackendOmitsIt,
TestDriveImportPreservesBackendURL,
TestDriveImportFallbackURLWhenServerURLIsWhitespace,
TestDriveImportFallbackURLWhenServerTypeIsAlias) to run each assertion for both
brands (Feishu and Lark) so BuildResourceURL is exercised for the larksuite.com
path. Ensure you pass the brand through runtime.Config (as production code does)
when invoking the code under test so assertions expect larksuite.com for the
Lark brand.

In `@shortcuts/sheets/sheet_create.go`:
- Around line 113-116: The stored URL is not trimmed before being written to
out, so whitespace-padded backend URLs slip through; update the branch that
reads spreadsheet["url"] to trim the value into a local (e.g., trimmedURL :=
strings.TrimSpace(url)) then check trimmedURL != "" and set out["url"] =
trimmedURL; keep the existing fallback to
common.BuildResourceURL(runtime.Config.Brand, "sheet", token) only when the
trimmed value is empty.
🪄 Autofix (Beta)

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

Run ID: 9c9f5f4d-386b-4b8f-87bf-a2a976346613

📥 Commits

Reviewing files that changed from the base of the PR and between 3fa4cbc and 0c19b9c.

⛔ Files ignored due to path filters (1)
  • span.log is excluded by !**/*.log
📒 Files selected for processing (15)
  • shortcuts/common/resource_url.go
  • shortcuts/common/resource_url_test.go
  • shortcuts/doc/docs_create.go
  • shortcuts/doc/docs_create_test.go
  • shortcuts/doc/docs_create_v2.go
  • shortcuts/drive/drive_create_folder.go
  • shortcuts/drive/drive_create_folder_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_import_test.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/drive/drive_upload.go
  • shortcuts/sheets/sheet_create.go
  • shortcuts/sheets/sheet_create_test.go
  • shortcuts/wiki/wiki_node_create.go
  • shortcuts/wiki/wiki_node_create_test.go
✅ Files skipped from review due to trivial changes (3)
  • shortcuts/wiki/wiki_node_create_test.go
  • shortcuts/drive/drive_io_test.go
  • shortcuts/common/resource_url.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • shortcuts/wiki/wiki_node_create.go
  • shortcuts/drive/drive_import.go
  • shortcuts/common/resource_url_test.go

Comment thread shortcuts/drive/drive_import_test.go Outdated
Comment thread shortcuts/sheets/sheet_create.go Outdated
Add BuildResourceURL helper and wire it into doc/sheets/drive/base/wiki
create paths so callers always receive a clickable link, even when the
backend response (MCP degraded path or upstream OpenAPI) returns an
empty URL field. The fallback uses the brand-standard host
(www.feishu.cn / www.larksuite.com), which redirects to the tenant
domain.

Affected entries:
- docs +create v1 / v2
- sheets +create
- drive +create-folder / +import / +upload (newly exposes url)
- wiki +node-create (newly exposes url)

drive +create-shortcut is intentionally skipped because the URL form
depends on the underlying file kind, which the shortcut payload does
not carry.
@fangshuyu-768 fangshuyu-768 merged commit fc22e9a into main Apr 28, 2026
20 checks passed
@fangshuyu-768 fangshuyu-768 deleted the feat/url branch April 28, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/ccm PR touches the ccm domain size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants