Skip to content

Not properly mapping "read only" attribute to computed #235

@kenny-statsig

Description

@kenny-statsig

tfplugingen-openapi CLI version

v0.3.0

OpenAPI Spec File

Paths

"/console/v1/experiments/entity_property/{name}": {
  "get": {
    "summary": "Get Entity Property Source",
    "parameters": [
      {
        "name": "name",
        "required": true,
        "in": "path",
        "description": "Name of entity property source",
        "schema": {
          "type": "string"
        }
      },
      {
        "name": "x-respect-review-settings",
        "in": "header",
        "description": "Optional header to respect review settings for mutation endpoints.",
        "required": false,
        "schema": {
          "type": "string"
        }
      }
    ],
    "responses": {
      "200": {
        "description": "Get Entity Property Source response",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/EntityPropertySourceDto"
                }
              },
              "example": {
                "message": "Entity Property Source read successfully.",
                "data": {
                  "name": "Location",
                  "description": "This is the the location description",
                  "tags": [
                    
                  ],
                  "sql": "SELECT * FROM shoppy-sales.setup.user_properties",
                  "timestampColumn": "timestamp",
                  "idTypeMapping": [
                    {
                      "statsigUnitID": "stableID",
                      "column": "user_id"
                    }
                  ],
                  "timestampAsDay": true
                }
              }
            },
            "example": {
              "message": "Entity Property Source read successfully.",
              "data": {
                "name": "Location",
                "description": "This is the the location description",
                "tags": [
                  
                ],
                "sql": "SELECT * FROM shoppy-sales.setup.user_properties",
                "timestampColumn": "timestamp",
                "idTypeMapping": [
                  {
                    "statsigUnitID": "stableID",
                    "column": "user_id"
                  }
                ],
                "timestampAsDay": true
              }
            }
          }
        }
      },
      "400": {
        "description": "Invalid request. Please check the request input and try again.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    400
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Invalid Request": {
                "value": {
                  "status": 400,
                  "message": "Invalid request. Please check the request input and try again."
                }
              }
            }
          }
        }
      },
      "401": {
        "description": "This endpoint only accepts an active CONSOLE key, but an invalid key was sent. Key: console-xxxXXXxxxXXXxxx",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    401
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Invalid Endpoint": {
                "value": {
                  "status": 401,
                  "message": "This endpoint only accepts an active CONSOLE key, but an invalid key was sent. Key: console-xxxXXXxxxXXXxxx"
                }
              }
            }
          }
        }
      }
    },
    "tags": [
      "Experiments (Warehouse Native)"
    ],
    "security": [
      {
        "STATSIG-API-KEY": [
          
        ]
      }
    ]
  },
  "post": {
    "summary": "Post Entity Property Source",
    "parameters": [
      {
        "name": "name",
        "required": true,
        "in": "path",
        "description": "name",
        "schema": {
          "type": "string"
        }
      },
      {
        "name": "x-respect-review-settings",
        "in": "header",
        "description": "Optional header to respect review settings for mutation endpoints.",
        "required": false,
        "schema": {
          "type": "string"
        }
      }
    ],
    "requestBody": {
      "required": true,
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EntityPropertySourceQueryUpdateDto"
          }
        }
      }
    },
    "responses": {
      "200": {
        "description": "Post Entity Property Source response",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/EntityPropertySourceDto"
                }
              },
              "example": {
                "message": "Entity Property Sources updated successfully.",
                "data": {
                  "name": "Location",
                  "description": "This is the the location description",
                  "tags": [
                    
                  ],
                  "sql": "SELECT * FROM  shoppy-sales.setup.user_properties",
                  "timestampColumn": "",
                  "idTypeMapping": [
                    {
                      "statsigUnitID": "stableID",
                      "column": "user_id"
                    }
                  ],
                  "timestampAsDay": true
                }
              }
            },
            "example": {
              "message": "Entity Property Sources updated successfully.",
              "data": {
                "name": "Location",
                "description": "This is the the location description",
                "tags": [
                  
                ],
                "sql": "SELECT * FROM  shoppy-sales.setup.user_properties",
                "timestampColumn": "",
                "idTypeMapping": [
                  {
                    "statsigUnitID": "stableID",
                    "column": "user_id"
                  }
                ],
                "timestampAsDay": true
              }
            }
          }
        }
      },
      "400": {
        "description": "Invalid request. Please check the request input and try again.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    400
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Invalid Request": {
                "value": {
                  "status": 400,
                  "message": "Invalid request. Please check the request input and try again."
                }
              }
            }
          }
        }
      },
      "401": {
        "description": "This endpoint only accepts an active CONSOLE key, but an invalid key was sent. Key: console-xxxXXXxxxXXXxxx",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    401
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Invalid Endpoint": {
                "value": {
                  "status": 401,
                  "message": "This endpoint only accepts an active CONSOLE key, but an invalid key was sent. Key: console-xxxXXXxxxXXXxxx"
                }
              }
            }
          }
        }
      },
      "404": {
        "description": "Not Found. The requested resource could not be found.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    404
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Not Found": {
                "value": {
                  "status": 404,
                  "message": "Not Found. The requested resource could not be found."
                }
              }
            }
          }
        }
      }
    },
    "tags": [
      "Experiments (Warehouse Native)"
    ],
    "security": [
      {
        "STATSIG-API-KEY": [
          
        ]
      }
    ]
  },
  "patch": {
    "summary": "Patch Entity Property Source",
    "parameters": [
      {
        "name": "name",
        "required": true,
        "in": "path",
        "description": "Name of entity property source",
        "schema": {
          "type": "string"
        }
      },
      {
        "name": "x-respect-review-settings",
        "in": "header",
        "description": "Optional header to respect review settings for mutation endpoints.",
        "required": false,
        "schema": {
          "type": "string"
        }
      }
    ],
    "requestBody": {
      "required": true,
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/EntityPropertySourcePartialUpdateDto"
          }
        }
      }
    },
    "responses": {
      "200": {
        "description": "Patch Entity Property Source response",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/EntityPropertySourceDto"
                }
              },
              "example": {
                "message": "Entity Property Source updated successfully",
                "data": {
                  "name": "Location",
                  "description": "This is the the location description",
                  "tags": [
                    
                  ],
                  "sql": "SELECT * FROM shoppy-sales.setup.user_properties",
                  "timestampColumn": "timestamp",
                  "idTypeMapping": [
                    {
                      "statsigUnitID": "stableID",
                      "column": "user_id"
                    }
                  ],
                  "timestampAsDay": true
                }
              }
            },
            "example": {
              "message": "Entity Property Source updated successfully",
              "data": {
                "name": "Location",
                "description": "This is the the location description",
                "tags": [
                  
                ],
                "sql": "SELECT * FROM shoppy-sales.setup.user_properties",
                "timestampColumn": "timestamp",
                "idTypeMapping": [
                  {
                    "statsigUnitID": "stableID",
                    "column": "user_id"
                  }
                ],
                "timestampAsDay": true
              }
            }
          }
        }
      },
      "400": {
        "description": "Invalid request. Please check the request input and try again.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    400
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Invalid Request": {
                "value": {
                  "status": 400,
                  "message": "Invalid request. Please check the request input and try again."
                }
              }
            }
          }
        }
      },
      "401": {
        "description": "This endpoint only accepts an active CONSOLE key, but an invalid key was sent. Key: console-xxxXXXxxxXXXxxx",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    401
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Invalid Endpoint": {
                "value": {
                  "status": 401,
                  "message": "This endpoint only accepts an active CONSOLE key, but an invalid key was sent. Key: console-xxxXXXxxxXXXxxx"
                }
              }
            }
          }
        }
      },
      "404": {
        "description": "Not Found. The requested resource could not be found.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    404
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Not Found": {
                "value": {
                  "status": 404,
                  "message": "Not Found. The requested resource could not be found."
                }
              }
            }
          }
        }
      }
    },
    "tags": [
      "Experiments (Warehouse Native)"
    ],
    "security": [
      {
        "STATSIG-API-KEY": [
          
        ]
      }
    ]
  },
  "delete": {
    "summary": "Delete Entity Property Source",
    "parameters": [
      {
        "name": "name",
        "required": true,
        "in": "path",
        "description": "name",
        "schema": {
          "type": "string"
        }
      },
      {
        "name": "x-respect-review-settings",
        "in": "header",
        "description": "Optional header to respect review settings for mutation endpoints.",
        "required": false,
        "schema": {
          "type": "string"
        }
      }
    ],
    "responses": {
      "200": {
        "description": "Delete Entity Property Source response",
        "content": {
          "application/json": {
            "schema": {
              "properties": {
                "message": {
                  "type": "string"
                }
              },
              "example": {
                "message": "Entity property source deleted successfully."
              }
            },
            "example": {
              "message": "Entity property source deleted successfully."
            }
          }
        }
      },
      "400": {
        "description": "Invalid request. Please check the request input and try again.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    400
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Invalid Request": {
                "value": {
                  "status": 400,
                  "message": "Invalid request. Please check the request input and try again."
                }
              }
            }
          }
        }
      },
      "401": {
        "description": "This endpoint only accepts an active CONSOLE key, but an invalid key was sent. Key: console-xxxXXXxxxXXXxxx",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    401
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Invalid Endpoint": {
                "value": {
                  "status": 401,
                  "message": "This endpoint only accepts an active CONSOLE key, but an invalid key was sent. Key: console-xxxXXXxxxXXXxxx"
                }
              }
            }
          }
        }
      },
      "404": {
        "description": "Not Found. The requested resource could not be found.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "enum": [
                    404
                  ]
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "status",
                "message"
              ]
            },
            "examples": {
              "Not Found": {
                "value": {
                  "status": 404,
                  "message": "Not Found. The requested resource could not be found."
                }
              }
            }
          }
        }
      }
    },
    "tags": [
      "Experiments (Warehouse Native)"
    ],
    "security": [
      {
        "STATSIG-API-KEY": [
          
        ]
      }
    ]
  }
}


Component schemas

"EntityPropertySourceDto": {
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Unique identifier for the entity property source."
    },
    "description": {
      "type": "string",
      "description": "Detailed context and purpose of the entity property source."
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Tags for categorization and search."
    },
    "sql": {
      "type": "string",
      "description": "SQL query defining the data source."
    },
    "timestampColumn": {
      "type": "string",
      "description": "Optional column name for timestamp."
    },
    "timestampAsDay": {
      "type": "boolean",
      "description": "Indicates if the timestamp is treated as a day."
    },
    "idTypeMapping": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "statsigUnitID": {
            "type": "string",
            "description": "ID for the Statsig unit."
          },
          "column": {
            "type": "string",
            "description": "Column name linked to the ID."
          }
        },
        "required": [
          "statsigUnitID",
          "column"
        ]
      },
      "description": "Mappings of Statsig units to their columns."
    },
    "isReadOnly": {
      "type": "boolean",
      "description": "Specifies if the source can only be edited via the Console API."
    },
    "owner": {
      "type": "object",
      "properties": {
        "ownerID": {
          "type": "string",
          "description": "ID of the owner",
          "example": "abc123"
        },
        "ownerType": {
          "type": "string",
          "description": "Type of the owner (e.g., SDK_KEY or USER)",
          "example": "USER"
        },
        "ownerName": {
          "type": "string",
          "description": "The name of the owner. This field is optional.",
          "example": "John Doe"
        },
        "ownerEmail": {
          "type": "string",
          "description": "The email of the owner. This field is optional."
        }
      },
      "description": "Schema for owner data including ID, type, name. Note that if Entity is created by CONSOLE API, owner will be undefined.",
      "example": {
        "ownerID": "user123",
        "ownerType": "USER",
        "ownerName": "John Doe",
        "ownerEmail": "[email protected]"
      },
      "nullable": true,
      "readonly": true
    }
  },
  "required": [
    "name",
    "description",
    "tags",
    "sql",
    "idTypeMapping"
  ]
},
"EntityPropertySourceCreationDto": {
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Unique identifier for the entity property source."
    },
    "description": {
      "type": "string",
      "description": "Optional detailed context for the entity property source."
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Optional tags for categorization."
    },
    "sql": {
      "type": "string",
      "description": "SQL query defining the data source."
    },
    "timestampColumn": {
      "type": "string",
      "description": "Optional column name for timestamp."
    },
    "timestampAsDay": {
      "type": "boolean",
      "description": "Indicates if the timestamp is treated as a day."
    },
    "idTypeMapping": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "statsigUnitID": {
            "type": "string",
            "description": "ID for the Statsig unit."
          },
          "column": {
            "type": "string",
            "description": "Column name linked to the ID."
          }
        },
        "required": [
          "statsigUnitID",
          "column"
        ]
      },
      "description": "Mappings of Statsig units to their columns."
    },
    "isReadOnly": {
      "type": "boolean",
      "description": "Specifies if the source can only be edited via the Console API."
    }
  },
  "required": [
    "name",
    "sql",
    "idTypeMapping"
  ]
},
"EntityPropertySourcePartialUpdateDto": {
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Unique identifier for the entity property source."
    },
    "description": {
      "type": "string",
      "description": "Detailed context and purpose of the entity property source."
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Tags for categorization and search."
    },
    "sql": {
      "readOnly": true,
      "description": "SQL query defining the data source"
    },
    "timestampColumn": {
      "type": "string",
      "description": "Optional column name for timestamp."
    },
    "timestampAsDay": {
      "type": "boolean",
      "description": "Indicates if the timestamp is treated as a day."
    },
    "idTypeMapping": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "statsigUnitID": {
            "type": "string",
            "description": "ID for the Statsig unit."
          },
          "column": {
            "type": "string",
            "description": "Column name linked to the ID."
          }
        },
        "required": [
          "statsigUnitID",
          "column"
        ]
      },
      "description": "Mappings of Statsig units to their columns."
    },
    "isReadOnly": {
      "type": "boolean",
      "description": "Specifies if the source can only be edited via the Console API."
    }
  }
},
"EntityPropertySourceQueryUpdateDto": {
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Optional new name for the entity property source."
    },
    "description": {
      "type": "string",
      "description": "Optional updated context for the entity property source."
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Optional updated tags for categorization."
    },
    "sql": {
      "type": "string",
      "description": "SQL query defining the data source."
    },
    "timestampColumn": {
      "type": "string",
      "description": "Optional column name for timestamp."
    },
    "timestampAsDay": {
      "type": "boolean",
      "description": "Indicates if the timestamp is treated as a day."
    },
    "idTypeMapping": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "statsigUnitID": {
            "type": "string",
            "description": "ID for the Statsig unit."
          },
          "column": {
            "type": "string",
            "description": "Column name linked to the ID."
          }
        },
        "required": [
          "statsigUnitID",
          "column"
        ]
      },
      "description": "Mappings of Statsig units to their columns."
    },
    "isReadOnly": {
      "type": "boolean",
      "description": "Specifies if the source can only be edited via the Console API."
    }
  },
  "required": [
    "sql",
    "idTypeMapping"
  ]
}

Generator Config

entity_property:
    read:
      path: /console/v1/experiments/entity_property/{name}
      method: GET
    create:
      path: /console/v1/experiments/entity_properties
      method: POST
    update:
      path: /console/v1/experiments/entity_property/{name}
      method: POST
    delete:
      path: /console/v1/experiments/entity_property/{name}
      method: DELETE
    schema:
      ignores:
        - message
        - data

Expected Behavior

Expected the generated resource spec in provider_code_spec.json to include the read-only attribute owner with computed_optional_required equal to computed. According to the following from DESIGN.md

If the field is only present in a schema other than the create operation requestBody, then the field will be mapped as computed.

					{
						"name": "owner",
						"single_nested": {
							"computed_optional_required": "computed",
							"attributes": [
								{
									"name": "owner_email",
									"string": {
										"computed_optional_required": "computed_optional",
										"description": "The email of the owner. This field is optional."
									}
								},
								{
									"name": "owner_id",
									"string": {
										"computed_optional_required": "computed_optional",
										"description": "ID of the owner"
									}
								},
								{
									"name": "owner_name",
									"string": {
										"computed_optional_required": "computed_optional",
										"description": "The name of the owner. This field is optional."
									}
								},
								{
									"name": "owner_type",
									"string": {
										"computed_optional_required": "computed_optional",
										"description": "Type of the owner (e.g., SDK_KEY or USER)"
									}
								}
							],
							"description": "Schema for owner data including ID, type, name. Note that if Entity is created by CONSOLE API, owner will be undefined."
						}
					},

Actual Behavior

owner is missing in the resource spec

{
  "name": "entity_property",
  "schema": {
    "attributes": [
      {
        "name": "description",
        "string": {
          "computed_optional_required": "computed_optional",
          "description": "Optional detailed context for the entity property source."
        }
      },
      {
        "name": "id_type_mapping",
        "list_nested": {
          "computed_optional_required": "required",
          "nested_object": {
            "attributes": [
              {
                "name": "column",
                "string": {
                  "computed_optional_required": "required",
                  "description": "Column name linked to the ID."
                }
              },
              {
                "name": "statsig_unit_id",
                "string": {
                  "computed_optional_required": "required",
                  "description": "ID for the Statsig unit."
                }
              }
            ]
          },
          "description": "Mappings of Statsig units to their columns."
        }
      },
      {
        "name": "is_read_only",
        "bool": {
          "computed_optional_required": "computed_optional",
          "description": "Specifies if the source can only be edited via the Console API."
        }
      },
      {
        "name": "name",
        "string": {
          "computed_optional_required": "required",
          "description": "Unique identifier for the entity property source."
        }
      },
      {
        "name": "sql",
        "string": {
          "computed_optional_required": "required",
          "description": "SQL query defining the data source."
        }
      },
      {
        "name": "tags",
        "list": {
          "computed_optional_required": "computed_optional",
          "element_type": {
            "string": {
              
            }
          },
          "description": "Optional tags for categorization."
        }
      },
      {
        "name": "timestamp_as_day",
        "bool": {
          "computed_optional_required": "computed_optional",
          "description": "Indicates if the timestamp is treated as a day."
        }
      },
      {
        "name": "timestamp_column",
        "string": {
          "computed_optional_required": "computed_optional",
          "description": "Optional column name for timestamp."
        }
      }
    ]
  }
},

Additional Information

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions