Skip to content

Conversation

@phamhieu
Copy link

@phamhieu phamhieu commented Oct 21, 2025

Description

Adds support for write conflict options in the JavaScript SDK to handle duplicate writes and missing deletes, as introduced in OpenFGA v1.10.0.

This implementation adds onDuplicateWrites and onMissingDeletes options to control behavior when:

  • Writing a tuple that already exists (onDuplicateWrites)
  • Deleting a tuple that doesn't exist (onMissingDeletes)

References

Review Checklist

  • I have clicked on "allow edits by maintainers".
  • I have added documentation for new/changed functionality in this PR or in a PR to openfga.dev [Provide a link to any relevant PRs in the references section above]
  • The correct base branch is being used, if not main
  • I have added tests to validate that the change in functionality is working as expected

Summary by CodeRabbit

  • New Features

    • Added conflict options for write operations: OnDuplicateWrites and OnMissingDeletes to control behavior when duplicates are encountered or tuples are missing during deletes.
    • Options include "ignore" or "error" actions, with error taking precedence in mixed scenarios.
    • Requires OpenFGA v1.10.0+.
  • Documentation

    • Updated API documentation with conflict option guidance and configuration examples.

@phamhieu phamhieu requested review from a team as code owners October 21, 2025 06:50
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Oct 21, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@coderabbitai
Copy link

coderabbitai bot commented Oct 21, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

The PR adds support for write-operation conflict options (on_duplicate for duplicate writes, on_missing for missing deletes) across the SDK by introducing new API model enums, client configuration interfaces, updated method signatures, and comprehensive documentation and test coverage.

Changes

Cohort / File(s) Summary
API Model Enums & Types
apiModel.ts
Added WriteRequestWritesOnDuplicateEnum and WriteRequestDeletesOnMissingEnum enums with 'error' and 'ignore' values. Added optional on_duplicate field to WriteRequestWrites and optional on_missing field to WriteRequestDeletes.
Client Public API
client.ts
Introduced OnDuplicateWrites and OnMissingDeletes type aliases. Added ClientWriteConflictOptions, ClientWriteTuplesRequestOpts, and ClientDeleteTuplesRequestOpts interfaces. Extended ClientWriteRequestOpts with optional conflict field. Updated write(), writeTuples(), and deleteTuples() method signatures to accept and propagate conflict options to API calls.
Documentation
README.md, api.ts
Added "Conflict Options for Write Operations" documentation block in README describing on_duplicate and on_missing options, precedence rules, transactional behavior, and OpenFGA v1.10.0 requirement. Updated JSDoc comments for Write-related API methods with expanded guidance on conflict options.
Example
example/example1/example1.mjs
Updated fgaClient.write() call to include conflict options in options object with onDuplicateWrites: 'ignore'.
Tests
tests/client.test.ts
Added test cases verifying conflict options propagation to API calls for write, writeTuples, and deleteTuples methods, including scenarios with onDuplicateWrites only, onMissingDeletes only, combined options, and mixed write/delete operations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

The PR spans multiple files with consistent pattern changes (new enums, interfaces, and option propagation). While the logic is relatively straightforward—adding optional conflict configuration that flows through to API calls—understanding the complete implementation requires reviewing type definitions, client method modifications, documentation, and test scenarios across the codebase.

Possibly related issues

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "feat: add support for write conflict settings" directly and accurately summarizes the main change across the changeset. The title clearly communicates that this PR adds support for conflict settings related to write operations, which is the primary objective reflected in all the code changes including API model updates, client-side implementation, documentation, examples, and tests. The title is concise, specific, and avoids vague or misleading language.
Linked Issues Check ✅ Passed The pull request successfully addresses all primary coding requirements from linked issue #268. The changes surface the on_duplicate and on_missing API options introduced in OpenFGA v1.10.0 through new SDK enums (WriteRequestWritesOnDuplicateEnum, WriteRequestDeletesOnMissingEnum) and public interfaces (ClientWriteConflictOptions, ClientWriteTuplesRequestOpts, ClientDeleteTuplesRequestOpts). The client methods (write, writeTuples, deleteTuples) are extended to accept and propagate these conflict options to the API, reducing the need for client-side error handling. Comprehensive documentation updates, example code, and test coverage are included to validate the new functionality and demonstrate correct usage.
Out of Scope Changes Check ✅ Passed All changes in this pull request are directly scoped to the objective of adding write conflict settings support. The modifications span the full implementation path: API model definitions introducing conflict enums, client-side public interfaces and method signatures, documentation updates, example usage, and comprehensive test coverage. No unrelated refactoring, bug fixes, or feature additions outside this scope are present in the changeset.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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.

@socket-security
Copy link

socket-security bot commented Oct 21, 2025

No dependency changes detected. Learn more about Socket for GitHub.

👍 No dependency changes detected in pull request

Copy link

@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

🧹 Nitpick comments (1)
example/example1/example1.mjs (1)

149-151: Use exported enum for conflict option.

Since we now surface OnDuplicateWrites, please lean on that constant instead of the raw string so the example mirrors the public API surface.

-import { CredentialsMethod, FgaApiValidationError, OpenFgaClient, TypeName } from "@openfga/sdk";
+import { CredentialsMethod, FgaApiValidationError, OnDuplicateWrites, OpenFgaClient, TypeName } from "@openfga/sdk";
@@
   }, {
     authorizationModelId,
-    conflict: { onDuplicateWrites: 'ignore' }
+    conflict: { onDuplicateWrites: OnDuplicateWrites.Ignore }
   });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3fe33ac and 8a3eb8d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • README.md (1 hunks)
  • api.ts (4 hunks)
  • apiModel.ts (2 hunks)
  • client.ts (9 hunks)
  • example/example1/example1.mjs (1 hunks)
  • tests/client.test.ts (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/client.test.ts (2)
client.ts (2)
  • OnDuplicateWrites (192-192)
  • OnMissingDeletes (194-194)
tests/helpers/default-config.ts (1)
  • baseConfig (54-67)
client.ts (1)
apiModel.ts (2)
  • TupleKey (1432-1457)
  • TupleKeyWithoutCondition (1463-1482)

@dyeam0
Copy link
Member

dyeam0 commented Oct 21, 2025

Thanks for your submission @phamhieu. We will assign someone to review your PR.

@codecov-commenter
Copy link

codecov-commenter commented Oct 22, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.98%. Comparing base (ab47bd4) to head (ceebe5c).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #276      +/-   ##
==========================================
+ Coverage   88.88%   88.98%   +0.09%     
==========================================
  Files          23       23              
  Lines        1260     1271      +11     
  Branches      211      213       +2     
==========================================
+ Hits         1120     1131      +11     
  Misses         84       84              
  Partials       56       56              

☔ 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.

@SoulPancake SoulPancake requested a review from Copilot October 22, 2025 05:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for write conflict handling options introduced in OpenFGA v1.10.0, enabling developers to control behavior when writing duplicate tuples or deleting non-existent tuples.

  • Added OnDuplicateWrites and OnMissingDeletes enums with Error and Ignore options
  • Extended write, writeTuples, and deleteTuples methods to accept conflict configuration
  • Updated API documentation to reflect the new conflict handling behavior

Reviewed Changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
apiModel.ts Added on_duplicate and on_missing fields to write/delete request interfaces with corresponding enums
client.ts Extended client interfaces and methods to support conflict options with proper type safety
api.ts Updated API documentation to describe conflict handling behavior and examples
tests/client.test.ts Added comprehensive test coverage for conflict options across write, writeTuples, and deleteTuples methods
example/example1/example1.mjs Demonstrated usage of conflict options in example code
README.md Added detailed documentation section explaining conflict options usage and behavior

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@phamhieu phamhieu requested a review from SoulPancake October 22, 2025 13:08
expect.objectContaining({
writes: {
tuple_keys: [tuple],
on_duplicate: undefined,
Copy link
Member

Choose a reason for hiding this comment

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

This might just be how the JS generator template works but in other languages the default value for each property is being sent ("error"), I'm not sure if we should make them aligned (which would require template updates) or just accept the language differences.

Copy link
Author

Choose a reason for hiding this comment

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

Good point! Just updated it to send "error" as the default for conflict options when they're not specified

@phamhieu phamhieu requested a review from ewanharris October 23, 2025 02:00
Copy link
Member

@SoulPancake SoulPancake left a comment

Choose a reason for hiding this comment

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

LG, Thanks a lot @phamhieu

Copy link
Member

@SoulPancake SoulPancake left a comment

Choose a reason for hiding this comment

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

@phamhieu Would it be possible for you to take a look at the lockfile changes once? I think it might be related to the latest merge

https://github.com/openfga/js-sdk/actions/runs/18768778003/job/53559732838#step:4:9

The CI check is currently failing because of this

@phamhieu phamhieu force-pushed the feat/add-write-conflict-options branch from 2fa3e77 to bb062f5 Compare October 27, 2025 01:59
@phamhieu
Copy link
Author

@phamhieu Would it be possible for you to take a look at the lockfile changes once? I think it might be related to the latest merge

https://github.com/openfga/js-sdk/actions/runs/18768778003/job/53559732838#step:4:9

The CI check is currently failing because of this

Fixed! I've resolved the conflicts.

@phamhieu phamhieu requested a review from SoulPancake October 27, 2025 02:02
SoulPancake
SoulPancake previously approved these changes Oct 27, 2025
Copy link
Member

@SoulPancake SoulPancake left a comment

Choose a reason for hiding this comment

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

LGTM, Thanks a lot @phamhieu

Copy link

@daniel-jonathan daniel-jonathan left a comment

Choose a reason for hiding this comment

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

Thank you for the submission—this is a solid PR overall.

I left a few focused comments to avoid overwhelming the review. There are still areas to address, notably:

  • Complete test coverage of write/delete conflict combinations and defaults.

  • Error-path tests (4xx/5xx mapping), timeouts/abort, and transaction options (chunking/concurrency).

  • Naming/typing consistency (singular option names, remove “Enum” suffix, prefer final types).

Happy to re-review once these are incorporated.

apiModel.ts Outdated
* @export
* @enum {string}
*/
export enum WriteRequestDeletesOnMissingEnum {

Choose a reason for hiding this comment

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

  • Drop the “Enum” suffix from names.

  • Optional: Prefer const object + string-literal unions for better tree-shaking and DX.

export const WriteRequestDeletesOnMissing = {
  Error: "error",
  Ignore: "ignore",
} as const;
export type WriteRequestDeletesOnMissing =
  typeof WriteRequestDeletesOnMissing[keyof typeof WriteRequestDeletesOnMissing];

export const WriteRequestWritesOnDuplicate = {
  Error: "error",
  Ignore: "ignore",
} as const;
export type WriteRequestWritesOnDuplicate =
  typeof WriteRequestWritesOnDuplicate[keyof typeof WriteRequestWritesOnDuplicate];

client.ts Outdated
result: ClientBatchCheckSingleResponse[];
}

export const OnDuplicateWrites = WriteRequestWritesOnDuplicateEnum;

Choose a reason for hiding this comment

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

  • Prefer singular option names for per-item behavior. For deletes, OnMissingDeletes reads better as OnMissingDelete. Likewise for writes, OnDuplicateWrites should be OnDuplicateWrite.

  • If you drop the enums, you don’t need extra const + typeof wrappers inside ClientWriteConflictOptions. Reuse the original const objects and their string-literal union type aliases directly to avoid duplication and keep types single-sourced.

  • Aim for consistent naming across options: onMissingDelete and onDuplicateWrite. This keeps the API readable, predictable, and aligned with common TS conventions.

);

mockWrite.mockRestore();
});

Choose a reason for hiding this comment

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

  • Add explicit tests for the Error mode. Current tests cover Ignore and implicitly assume Error via defaults; verify Error behavior directly instead of relying on defaults.

onDuplicateWrites: OnDuplicateWrites.Ignore,
onMissingDeletes: OnMissingDeletes.Error,
}
});

Choose a reason for hiding this comment

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

  • Add matrix tests to exercise both knobs together:

writes only: onDuplicateWrite = Error | Ignore
deletes only: onMissingDelete = Error | Ignore

mixed writes + deletes:
(Ignore, Ignore)
(Ignore, Error)
(Error, Ignore)
(Error, Error)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Add SDK support for ignoring errors on duplicate writes or missing deletes

6 participants