Skip to content

Conversation

@rhamzeh
Copy link
Member

@rhamzeh rhamzeh commented Oct 31, 2025

Description

Add support for configuring the write conflict options

What problem is being solved?

How is it being solved?

What changes are made to solve it?

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

Release Notes

  • New Features

    • Added --on-duplicate flag for tuple write operations to control duplicate handling (ignore or error).
    • Added --on-missing flag for tuple delete operations to control missing tuple handling (ignore or error).
    • Defaults: ignore when importing/deleting files; error for single tuple operations.
  • Bug Fixes

    • Fixed relative path resolution in model tests.
  • Documentation

    • Updated README with new flags and examples.

Copilot AI review requested due to automatic review settings October 31, 2025 22:06
@rhamzeh rhamzeh requested review from a team as code owners October 31, 2025 22:06
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 31, 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

This PR introduces configurable conflict-handling options for tuple write and delete operations via new CLI flags (--on-duplicate, --on-missing), adds corresponding enum-like types to bridge CLI and SDK layers, performs widespread type migrations from interface{} to Go's any alias, and includes minor optimizations and bug fixes.

Changes

Cohort / File(s) Summary
Documentation
CHANGELOG.md, README.md
Added documentation for new --on-duplicate and --on-missing CLI flags with context-dependent defaults and behavior descriptions
Conflict Options Infrastructure
internal/tuple/conflictoptions.go
New file introducing ClientWriteRequestOnDuplicateWrites and ClientWriteRequestOnMissingDeletes wrapper types with String(), ToSdkEnum(), Set(), and Type() methods for parsing, validating, and converting between CLI and SDK representations
Query Command Type Migrations
cmd/query/check.go, cmd/query/list-objects.go, cmd/query/list-relations.go, cmd/query/list-users.go
Updated queryContext parameter type from *map[string]interface{} to *map[string]any across all query subcommands
Write Command Enhancements
cmd/tuple/write.go
Added --on-duplicate flag with per-context defaults (IGNORE for file imports, ERROR for single writes); introduced options object construction and propagation to SDK calls; optimized max-parallel calculation
Delete Command Enhancements
cmd/tuple/delete.go
Added --on-missing flag with per-context defaults (IGNORE for file deletes, ERROR for single deletes); wired options object to import/delete calls
Store Import Refactoring
cmd/store/import.go
Updated batch end-index calculation; added options object with OnDuplicateWrites set to IGNORE; modified ImportTuplesWithoutRampUp call signature to pass options parameter
Import/Tuple Logic
internal/tuple/import.go
Added opts client.ClientWriteOptions parameter to ImportTuplesWithoutRampUp and ImportTuples; updated conflict configuration to use opts.Conflict instead of hardcoded values
Type Migrations (Context Fields)
cmd/tuple/write_test.go, cmd/tuple/read_test.go, internal/storetest/storedata.go, internal/tuplefile/csv.go
Updated RelationshipCondition.Context and model test Context fields from *map[string]interface{} to *map[string]any; updated test data accordingly
Utility Improvements
internal/cmdutils/get-query-context.go, internal/slices/contains.go, internal/storetest/testresult.go
Updated ParseQueryContext to return *map[string]any; refactored Contains to use stdlib slices.Contains; optimized test result building with strings.Builder instead of string concatenation

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI as CLI Layer
    participant Parser as Options Parser
    participant SDK as SDK Client
    
    User->>CLI: fga tuple write --on-duplicate ignore
    CLI->>Parser: Parse --on-duplicate flag
    Parser->>Parser: Validate "ignore" value
    Parser->>SDK: Create ClientWriteOptions<br/>with Conflict.OnDuplicateWrites=IGNORE
    SDK->>SDK: Process write request<br/>with conflict options
    SDK-->>CLI: Response
    CLI-->>User: Success
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

  • internal/tuple/conflictoptions.go: New public types and conversion methods require careful review for correctness and error handling patterns
  • internal/tuple/import.go: Function signature changes with new opts parameter flow through multiple call sites; verify all call sites pass correct options
  • cmd/tuple/write.go, cmd/tuple/delete.go: New flag parsing and per-context default logic; verify defaults are correctly applied and flags properly wired
  • Widespread type migrations: Although mostly mechanical (interface{} → any), verify no semantic differences in type handling across query commands and test data
  • cmd/store/import.go: Batch index calculation and options propagation logic

Possibly related PRs

Suggested labels

codex

Suggested reviewers

  • jimmyjames
  • Siddhant-K-code

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "feat: add support for configurable write conflict options" clearly and specifically describes the primary objective of the pull request. The raw summary confirms that the main changes introduce new CLI flags (--on-duplicate and --on-missing) for managing write and delete conflict scenarios, with configurable behavior (error or ignore) and context-specific defaults. The title is concise, unambiguous, and accurately captures the core feature being added without unnecessary noise or vague language. A teammate reviewing the git history would immediately understand that this PR implements configurable conflict handling options for write operations.

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.

Copy link

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 configurable write conflict options for tuple operations, allowing users to control behavior when writing duplicate tuples or deleting missing tuples.

Key changes:

  • Adds --on-duplicate flag to tuple write command with ignore or error options
  • Adds --on-missing flag to tuple delete command with ignore or error options
  • Replaces interface{} with any throughout the codebase for better readability

Reviewed Changes

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

Show a summary per file
File Description
internal/tuple/conflictoptions.go New file defining custom types for conflict handling options with validation
cmd/tuple/write.go Adds --on-duplicate flag and passes conflict options through import functions
cmd/tuple/delete.go Adds --on-missing flag and passes conflict options through import functions
internal/tuple/import.go Updates import functions to accept and use ClientWriteOptions parameter
cmd/store/import.go Updates import call to pass default conflict options
internal/storetest/testresult.go Refactors string concatenation to use strings.Builder for performance
internal/slices/contains.go Refactors to use standard library slices.Contains
internal/tuplefile/csv.go Changes map[string]interface{} to map[string]any
internal/storetest/storedata.go Changes map[string]interface{} to map[string]any
internal/cmdutils/get-query-context.go Changes map[string]interface{} to map[string]any
cmd/query/*.go Updates function signatures to use map[string]any
cmd/tuple/*_test.go Updates test fixtures to use map[string]any
README.md Documents the new flags and parameters
CHANGELOG.md Documents the added features

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@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: 3

🧹 Nitpick comments (1)
internal/slices/contains.go (1)

22-23: Update the comment to reflect standard library usage.

The comment references golang.org/x/exp/slices, but the implementation now uses the standard library slices package (available since Go 1.21). Consider updating the comment to reflect this change or removing it entirely since the function now directly delegates to a standard library implementation.

Apply this diff to update the comment:

 // Contains returns whether a string is in a list of strings
-// Similar to slices.Contains from golang.org/x/exp/slices
-// https://cs.opensource.google/go/x/exp/+/515e97eb:slices/slices.go;l=116
 func Contains(itemArray []string, lookingFor string) bool {
 	return slices.Contains(itemArray, lookingFor)
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9eeb829 and b645432.

📒 Files selected for processing (18)
  • CHANGELOG.md (1 hunks)
  • README.md (3 hunks)
  • cmd/query/check.go (1 hunks)
  • cmd/query/list-objects.go (1 hunks)
  • cmd/query/list-relations.go (1 hunks)
  • cmd/query/list-users.go (1 hunks)
  • cmd/store/import.go (1 hunks)
  • cmd/tuple/delete.go (4 hunks)
  • cmd/tuple/read_test.go (1 hunks)
  • cmd/tuple/write.go (6 hunks)
  • cmd/tuple/write_test.go (7 hunks)
  • internal/cmdutils/get-query-context.go (2 hunks)
  • internal/slices/contains.go (1 hunks)
  • internal/storetest/storedata.go (1 hunks)
  • internal/storetest/testresult.go (6 hunks)
  • internal/tuple/conflictoptions.go (1 hunks)
  • internal/tuple/import.go (3 hunks)
  • internal/tuplefile/csv.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
internal/tuple/conflictoptions.go (1)
internal/clierrors/clierrors.go (1)
  • ErrInvalidFormat (27-27)
cmd/store/import.go (2)
internal/tuple/conflictoptions.go (1)
  • CLIENT_WRITE_REQUEST_ON_DUPLICATE_WRITES_IGNORE (15-15)
internal/tuple/import.go (1)
  • ImportTuplesWithoutRampUp (85-90)
cmd/tuple/write.go (2)
internal/tuple/conflictoptions.go (3)
  • CLIENT_WRITE_REQUEST_ON_DUPLICATE_WRITES_ERROR (14-14)
  • CLIENT_WRITE_REQUEST_ON_DUPLICATE_WRITES_IGNORE (15-15)
  • ClientWriteRequestOnDuplicateWrites (11-11)
internal/tuple/import.go (3)
  • RPSToParallelRequestsDivisor (34-34)
  • ImportTuples (97-134)
  • DefaultMinRPS (28-28)
cmd/tuple/delete.go (2)
internal/tuple/conflictoptions.go (3)
  • CLIENT_WRITE_REQUEST_ON_MISSING_DELETES_IGNORE (50-50)
  • CLIENT_WRITE_REQUEST_ON_MISSING_DELETES_ERROR (49-49)
  • ClientWriteRequestOnMissingDeletes (46-46)
internal/tuple/import.go (3)
  • ImportTuplesWithoutRampUp (85-90)
  • MaxTuplesPerWrite (22-22)
  • MaxParallelRequests (25-25)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: CodeQL analysis (go)
  • GitHub Check: Test Release Process
  • GitHub Check: Tests
  • GitHub Check: Analyze (go)
🔇 Additional comments (14)
internal/slices/contains.go (1)

24-25: LGTM! Good refactor to use standard library.

Replacing the custom loop implementation with slices.Contains from the standard library improves maintainability and leverages well-tested code.

internal/tuplefile/csv.go (1)

67-67: LGTM! Type alias migration aligns with modern Go conventions.

The change from map[string]interface{} to map[string]any is functionally equivalent and aligns with Go 1.18+ conventions. This improves readability without affecting behavior.

internal/cmdutils/get-query-context.go (2)

26-38: LGTM! Type alias migration improves readability.

The migration from map[string]interface{} to map[string]any in both the return type and map initialization is functionally equivalent and improves code readability. This aligns with the broader codebase migration to use the any alias.


41-44: LGTM! Consistent type alias usage.

The return type update maintains consistency with the inner function changes.

cmd/query/list-users.go (1)

69-77: LGTM! Type alias migration maintains consistency.

The parameter type change from *map[string]interface{} to *map[string]any is functionally equivalent and consistent with similar updates across other query command files.

CHANGELOG.md (1)

10-14: LGTM! Clear documentation of new features.

The CHANGELOG entry clearly documents the new configurable write conflict options with:

  • The new flags (--on-duplicate and --on-missing)
  • Available choices (error or ignore)
  • Default behaviors (ignore for file imports/deletes, error for single tuple operations)

This provides users with the necessary information to understand and use the new features.

internal/storetest/testresult.go (3)

126-155: LGTM! Excellent performance optimization using strings.Builder.

Replacing repeated string concatenation with strings.Builder significantly reduces memory allocations and improves performance, especially when processing many test results. The refactor maintains identical output while being more efficient.


165-194: LGTM! Consistent application of strings.Builder pattern.

The same efficient pattern is applied to list objects results, maintaining consistency with the check results refactor.


204-236: LGTM! Complete strings.Builder migration.

The list users results follow the same efficient pattern, completing the performance optimization across all three result types.

cmd/query/check.go (1)

38-46: LGTM! Type alias migration aligns with broader refactor.

The parameter type change from *map[string]interface{} to *map[string]any is part of the consistent type alias migration across all query-related functions. The change is functionally equivalent and improves code readability.

internal/storetest/storedata.go (3)

44-51: LGTM! Context field type updated to use modern alias.

The migration of the Context field from *map[string]interface{} to *map[string]any aligns with the broader type alias migration across test data structures. The struct tag formatting adjustments maintain consistency.


53-58: LGTM! Consistent Context field type migration.

The same type alias update applied to ModelTestListObjects.Context maintains consistency across test structures.


60-65: LGTM! Complete Context field migration.

The ModelTestListUsers.Context field completes the consistent type alias migration across all test data structures.

cmd/tuple/write.go (1)

186-186: Go version 1.24.0 supports the max builtin—no changes required.

The module declares Go 1.24.0 in go.mod, which is well above the Go 1.21 threshold where max became a predeclared identifier. The code at line 186 will compile without issues.

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

@rhamzeh rhamzeh added this pull request to the merge queue Nov 4, 2025
Merged via the queue into main with commit 57deac8 Nov 4, 2025
22 checks passed
@rhamzeh rhamzeh deleted the feat/write-options branch November 4, 2025 15:38
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.

3 participants