# Apply a change

Apply a change to the system. This is one of the most important endpoints as it centralizes every change the user can apply to the system.

**Important**. The API specifies a set of *basic* changes applicable to all dialect analized. However, this list can be extended to support more changes and refactorings by means of [/extensions](/webside/api/extensions/changes.md) endpoint.

Special attention must be paid to the way the target system must handle compilation errors so Webside IDE can react properly (see [Errors](#errors) below).

**URL**: `/changes`

**Method**: `POST`

**Payload**: The payload will contain the change to be applied in JSON format. The table below lists all supported changes at this moment. Though types are self-descripted, a short description of what they do is included. All changes should include `author` proprerty and might specify a `package` property indicating the package in which the change should be applied (for example, the package that will contain a new class).

<table><thead><tr><th align="center">Type</th><th>Description</th><th>Payload</th></tr></thead><tbody><tr><td align="center">AddMethod</td><td>Compile a method in a given class.</td><td><pre><code>{
 "type": "AddMethod",
 "package": "string",
 "className": "string",
 "category": "string",
 "sourceCode": "string"
} 
</code></pre></td></tr><tr><td align="center">RemoveMethod</td><td>Remove a given method.</td><td><pre><code>{
 "type": "RemoveMethod",
 "className": "string",
 "selector": "string"
} 
</code></pre></td></tr><tr><td align="center">ClassifyMethod</td><td>Classify a given method under a given category.</td><td><pre><code>{
 "type": "ClassifyMethod",
 "className": "string",
 "selector": "string",
 "category": "string"
} 
</code></pre></td></tr><tr><td align="center">RenameMethod</td><td>Rename a given selector. The scope is the whole system.</td><td><pre><code>{
 "type": "RenameMethod",
 "className": "string",
 "selector": "string",
 "newSelector": "string"
} 
</code></pre></td></tr><tr><td align="center">AddClass</td><td>Define a new class or change the definition of an existing one.</td><td><pre><code>{
 "type": "AddClass",
 "className": "string",
 "package": "string",
 "definition": "string" ,
 "instanceVariables": ["string"],
 "classVariables": ["string"],
 "poolDictionaries": ["string"]
} 
</code></pre></td></tr><tr><td align="center">CommentClass</td><td>Change the comment of a given class.</td><td><pre><code>{
 "type": "CommentClass",
 "className": "string",
 "comment": "string"
} 
</code></pre></td></tr><tr><td align="center">RemoveClass</td><td>Remove a given class.</td><td><pre><code>{
 "type": "RemoveClass",
 "className": "string"
} 
</code></pre></td></tr><tr><td align="center">RenameClass</td><td>Rename a given class.</td><td><pre><code>{
 "type": "RenameClass",
 "className": "string",
 "newName": "string",
 "renameReferences": "boolean"
} 
</code></pre></td></tr><tr><td align="center">AddClassCategory</td><td>Add a new class category.</td><td><pre><code>{
 "type": "AddClassCategory",
 "package": "string",
 "category": "string"
} 
</code></pre></td></tr><tr><td align="center">RenameClassCategory</td><td>Rename a class category.</td><td><pre><code>{
 "type": "RenameClassCategory",
 "package": "string",
 "category": "string",
 "newName": "string"
} 
</code></pre></td></tr><tr><td align="center">RemoveClassCategory</td><td>Remove a class category.</td><td><pre><code>{
 "type": "RemoveClassCategory",
 "package": "string",
 "category": "string"
} 
</code></pre></td></tr><tr><td align="center">AddInstanceVariable</td><td>Add a new instance variable to a given class.</td><td><pre><code>{
 "type": "AddInstanceVariable",
 "package": "string",
 "variable": "string"
} 
</code></pre></td></tr><tr><td align="center">RemoveInstanceVariable</td><td>Remove an instance variable from a given class.</td><td><pre><code>{
 "type": "RemoveInstanceVariable",
 "className": "string",
 "variable": "string"
} 
</code></pre></td></tr><tr><td align="center">RenameInstanceVariable</td><td>Rename an instance variable of a given class.</td><td><pre><code>{
 "type": "RenameInstanceVariable",
 "className": "string",
 "variable": "string",
 "newName": "string"
} 
</code></pre></td></tr><tr><td align="center">MoveUpInstanceVariable</td><td>Move an instance variable from a given class to its superclass.</td><td><pre><code>{
 "type": "MoveUpInstanceVariable",
 "className": "string",
 "variable": "string"
} 
</code></pre></td></tr><tr><td align="center">MoveDownInstanceVariable</td><td>Move an instance variable from a given class to one of its subclasses.</td><td><pre><code>{
 "type": "MoveDownInstanceVariable",
 "className": "string",
 "variable": "string",
 "target": "string"
} 
</code></pre></td></tr><tr><td align="center">AddClassVariable</td><td>Add a new class variable to a given class.</td><td><pre><code>{
 "type": "AddClassVariable",
 "className": "string",
 "variable": "string"
} 
</code></pre></td></tr><tr><td align="center">RemoveClassVariable</td><td>Remove a class variable from a given class.</td><td><pre><code>{
 "type": "RemoveClassVariable",
 "className": "string",
 "variable": "string"
} 
</code></pre></td></tr><tr><td align="center">RenameClassVariable</td><td>Rename a class variable of a given class.</td><td><pre><code>{
 "type": "RenameClassVariable",
 "className": "string",
 "variable": "string",
 "newName": "string"
} 
</code></pre></td></tr><tr><td align="center">RenameCategory</td><td>Rename a category within a class.</td><td><pre><code>{
 "type": "RenameCategory",
 "className": "string",
 "category": "string",
 "newName": "string"
} 
</code></pre></td></tr><tr><td align="center">RemoveCategory</td><td>Remove a category from a class.</td><td><pre><code>{
 "type": "RemoveCategory",
 "className": "string",
 "category": "string"
} 
</code></pre></td></tr><tr><td align="center">AddPackage</td><td>Add a new package.</td><td><pre><code>{
 "type": "AddPackage",
 "name": "string"
} 
</code></pre></td></tr><tr><td align="center">RemovePackage</td><td>Remove a given package</td><td><pre><code>{
 "type": "RemovePackage",
 "name": "string"
} 
</code></pre></td></tr><tr><td align="center">RenamePackage</td><td>Rename a given package.</td><td><pre><code>{
 "type": "RenamePackage",
 "name": "string",
 "newName": "string"
} 
</code></pre></td></tr></tbody></table>

**Example:**: compile method `phi` in `Float` `POST /changes`

```json
{
  "type": "AddMethod",
  "className": "Float class",
  "category": "constants",
  "sourceCode": "phi\r\t^1.0 + 5.0 sqrt / 2.0",
  "author": "guille"
}
```

## Success Responses

**Code** : `200 OK`

**Content**: the `change` applied (see [get](/webside/api/changes/get.md) to see the structure of a change). The change is validated before being applied and updated with some information afterwards, thus, the change returned contains more information. For instance, one of the common properties added to the change is `timestamp`, corresponding to the moment at which the change is applied. There are some special cases like the `selector` property in a `AddMethod`. This property is not required as it is determined by the `sourceCode` property. However, this property is filled by the server and returned to the client.

## Errors

Whenever a change cannot be appplied, the backend should respond with an client error code (typically `409`), indicating what went wrong using the `description` property.\
Also, the backend might provide one or more *suggestions* on how to carry on the intended change. These should be variations of the original change, together with a description that could be used by the IDE to prompt the user what they want to do. This is the aspect of an error response data.

```json
{
  "description": "string",
  "suggestions": ["suggestion"]
}
```

Where, `suggestion` has the following shape:

```json
{
  "description": "string",
  "changes": ["change"]
}
```

and `changes` is the set of changes that will be applied to mitigate the reported error.

Note that this is a list as it would be necessary to apply several changes to accomplish what the client wanted to do (i.e., the original change). This is better understood by an example like the one below.

### Compilation Errors

As explained above, these should be reported with code `409`, a `description` and eventually a list of `suggestions`. In addition to that information, compilation errors should be reported with a more detail description, `fullDescription`, and the `interval` in the source code where the error was detected. This would be the structure of such a response:

```json
{
  "description": "string",
  "fullDescription": "string",
  "interval": {
    "start": "number",
    "end": "number"
  },
  "suggestions": ["suggestion"]
}
```

For example, after sending a `AddMethod` change on `Number` class with the source code `^1 +` , the the following error is returned:

```json
409
{
	"description": "primary missing",
	"fullDescription": "primary missing",
	"interval": {
		"start": 7,
		"end": 7
	}
}
```

Note that the interval corresponds the the missing part and there are no suggestions.

Here is another example with suggestions: Lets suppose we try to compile a method with a single line `t := 1` on a class where `t` is not in the scope. The error returned should look like this:

```json
409
{
	"description": "undeclared t",
	"fullDescription": "undeclared identifier t at line 2 position 2",
	"interval": {
		"start": 4,
		"end": 4
	},
	"suggestions": [
		{
			"description": "Declare 't' as a temporary",
			"changes": [
				{
					"type": "AddMethod",
					"author": "guille",
					"sourceCode": "m\r\t | t | \r\tt := 1",
					"className": "Number",
					"selector": "m",
					"category": "arithmetic"
				}
			]
		}
	]
}
```

Note that `changes` contains a list with another `AddMethod` with a modified source, which corresponds to accepting the suggestion.

Note also that the original source could contain more than one error. These should be presented one at a time, offering suggestions for each error, applying the changes if the user chooses one, and repeating cycle for every error found in the process.\
For instance, if the code sent in an `AddMethod` change is the following `m t1 := 1. t2 := 2`, and neither `t1` and `t2` are defined, a first response will be like before:

```json
409
{
    "description": "undeclared t1",
    "fullDescription": "undeclared identifier t1 at line 2 position 3",
    "interval": {
        "start": 5,
        "end": 6
    },
    "suggestions": [
        {
            "description": "Declare 't1' as a temporary",
            "changes": [
                {
                    "type": "AddMethod",
                    "author": "guille",
                    "sourceCode": "m\r   | t1 | \r\tt1 := 1.\r  t2 := 2.",
                    "className": "Number",
                    "category": "arithmetic"
                }
            ]
        }
    ]
}
```

And once the user choses the suggestion, a new error is generated indicating `t2` is not defined, but this time based on the code of the previously accepted suggestion.

```json
409
{
    "description": "undeclared t2",
    "fullDescription": "undeclared identifier t2 at line 4 position 3",
    "interval": {
        "start": 26,
        "end": 27
    },
    "suggestions": [
        {
            "description": "Declare 't2' as a temporary",
            "changes": [
                {
                    "type": "AddMethod",
                    "author": "guille",
                    "sourceCode": "m\r   | t1 t2 | \r\tt1 := 1.\r  t2 := 2.",
                    "className": "Number",
                    "category": "arithmetic"
                }
            ]
        }
    ]
}
```

### Confirmation

Notice that this mechanism can be used to confirm a change on the server side: by just providing a suggestion with the original change (plus a flag with the confirmation) and a description like `Are you sure?`.

This differs from any confirmation on the client side as the backend might have (and surely has) a richer context.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://webside.gitbook.io/webside/api/changes/post.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
