From e872363e52045a022a892136a4fc046a177c3d7f Mon Sep 17 00:00:00 2001 From: Lilith-In-Starlight Date: Wed, 8 Apr 2026 08:45:05 -0500 Subject: [PATCH 1/3] chore(docs): update documentation of existing endpoints Specifically, document all the new capabilities it has, as well as other older things that were not in the documentation. --- docs/api.md | 67 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/docs/api.md b/docs/api.md index 4b63525..24f75c4 100644 --- a/docs/api.md +++ b/docs/api.md @@ -40,13 +40,15 @@ object are determined by the chosen action. In addition, if an action requires the sender to be logged in – as marked with `(L)` – a `token` field containing a valid UUID token must be present in the -object. +object. `(L?)` indicates an action that behaves differently when logged in. -### `search` +All requests error with "unknown action" if the action is not recognized or is not present. + +### `search` (L?) > **Inputs:** > -> - `query` array of +> - `query` array of queries > - `ordering` string? > - `limit` number? > @@ -67,8 +69,11 @@ field can therefore be described thus: query := ["and" | "or", ...query] | ["not", query] | ["arity", number] - | ["id" | "user" | "scope" | "term", string] - | ["myvote", number] + | ["id" | "user" | "scope" | "term" | "head" | "body" | "date" | "score" | "before" | "after", string] + | ["id_raw" | "user_raw" | "scope_raw" | "head_raw" | "body_raw" | "date_raw" | "score_raw", string] + | ["pronominal_class" | "pronoun" | "animacy" | "pro" | "class", string] + | ["frame" | "distribution" | "subject", string] + | ["myvote", -1 | 0 | 1] ``` Here are listed the semantics of each operator: @@ -85,13 +90,28 @@ Here are listed the semantics of each operator: - `arity` (_Toaq-specific_): succeeds if the highest number of argument places in the parts of a definition is equal to the one supplied (must be a number, not a string representation thereof) - - `myvote`: succeeds if someone is logged in and their vote on the entry is the same as the value passed (`-1`, `0`, or `1`). + - `myvote`: succeeds if someone is logged in and their vote on the entry is the + same as the value passed (`-1`, `0`, or `1`). + - `head`: succeeds if the entire head matches the supplied string, interpreting + `C` as any consonant, `V` as any vowel and `*` as the regex `/.*/`. + - `body`: succeeds if the entire body matches the supplied string, interpreting + `C` as any consonant, `V` as any vowel and `*` as the regex `/.*/`. + - `head_raw`, etc: these do the same as their non-raw counterparts, but they do + not replace latin characters for their toaq-specific counterparts before + matching. All property constraints have raw counterparts, but only `head_raw` + and `body_raw` behave differently. - **Textual constraints**: - `term`: succeeds if the supplied string, after removing special characters, appears in either the head, the definition, or the comments of an entry +- **Metadata field access:** + - `pronominal_class`: succeeds if an entry's pronominal class matches the supplied class. + valid aliases are `pronoun`, `animacy`, `pro` or `class`. + - `frame`: succeeds if an entry's frame matches the provided frame, without spaces + - `distribution`: succeeds if an entry's distribution class matches the provided class + - `subject`. succeeds if an entry's subject class matches the provided class Alternatively, `query` may be a string like `"hello scope:en user:official"` -which is then interpreted as in the Toadua frontend. See +which is then interpreted as it would be in the Toadua frontend. See for more information. `ordering` describes the metric by which entries should be sorted. @@ -131,8 +151,10 @@ them have a `pronominal_class` set. > > - `entry` entry -Adds a note to the entry with the given ID. Note that `content` may not be over -2048 characters long. Returns the new state of the entry. +Adds a note to the entry with the given ID authored by +the user to whom the given token corresponds. Note that +`content` may not be over 2048 characters long. +Returns the new state of the entry. ### `create` (L) @@ -147,9 +169,9 @@ Adds a note to the entry with the given ID. Note that `content` may not be over > - `entry` entry Creates a new entry with the given Toaq word and definition in the given scope -(which defaults to `"en"`). Note that the head–body pair must be unique; note -also that there is a restriction of 2048 characters on each of the head and the -body. Don't go crazy. +(which defaults to `"en"`) authored by the user to whom the token corresponds. +Note that the head–body pair must be unique; note also that there is a +restriction of 2048 characters on each of the head and the body. Don't go crazy. ### `login` @@ -160,9 +182,10 @@ body. Don't go crazy. > > **Outputs:** > -> - `token` string +> - `token` string? -Attempts to log in with the given credentials. +Attempts to log in with the given credentials. If credentials correspond to a user, +the token is returned. ### `logout` (L) @@ -180,8 +203,8 @@ Invalidates the token passed as input. > - `token` string Attempts to register with the given credentials. Note that `name` may only -contain letters from the Latin alphabet; there is a restriction on the length, -too. +contain letters from the Latin alphabet, and must contain at least 1 character, +and at most 64. Similarly, the password can have at most 128 characters. ### `vote` (L) @@ -194,8 +217,10 @@ too. > > - `entry` entry -Casts a vote on the entry with the given ID. Possible values of `vote` are `-1`, -`0`, and `1`; `0` effectively cancels your previous vote. +Casts a vote by the user to whom the token corresponds, on the entry +with the given ID. Possible values of `vote` are `-1`, `0`, and `1`. + +Sending `0` effectively cancels your previous vote. ### `welcome` @@ -205,8 +230,8 @@ Casts a vote on the entry with the given ID. Possible values of `vote` are `-1`, > > **Outputs:** > -> - `user` string | `null` +> - `user` string? Make `welcome` the first message you send to the server. If you send a valid -token, you will get your username back in `user`; otherwise, `user` will be -`null` and you will know your token is invalid or has expired. +token, you will get your username back in `user`; otherwise, `user` will not +be in the output, and you will know your token is invalid or has expired. From 52777b9f0078e7a4c2f65baf7b96f59a0c2b6e43 Mon Sep 17 00:00:00 2001 From: Lilith-In-Starlight Date: Wed, 8 Apr 2026 09:33:55 -0500 Subject: [PATCH 2/3] chore(docs): document errors for each action --- docs/api.md | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/docs/api.md b/docs/api.md index 24f75c4..5098d6c 100644 --- a/docs/api.md +++ b/docs/api.md @@ -42,7 +42,15 @@ In addition, if an action requires the sender to be logged in – as marked with `(L)` – a `token` field containing a valid UUID token must be present in the object. `(L?)` indicates an action that behaves differently when logged in. -All requests error with "unknown action" if the action is not recognized or is not present. +All requests error with `unknown action` if the action is not recognized or is not present. + +All requests error with `The request body could not be parsed as JSON.` if the request body is not valid JSON. + +All requests that require the sender to be logged in fail with `must be logged in` if a token is not sent or if the token does not correspond to any session, including actions that are said to never error. + +Requests may error with `internal error` if the request caused a failure that toadua was not prepared to or report, including actions that are said to never error. + +See the bottom of this document for a description of various common errors relating to fields in the request JSON. The `Errors` section of each action will use them as a reference. ### `search` (L?) @@ -126,6 +134,16 @@ which is then interpreted as it would be in the Toadua frontend. See `limit` describes the maximum number of entries that should be returned. +#### Errors +- `invalid field 'query': absent` - If `query` is missing or falsy. +- `invalid field 'query': found non-array branch` - If `query` is not a string or a valid query structure. +- `ordering` - Length errors. +- `limit` - Number errors. +- `scope` - Scope errors. +- `preferred_scope` - Scope errors. This field is unused. +- `preferred_scope_bias` - Scope errors. This field is unused. +- `unknown operation {op name}` - If the query contains an unknown operation. + ### `count` > **Inputs:** @@ -140,6 +158,9 @@ which is then interpreted as it would be in the Toadua frontend. See Returns the total number of entries in Toadua's database, and how many of them have a `pronominal_class` set. +#### Errors +Never. + ### `note` (L) > **Inputs:** @@ -156,6 +177,10 @@ the user to whom the given token corresponds. Note that `content` may not be over 2048 characters long. Returns the new state of the entry. +#### Errors +- `id` - ID errors +- `content` - Length errors + ### `create` (L) > **Inputs:** @@ -173,6 +198,12 @@ Creates a new entry with the given Toaq word and definition in the given scope Note that the head–body pair must be unique; note also that there is a restriction of 2048 characters on each of the head and the body. Don't go crazy. +#### Errors +- `head` - Length errors +- `body` - Length errors +- `scope` - Scope errors if present (otherwise, field defauts to "en" which is a valid scope) +- `entry already exists` - If the database already contains an entry which is exactly identical to the one being inserted - specifically if head, body, frame, pronominal_class, subject, distribution, user and scope are all identical. + ### `login` > **Inputs:** @@ -187,10 +218,19 @@ restriction of 2048 characters on each of the head and the body. Don't go crazy. Attempts to log in with the given credentials. If credentials correspond to a user, the token is returned. +#### Errors +- `name` - Absence errors +- `pass` - Absence errors +- `user not registered` - The name is not in the database +- `password doesn't match` - The name is in the database but the password does not match + ### `logout` (L) Invalidates the token passed as input. +#### Errors +Never. + ### `register` > **Inputs:** @@ -206,6 +246,11 @@ Attempts to register with the given credentials. Note that `name` may only contain letters from the Latin alphabet, and must contain at least 1 character, and at most 64. Similarly, the password can have at most 128 characters. +- `invalid field 'name': name must be 1-64 Latin characters` - If the name is not comprised of 1 to 64 ascii-alphabetic characters +- `pass` - Length errors (for 128 instead of 1024) +- `registrations are temporarily disabled` - The server does not allow registrations at this time +- `already registered` - Name already exists in the database + ### `vote` (L) > **Inputs:** @@ -222,6 +267,10 @@ with the given ID. Possible values of `vote` are `-1`, `0`, and `1`. Sending `0` effectively cancels your previous vote. +# Errors +- `id` - ID errors +- `invalid field 'vote': invalid vote` - if `vote` is absent or a value other than -1, 0 or 1 + ### `welcome` > **Inputs:** @@ -235,3 +284,27 @@ Sending `0` effectively cancels your previous vote. Make `welcome` the first message you send to the server. If you send a valid token, you will get your username back in `user`; otherwise, `user` will not be in the output, and you will know your token is invalid or has expired. + +Notice that this action _does not require the user to be logged in_, it simply may have a token as a field. + +#### Errors +Never + +## Errors +### Absence error +- `invalid field 'FIELD': absent` + +### Length errors +Toadua rejects some fields if they are too long. + +- `ìnvalid field 'FIELD': too long (max. 2048 characters)` - If the field is present and exceeds 2048 characters + +### Number errors +- `invalid field 'FIELD': not a valid number` - If the field is present and not a number. + +### Scope errors +- `invalid field 'FIELD': scope must match [a-z-]{1,24}` - If the field is not a string of at least 1 and at most 24 lowercase ascii-alphabetic characters + +### ID errors +- `invalid field 'FIELD': invalid ID` - if field is missing, or present and not a valid ID +- `invalid field 'FIELD': not a recognized ID` - if field is a valid ID, but doesn't correspond to a word From 7635e56232d86a8074391cf9807c373df7c1437a Mon Sep 17 00:00:00 2001 From: Lilith-In-Starlight Date: Wed, 8 Apr 2026 15:43:36 -0500 Subject: [PATCH 3/3] chore(docs): document remaining actions --- docs/api.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/docs/api.md b/docs/api.md index 5098d6c..b7b0e79 100644 --- a/docs/api.md +++ b/docs/api.md @@ -181,6 +181,26 @@ Returns the new state of the entry. - `id` - ID errors - `content` - Length errors +## `removenote` (L) + +> **Inputs:** +> +> - `id` string +> - `date` string +> +> **Outputs:** +> +> - `entry` entry + +Removes the entries made at the given `date` under the entry with the given ID, provided they were authored by the logged in user. If, under some strange circumstance, multiple notes by the same user had the same `date` (which includes not only date but also time), then all of them would be deleted. + +Returns the entry as it is after having the notes deleted. + +#### Errors +- `id` - ID errors +- `date` - Absence errors +- `no such note by you` logged in user has not sent a note under the given entry at the given date. + ### `create` (L) > **Inputs:** @@ -198,12 +218,66 @@ Creates a new entry with the given Toaq word and definition in the given scope Note that the head–body pair must be unique; note also that there is a restriction of 2048 characters on each of the head and the body. Don't go crazy. +Returns the created entry. + #### Errors - `head` - Length errors - `body` - Length errors - `scope` - Scope errors if present (otherwise, field defauts to "en" which is a valid scope) - `entry already exists` - If the database already contains an entry which is exactly identical to the one being inserted - specifically if head, body, frame, pronominal_class, subject, distribution, user and scope are all identical. +### Edit (L) +> **Inputs:** +> +> - `id` string +> - `body` string +> - `scope` string +> +> **Outputs:** +> +> - `entry` entry + +Edits the entry with the given ID to have the given body and scope. The entry must be owned by the logged in user (i.e. its `user` field and the user the session belongs to are the same.) + +Returns the entry in its new state after editing. + +#### Errors +- `id` - ID errors +- `body` - Length errors +- `scope` - Scope errors +- `you are not the owner of this entry` - The given ID's `user` field does not correspond to the user the given token belongs to. + +### Annotate (L) +> **Inputs:** +> +> - `id` string +> - `pronominal_class` string? +> - `frame` string? +> - `distribution` string? +> - `subject` string? +> +> **Outputs:** +> +> - `entry` entry + +Edits the entry with the given ID to have the given pronominal class, frame, distribution and subject, if they are given. Absent fields will remove the values. + +The entry must be owned by the logged in user (i.e. its `user` field and the user the session belongs to must be the same.) + +Returns the entry in its new state after editing. + +### `remove` +> **Inputs:** +> +> - `id` string + +Removes the entry with the given ID, provider that it is authored by the logged in user. + +### Errors + +- `id` - ID errors +- `you are not the owner of this entry` - The logged in user is not the author of the entry with the given ID. + ### `login` > **Inputs:**