Skip to content

Conversation

@GAlexIHU
Copy link
Contributor

@GAlexIHU GAlexIHU commented Oct 1, 2025

Overview

As of #3434 we've been storing the metadata input of the V1 API incorrectly as annotations.

-- RUN AT YOUR OWN RISK
-- copies incorrectly stored records from annotations to metadata

BEGIN;

CREATE OR REPLACE FUNCTION pg_temp.jsonb_convert_values_to_strings(input_jsonb jsonb)
RETURNS jsonb
LANGUAGE plpgsql
IMMUTABLE STRICT
AS $$
DECLARE
    key_value_pair RECORD;
    result_jsonb jsonb := '{}'::jsonb;
    string_value text;
BEGIN
    IF jsonb_typeof(input_jsonb) != 'object' THEN
        RETURN input_jsonb;
    END IF;

    FOR key_value_pair IN SELECT * FROM jsonb_each(input_jsonb)
    LOOP
        -- JSON only has 4 primitive types: string, number, boolean, null
        CASE jsonb_typeof(key_value_pair.value)
            WHEN 'string' THEN
                string_value := key_value_pair.value #>> '{}';

            WHEN 'number' THEN
                string_value := key_value_pair.value #>> '{}';

            WHEN 'boolean' THEN
                string_value := CASE
                    WHEN (key_value_pair.value)::boolean THEN 'true'
                    ELSE 'false'
                END;

            WHEN 'null' THEN
                string_value := '';

            -- array and object
            ELSE
                string_value := key_value_pair.value #>> '{}';
        END CASE;

        result_jsonb := jsonb_set(result_jsonb, ARRAY[key_value_pair.key], to_jsonb(string_value));
    END LOOP;

    RETURN result_jsonb;
END;
$$;

SAVEPOINT functions;

UPDATE grants
    -- this conversion is for parsing safety, due to API typings
    SET metadata = pg_temp.jsonb_convert_values_to_strings(annotations)
WHERE 
    -- First, let's make sure there's nothing important we could be overwriting
    (jsonb_typeof(metadata) = 'null' OR metadata IS NULL)
AND jsonb_typeof(annotations) != 'null' -- we have something to write
AND 
    -- filter for safety, THE DATES ARE EXAMPLES
    (namespace = 'replace_me' 
    AND created_at > '2025-09-28 18:10:26.291821+00'::TIMESTAMP 
    AND created_At < '2025-09-29 18:10:26.291821+00'::TIMESTAMP);

Summary by CodeRabbit

  • Bug Fixes

    • Ensures grant metadata is preserved and applied consistently when creating metered entitlements, preventing unexpected key drops or transformations.
  • Refactor

    • Simplified metadata handling by passing metadata directly, removing internal conversion logic to reduce complexity and potential mismatches.

@GAlexIHU GAlexIHU requested a review from a team as a code owner October 1, 2025 10:19
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 1, 2025

📝 Walkthrough

Walkthrough

The CreateGrant path in metered.go now assigns apiGrant.Metadata directly to GrantInput.Metadata. Helper functions converting between annotations and metadata were removed, eliminating the conversion layer.

Changes

Cohort / File(s) Summary of changes
Grant metadata handling
openmeter/entitlement/driver/metered.go
- In CreateGrant, assign apiGrant.Metadata directly to req.GrantInput.Metadata
- Remove MetadataFromAnnotations and AnnotationsFromMetadata helpers
- Shift from annotations-conversion to direct metadata pass-through

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

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 (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title “fix: store metadata in metadata” directly references the core change of correcting where API metadata is stored and aligns with the PR’s main intent to stop writing metadata into annotations. It is concise, focused on the primary fix, and does not include extraneous details such as file lists or vague terms. While it could clarify the target column more explicitly, it nonetheless conveys the essential purpose of the changeset.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/grant-create/annotations

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.

@GAlexIHU GAlexIHU added the release-note/bug-fix Release note: Bug Fixes label Oct 1, 2025
@GAlexIHU GAlexIHU enabled auto-merge (squash) October 1, 2025 10:33
@GAlexIHU GAlexIHU disabled auto-merge October 1, 2025 10:33
@GAlexIHU GAlexIHU merged commit dbc4758 into main Oct 1, 2025
32 of 33 checks passed
@GAlexIHU GAlexIHU deleted the fix/grant-create/annotations branch October 1, 2025 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note/bug-fix Release note: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants