# Architecture
This file contains description of the software architecture. Before starting any development, consult this file.
The plugin is made out of a Gutenberg widget that communicates with the backend using endpoints handled by PHP. The endpoints are defined in the *controllers*, that handle everything between the request and creating a application specific models to pass down to the application. It hides all the details about network communication.
## Forms
The main component of the plugin are the *forms*. The administrator defines information that the user submits to them. There are two objects, the *definition* and *submission*. The administrator makes the definition: list of fields & elements the form is made out of. The user fills in the information and submits the form.
### Submitting forms
Use POST endpoint `forms/{form_id}` to submit form. The `RsvFormProcessor` will validate the form and call handler for each element in the definition.
## JavaScript
The JavaScript is mostly used for frontend components and slightly for the administration editor of the Wordpress widget. Each JS file and symbol in global scope must have the prefix `Rsv` or `rsv`. Each component should be encapsulated within it's own `const` object in separate file. The root directory is `assets/js/components/`.
The other JavaScript files are split between user-space and admin-space. Example of admin-space component is Wordpress-looking datagrid. Example of user-space component is calendar.
The JavaScript code should always use a resource object for communicating with the backend REST API. See **Data Layer** below.
### Error handling
## Data Layer
All REST API communication goes through the data layer in `assets/js/datasource/`.
### RsvDataSource
`RsvDataSource` is a factory object with a single method:
```js
RsvDataSource.create_rsv_resource(base_url, { nonce })
```
It returns a resource object that wraps `fetch` and provides a consistent CRUD interface:
| Method | Signature | HTTP |
|---|---|---|
| `get_page` | `(skip = 0, limit = 20, params = {})` | `GET base_url?skip=…&limit=…` |
| `get` | `(id)` | `GET base_url/{id}` |
| `post` | `(data)` | `POST base_url` |
| `put` | `(id, data)` | `PUT base_url/{id}` |
| `delete` | `(id)` | `DELETE base_url/{id}` |
Every method returns a `Promise`. Non-2xx responses reject with an `Error`. A `204 No Content` response resolves to `null`.
When a `nonce` is supplied, it is sent as the `X-WP-Nonce` header, which satisfies WordPress REST API authentication.
### Resource files
Each REST endpoint has its own factory function in `assets/js/datasource/`. The factory calls `RsvDataSource.create_rsv_resource` and fills in the endpoint path using the `ReservairServiceAPI.restUrl` global (injected by PHP via `wp_localize_script`).
| File | Factory | Endpoint |
|---|---|---|
| `RsvReservationResource.js` | `RsvReservationResource()` | `/reservation` |
| `RsvFormDefinitionResource.js` | `RsvFormDefinitionResource()` | `/form-definition` |
| `RsvTimetableResource.js` | `RsvTimetableResource()` | `/timetable` |
| `RsvTimetableCapacityResource.js` | `RsvTimetableCapacityResource(id)` | `/timetable/{id}/capacity` |
To add a new endpoint, create a new file following the same pattern and register it in `includes/RsvAssetsDefinition.php`.
## Admin REST Forms
Admin pages that write to the REST API follow a standard pattern to keep the code consistent and easy to extend.
### HTML
Use a `
```
- `action` — the full REST endpoint URL (use `get_rest_url` + `esc_url`).
- `data-method` — HTTP verb (`POST`, `PATCH`, `PUT`, `DELETE`). Standard HTML forms only support GET/POST; this attribute carries the real verb for the JS layer.
- `data-success-msg` — human-readable message passed to `show_notice` on success.
Fields that should not appear as literal HTML inputs (e.g. a `