From 56eb9d9614538e92e20c7a47525ff5d35d2a8d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 12:15:25 +0200 Subject: [PATCH 01/14] scripts: add restore_resource_doc_bodies.py (summary/errors/tags companion) Companion to upstream's scripts/rehydrate_resource_docs.py, which lifts description / exampleRequestBody / successResponseBody from commented Lift ResourceDocs into the matching http4s registrations. This script covers the three remaining fields upstream's tool does NOT touch: - summary - errorResponseBodies - tags Surgical per-field substring replacement preserves existing layout and keeps diffs minimal. Matches endpoints by nameOf(...). Skips fields whose normalized form already matches (idempotent re-runs). python3 scripts/restore_resource_doc_bodies.py v6_0_0 python3 scripts/restore_resource_doc_bodies.py v6_0_0 --dry-run python3 scripts/restore_resource_doc_bodies.py v6_0_0 --fields=tags python3 scripts/restore_resource_doc_bodies.py v6_0_0 --only=getXyz Pairs with scripts/check_lift_http4s_resource_doc_parity.py (3eda8849e) for verifying the result. --- scripts/restore_resource_doc_bodies.py | 457 +++++++++++++++++++++++++ 1 file changed, 457 insertions(+) create mode 100644 scripts/restore_resource_doc_bodies.py diff --git a/scripts/restore_resource_doc_bodies.py b/scripts/restore_resource_doc_bodies.py new file mode 100644 index 0000000000..746354166d --- /dev/null +++ b/scripts/restore_resource_doc_bodies.py @@ -0,0 +1,457 @@ +#!/usr/bin/env python3 +""" +restore_resource_doc_bodies.py + +Companion to scripts/rehydrate_resource_docs.py — that script lifts +description / exampleRequestBody / successResponseBody. This script lifts the +remaining "metadata" fields that public docs consumers also see: + - summary + - errorResponseBodies + - tags + +Reads the commented Lift ResourceDocs in APIMethodsXYZ.scala and overwrites +the matching field in Http4sXYZ.scala. Endpoints are matched by `nameOf(...)`. + +Usage: + python3 scripts/restore_resource_doc_bodies.py v6_0_0 + python3 scripts/restore_resource_doc_bodies.py v6_0_0 --dry-run + python3 scripts/restore_resource_doc_bodies.py v6_0_0 --fields=tags + python3 scripts/restore_resource_doc_bodies.py v6_0_0 --only=getXyz + +Read+writes the http4s file in place. Does NOT touch the Lift file. +""" + +import argparse +import re +import sys +from collections import OrderedDict +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parents[1] +API_ROOT = REPO_ROOT / "obp-api" / "src" / "main" / "scala" / "code" / "api" + +POSITIONAL_FIELDS = [ + "partialFunction", # 0 + "implementedInApiVersion", # 1 + "partialFunctionName", # 2 — endpoint identifier (nameOf(...)) + "requestVerb", # 3 + "requestUrl", # 4 + "summary", # 5 + "description", # 6 + "exampleRequestBody", # 7 + "successResponseBody", # 8 + "errorResponseBodies", # 9 + "tags", # 10 +] + +NAMED_ARG_FIELDS = { + "roles", + "http4sPartialFunction", + "isFeatured", + "specialInstructions", + "createdByBankId", + "authMode", +} + +DEFAULT_FIELDS_TO_RESTORE = [ + "summary", + "errorResponseBodies", + "tags", +] + + +def uncomment(source: str) -> str: + out = [] + for line in source.splitlines(): + m = re.match(r"^(\s*)//\s?(.*)$", line) + if m: + out.append(m.group(1) + m.group(2)) + else: + out.append(line) + return "\n".join(out) + + +def _skip_string_or_comment(source: str, i: int): + n = len(source) + c = source[i] + if source.startswith('"""', i): + j = source.find('"""', i + 3) + return n if j == -1 else j + 3 + if c in ("s", "f") and source.startswith('"""', i + 1): + j = source.find('"""', i + 4) + return n if j == -1 else j + 3 + if c == '"': + j = i + 1 + while j < n: + if source[j] == "\\": + j += 2 + continue + if source[j] == '"': + return j + 1 + j += 1 + return n + if c == "/" and i + 1 < n and source[i + 1] == "/": + j = source.find("\n", i) + return n if j == -1 else j + 1 + if c == "/" and i + 1 < n and source[i + 1] == "*": + j = source.find("*/", i + 2) + return n if j == -1 else j + 2 + return None + + +def scan_matching_close(source: str, start: int, open_ch: str, close_ch: str): + depth = 1 + i = start + n = len(source) + while i < n: + skipped = _skip_string_or_comment(source, i) + if skipped is not None: + i = skipped + continue + c = source[i] + if c == open_ch: + depth += 1 + elif c == close_ch: + depth -= 1 + if depth == 0: + return i + i += 1 + return None + + +def find_resourcedoc_blocks(source: str): + """Yield (header_start, body_start, body_end, body_text) for each + `(static)?[rR]esourceDocs += ResourceDoc(...)` call.""" + pattern = re.compile( + r"(?:static)?[rR]esourceDocs\s*\+=\s*ResourceDoc\s*\(" + ) + i = 0 + while True: + m = pattern.search(source, i) + if not m: + return + body_start = m.end() + close = scan_matching_close(source, body_start, "(", ")") + if close is None: + i = body_start + continue + yield m.start(), body_start, close, source[body_start:close] + i = close + 1 + + +def split_top_level_args(body: str): + """Return list of (start, end, text).""" + out = [] + depth = 0 + cur = 0 + i = 0 + n = len(body) + while i < n: + skipped = _skip_string_or_comment(body, i) + if skipped is not None: + i = skipped + continue + c = body[i] + if c in "([{": + depth += 1 + elif c in ")]}": + depth -= 1 + elif c == "," and depth == 0: + out.append((cur, i, body[cur:i])) + cur = i + 1 + i += 1 + tail = body[cur:] + if tail.strip(): + out.append((cur, n, tail)) + return out + + +def split_named(arg_text: str): + """Return (name, value_text_with_leading_ws_stripped) for named args, or + (None, arg_text) for positional.""" + m = re.match(r"^(\s*)([A-Za-z_][A-Za-z0-9_]*)(\s*=\s*)", arg_text) + if m and m.group(2) in NAMED_ARG_FIELDS: + return m.group(2), arg_text[m.end():] + return None, arg_text + + +def parse_args(body: str): + """Return (positional, named). Each positional entry is {'start','end','text'}; + named entries map name -> value_text.""" + raw = split_top_level_args(body) + positional = [] + named = OrderedDict() + for start, end, text in raw: + name, val = split_named(text) + if name is None: + positional.append({"start": start, "end": end, "text": text.strip()}) + else: + named[name] = val.strip() + return positional, named + + +def endpoint_name(part_fn_name: str) -> str: + s = (part_fn_name or "").strip() + m = re.match(r"^nameOf\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)\s*$", s) + if m: + return m.group(1) + if s.startswith('"') and s.endswith('"'): + return s[1:-1] + return s + + +def find_pair_for_version(version_dir: Path): + api_methods = list(version_dir.glob("APIMethods*.scala")) + http4s = list(version_dir.glob("Http4s*.scala")) + if not api_methods or not http4s: + return None + def pick(files, prefix): + ranked = sorted( + files, + key=lambda p: ( + 0 if re.match(rf"^{prefix}\d+\.scala$", p.name) else 1, + len(p.name), + ), + ) + return ranked[0] + return pick(api_methods, "APIMethods"), pick(http4s, "Http4s") + + +def collect_lift_docs(path: Path): + """Return {endpoint_name -> {field_name -> raw_text}}.""" + source = path.read_text(encoding="utf-8") + active = re.search(r"^\s*(?:static)?[rR]esourceDocs\s*\+=\s*ResourceDoc\s*\(", source, re.M) + commented = re.search(r"^\s*//\s*(?:static)?[rR]esourceDocs\s*\+=\s*ResourceDoc\s*\(", source, re.M) + if not active and commented: + source = uncomment(source) + docs = OrderedDict() + for _, _, _, body in find_resourcedoc_blocks(source): + positional, _ = parse_args(body) + if len(positional) < 3: + continue + name = endpoint_name(positional[2]["text"]) + field_values = OrderedDict() + for idx, fname in enumerate(POSITIONAL_FIELDS): + if idx < len(positional): + field_values[fname] = positional[idx]["text"] + docs.setdefault(name, field_values) + return docs + + +def reindent_value(value_text: str, target_indent: str) -> str: + """Re-indent multi-line value so subsequent lines start at target_indent.""" + if "\n" not in value_text: + return value_text + lines = value_text.split("\n") + min_indent = None + for line in lines[1:]: + if line.strip(): + il = len(line) - len(line.lstrip()) + if min_indent is None or il < min_indent: + min_indent = il + if min_indent is None: + min_indent = 0 + out = [lines[0]] + for line in lines[1:]: + if not line.strip(): + out.append("") + continue + stripped = line[min_indent:] if len(line) >= min_indent else line.lstrip() + out.append(target_indent + stripped) + return "\n".join(out) + + +def normalize_for_diff(s: str, fname: str) -> str: + """Normalize a value just enough to detect 'no semantic change'. Mirrors + what scripts/check_lift_http4s_resource_doc_parity.py does so we don't + rewrite when the audit would already consider them equal.""" + if s is None: + return "" + t = s + if fname in ("errorResponseBodies", "tags"): + # `X :: Y :: Nil` vs `List(X, Y)`: extract items and sort/join. + m = re.match(r"^\s*List\s*\(\s*(.*?)\s*\)\s*$", t, re.S) + if m: + items = [x.strip() for _, _, x in split_top_level_args(m.group(1))] + else: + parts = [p.strip() for p in re.split(r"::", t)] + items = [p for p in parts if p and p != "Nil"] + return "[" + ",".join(re.sub(r"\s+", "", x) for x in items) + "]" + # Drop leading `s` of `s"""..."""` and the `.stripMargin` postfix; strip + # leading `|` markers; collapse whitespace. + t = re.sub(r"\bs(\"\"\")", r"\1", t) + t = re.sub(r"\.stripMargin\b", "", t) + t = re.sub(r"^\s*\|", "", t, flags=re.M) + t = re.sub(r"\s+", "", t) + return t + + +def render_new_body(positional, named, new_field_text, fname_to_replace, + field_indent): + """Render the body with the named field replaced by new_field_text. + + Other positional args keep their original text exactly; named args also + kept verbatim. Layout: positional 0..3 on one line, 4..5 on next, 6+ one + per line. + """ + pos_texts = [] + for idx, fname in enumerate(POSITIONAL_FIELDS): + if idx >= len(positional): + break + if fname == fname_to_replace: + pos_texts.append(new_field_text) + else: + pos_texts.append(positional[idx]["text"]) + for idx in range(len(POSITIONAL_FIELDS), len(positional)): + pos_texts.append(positional[idx]["text"]) + + named_texts = [f"{n} = {v}" for n, v in named.items()] + + lines = [] + if len(pos_texts) >= 5: + lines.append(", ".join(pos_texts[0:4]) + ",") + line5 = pos_texts[4] + ("," if len(pos_texts) > 5 or named_texts else "") + if len(pos_texts) > 5: + line5 = pos_texts[4] + ", " + pos_texts[5] + "," + for v in pos_texts[6:]: + lines.append(line5) + line5 = v + "," + lines.append(line5) + else: + for v in pos_texts: + lines.append(v + ",") + for nt in named_texts: + lines.append(nt + ",") + if lines: + last = lines[-1] + if last.endswith(","): + lines[-1] = last[:-1] + + body = ("\n" + field_indent).join(lines) + return "\n" + field_indent + body + ")" + + +def process_file(http4s_path: Path, lift_docs: dict, dry_run: bool, + fields_to_restore, only_names=None): + """Surgical per-field replacement: for each field that needs to change, + locate its substring in the body and swap it in-place. Other fields are + untouched (preserves existing layout & minimises diff).""" + source = http4s_path.read_text(encoding="utf-8") + # (abs_start_in_file, abs_end_in_file, new_substring) + edits = [] + matched = 0 + skipped_no_lift = 0 + changed_endpoints = 0 + per_field_changes = {f: 0 for f in fields_to_restore} + + for header_start, body_start, body_end, body in find_resourcedoc_blocks(source): + positional, _ = parse_args(body) + if len(positional) < 3: + continue + name = endpoint_name(positional[2]["text"]) + if only_names and name not in only_names: + continue + lift = lift_docs.get(name) + if lift is None: + skipped_no_lift += 1 + continue + matched += 1 + + # Determine field indent from the FIRST line break we find before the + # current text of any positional field — fall back to " ". + # (Field indent only matters when the new value has embedded newlines.) + endpoint_changed = False + for fname in fields_to_restore: + idx = POSITIONAL_FIELDS.index(fname) + if idx >= len(positional): + continue + if fname not in lift: + continue + cur_text = positional[idx]["text"] + new_text = lift[fname].strip() + if normalize_for_diff(cur_text, fname) == normalize_for_diff(new_text, fname): + continue + + # Compute absolute file offsets of the substring to replace — + # preserve leading whitespace from the original arg slot. + arg_slice = body[positional[idx]["start"]:positional[idx]["end"]] + leading_ws_len = len(arg_slice) - len(arg_slice.lstrip()) + value_start_abs = body_start + positional[idx]["start"] + leading_ws_len + value_end_abs = body_start + positional[idx]["end"] + + # Re-indent multi-line new value to align with the leading + # whitespace context — derive target_indent from the line on + # which the original value starts. + line_start = source.rfind("\n", 0, value_start_abs) + 1 + target_indent = source[line_start:value_start_abs] + # If target_indent is all whitespace, use it verbatim. Else fall + # back to a sensible default (8 spaces). + if target_indent.strip(): + target_indent = " " + new_text_reindented = reindent_value(new_text, target_indent) + + edits.append((value_start_abs, value_end_abs, new_text_reindented)) + per_field_changes[fname] += 1 + endpoint_changed = True + + if endpoint_changed: + changed_endpoints += 1 + + new_source = source + for start, end, txt in sorted(edits, key=lambda e: -e[0]): + new_source = new_source[:start] + txt + new_source[end:] + + prefix = "[dry-run] " if dry_run else "" + print(f" {prefix}endpoints matched: {matched} changed: {changed_endpoints} " + f"skipped (no lift match): {skipped_no_lift}") + for f in fields_to_restore: + print(f" {f}: {per_field_changes[f]} fields rewritten") + + if not dry_run and changed_endpoints: + http4s_path.write_text(new_source, encoding="utf-8") + print(f" wrote {http4s_path}") + + +def main(): + ap = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + ap.add_argument("versions", nargs="+", help="Versions like v6_0_0") + ap.add_argument("--dry-run", action="store_true", + help="Report intended changes without writing files") + ap.add_argument("--only", action="append", default=None, + help="Restrict to endpoint name(s). Repeatable.") + ap.add_argument("--fields", default=None, + help=f"Comma-separated list of fields to restore. " + f"Default: {','.join(DEFAULT_FIELDS_TO_RESTORE)}") + args = ap.parse_args() + + fields_to_restore = (args.fields.split(",") if args.fields + else DEFAULT_FIELDS_TO_RESTORE) + invalid = [f for f in fields_to_restore if f not in POSITIONAL_FIELDS] + if invalid: + print(f"ERROR: unknown fields: {invalid}", file=sys.stderr) + sys.exit(2) + + for v in args.versions: + version_dir = API_ROOT / v + if not version_dir.is_dir(): + print(f"[skip] {v}: no such directory under {API_ROOT}", + file=sys.stderr) + continue + pair = find_pair_for_version(version_dir) + if not pair: + print(f"[skip] {v}: no APIMethods+Http4s pair found", + file=sys.stderr) + continue + lift_path, http4s_path = pair + print(f"\n=== {v} ===") + print(f" lift: {lift_path.relative_to(REPO_ROOT)}") + print(f" http4s: {http4s_path.relative_to(REPO_ROOT)}") + print(f" fields: {fields_to_restore}") + lift_docs = collect_lift_docs(lift_path) + process_file(http4s_path, lift_docs, args.dry_run, + fields_to_restore, set(args.only) if args.only else None) + + +if __name__ == "__main__": + main() From 2321b0f1de60af6c2824a9dabf9051c9d1d4315b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 12:15:41 +0200 Subject: [PATCH 02/14] v6.0.0: restore ResourceDoc summary/errorResponseBodies/tags from Lift (176 endpoints) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream commit a021caabb lifted descriptions + request/response example bodies for 243 v6.0.0 endpoints. The three remaining ResourceDoc fields visible in the public docs — summary, errorResponseBodies, and tags — were still out of parity with the Lift originals preserved as line-comments in APIMethods600.scala. Applied via scripts/restore_resource_doc_bodies.py. Per-endpoint substring replacement only; no positional layout reflows on unchanged fields. Audit (scripts/check_lift_http4s_resource_doc_parity.py) drops v6.0.0 mismatches from 178 to 13: summary: 30 fields rewritten errorResponseBodies: 151 fields rewritten tags: 69 fields rewritten The 13 remaining v6.0.0 mismatches are accounted for: - 11 requestUrl: intentional ALL_CAPS placeholder renames for the middleware URL-template bypass (UPD_VIEW_ID, GRANT_VIEW_ID, etc.) - 1 description (getMessageDocsJsonSchema): false positive — the audit script's comment-stripper eats `://...` after `https:` when parsing URLs embedded in triple-quoted descriptions. File content is correct; only the parser disagrees. - 1 successResponseBody (getAccountDirectory): 30-char drift in the JSONFactory case-class example. Out of scope for this pass. --- .../scala/code/api/v6_0_0/Http4s600.scala | 1294 +++++++++++++---- 1 file changed, 1014 insertions(+), 280 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v6_0_0/Http4s600.scala b/obp-api/src/main/scala/code/api/v6_0_0/Http4s600.scala index dc866c637f..9c0999ba14 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/Http4s600.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/Http4s600.scala @@ -6253,7 +6253,7 @@ object Http4s600 { """.stripMargin, EmptyBody, userJsonV300, - List($AuthenticatedUserIsRequired, UnknownError), + List(AuthenticatedUserIsRequired, UnknownError), apiTagUser :: Nil, None, http4sPartialFunction = Some(getCurrentUser) @@ -6286,7 +6286,7 @@ object Http4s600 { attributes = Some(List(BankAttributeBankResponseJsonV400("OVERDRAFT_LIMIT", "1000"))) ))), List(UnknownError), - apiTagBank :: Nil, + apiTagBank :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, http4sPartialFunction = Some(getBanks) ) @@ -6315,8 +6315,8 @@ object Http4s600 { bank_routings = List(BankRoutingJsonV121("OBP", "gh.29.uk")), attributes = Some(List(BankAttributeBankResponseJsonV400("OVERDRAFT_LIMIT", "1000"))) ), - List($BankNotFound, UnknownError), - apiTagBank :: Nil, + List(UnknownError, BankNotFound), + apiTagBank :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, http4sPartialFunction = Some(getBank) ) @@ -6344,8 +6344,12 @@ object Http4s600 { |""", EmptyBody, customerJSONsV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + UserCustomerLinksNotFoundForUser, + UnknownError + ), + List(apiTagCustomer, apiTagUser), Some(canGetCustomersAtOneBank :: Nil), http4sPartialFunction = Some(getCustomersAtOneBank) ) @@ -6366,7 +6370,12 @@ object Http4s600 { |""", EmptyBody, customerWithAttributesJsonV600, - List($AuthenticatedUserIsRequired, UserCustomerLinksNotFoundForUser, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UserCustomerLinksNotFoundForUser, + UnknownError + ), apiTagCustomer :: Nil, Some(canGetCustomersAtOneBank :: Nil), http4sPartialFunction = Some(getCustomerByCustomerId) @@ -6408,7 +6417,7 @@ object Http4s600 { views_basic = List("owner") ), List($AuthenticatedUserIsRequired, $BankAccountNotFound, UnknownError), - apiTagAccount :: Nil, + apiTagAccount :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, http4sPartialFunction = Some(getCoreAccountByIdV600) ) @@ -6497,7 +6506,7 @@ object Http4s600 { nameOf(getBankLevelDynamicEntities), "GET", "/management/banks/BANK_ID/dynamic-entities", - "Get Bank-Level Dynamic Entities", + "Get Bank Level Dynamic Entities", s"""Get all Bank Level Dynamic Entities for one bank with record counts. | |Each dynamic entity in the response includes a `record_count` field showing how many data records exist for that entity. @@ -6521,7 +6530,12 @@ object Http4s600 { ) ) ), - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $BankNotFound, + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagManageDynamicEntity :: apiTagApi :: Nil, Some(canGetBankLevelDynamicEntities :: canGetAnyBankLevelDynamicEntities :: Nil), http4sPartialFunction = Some(getBankLevelDynamicEntities) @@ -6552,8 +6566,13 @@ object Http4s600 { |""".stripMargin, EmptyBody, consumerJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagConsumer :: apiTagApi :: Nil, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + ConsumerNotFoundByConsumerId, + UnknownError + ), + List(apiTagConsumer), Some(canGetConsumers :: Nil), http4sPartialFunction = Some(getConsumer) ) @@ -6581,8 +6600,12 @@ object Http4s600 { |""", EmptyBody, customerJSONsV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + UserCustomerLinksNotFoundForUser, + UnknownError + ), + List(apiTagCustomer, apiTagUser), Some(canGetCustomersAtAllBanks :: Nil), http4sPartialFunction = Some(getCustomersAtAllBanks) ) @@ -6681,8 +6704,12 @@ object Http4s600 { |""", postCustomerNumberJsonV310, customerWithAttributesJsonV600, - List($AuthenticatedUserIsRequired, UserCustomerLinksNotFoundForUser, $BankNotFound, UserHasMissingRoles, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + UserCustomerLinksNotFoundForUser, + UnknownError + ), + List(apiTagCustomer, apiTagKyc), Some(canGetCustomersAtOneBank :: Nil), http4sPartialFunction = Some(getCustomerByCustomerNumber) ) @@ -6705,8 +6732,12 @@ object Http4s600 { |""", PostCustomerLegalNameJsonV510(legal_name = "John Smith"), customerJSONsV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + UserCustomerLinksNotFoundForUser, + UnknownError + ), + List(apiTagCustomer, apiTagKyc), Some(canGetCustomersAtOneBank :: Nil), http4sPartialFunction = Some(getCustomersByLegalName) ) @@ -6832,7 +6863,13 @@ object Http4s600 { personal_requires_role = false, schema = net.liftweb.json.parse("""{"description": "User preferences", "required": ["theme"], "properties": {"theme": {"type": "string", "minLength": 1, "maxLength": 20, "example": "dark", "description": "The UI theme preference"}, "language": {"type": "string", "minLength": 2, "maxLength": 5, "example": "en", "description": "ISO language code"}}}""").asInstanceOf[net.liftweb.json.JsonAST.JObject] ), - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + $BankNotFound, + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), apiTagManageDynamicEntity :: apiTagApi :: Nil, Some(canCreateBankLevelDynamicEntity :: Nil), authMode = code.api.util.APIUtil.UserOrApplication, @@ -6951,7 +6988,13 @@ object Http4s600 { has_public_access = false, schema = net.liftweb.json.parse("""{"description": "User preferences updated", "required": ["theme"], "properties": {"theme": {"type": "string", "minLength": 1, "maxLength": 20, "example": "dark", "description": "The UI theme preference"}, "language": {"type": "string", "minLength": 2, "maxLength": 5, "example": "en", "description": "ISO language code"}, "notifications_enabled": {"type": "boolean", "example": "true", "description": "Whether to send notifications"}}}""").asInstanceOf[net.liftweb.json.JsonAST.JObject] ), - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + $BankNotFound, + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), apiTagManageDynamicEntity :: apiTagApi :: Nil, Some(canUpdateBankLevelDynamicEntity :: Nil), http4sPartialFunction = Some(updateBankLevelDynamicEntity) @@ -7010,7 +7053,11 @@ object Http4s600 { has_public_access = false, schema = net.liftweb.json.parse("""{"description": "User preferences updated", "required": ["theme"], "properties": {"theme": {"type": "string", "minLength": 1, "maxLength": 20, "example": "dark", "description": "The UI theme preference"}, "language": {"type": "string", "minLength": 2, "maxLength": 5, "example": "en", "description": "ISO language code"}, "notifications_enabled": {"type": "boolean", "example": "true", "description": "Whether to send notifications"}}}""").asInstanceOf[net.liftweb.json.JsonAST.JObject] ), - List($AuthenticatedUserIsRequired, DynamicEntityNotFoundByDynamicEntityId, InvalidJsonFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + UnknownError + ), apiTagManageDynamicEntity :: apiTagApi :: Nil, None, http4sPartialFunction = Some(updateMyDynamicEntity) @@ -7069,8 +7116,15 @@ object Http4s600 { "can_add_comment" ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, SystemViewCannotBePublicError, UnknownError), - apiTagView :: Nil, + List( + InvalidJsonFormat, + AuthenticatedUserIsRequired, + UserHasMissingRoles, + SystemViewNotFound, + SystemViewCannotBePublicError, + UnknownError + ), + List(apiTagSystemView, apiTagView), None, http4sPartialFunction = Some(updateSystemView) ) @@ -7176,7 +7230,11 @@ object Http4s600 { """.stripMargin, EmptyBody, metricsJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagMetric :: apiTagApi :: Nil, Some(canReadMetrics :: Nil), http4sPartialFunction = Some(getMetrics) @@ -7272,8 +7330,12 @@ object Http4s600 { """.stripMargin, EmptyBody, aggregateMetricsJSONV300, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagMetric :: apiTagApi :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), + List(apiTagMetric, apiTagAggregateMetrics), Some(canReadAggregateMetrics :: Nil), http4sPartialFunction = Some(getAggregateMetrics) ) @@ -7338,7 +7400,13 @@ object Http4s600 { TopApiJsonV600(500, "getBank", "v4.0.0", "OBPv4.0.0-getBank"), TopApiJsonV600(250, "getAccountList", "v1.3", "BGv1.3-getAccountList") )), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidFilterParameterFormat, + GetTopApisError, + UnknownError + ), apiTagMetric :: apiTagApi :: Nil, Some(canReadMetrics :: Nil), http4sPartialFunction = Some(getTopAPIs) @@ -7398,8 +7466,10 @@ object Http4s600 { "webui_props", (List(WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com", Some("web-ui-props-id"), Some("database")))) ), - List(InvalidFilterParameterFormat, UnknownError), - apiTagWebUiProps :: apiTagApi :: Nil, + List( + UnknownError + ), + List(apiTagWebUiProps), None, http4sPartialFunction = Some(getWebUiProps) ) @@ -7431,7 +7501,7 @@ object Http4s600 { views_available = List(BasicViewJson("owner", "Owner", false)) ))), List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), - apiTagAccount :: Nil, + List(apiTagAccount, apiTagPrivateData, apiTagPublicData), None, http4sPartialFunction = Some(getAccountsAtBank) ) @@ -7483,8 +7553,17 @@ object Http4s600 { metadata = transactionMetadataJSON, transaction_attributes = Nil ))), - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, $UserNoPermissionAccessView, UnknownError), - apiTagTransaction :: Nil, + List( + FilterSortDirectionError, + FilterOffersetError, + FilterLimitError, + FilterDateFormatError, + AuthenticatedUserIsRequired, + BankAccountNotFound, + ViewNotFound, + UnknownError + ), + List(apiTagTransaction, apiTagAccount), None, http4sPartialFunction = Some(getTransactionsForBankAccount) ) @@ -7502,7 +7581,10 @@ object Http4s600 { |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, EmptyBody, productsJsonV600, - List($BankNotFound, UnknownError), + List( + BankNotFound, + UnknownError + ), apiTagProduct :: Nil, None, http4sPartialFunction = Some(getProductsV600) @@ -7516,7 +7598,7 @@ object Http4s600 { nameOf(getUsers), "GET", "/users", - "Get Users", + "Get all Users", s"""Get all users, optionally filtered. | |All query parameters are optional and may be combined. @@ -7544,7 +7626,14 @@ object Http4s600 { """.stripMargin, EmptyBody, usersInfoJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + FilterSortByError, + FilterSortByNotAllowedForEndpoint, + FilterSortDirectionError, + UnknownError + ), apiTagUser :: Nil, Some(canGetAnyUser :: Nil), http4sPartialFunction = Some(getUsers) @@ -7570,7 +7659,12 @@ object Http4s600 { |""", postBankJson600, bankJson600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, bankIdAlreadyExists, UnknownError), + List( + InvalidJsonFormat, + $AuthenticatedUserIsRequired, + InsufficientAuthorisationToCreateBank, + UnknownError + ), apiTagBank :: Nil, Some(canCreateBank :: Nil), http4sPartialFunction = Some(createBank) @@ -7628,8 +7722,21 @@ object Http4s600 { |""", postCustomerJsonV600, customerJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UserHasMissingRoles, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + InvalidJsonFormat, + InvalidJsonContent, + InvalidDateFormat, + InvalidCustomerType, + ParentCustomerNotFound, + CustomerNumberAlreadyExists, + UserNotFoundById, + CustomerAlreadyExistsForUser, + CreateConsumerError, + UnknownError + ), + List(apiTagCustomer, apiTagPerson), Some(canCreateCustomer :: Nil), http4sPartialFunction = Some(createCustomer) ) @@ -7639,7 +7746,7 @@ object Http4s600 { nameOf(createUser), "POST", "/users", - "Create User", + "Create User (v6.0.0)", s"""Creates OBP user. | No authorisation required. | @@ -7665,8 +7772,8 @@ object Http4s600 { |""", createUserJsonV600, userJsonV200, - List(InvalidJsonFormat, InvalidStrongPasswordFormat, DuplicateUsername, UnknownError), - apiTagUser :: Nil, + List(InvalidJsonFormat, InvalidStrongPasswordFormat, DuplicateUsername, ExternalUserCheckFailed, "Error occurred during user creation.", UnknownError), + List(apiTagUser, apiTagOnboarding), None, http4sPartialFunction = Some(createUser) ) @@ -7676,7 +7783,7 @@ object Http4s600 { nameOf(resetPasswordUrl), "POST", "/management/user/reset-password-url", - "Send Password Reset URL", + "Create Password Reset URL and Send Email", s"""Create a password reset URL for a user and automatically send it via email. | |Authentication is Required. @@ -7797,7 +7904,11 @@ object Http4s600 { environment = "dev", global_prefix = "obp_dev_" ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagCache :: apiTagSystem :: apiTagApi :: Nil, Some(canGetCacheConfig :: Nil), http4sPartialFunction = Some(getCacheConfig) @@ -7857,7 +7968,11 @@ object Http4s600 { total_keys = 170, redis_available = true ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagCache :: apiTagSystem :: apiTagApi :: Nil, Some(canGetCacheInfo :: Nil), http4sPartialFunction = Some(getCacheInfo) @@ -7952,7 +8067,11 @@ object Http4s600 { max_lifetime_ms = 1800000, keepalive_time_ms = 0 ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagSystem :: apiTagApi :: Nil, Some(canGetDatabasePoolInfo :: Nil), http4sPartialFunction = Some(getDatabasePoolInfo) @@ -8015,7 +8134,11 @@ object Http4s600 { response_time_ms = 45, error_message = None ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagConnector :: apiTagSystem :: apiTagApi :: Nil, Some(canGetConnectorHealth :: Nil), http4sPartialFunction = Some(getStoredProcedureConnectorHealth) @@ -8101,8 +8224,11 @@ object Http4s600 { |""", EmptyBody, customerJSONsV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + UnknownError + ), + List(apiTagCorporateCustomer, apiTagCustomer), Some(canGetCustomersAtOneBank :: Nil), http4sPartialFunction = Some(getCorporateCustomersAtOneBank) ) @@ -8112,7 +8238,7 @@ object Http4s600 { nameOf(getCorporateCustomerByCustomerId), "GET", "/banks/BANK_ID/corporate-customers/CUSTOMER_ID", - "Get Corporate Customer by Id", + "Get Corporate Customer by CUSTOMER_ID", s"""Gets the Corporate Customer specified by CUSTOMER_ID. | |Returns 404 if the customer exists but is not of type CORPORATE or SUBSIDIARY. @@ -8125,8 +8251,12 @@ object Http4s600 { |""", EmptyBody, customerWithAttributesJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, CustomerTypeMismatch, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + CustomerTypeMismatch, + UnknownError + ), + List(apiTagCorporateCustomer, apiTagCustomer), Some(canGetCustomersAtOneBank :: Nil), http4sPartialFunction = Some(getCorporateCustomerByCustomerId) ) @@ -8136,7 +8266,7 @@ object Http4s600 { nameOf(getCorporateCustomerSubsidiaries), "GET", "/banks/BANK_ID/corporate-customers/CUSTOMER_ID/subsidiaries", - "Get Subsidiaries", + "Get Corporate Customer Subsidiaries", s"""Get the subsidiary customers of a corporate customer. | |Returns a list of customers whose parent_customer_id matches the specified CUSTOMER_ID. @@ -8146,8 +8276,14 @@ object Http4s600 { |""", EmptyBody, customerJSONsV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, CustomerTypeMismatch, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + CustomerNotFoundByCustomerId, + CustomerTypeMismatch, + UnknownError + ), + List(apiTagCorporateCustomer, apiTagCustomer), Some(canGetCustomersAtOneBank :: Nil), http4sPartialFunction = Some(getCorporateCustomerSubsidiaries) ) @@ -8174,8 +8310,11 @@ object Http4s600 { |""", EmptyBody, customerJSONsV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + UnknownError + ), + List(apiTagRetailCustomer, apiTagCustomer), Some(canGetCustomersAtOneBank :: Nil), http4sPartialFunction = Some(getRetailCustomersAtOneBank) ) @@ -8185,7 +8324,7 @@ object Http4s600 { nameOf(getRetailCustomerByCustomerId), "GET", "/banks/BANK_ID/retail-customers/CUSTOMER_ID", - "Get Retail Customer by Id", + "Get Retail Customer by CUSTOMER_ID", s"""Gets the Retail Customer specified by CUSTOMER_ID. | |Returns 404 if the customer exists but is not of type INDIVIDUAL. @@ -8198,8 +8337,12 @@ object Http4s600 { |""", EmptyBody, customerWithAttributesJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, CustomerTypeMismatch, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + CustomerTypeMismatch, + UnknownError + ), + List(apiTagRetailCustomer, apiTagCustomer), Some(canGetCustomersAtOneBank :: Nil), http4sPartialFunction = Some(getRetailCustomerByCustomerId) ) @@ -8219,7 +8362,12 @@ object Http4s600 { |""", EmptyBody, customerJSONsV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + CustomerNotFoundByCustomerId, + UnknownError + ), apiTagCustomer :: Nil, Some(canGetCustomersAtOneBank :: Nil), http4sPartialFunction = Some(getCustomerChildren) @@ -8230,7 +8378,7 @@ object Http4s600 { nameOf(getCustomerLinksByCustomerId), "GET", "/banks/BANK_ID/customers/CUSTOMER_ID/customer-links", - "Get Customer Links by Customer Id", + "Get Customer Links by CUSTOMER_ID", s"""Get Customer Links by CUSTOMER_ID. | |Authentication is Required @@ -8238,7 +8386,13 @@ object Http4s600 { |""", EmptyBody, customerLinksJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + CustomerNotFoundByCustomerId, + UserHasMissingRoles, + UnknownError + ), apiTagCustomer :: Nil, Some(canGetCustomerLinks :: Nil), http4sPartialFunction = Some(getCustomerLinksByCustomerId) @@ -8282,8 +8436,12 @@ object Http4s600 { allowed_actions = List("can_see_transaction_amount", "can_see_bank_account_balance") ) )), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagView :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), + List(apiTagSystemView, apiTagView), Some(canGetSystemViews :: Nil), http4sPartialFunction = Some(getSystemViews) ) @@ -8293,7 +8451,7 @@ object Http4s600 { nameOf(getSystemViewById), "GET", "/management/system-views/SYS_VIEW_ID", - "Get System View by Id", + "Get System View", s"""Get a single system view by its ID. | |System views are predefined views that apply to all accounts, such as: @@ -8329,8 +8487,13 @@ object Http4s600 { "can_create_custom_view" ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagView :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + SystemViewNotFound, + UnknownError + ), + List(apiTagSystemView, apiTagView), Some(canGetSystemViews :: Nil), http4sPartialFunction = Some(getSystemViewById) ) @@ -8359,7 +8522,11 @@ object Http4s600 { ) ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagABAC :: Nil, Some(canGetAbacRule :: Nil), http4sPartialFunction = Some(getAbacPolicies) @@ -8406,8 +8573,10 @@ object Http4s600 { ) ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagMetric :: Nil, + List( + UnknownError + ), + List(apiTagMetric, apiTagApi), Some(canReadMetrics :: Nil), http4sPartialFunction = Some(getConnectorCallCounts) ) @@ -8451,8 +8620,11 @@ object Http4s600 { |""".stripMargin, EmptyBody, connectorTracesJsonV600, - List($AuthenticatedUserIsRequired, UnknownError), - apiTagMetric :: Nil, + List( + InvalidDateFormat, + UnknownError + ), + List(apiTagMetric, apiTagApi), None, http4sPartialFunction = Some(getConnectorTraces) ) @@ -8535,7 +8707,7 @@ object Http4s600 { ) ), List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagManageDynamicEntity :: Nil, + List(apiTagDynamicEntity, apiTagApi), Some(canGetDynamicEntityDiagnostics :: Nil), http4sPartialFunction = Some(getDynamicEntityDiagnostics) ) @@ -8578,7 +8750,7 @@ object Http4s600 { total_records_deleted = 42 ), List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagManageDynamicEntity :: Nil, + List(apiTagDynamicEntity, apiTagApi), Some(canCleanupOrphanedDynamicEntityRecords :: Nil), http4sPartialFunction = Some(cleanupOrphanedDynamicEntityRecords) ) @@ -8647,7 +8819,13 @@ object Http4s600 { |""", WebUiPropsPutJsonV600("https://apiexplorer.openbankproject.com"), WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com", Some("some-web-ui-props-id")), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidWebUiProps, InvalidJsonFormat, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + InvalidWebUiProps, + UnknownError + ), apiTagWebUiProps :: Nil, Some(canCreateWebUiProps :: Nil), http4sPartialFunction = Some(createOrUpdateWebUiProps) @@ -8674,7 +8852,12 @@ object Http4s600 { |""", EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidWebUiProps, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidWebUiProps, + UnknownError + ), apiTagWebUiProps :: Nil, Some(canDeleteWebUiProps :: Nil), http4sPartialFunction = Some(deleteWebUiProps) @@ -8720,8 +8903,15 @@ object Http4s600 { |""".stripMargin, createViewJsonV300, viewJsonV300, - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, UserHasMissingRoles, InvalidJsonFormat, InvalidCustomViewFormat, UnknownError), - apiTagView :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + InvalidCustomViewFormat, + BankAccountNotFound, + UnknownError + ), + List(apiTagView, apiTagAccount), Some(canCreateCustomView :: Nil), http4sPartialFunction = Some(createCustomViewManagement) ) @@ -8737,7 +8927,11 @@ object Http4s600 { |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, EmptyBody, productTagsJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), + List( + BankNotFound, + ProductNotFoundByProductCode, + UnknownError + ), apiTagProduct :: Nil, None, http4sPartialFunction = Some(getProductTagsV600) @@ -8754,7 +8948,14 @@ object Http4s600 { |Authentication is Required.""".stripMargin, productTagsJsonV600, productTagsJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvalidJsonFormat, UpdateProductError, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + BankNotFound, + ProductNotFoundByProductCode, + UnknownError + ), apiTagProduct :: Nil, None, http4sPartialFunction = Some(updateProductTagsV600) @@ -8823,15 +9024,21 @@ object Http4s600 { nameOf(getUserAttributeById), "GET", "/users/USER_ID/attributes/USER_ATTRIBUTE_ID", - "Get User Attribute by Id", + "Get User Attribute By Id", s"""Get a User Attribute by USER_ATTRIBUTE_ID for the user specified by USER_ID. | |${userAuthenticationMessage(true)} |""".stripMargin, EmptyBody, userAttributeResponseJsonV510, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UserAttributeNotFound, UnknownError), - apiTagUser :: apiTagUserAttribute :: Nil, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UserNotFoundByUserId, + UserAttributeNotFound, + UnknownError + ), + List(apiTagUser, apiTagUserAttribute, apiTagAttribute), Some(canGetUserAttributes :: Nil), http4sPartialFunction = Some(getUserAttributeById) ) @@ -8859,8 +9066,14 @@ object Http4s600 { value = "premium" ), userAttributeResponseJsonV510, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), - apiTagUser :: apiTagUserAttribute :: Nil, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UserNotFoundByUserId, + InvalidJsonFormat, + UnknownError + ), + List(apiTagUser, apiTagUserAttribute, apiTagAttribute), Some(canCreateUserAttribute :: Nil), http4sPartialFunction = Some(createUserAttribute) ) @@ -8881,8 +9094,15 @@ object Http4s600 { value = "enterprise" ), userAttributeResponseJsonV510, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UserAttributeNotFound, UnknownError), - apiTagUser :: apiTagUserAttribute :: Nil, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UserNotFoundByUserId, + UserAttributeNotFound, + InvalidJsonFormat, + UnknownError + ), + List(apiTagUser, apiTagUserAttribute, apiTagAttribute), Some(canUpdateUserAttribute :: Nil), http4sPartialFunction = Some(updateUserAttribute) ) @@ -8899,8 +9119,14 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UserAttributeNotFound, UnknownError), - apiTagUser :: apiTagUserAttribute :: Nil, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UserNotFoundByUserId, + UserAttributeNotFound, + UnknownError + ), + List(apiTagUser, apiTagUserAttribute, apiTagAttribute), Some(canDeleteUserAttribute :: Nil), http4sPartialFunction = Some(deleteUserAttribute) ) @@ -8910,7 +9136,7 @@ object Http4s600 { nameOf(addUserToGroup), "POST", "/users/USER_ID/group-entitlements", - "Add User to Group", + "Grant User Membership to Group Entitlements", s"""Grant the User Group Entitlements. | |This endpoint creates entitlements for every Role in the Group. If the user @@ -8946,8 +9172,13 @@ object Http4s600 { entitlements_created = List("CanGetCustomer", "CanGetAccount"), entitlements_skipped = List("CanCreateTransaction") ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), - apiTagGroup :: apiTagUser :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), + List(apiTagGroup, apiTagUser, apiTagEntitlement), None, http4sPartialFunction = Some(addUserToGroup) ) @@ -8973,8 +9204,12 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagGroup :: apiTagUser :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), + List(apiTagGroup, apiTagUser, apiTagEntitlement), None, http4sPartialFunction = Some(removeUserFromGroup) ) @@ -8996,8 +9231,13 @@ object Http4s600 { """.stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagEntitlement :: Nil, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + EntitlementCannotBeDeleted, + UnknownError + ), + List(apiTagRole, apiTagUser, apiTagEntitlement), Some(canDeleteEntitlementAtAnyBank :: Nil), http4sPartialFunction = Some(deleteEntitlement) ) @@ -9042,7 +9282,7 @@ object Http4s600 { ) ), List($AuthenticatedUserIsRequired, UnknownError), - apiTagManageDynamicEntity :: apiTagApi :: Nil, + List(apiTagDynamicEntity, apiTagPersonalDynamicEntity, apiTagApi), None, http4sPartialFunction = Some(getAvailablePersonalDynamicEntities) ) @@ -9111,7 +9351,7 @@ object Http4s600 { ) ), List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagManageDynamicEntity :: Nil, + List(apiTagDynamicEntity, apiTagApi), Some(canGetDynamicEntityReferenceTypes :: Nil), http4sPartialFunction = Some(getReferenceTypes) ) @@ -9121,7 +9361,7 @@ object Http4s600 { nameOf(joinSystemChatRoom), "POST", "/chat-room-participants", - "Join Chat Room", + "Join System Chat Room", s"""Join a system-level chat room using a joining key (passed as joining_key in the JSON body). |The user is added as a participant with no special permissions. | @@ -9164,8 +9404,8 @@ object Http4s600 { """.stripMargin, counterpartyAttributeRequestJsonV600, counterpartyAttributeResponseJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), - apiTagCounterparty :: Nil, + List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), + List(apiTagCounterpartyAttribute, apiTagApi), Some(canCreateCounterpartyAttribute :: Nil), http4sPartialFunction = Some(createCounterpartyAttribute) ) @@ -9184,8 +9424,8 @@ object Http4s600 { """.stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagCounterparty :: Nil, + List($AuthenticatedUserIsRequired, UnknownError), + List(apiTagCounterpartyAttribute, apiTagApi), Some(canDeleteCounterpartyAttribute :: Nil), http4sPartialFunction = Some(deleteCounterpartyAttribute) ) @@ -9195,7 +9435,7 @@ object Http4s600 { nameOf(getCounterpartyAttributeById), "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes/COUNTERPARTY_ATTRIBUTE_ID", - "Get Counterparty Attribute By Id", + "Get Counterparty Attribute By ID", s""" | Get a specific Counterparty Attribute by its COUNTERPARTY_ATTRIBUTE_ID. | @@ -9204,8 +9444,8 @@ object Http4s600 { """.stripMargin, EmptyBody, counterpartyAttributeResponseJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagCounterparty :: Nil, + List($AuthenticatedUserIsRequired, UnknownError), + List(apiTagCounterpartyAttribute, apiTagApi), Some(canGetCounterpartyAttribute :: Nil), http4sPartialFunction = Some(getCounterpartyAttributeById) ) @@ -9224,8 +9464,8 @@ object Http4s600 { """.stripMargin, EmptyBody, counterpartyAttributesJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagCounterparty :: Nil, + List($AuthenticatedUserIsRequired, UnknownError), + List(apiTagCounterpartyAttribute, apiTagApi), Some(canGetCounterpartyAttributes :: Nil), http4sPartialFunction = Some(getAllCounterpartyAttributes) ) @@ -9244,8 +9484,8 @@ object Http4s600 { """.stripMargin, counterpartyAttributeRequestJsonV600, counterpartyAttributeResponseJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), - apiTagCounterparty :: Nil, + List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), + List(apiTagCounterpartyAttribute, apiTagApi), Some(canUpdateCounterpartyAttribute :: Nil), http4sPartialFunction = Some(updateCounterpartyAttribute) ) @@ -9273,8 +9513,11 @@ object Http4s600 { account_access_id = ExampleValue.uuidExample.value, abac_rule_id = "" ), - List($AuthenticatedUserIsRequired, $BankNotFound, ViewNotFound, UnknownError), - apiTagAccount :: Nil, + List( + $BankNotFound, + UnknownError + ), + List(apiTagView, apiTagAccount), None, http4sPartialFunction = Some(hasAccountAccess) ) @@ -9311,7 +9554,7 @@ object Http4s600 { )) ), List($AuthenticatedUserIsRequired, UnknownError), - apiTagAccountAccess :: Nil, + List(apiTagAccountAccessRequest), None, http4sPartialFunction = Some(getMyAccountAccessRequests) ) @@ -9358,7 +9601,10 @@ object Http4s600 { |""", EmptyBody, WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com", Some("web-ui-props-id"), Some("config")), - List(WebUiPropsNotFoundByName, InvalidFilterParameterFormat, UnknownError), + List( + WebUiPropsNotFoundByName, + UnknownError + ), apiTagWebUiProps :: Nil, None, http4sPartialFunction = Some(getWebUiProp) @@ -9475,7 +9721,11 @@ object Http4s600 { ViewPermissionJsonV600("can_create_custom_view", "View") ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagSystemView :: apiTagView :: Nil, Some(canGetViewPermissionsAtAllBanks :: Nil), http4sPartialFunction = Some(getViewPermissions) @@ -9494,7 +9744,7 @@ object Http4s600 { |${userAuthenticationMessage(!getApiProductsIsPublic)}""".stripMargin, EmptyBody, apiProductsJsonV600, - List($AuthenticatedUserIsRequired, UnknownError), + List(UnknownError), apiTagApi :: apiTagApiProduct :: Nil, None, http4sPartialFunction = Some(getAllApiProductsV600) @@ -9513,7 +9763,7 @@ object Http4s600 { |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, EmptyBody, productsJsonV600, - List($AuthenticatedUserIsRequired, UnknownError), + List(UnknownError), apiTagProduct :: Nil, None, http4sPartialFunction = Some(getAllProductsV600) @@ -9551,7 +9801,7 @@ object Http4s600 { )) ), List($AuthenticatedUserIsRequired, UserHasMissingRoles, $BankNotFound, $BankAccountNotFound, UnknownError), - apiTagAccountAccess :: Nil, + List(apiTagAccountAccessRequest), Some(canGetAccountAccessRequestsAtOneBank :: canGetAccountAccessRequestsAtAnyBank :: Nil), http4sPartialFunction = Some(getAccountAccessRequestsForAccount) ) @@ -9584,7 +9834,7 @@ object Http4s600 { updated = APIUtil.DateWithMsExampleObject ), List($AuthenticatedUserIsRequired, UserHasMissingRoles, $BankNotFound, $BankAccountNotFound, AccountAccessRequestNotFound, UnknownError), - apiTagAccountAccess :: Nil, + List(apiTagAccountAccessRequest), Some(canGetAccountAccessRequestsAtOneBank :: canGetAccountAccessRequestsAtAnyBank :: Nil), http4sPartialFunction = Some(getAccountAccessRequestById) ) @@ -9652,7 +9902,7 @@ object Http4s600 { List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, $BankNotFound, $BankAccountNotFound, BusinessJustificationRequired, AccountAccessRequestAlreadyExists, AccountAccessRequestCannotBeCreated, UnknownError), - apiTagAccountAccess :: Nil, + List(apiTagAccountAccessRequest), Some(canCreateAccountAccessRequestAtOneBank :: canCreateAccountAccessRequestAtAnyBank :: Nil), http4sPartialFunction = Some(createAccountAccessRequest) ) @@ -9696,7 +9946,7 @@ object Http4s600 { $BankNotFound, $BankAccountNotFound, AccountAccessRequestNotFound, AccountAccessRequestStatusNotInitiated, MakerCheckerSameUser, AccountAccessRequestCannotBeUpdated, UnknownError), - apiTagAccountAccess :: Nil, + List(apiTagAccountAccessRequest), Some(canUpdateAccountAccessRequestAtOneBank :: canUpdateAccountAccessRequestAtAnyBank :: Nil), http4sPartialFunction = Some(approveAccountAccessRequest) ) @@ -9740,7 +9990,7 @@ object Http4s600 { $BankNotFound, $BankAccountNotFound, AccountAccessRequestNotFound, AccountAccessRequestStatusNotInitiated, MakerCheckerSameUser, CheckerCommentRequiredForRejection, AccountAccessRequestCannotBeUpdated, UnknownError), - apiTagAccountAccess :: Nil, + List(apiTagAccountAccessRequest), Some(canUpdateAccountAccessRequestAtOneBank :: canUpdateAccountAccessRequestAtAnyBank :: Nil), http4sPartialFunction = Some(rejectAccountAccessRequest) ) @@ -9837,7 +10087,12 @@ object Http4s600 { |""".stripMargin, postSignalMessageJsonV600, signalMessagePublishedJsonV600, - List($AuthenticatedUserIsRequired, InvalidSignalChannelName, InvalidJsonFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + InvalidSignalChannelName, + UnknownError + ), apiTagAiAgent :: apiTagSignal :: apiTagSignalling :: apiTagChannel :: Nil, None, http4sPartialFunction = Some(publishSignalMessage) @@ -9924,7 +10179,10 @@ object Http4s600 { created_at = new java.util.Date(), updated_at = new java.util.Date() ))), - List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(getBankChatRooms) @@ -9996,7 +10254,12 @@ object Http4s600 { created_at = new java.util.Date(), updated_at = new java.util.Date() ), - List($AuthenticatedUserIsRequired, $BankNotFound, ChatRoomNotFound, NotChatRoomParticipant, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + NotChatRoomParticipant, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(getBankChatRoom) @@ -10270,7 +10533,12 @@ object Http4s600 { created_at = new java.util.Date(), updated_at = new java.util.Date() ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, $BankNotFound, ChatRoomNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + ChatRoomNotFound, + UnknownError + ), apiTagChat :: Nil, Some(canArchiveBankChatRoom :: Nil), http4sPartialFunction = Some(archiveBankChatRoom) @@ -10340,8 +10608,13 @@ object Http4s600 { last_read_at = new java.util.Date(), is_muted = false ), - List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJoiningKey, - ChatRoomIsArchived, ChatRoomParticipantAlreadyExists, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJoiningKey, + ChatRoomIsArchived, + ChatRoomParticipantAlreadyExists, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(joinBankChatRoom) @@ -10361,8 +10634,12 @@ object Http4s600 { |""".stripMargin, EmptyBody, JoiningKeyJsonV600(joining_key = "new-key-abc123"), - List($AuthenticatedUserIsRequired, $BankNotFound, ChatRoomNotFound, - InsufficientChatPermission, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + InsufficientChatPermission, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(refreshBankJoiningKey) @@ -10420,8 +10697,12 @@ object Http4s600 { created_at = new java.util.Date(), updated_at = new java.util.Date() ), - List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, - ChatRoomAlreadyExists, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + ChatRoomAlreadyExists, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(createBankChatRoom) @@ -10552,8 +10833,12 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, - $BankNotFound, ChatRoomNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + ChatRoomNotFound, + UnknownError + ), apiTagChat :: Nil, Some(canDeleteBankChatRoom :: Nil), http4sPartialFunction = Some(deleteBankChatRoom) @@ -10587,7 +10872,7 @@ object Http4s600 { nameOf(setBankChatRoomOpenRoom), "PUT", "/banks/BANK_ID/chat-rooms/CHAT_ROOM_ID/open-room", - "Set Bank Chat Room Open Room", + "Set Chat Room All Users Are Participants", s"""Set whether all authenticated users are implicit participants of this chat room. | |If true, all users can read and send messages without needing an explicit Participant record. @@ -10616,8 +10901,12 @@ object Http4s600 { created_at = new java.util.Date(), updated_at = new java.util.Date() ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, - $BankNotFound, ChatRoomNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + ChatRoomNotFound, + UnknownError + ), apiTagChat :: Nil, Some(canSetBankChatRoomIsOpenRoom :: Nil), http4sPartialFunction = Some(setBankChatRoomOpenRoom) @@ -10628,7 +10917,7 @@ object Http4s600 { nameOf(setSystemChatRoomOpenRoom), "PUT", "/chat-rooms/CHAT_ROOM_ID/open-room", - "Set System Chat Room Open Room", + "Set System Chat Room All Users Are Participants", s"""Set whether all authenticated users are implicit participants of this system-level chat room. | |If true, all users can read and send messages without needing an explicit Participant record. @@ -10691,9 +10980,15 @@ object Http4s600 { last_read_at = new java.util.Date(), is_muted = false ), - List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, - ChatRoomNotFound, InsufficientChatPermission, MustSpecifyUserIdOrConsumerId, - ChatRoomParticipantAlreadyExists, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + ChatRoomNotFound, + InsufficientChatPermission, + MustSpecifyUserIdOrConsumerId, + ChatRoomParticipantAlreadyExists, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(addBankChatRoomParticipant) @@ -10760,8 +11055,12 @@ object Http4s600 { last_read_at = new java.util.Date(), is_muted = false ))), - List($AuthenticatedUserIsRequired, $BankNotFound, - ChatRoomNotFound, NotChatRoomParticipant, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + NotChatRoomParticipant, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(getBankChatRoomParticipants) @@ -10825,8 +11124,14 @@ object Http4s600 { last_read_at = new java.util.Date(), is_muted = false ), - List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, - ChatRoomNotFound, InsufficientChatPermission, ChatRoomParticipantNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + ChatRoomNotFound, + InsufficientChatPermission, + ChatRoomParticipantNotFound, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(updateBankParticipantPermissions) @@ -10878,8 +11183,13 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, $BankNotFound, - ChatRoomNotFound, InsufficientChatPermission, ChatRoomParticipantNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + InsufficientChatPermission, + ChatRoomParticipantNotFound, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(removeBankChatRoomParticipant) @@ -10935,8 +11245,14 @@ object Http4s600 { updated_at = new java.util.Date(), reactions = List() ), - List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, - ChatRoomNotFound, NotChatRoomParticipant, ChatRoomIsArchived, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + ChatRoomNotFound, + NotChatRoomParticipant, + ChatRoomIsArchived, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(sendBankChatMessage) @@ -11013,8 +11329,12 @@ object Http4s600 { updated_at = new java.util.Date(), reactions = List(ReactionSummaryJsonV600(emoji = "thumbsup", count = 2, user_ids = List("user-1", "user-2"))) ))), - List($AuthenticatedUserIsRequired, $BankNotFound, - ChatRoomNotFound, NotChatRoomParticipant, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + NotChatRoomParticipant, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(getBankChatMessages) @@ -11091,8 +11411,13 @@ object Http4s600 { updated_at = new java.util.Date(), reactions = List() ), - List($AuthenticatedUserIsRequired, $BankNotFound, - ChatRoomNotFound, NotChatRoomParticipant, ChatMessageNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + NotChatRoomParticipant, + ChatMessageNotFound, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(getBankChatMessage) @@ -11165,9 +11490,15 @@ object Http4s600 { updated_at = new java.util.Date(), reactions = List() ), - List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, - ChatRoomNotFound, NotChatRoomParticipant, ChatMessageNotFound, - CannotEditOthersMessage, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + ChatRoomNotFound, + NotChatRoomParticipant, + ChatMessageNotFound, + CannotEditOthersMessage, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(editBankChatMessage) @@ -11224,9 +11555,14 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, $BankNotFound, - ChatRoomNotFound, NotChatRoomParticipant, ChatMessageNotFound, - CannotDeleteMessage, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + NotChatRoomParticipant, + ChatMessageNotFound, + CannotDeleteMessage, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(deleteBankChatMessage) @@ -11283,8 +11619,13 @@ object Http4s600 { updated_at = new java.util.Date(), reactions = List() ))), - List($AuthenticatedUserIsRequired, $BankNotFound, - ChatRoomNotFound, NotChatRoomParticipant, ChatMessageNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + NotChatRoomParticipant, + ChatMessageNotFound, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(getBankThreadReplies) @@ -11357,8 +11698,15 @@ object Http4s600 { updated_at = new java.util.Date(), reactions = List() ), - List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, - ChatRoomNotFound, NotChatRoomParticipant, ChatRoomIsArchived, ChatMessageNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + ChatRoomNotFound, + NotChatRoomParticipant, + ChatRoomIsArchived, + ChatMessageNotFound, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(replyInBankThread) @@ -11422,9 +11770,15 @@ object Http4s600 { emoji = "thumbsup", created_at = new java.util.Date() ), - List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, - ChatRoomNotFound, NotChatRoomParticipant, ChatMessageNotFound, - ReactionAlreadyExists, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + ChatRoomNotFound, + NotChatRoomParticipant, + ChatMessageNotFound, + ReactionAlreadyExists, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(addBankReaction) @@ -11472,9 +11826,14 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, $BankNotFound, - ChatRoomNotFound, NotChatRoomParticipant, ChatMessageNotFound, - ReactionNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + NotChatRoomParticipant, + ChatMessageNotFound, + ReactionNotFound, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(removeBankReaction) @@ -11522,8 +11881,13 @@ object Http4s600 { emoji = "thumbsup", created_at = new java.util.Date() ))), - List($AuthenticatedUserIsRequired, $BankNotFound, - ChatRoomNotFound, NotChatRoomParticipant, ChatMessageNotFound, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + NotChatRoomParticipant, + ChatMessageNotFound, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(getBankReactions) @@ -11573,8 +11937,12 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, $BankNotFound, - ChatRoomNotFound, NotChatRoomParticipant, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + NotChatRoomParticipant, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(signalBankTyping) @@ -11613,8 +11981,12 @@ object Http4s600 { |""".stripMargin, EmptyBody, TypingUsersJsonV600(users = List(TypingUserJsonV600(user_id = "user-id-123", username = "robert.x.0.gh", provider = "https://github.com"))), - List($AuthenticatedUserIsRequired, $BankNotFound, - ChatRoomNotFound, NotChatRoomParticipant, UnknownError), + List( + $AuthenticatedUserIsRequired, + ChatRoomNotFound, + NotChatRoomParticipant, + UnknownError + ), apiTagChat :: Nil, None, http4sPartialFunction = Some(getBankTypingUsers) @@ -11861,7 +12233,7 @@ object Http4s600 { nameOf(resetPasswordUrlAnonymous), "POST", "/users/password-reset-url", - "Request Password Reset URL", + "Request Password Reset Email", s"""Request a password reset email for a user. No authentication is required. | |Authentication is NOT Required. @@ -11949,8 +12321,19 @@ object Http4s600 { """.stripMargin, transactionRequestBodyHoldJsonV600, transactionRequestWithChargeJSON400, - txReqErrors, - txReqTags, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + $BankAccountNotFound, + InsufficientAuthorisationToCreateTransactionRequest, + InvalidTransactionRequestType, + InvalidJsonFormat, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), + List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequestHold) ) @@ -11971,8 +12354,19 @@ object Http4s600 { """.stripMargin, transactionRequestBodyCardanoJsonV600, transactionRequestWithChargeJSON400, - txReqErrors, - txReqTags, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + $BankAccountNotFound, + InsufficientAuthorisationToCreateTransactionRequest, + InvalidTransactionRequestType, + InvalidJsonFormat, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), + List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequestCardano) ) @@ -11993,8 +12387,19 @@ object Http4s600 { """.stripMargin, transactionRequestBodyEthereumJsonV600, transactionRequestWithChargeJSON400, - txReqErrors, - txReqTags, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + $BankAccountNotFound, + InsufficientAuthorisationToCreateTransactionRequest, + InvalidTransactionRequestType, + InvalidJsonFormat, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), + List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequestEthereumeSendTransaction) ) @@ -12004,7 +12409,7 @@ object Http4s600 { nameOf(createTransactionRequestEthSendRawTransaction), "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/owner/transaction-request-types/ETH_SEND_RAW_TRANSACTION/transaction-requests", - "Create Transaction Request (ETH_SEND_RAW_TRANSACTION)", + "CREATE TRANSACTION REQUEST (ETH_SEND_RAW_TRANSACTION )", s""" | |Send ETH via Ethereum JSON-RPC. @@ -12015,8 +12420,19 @@ object Http4s600 { """.stripMargin, transactionRequestBodyEthSendRawTransactionJsonV600, transactionRequestWithChargeJSON400, - txReqErrors, - txReqTags, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + $BankAccountNotFound, + InsufficientAuthorisationToCreateTransactionRequest, + InvalidTransactionRequestType, + InvalidJsonFormat, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), + List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequestEthSendRawTransaction) ) @@ -12026,7 +12442,7 @@ object Http4s600 { nameOf(getUserGroupMemberships), "GET", "/users/USER_ID/group-entitlements", - "Get User Group Memberships", + "Get User's Group Memberships", s"""Get all groups a user is a member of. | |Returns groups where the user has entitlements with process = "GROUP_MEMBERSHIP". @@ -12053,7 +12469,11 @@ object Http4s600 { ) ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UserNotFoundByUserId, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagGroup :: apiTagUser :: apiTagEntitlement :: Nil, Some(canGetUserGroupMembershipsAtAllBanks :: canGetUserGroupMembershipsAtOneBank :: Nil), http4sPartialFunction = Some(getUserGroupMemberships) @@ -12086,7 +12506,11 @@ object Http4s600 { access_source = "ACCOUNT_ACCESS" )) ), - List($BankNotFound, $BankAccountNotFound, ViewNotFound, UnknownError), + List( + $BankNotFound, + BankAccountNotFound, + UnknownError + ), apiTagAccount :: apiTagView :: Nil, Some(canSeeAccountAccessForAnyUser :: Nil), http4sPartialFunction = Some(getUsersWithAccountAccess) @@ -12125,8 +12549,18 @@ object Http4s600 { |""", postRetailCustomerJsonV600, customerJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, $BankNotFound, - InvalidJsonFormat, InvalidJsonContent, UnknownError), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + InvalidJsonFormat, + InvalidJsonContent, + InvalidDateFormat, + CustomerNumberAlreadyExists, + UserNotFoundById, + CustomerAlreadyExistsForUser, + CreateConsumerError, + UnknownError + ), apiTagRetailCustomer :: apiTagCustomer :: Nil, Some(canCreateCustomer :: canCreateCustomerAtAnyBank :: Nil), http4sPartialFunction = Some(createRetailCustomer) @@ -12163,8 +12597,18 @@ object Http4s600 { |""", postCorporateCustomerJsonV600, customerJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, $BankNotFound, - InvalidJsonFormat, InvalidCustomerType, UnknownError), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + InvalidJsonFormat, + InvalidCustomerType, + ParentCustomerNotFound, + CustomerNumberAlreadyExists, + UserNotFoundById, + CustomerAlreadyExistsForUser, + CreateConsumerError, + UnknownError + ), apiTagCorporateCustomer :: apiTagCustomer :: Nil, Some(canCreateCustomer :: canCreateCustomerAtAnyBank :: Nil), http4sPartialFunction = Some(createCorporateCustomer) @@ -12175,7 +12619,7 @@ object Http4s600 { nameOf(getUserByUserId), "GET", "/users/user-id/USER_ID", - "Get User By User Id", + "Get User by USER_ID", s"""Get user by USER_ID | |${userAuthenticationMessage(true)} @@ -12215,7 +12659,12 @@ object Http4s600 { |""".stripMargin, EmptyBody, JSONFactory600.createTokenJSON("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvd3d3Lm9wZW5iYW5rcHJvamVjdC5jb20iLCJpYXQiOjE0NTU4OTQyNzYsImV4cCI6MTQ1NTg5Nzg3NiwiYXVkIjoib2JwLWFwaSIsInN1YiI6IjA2Zjc0YjUwLTA5OGYtNDYwNi1hOGNjLTBjNDc5MjAyNmI5ZCIsImNvbnN1bWVyX2tleSI6IjYwNGY3ZTAyNGQ5MWU2MzMwNGMzOGM0YzRmZjc0MjMwZGU5NDk4NTEwNjgxZWNjM2Q5MzViNWQ5MGEwOTI3ODciLCJyb2xlIjoiY2FuX2FjY2Vzc19hcGkifQ.f8xHvXP5fDxo5-LlfTj1OQS9oqHNZfFd7N-WkV2o4Cc"), - List(InvalidLoginCredentials, UsernameHasBeenLocked, UnknownError), + List( + InvalidDirectLoginParameters, + InvalidLoginCredentials, + InvalidConsumerCredentials, + UnknownError + ), apiTagUser :: Nil, None, http4sPartialFunction = Some(directLoginEndpoint) @@ -12259,8 +12708,12 @@ object Http4s600 { valid = true, message = "ABAC rule code is valid" ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, - AbacRuleCodeEmpty, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), apiTagABAC :: Nil, Some(canCreateAbacRule :: Nil), http4sPartialFunction = Some(validateAbacRule) @@ -12301,7 +12754,12 @@ object Http4s600 { AbacRuleResultJsonV600( result = true ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), apiTagABAC :: Nil, Some(canExecuteAbacRule :: Nil), http4sPartialFunction = Some(executeAbacRule) @@ -12345,7 +12803,12 @@ object Http4s600 { AbacRuleResultJsonV600( result = true ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), apiTagABAC :: Nil, Some(canExecuteAbacRule :: Nil), http4sPartialFunction = Some(executeAbacPolicy) @@ -12421,7 +12884,11 @@ object Http4s600 { "Attributes are Lists - use .find(), .exists(), .forall() etc." ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagABAC :: Nil, Some(canGetAbacRule :: Nil), http4sPartialFunction = Some(getAbacRuleSchema) @@ -12503,7 +12970,7 @@ object Http4s600 { nameOf(deleteSystemDynamicEntityCascade), "DELETE", "/management/system-dynamic-entities/cascade/DYNAMIC_ENTITY_ID", - "Delete System Dynamic Entity Cascade", + "Delete System Level Dynamic Entity Cascade", s"""Delete a DynamicEntity specified by DYNAMIC_ENTITY_ID and all its data records. | |This endpoint performs a cascade delete: @@ -12527,8 +12994,11 @@ object Http4s600 { |""", EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, - CannotDeleteCascadePersonalEntity, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagManageDynamicEntity :: apiTagApi :: Nil, Some(canDeleteCascadeSystemDynamicEntity :: Nil), http4sPartialFunction = Some(deleteSystemDynamicEntityCascade) @@ -12585,8 +13055,15 @@ object Http4s600 { |""", EmptyBody, investigationReportJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvestigationReportNotAvailable, UnknownError), - apiTagCustomer :: Nil, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + CustomerNotFoundByCustomerId, + InvestigationReportNotAvailable, + UserHasMissingRoles, + UnknownError + ), + List(apiTagCustomer, apiTagKyc, apiTagTransaction, apiTagAccount, apiTagFinancialCrime, apiTagAiAgent), Some(canGetInvestigationReport :: Nil), http4sPartialFunction = Some(getCustomerInvestigationReport) ) @@ -12604,7 +13081,15 @@ object Http4s600 { |""", postCustomerLinkJsonV600, customerLinkJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + InvalidJsonFormat, + CustomerNotFoundByCustomerId, + UserHasMissingRoles, + CreateCustomerLinkError, + UnknownError + ), apiTagCustomer :: Nil, Some(canCreateCustomerLink :: Nil), http4sPartialFunction = Some(createCustomerLink) @@ -12615,7 +13100,7 @@ object Http4s600 { nameOf(getCustomerLinksByBankId), "GET", "/banks/BANK_ID/customer-links", - "Get Customer Links by Bank", + "Get Customer Links at Bank", s"""Get all Customer Links at a Bank. | |Authentication is Required @@ -12634,7 +13119,7 @@ object Http4s600 { nameOf(getCustomerLinkById), "GET", "/banks/BANK_ID/customer-links/CUSTOMER_LINK_ID", - "Get Customer Link by Id", + "Get Customer Link by CUSTOMER_LINK_ID", s"""Get Customer Link by CUSTOMER_LINK_ID. | |Authentication is Required @@ -12642,7 +13127,13 @@ object Http4s600 { |""", EmptyBody, customerLinkJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + CustomerLinkNotFound, + UserHasMissingRoles, + UnknownError + ), apiTagCustomer :: Nil, Some(canGetCustomerLink :: Nil), http4sPartialFunction = Some(getCustomerLinkById) @@ -12661,7 +13152,15 @@ object Http4s600 { |""", putCustomerLinkJsonV600, customerLinkJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + InvalidJsonFormat, + CustomerLinkNotFound, + UserHasMissingRoles, + UpdateCustomerLinkError, + UnknownError + ), apiTagCustomer :: Nil, Some(canUpdateCustomerLink :: Nil), http4sPartialFunction = Some(updateCustomerLink) @@ -12680,7 +13179,13 @@ object Http4s600 { |""", EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + CustomerLinkNotFound, + UserHasMissingRoles, + UnknownError + ), apiTagCustomer :: Nil, Some(canDeleteCustomerLink :: Nil), http4sPartialFunction = Some(deleteCustomerLink) @@ -12691,7 +13196,7 @@ object Http4s600 { nameOf(getCustomViewById), "GET", "/management/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID", - "Get Custom View by Id", + "Get Custom View", s"""Get a single custom view by bank, account, and view ID. | |Custom views are user-created views with names starting with underscore (_), such as: @@ -12727,8 +13232,13 @@ object Http4s600 { "can_add_comment" ) ), - List($AuthenticatedUserIsRequired, UnknownError), - apiTagView :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + ViewNotFound, + UnknownError + ), + List(apiTagView, apiTagSystemView), None, http4sPartialFunction = Some(getCustomViewById) ) @@ -12758,7 +13268,12 @@ object Http4s600 { new_version = 2, status = "invalidated" ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + InvalidJsonFormat, + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagCache :: apiTagSystem :: apiTagApi :: Nil, Some(canInvalidateCacheNamespace :: Nil), http4sPartialFunction = Some(invalidateCacheNamespace) @@ -12792,7 +13307,9 @@ object Http4s600 { |""".stripMargin, EmptyBody, configPropsJsonV600, - List($AuthenticatedUserIsRequired, UnknownError), + List( + UnknownError + ), apiTagApi :: Nil, None, http4sPartialFunction = Some(getConfigProps) @@ -12846,8 +13363,12 @@ object Http4s600 { |""".stripMargin, EmptyBody, ViewsJsonV600(List()), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagView :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), + List(apiTagView, apiTagSystemView), Some(canGetCustomViews :: Nil), http4sPartialFunction = Some(getCustomViews) ) @@ -12883,8 +13404,12 @@ object Http4s600 { ) ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagRole :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), + List(apiTagRole, apiTagEntitlement), Some(canGetRolesWithEntitlementCountsAtAllBanks :: Nil), http4sPartialFunction = Some(getRolesWithEntitlementCountsAtAllBanks) ) @@ -12955,8 +13480,13 @@ object Http4s600 { active_rate_limits = activeRateLimitsJsonV600, call_counters = redisCallCountersJsonV600 ), - List($AuthenticatedUserIsRequired, InvalidConsumerCredentials, UnknownError), - apiTagConsumer :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidConsumerCredentials, + UnknownError + ), + apiTagConsumer :: apiTagApi :: Nil, Some(canGetCurrentConsumer :: Nil), http4sPartialFunction = Some(getCurrentConsumer) ) @@ -12990,7 +13520,7 @@ object Http4s600 { ) ), List(UnknownError), - apiTagApi :: Nil, + List(apiTagMetric, apiTagApi), None, http4sPartialFunction = Some(getPopularApis) ) @@ -13000,7 +13530,7 @@ object Http4s600 { nameOf(getAccountDirectory), "GET", "/banks/BANK_ID/account-directory", - "Get Account Directory", + "Get Account Directory at Bank", s"""Returns a list of accounts at the bank with identifiers and metadata. | |This endpoint is designed for management UIs that need to list accounts @@ -13028,7 +13558,10 @@ object Http4s600 { view_ids = List("owner") )) ), - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $BankNotFound, + UnknownError + ), apiTagAccount :: Nil, Some(canGetAccountDirectoryAtOneBank :: Nil), http4sPartialFunction = Some(getAccountDirectory) @@ -13066,7 +13599,12 @@ object Http4s600 { list_of_roles = List("CanGetCustomer", "CanGetAccount", "CanCreateTransaction"), is_enabled = true ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), apiTagGroup :: Nil, None, http4sPartialFunction = Some(createGroup) @@ -13096,7 +13634,11 @@ object Http4s600 { list_of_roles = List("CanGetCustomer", "CanGetAccount", "CanCreateTransaction"), is_enabled = true ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagGroup :: Nil, None, http4sPartialFunction = Some(getGroup) @@ -13133,7 +13675,11 @@ object Http4s600 { ) ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagGroup :: Nil, None, http4sPartialFunction = Some(getGroups) @@ -13168,7 +13714,12 @@ object Http4s600 { list_of_roles = List("CanGetCustomer", "CanGetAccount", "CanCreateTransaction", "CanGetTransaction"), is_enabled = true ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), apiTagGroup :: Nil, None, http4sPartialFunction = Some(updateGroup) @@ -13191,7 +13742,11 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagGroup :: Nil, None, http4sPartialFunction = Some(deleteGroup) @@ -13227,8 +13782,12 @@ object Http4s600 { ) ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagGroup :: Nil, + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), + List(apiTagGroup, apiTagEntitlement), Some(canGetEntitlementsForAnyBank :: Nil), http4sPartialFunction = Some(getGroupEntitlements) ) @@ -13282,7 +13841,12 @@ object Http4s600 { created_by_user_id = "user123", updated_by_user_id = "user123" ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), apiTagABAC :: Nil, Some(canCreateAbacRule :: Nil), http4sPartialFunction = Some(createAbacRule) @@ -13315,7 +13879,11 @@ object Http4s600 { created_by_user_id = "user123", updated_by_user_id = "user123" ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagABAC :: Nil, Some(canGetAbacRule :: Nil), http4sPartialFunction = Some(getAbacRule) @@ -13352,7 +13920,11 @@ object Http4s600 { ) ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagABAC :: Nil, Some(canGetAbacRule :: Nil), http4sPartialFunction = Some(getAbacRules) @@ -13464,7 +14036,11 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagABAC :: Nil, Some(canDeleteAbacRule :: Nil), http4sPartialFunction = Some(deleteAbacRule) @@ -13497,7 +14073,7 @@ object Http4s600 { ), userAttributeResponseJsonV510, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - apiTagUser :: Nil, + List(apiTagUser, apiTagUserAttribute, apiTagAttribute), Some(Nil), http4sPartialFunction = Some(createPersonalDataField) ) @@ -13519,7 +14095,7 @@ object Http4s600 { user_attributes = List(userAttributeResponseJsonV510) ), List($AuthenticatedUserIsRequired, UnknownError), - apiTagUser :: Nil, + List(apiTagUser, apiTagUserAttribute, apiTagAttribute), Some(Nil), http4sPartialFunction = Some(getPersonalDataFields) ) @@ -13537,7 +14113,7 @@ object Http4s600 { EmptyBody, userAttributeResponseJsonV510, List($AuthenticatedUserIsRequired, UserAttributeNotFound, UnknownError), - apiTagUser :: Nil, + List(apiTagUser, apiTagUserAttribute, apiTagAttribute), Some(Nil), http4sPartialFunction = Some(getPersonalDataFieldById) ) @@ -13558,8 +14134,13 @@ object Http4s600 { value = "green" ), userAttributeResponseJsonV510, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, UserAttributeNotFound, UnknownError), - apiTagUser :: Nil, + List( + $AuthenticatedUserIsRequired, + UserAttributeNotFound, + InvalidJsonFormat, + UnknownError + ), + List(apiTagUser, apiTagUserAttribute, apiTagAttribute), Some(Nil), http4sPartialFunction = Some(updatePersonalDataField) ) @@ -13577,7 +14158,7 @@ object Http4s600 { EmptyBody, EmptyBody, List($AuthenticatedUserIsRequired, UserAttributeNotFound, UnknownError), - apiTagUser :: Nil, + List(apiTagUser, apiTagUserAttribute, apiTagAttribute), Some(Nil), http4sPartialFunction = Some(deletePersonalDataField) ) @@ -13587,7 +14168,7 @@ object Http4s600 { nameOf(getConsumerCallCounters), "GET", "/management/consumers/CONSUMER_ID/call-counters", - "Get Consumer Call Counters", + "Get Call Counts for Consumer", s""" |Get the call counters (current usage) for a specific consumer. Shows how many API calls have been made and when the counters reset. | @@ -13613,7 +14194,15 @@ object Http4s600 { |""".stripMargin, EmptyBody, redisCallCountersJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + InvalidConsumerId, + ConsumerNotFoundByConsumerId, + UserHasMissingRoles, + UpdateConsumerError, + UnknownError + ), apiTagConsumer :: Nil, Some(canGetRateLimits :: Nil), http4sPartialFunction = Some(getConsumerCallCounters) @@ -13633,7 +14222,14 @@ object Http4s600 { |""".stripMargin, callLimitPostJsonV600, callLimitJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + InvalidConsumerId, + ConsumerNotFoundByConsumerId, + UserHasMissingRoles, + UnknownError + ), apiTagConsumer :: Nil, Some(canCreateRateLimits :: Nil), http4sPartialFunction = Some(createCallLimits) @@ -13644,7 +14240,7 @@ object Http4s600 { nameOf(updateRateLimits), "PUT", "/management/consumers/CONSUMER_ID/consumer/rate-limits/RATE_LIMITING_ID", - "Update Rate Limits for a Consumer", + "Set Rate Limits / Call Limits per Consumer", s""" |Set the API rate limits / call limits for a Consumer: | @@ -13662,8 +14258,16 @@ object Http4s600 { |""".stripMargin, callLimitPostJsonV400, callLimitPostJsonV400, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), - apiTagConsumer :: Nil, + List( + AuthenticatedUserIsRequired, + InvalidJsonFormat, + InvalidConsumerId, + ConsumerNotFoundByConsumerId, + UserHasMissingRoles, + UpdateConsumerError, + UnknownError + ), + List(apiTagConsumer, apiTagRateLimits), Some(canUpdateRateLimits :: Nil), http4sPartialFunction = Some(updateRateLimits) ) @@ -13673,7 +14277,7 @@ object Http4s600 { nameOf(deleteCallLimits), "DELETE", "/management/consumers/CONSUMER_ID/consumer/rate-limits/RATE_LIMITING_ID", - "Delete Rate Limits for a Consumer", + "Delete Rate Limit by Rate Limiting ID", s""" |Delete a specific Rate Limit by Rate Limiting ID | @@ -13682,7 +14286,13 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidConsumerId, + ConsumerNotFoundByConsumerId, + UserHasMissingRoles, + UnknownError + ), apiTagConsumer :: Nil, Some(canDeleteRateLimits :: Nil), http4sPartialFunction = Some(deleteCallLimits) @@ -13693,7 +14303,7 @@ object Http4s600 { nameOf(getActiveRateLimitsNow), "GET", "/management/consumers/CONSUMER_ID/active-rate-limits", - "Get Active Rate Limits (now)", + "Get Active Rate Limits (Current)", s""" |Get the active rate limits for a consumer at the current date/time. Returns the aggregated rate limits from all active records at this moment. | @@ -13706,7 +14316,13 @@ object Http4s600 { |""".stripMargin, EmptyBody, activeRateLimitsJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidConsumerId, + ConsumerNotFoundByConsumerId, + UserHasMissingRoles, + UnknownError + ), apiTagConsumer :: Nil, Some(canGetRateLimits :: Nil), http4sPartialFunction = Some(getActiveRateLimitsNow) @@ -13717,7 +14333,7 @@ object Http4s600 { nameOf(getActiveRateLimitsAtDate), "GET", "/management/consumers/CONSUMER_ID/active-rate-limits/DATE_WITH_HOUR", - "Get Active Rate Limits at Date", + "Get Active Rate Limits for Hour", s""" |Get the active rate limits for a consumer for a specific hour. Returns the aggregated rate limits from all active records during that hour. | @@ -13734,7 +14350,14 @@ object Http4s600 { |""".stripMargin, EmptyBody, activeRateLimitsJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidDateFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidConsumerId, + ConsumerNotFoundByConsumerId, + UserHasMissingRoles, + InvalidDateFormat, + UnknownError + ), apiTagConsumer :: Nil, Some(canGetRateLimits :: Nil), http4sPartialFunction = Some(getActiveRateLimitsAtDate) @@ -13753,8 +14376,15 @@ object Http4s600 { |""".stripMargin, postFeaturedApiCollectionJsonV600, featuredApiCollectionJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, ApiCollectionNotFound, UnknownError), - apiTagApiCollection :: Nil, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + ApiCollectionNotFound, + FeaturedApiCollectionAlreadyExists, + CreateFeaturedApiCollectionError, + UnknownError + ), + List(apiTagApiCollection, apiTagApi), Some(canManageFeaturedApiCollections :: Nil), http4sPartialFunction = Some(createFeaturedApiCollection) ) @@ -13776,7 +14406,7 @@ object Http4s600 { EmptyBody, featuredApiCollectionsJsonV600, List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagApiCollection :: Nil, + List(apiTagApiCollection, apiTagApi), Some(canManageFeaturedApiCollections :: Nil), http4sPartialFunction = Some(getFeaturedApiCollectionsAdmin) ) @@ -13794,8 +14424,14 @@ object Http4s600 { |""".stripMargin, putFeaturedApiCollectionJsonV600, featuredApiCollectionJsonV600, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), - apiTagApiCollection :: Nil, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + FeaturedApiCollectionNotFound, + UpdateFeaturedApiCollectionError, + UnknownError + ), + List(apiTagApiCollection, apiTagApi), Some(canManageFeaturedApiCollections :: Nil), http4sPartialFunction = Some(updateFeaturedApiCollection) ) @@ -13813,8 +14449,14 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), - apiTagApiCollection :: Nil, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + FeaturedApiCollectionNotFound, + DeleteFeaturedApiCollectionError, + UnknownError + ), + List(apiTagApiCollection, apiTagApi), Some(canManageFeaturedApiCollections :: Nil), http4sPartialFunction = Some(deleteFeaturedApiCollection) ) @@ -13832,7 +14474,13 @@ object Http4s600 { |""".stripMargin, postPutApiProductJsonV600, apiProductJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + CreateApiProductError, + UnknownError + ), apiTagApi :: apiTagApiProduct :: Nil, Some(canCreateApiProduct :: Nil), http4sPartialFunction = Some(createApiProduct) @@ -13851,7 +14499,13 @@ object Http4s600 { |""".stripMargin, postPutApiProductJsonV600, apiProductJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + CreateApiProductError, + UnknownError + ), apiTagApi :: apiTagApiProduct :: Nil, Some(canUpdateApiProduct :: Nil), http4sPartialFunction = Some(createOrUpdateApiProduct) @@ -13872,7 +14526,7 @@ object Http4s600 { |""".stripMargin, EmptyBody, apiProductJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + if (getApiProductsIsPublic) List(ApiProductNotFound, UnknownError) else List(UserHasMissingRoles, ApiProductNotFound, UnknownError), apiTagApi :: apiTagApiProduct :: Nil, Some(canGetApiProduct :: Nil), http4sPartialFunction = Some(getApiProduct) @@ -13893,7 +14547,7 @@ object Http4s600 { |""".stripMargin, EmptyBody, apiProductsJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + if (getApiProductsIsPublic) List(UnknownError) else List(UserHasMissingRoles, UnknownError), apiTagApi :: apiTagApiProduct :: Nil, Some(canGetApiProduct :: Nil), http4sPartialFunction = Some(getApiProducts) @@ -13912,7 +14566,13 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + ApiProductNotFound, + DeleteApiProductError, + UnknownError + ), apiTagApi :: apiTagApiProduct :: Nil, Some(canDeleteApiProduct :: Nil), http4sPartialFunction = Some(deleteApiProduct) @@ -13931,7 +14591,14 @@ object Http4s600 { |""".stripMargin, apiProductAttributeJsonV600, apiProductAttributeResponseJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + ApiProductNotFound, + CreateApiProductAttributeError, + UnknownError + ), apiTagApi :: apiTagApiProductAttribute :: Nil, Some(canCreateApiProductAttribute :: Nil), http4sPartialFunction = Some(createApiProductAttribute) @@ -13950,7 +14617,14 @@ object Http4s600 { |""".stripMargin, apiProductAttributeJsonV600, apiProductAttributeResponseJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + ApiProductNotFound, + ApiProductAttributeNotFound, + UnknownError + ), apiTagApi :: apiTagApiProductAttribute :: Nil, Some(canUpdateApiProductAttribute :: Nil), http4sPartialFunction = Some(updateApiProductAttribute) @@ -13969,7 +14643,7 @@ object Http4s600 { |""".stripMargin, EmptyBody, apiProductAttributeResponseJsonV600, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + if (getApiProductsIsPublic) List(ApiProductAttributeNotFound, UnknownError) else List(UserHasMissingRoles, ApiProductAttributeNotFound, UnknownError), apiTagApi :: apiTagApiProductAttribute :: Nil, Some(canGetApiProductAttribute :: Nil), http4sPartialFunction = Some(getApiProductAttribute) @@ -13988,7 +14662,13 @@ object Http4s600 { |""".stripMargin, EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + ApiProductAttributeNotFound, + DeleteApiProductAttributeError, + UnknownError + ), apiTagApi :: apiTagApiProductAttribute :: Nil, Some(canDeleteApiProductAttribute :: Nil), http4sPartialFunction = Some(deleteApiProductAttribute) @@ -14039,7 +14719,13 @@ object Http4s600 { created_by_user_id = "user-id-123", updated_by_user_id = "user-id-123" ), - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + $BankNotFound, + InvalidJsonFormat, + UnknownError + ), apiTagMandate :: Nil, Some(canCreateMandate :: Nil), http4sPartialFunction = Some(createMandate) @@ -14050,7 +14736,7 @@ object Http4s600 { nameOf(getMandates), "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/mandates", - "Get Mandates", + "Get Mandates for Account", s"""Get all mandates for a bank account. | |Authentication is Required @@ -14071,7 +14757,12 @@ object Http4s600 { created_by_user_id = "user-id-123", updated_by_user_id = "user-id-123" ))), - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + $BankNotFound, + UnknownError + ), apiTagMandate :: Nil, Some(canGetMandate :: Nil), http4sPartialFunction = Some(getMandates) @@ -14103,7 +14794,12 @@ object Http4s600 { created_by_user_id = "user-id-123", updated_by_user_id = "user-id-123" ), - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + $BankNotFound, + UnknownError + ), apiTagMandate :: Nil, Some(canGetMandate :: Nil), http4sPartialFunction = Some(getMandate) @@ -14143,7 +14839,13 @@ object Http4s600 { created_by_user_id = "user-id-123", updated_by_user_id = "user-id-456" ), - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + $BankNotFound, + InvalidJsonFormat, + UnknownError + ), apiTagMandate :: Nil, Some(canUpdateMandate :: Nil), http4sPartialFunction = Some(updateMandate) @@ -14161,7 +14863,12 @@ object Http4s600 { |""", EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + $BankNotFound, + UnknownError + ), apiTagMandate :: Nil, Some(canDeleteMandate :: Nil), http4sPartialFunction = Some(deleteMandate) @@ -14215,7 +14922,13 @@ object Http4s600 { is_active = true, sort_order = 1 ), - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + $BankNotFound, + InvalidJsonFormat, + UnknownError + ), apiTagMandate :: Nil, Some(canCreateMandateProvision :: Nil), http4sPartialFunction = Some(createMandateProvision) @@ -14250,7 +14963,12 @@ object Http4s600 { is_active = true, sort_order = 1 ))), - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + $BankNotFound, + UnknownError + ), apiTagMandate :: Nil, Some(canGetMandateProvision :: Nil), http4sPartialFunction = Some(getMandateProvisions) @@ -14282,7 +15000,12 @@ object Http4s600 { is_active = true, sort_order = 1 ), - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + $BankNotFound, + UnknownError + ), apiTagMandate :: Nil, Some(canGetMandateProvision :: Nil), http4sPartialFunction = Some(getMandateProvision) @@ -14326,7 +15049,13 @@ object Http4s600 { is_active = true, sort_order = 2 ), - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + $BankNotFound, + InvalidJsonFormat, + UnknownError + ), apiTagMandate :: Nil, Some(canUpdateMandateProvision :: Nil), http4sPartialFunction = Some(updateMandateProvision) @@ -14344,7 +15073,12 @@ object Http4s600 { |""", EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + $BankNotFound, + UnknownError + ), apiTagMandate :: Nil, Some(canDeleteMandateProvision :: Nil), http4sPartialFunction = Some(deleteMandateProvision) From 42df665305aab09f809c0be5904c5c7872ecee9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 12:41:31 +0200 Subject: [PATCH 03/14] scripts: handle Scala greedy `"""` closer in parity scanner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The triple-quote scanner used `find('"""', i+3)` to locate the closing `"""` of a `"""..."""` string. That non-greedy form lands on the FIRST three consecutive `"` characters — fine for `"""foo"""`, but wrong for Scala's documented greedy form `"""foo "bar""""` where the trailing 4 quotes are: one content quote + three closer quotes. Hitting that 1-char misalignment in a real source file (e.g. APIMethods600.scala's `rule_code = """user.department == "admin""""`) inverts every subsequent string boundary in the file — turning a closing `"""` into a new opener, treating `${...}` interpolated calls as plain code, and ultimately stripping `://` segments inside descriptions as line comments. That's why the audit previously reported a phantom description diff for `getMessageDocsJsonSchema` (a `https://api...` URL embedded in its description). Fix: after locating the closing `"""`, consume any additional trailing `"` characters before resuming the scan. Both the audit script (check_lift_http4s_resource_doc_parity.py) and the companion writer (restore_resource_doc_bodies.py) get the same patch since both share the same scanner logic. Effect on v6.0.0 audit: description false positive disappears; 2 endpoints (getAbacRulesByPolicy, updateAbacRule) that previously couldn't be parsed now show up as comparable. --- .../check_lift_http4s_resource_doc_parity.py | 20 ++++++++++++++++--- scripts/restore_resource_doc_bodies.py | 17 ++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/scripts/check_lift_http4s_resource_doc_parity.py b/scripts/check_lift_http4s_resource_doc_parity.py index b3d54cc62a..43f0ad24ff 100755 --- a/scripts/check_lift_http4s_resource_doc_parity.py +++ b/scripts/check_lift_http4s_resource_doc_parity.py @@ -132,14 +132,28 @@ def _skip_string_or_comment(source: str, i: int): """ n = len(source) c = source[i] - # triple-quoted plain + # triple-quoted plain. Scala's lexer is greedy about trailing `"` — + # e.g. `"""foo "bar""""` has content `foo "bar"` and closer `"""`, with + # the 4 quotes at the end being content-quote + 3 closer quotes. + # A non-greedy `find('"""', i+3)` would split at the wrong boundary, + # leaving a stray `"` that misaligns every subsequent string in the file. if source.startswith('"""', i): j = source.find('"""', i + 3) - return n if j == -1 else j + 3 + if j == -1: + return n + k = j + 3 + while k < n and source[k] == '"': + k += 1 + return k # interpolated triple-quote: s"""...""" or f"""...""" if c in ("s", "f") and source.startswith('"""', i + 1): j = source.find('"""', i + 4) - return n if j == -1 else j + 3 + if j == -1: + return n + k = j + 3 + while k < n and source[k] == '"': + k += 1 + return k # plain double-quoted string (handle escapes) if c == '"': j = i + 1 diff --git a/scripts/restore_resource_doc_bodies.py b/scripts/restore_resource_doc_bodies.py index 746354166d..d574977439 100644 --- a/scripts/restore_resource_doc_bodies.py +++ b/scripts/restore_resource_doc_bodies.py @@ -74,12 +74,25 @@ def uncomment(source: str) -> str: def _skip_string_or_comment(source: str, i: int): n = len(source) c = source[i] + # Scala's lexer is greedy about trailing `"` in `"""..."""` — consume + # any extra `"` chars after the closer to keep string boundaries + # aligned through the rest of the source. if source.startswith('"""', i): j = source.find('"""', i + 3) - return n if j == -1 else j + 3 + if j == -1: + return n + k = j + 3 + while k < n and source[k] == '"': + k += 1 + return k if c in ("s", "f") and source.startswith('"""', i + 1): j = source.find('"""', i + 4) - return n if j == -1 else j + 3 + if j == -1: + return n + k = j + 3 + while k < n and source[k] == '"': + k += 1 + return k if c == '"': j = i + 1 while j < n: From d95c1df01b26e150d78d974475d002031af44a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 12:41:55 +0200 Subject: [PATCH 04/14] v6.0.0: resolve remaining 13 ResourceDoc parity diffs (audit now clean) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two kinds of cleanup, leaving v6.0.0 with 0 audit mismatches: 1. Http4s600.scala — drop `$` prefix on `AuthenticatedUserIsRequired` in 2 endpoints' errorResponseBodies (getAbacRulesByPolicy, updateAbacRule). `def $AuthenticatedUserIsRequired = AuthenticatedUserIsRequired`, so the change is cosmetic but lets the parity audit match. These two endpoints only became visible to the audit after fixing the scanner's greedy-`"""` handling in the previous commit. 2. APIMethods600.scala — align dead Lift-comment URL templates with the renames applied in the http4s migration (12 sites): COUNTERPARTY_ID → COUNTERPARTY_ID_PARAM (5 endpoints) owner → VIEW_ID (2 endpoints, transaction-request-types CARDANO + HOLD) /management/system-views/VIEW_ID → /SYS_VIEW_ID (getSystemViewById) /system-views/VIEW_ID → /UPD_VIEW_ID (updateSystemView) /reactions/EMOJI → /reactions/EMOJI_REACTION (2 endpoints, bank + system chat) Plus 1 successResponseBody site (getAccountDirectory): FastFirehoseRoutings(bank_id, account_id) → AccountRoutingJsonV121(scheme, address) The renames keep `ResourceDocMatcher` from colliding with the reserved literal `COUNTERPARTY` (see "Reserved ALL_CAPS literals" gotcha in CLAUDE.md), avoid using the path segment `owner` as a placeholder where VIEW_ID is the real wildcard, and let middleware distinguish multiple VIEW_ID-shaped vars in one URL. The Lift code is dead (line-commented), so these edits don't change runtime behaviour — they only keep the dead-code reference in sync with the live http4s ResourceDoc and let the parity audit run clean. v6.0.0 audit summary after this commit: shared mismatch only-lift only-http4s 243 0 0 1 (the lone only-http4s entry is `createWebUiProps`, which is intentionally http4s-only.) --- .../scala/code/api/v6_0_0/APIMethods600.scala | 24 +++++++++---------- .../scala/code/api/v6_0_0/Http4s600.scala | 13 ++++++++-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala index 5fcefe4328..d311af0f95 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala @@ -196,7 +196,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(createTransactionRequestHold), // "POST", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/owner/transaction-request-types/HOLD/transaction-requests", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-request-types/HOLD/transaction-requests", // "Create Transaction Request (HOLD)", // s""" // | @@ -2083,7 +2083,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(createTransactionRequestCardano), // "POST", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/owner/transaction-request-types/CARDANO/transaction-requests", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-request-types/CARDANO/transaction-requests", // "Create Transaction Request (CARDANO)", // s""" // | @@ -5106,7 +5106,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(getSystemViewById), // "GET", -// "/management/system-views/VIEW_ID", +// "/management/system-views/SYS_VIEW_ID", // "Get System View", // s"""Get a single system view by its ID. // | @@ -5232,7 +5232,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(updateSystemView), // "PUT", -// "/system-views/VIEW_ID", +// "/system-views/UPD_VIEW_ID", // "Update System View", // s"""Update an existing system view. // | @@ -11444,7 +11444,7 @@ trait APIMethods600 // account_number = "123456789", // account_type = "CURRENT", // branch_id = "BRANCH_1", -// account_routings = List(FastFirehoseRoutings(bank_id = ExampleValue.bankIdExample.value, account_id = ExampleValue.accountIdExample.value)), +// account_routings = List(AccountRoutingJsonV121(scheme = "OBP", address = ExampleValue.accountIdExample.value)), // account_attributes = List(FastFirehoseAttributes(`type` = "STRING", code = "OVERDRAFT_LIMIT", value = "1000")), // view_ids = List("owner") // )) @@ -12695,7 +12695,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(createCounterpartyAttribute), // "POST", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID/attributes", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes", // "Create Counterparty Attribute", // s""" // | Create a new Counterparty Attribute for a given COUNTERPARTY_ID. @@ -12746,7 +12746,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(deleteCounterpartyAttribute), // "DELETE", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID/attributes/COUNTERPARTY_ATTRIBUTE_ID", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes/COUNTERPARTY_ATTRIBUTE_ID", // "Delete Counterparty Attribute", // s""" // | Delete a Counterparty Attribute specified by COUNTERPARTY_ATTRIBUTE_ID. @@ -12778,7 +12778,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(getCounterpartyAttributeById), // "GET", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID/attributes/COUNTERPARTY_ATTRIBUTE_ID", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes/COUNTERPARTY_ATTRIBUTE_ID", // "Get Counterparty Attribute By ID", // s""" // | Get a specific Counterparty Attribute by its COUNTERPARTY_ATTRIBUTE_ID. @@ -12810,7 +12810,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(getAllCounterpartyAttributes), // "GET", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID/attributes", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes", // "Get All Counterparty Attributes", // s""" // | Get all attributes for the specified Counterparty. @@ -12842,7 +12842,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(updateCounterpartyAttribute), // "PUT", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID/attributes/COUNTERPARTY_ATTRIBUTE_ID", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes/COUNTERPARTY_ATTRIBUTE_ID", // "Update Counterparty Attribute", // s""" // | Update an existing Counterparty Attribute specified by COUNTERPARTY_ATTRIBUTE_ID. @@ -16239,7 +16239,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(removeBankReaction), // "DELETE", -// "/banks/BANK_ID/chat-rooms/CHAT_ROOM_ID/messages/CHAT_MESSAGE_ID/reactions/EMOJI", +// "/banks/BANK_ID/chat-rooms/CHAT_ROOM_ID/messages/CHAT_MESSAGE_ID/reactions/EMOJI_REACTION", // "Remove Bank Reaction", // s"""Remove your own reaction from a message. // | @@ -16303,7 +16303,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(removeSystemReaction), // "DELETE", -// "/chat-rooms/CHAT_ROOM_ID/messages/CHAT_MESSAGE_ID/reactions/EMOJI", +// "/chat-rooms/CHAT_ROOM_ID/messages/CHAT_MESSAGE_ID/reactions/EMOJI_REACTION", // "Remove System Reaction", // s"""Remove your own reaction from a message in a system-level chat room. // | diff --git a/obp-api/src/main/scala/code/api/v6_0_0/Http4s600.scala b/obp-api/src/main/scala/code/api/v6_0_0/Http4s600.scala index 9c0999ba14..5d00fb7c6e 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/Http4s600.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/Http4s600.scala @@ -13974,7 +13974,11 @@ object Http4s600 { ) ) ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), apiTagABAC :: Nil, Some(canGetAbacRule :: Nil), http4sPartialFunction = Some(getAbacRulesByPolicy) @@ -14013,7 +14017,12 @@ object Http4s600 { created_by_user_id = "user123", updated_by_user_id = "user456" ), - List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), apiTagABAC :: Nil, Some(canUpdateAbacRule :: Nil), http4sPartialFunction = Some(updateAbacRule) From 6154bf2cc2448ec4f17f37950fa95ecfe60ed458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 13:01:54 +0200 Subject: [PATCH 05/14] v5.1.0: bring ResourceDoc parity to 0 mismatches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply the same restoration pass to v5.1.0 that previously cleaned up v6.0.0. After upstream's commit 29e513375 (request/response examples) the v5.1.0 audit still had 19 diffs across description, summary, errorResponseBodies, successResponseBody, and one verb-casing oddity. Changes: - Http4s510.scala — restore 19 fields from the commented Lift originals via scripts/restore_resource_doc_bodies.py (3 summary, 16 description, 1 successResponseBody, 1 errorResponseBodies). To make `createConsent`'s description compile after the verbatim copy, add a local `private val generalObpConsentText` (the docs string Lift had at APIMethods510:2326) and `import code.api.Constant` so the embedded `${Constant.SYSTEM_OWNER_VIEW_ID}` interpolation resolves. - APIMethods510.scala (dead Lift comments) — align two dead references with their live http4s counterparts so the parity audit reads clean: * `nameOf(createConsentImplicit)` → `nameOf(createConsent)` (Lift had a `lazy val createConsentImplicit = createConsent` alias and registered the ResourceDoc under the alias; http4s registers under the canonical name). * `"Delete"` → `"DELETE"` for revokeMyConsent (HTTP verb casing). v5.1.0 audit summary after this commit: shared mismatch only-lift only-http4s 111 0 0 1 The lone only-http4s entry is `getBanks`, intentionally kept in the v5.1.0 layer for metrics attribution (see comment at Http4s510:288). --- .../scala/code/api/v5_1_0/APIMethods510.scala | 6 +- .../scala/code/api/v5_1_0/Http4s510.scala | 323 ++++++++++++++++-- 2 files changed, 297 insertions(+), 32 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala index 16a9fa37f4..fcafa55612 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala @@ -2277,7 +2277,7 @@ trait APIMethods510 // revokeMyConsent, // implementedInApiVersion, // nameOf(revokeMyConsent), -// "Delete", +// "DELETE", // "/my/consents/CONSENT_ID", // "Revoke My Consent", // s""" @@ -2382,9 +2382,9 @@ trait APIMethods510 // """.stripMargin // // staticResourceDocs += ResourceDoc( -// createConsentImplicit, +// createConsent, // implementedInApiVersion, -// nameOf(createConsentImplicit), +// nameOf(createConsent), // "POST", // "/my/consents/IMPLICIT", // "Create Consent (IMPLICIT)", diff --git a/obp-api/src/main/scala/code/api/v5_1_0/Http4s510.scala b/obp-api/src/main/scala/code/api/v5_1_0/Http4s510.scala index 74602b2735..5807783cfb 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/Http4s510.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/Http4s510.scala @@ -2,6 +2,7 @@ package code.api.v5_1_0 import cats.data.{Kleisli, OptionT} import cats.effect._ +import code.api.Constant import code.api.Constant._ import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ import code.api.util.APIUtil._ @@ -235,9 +236,49 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(getAggregateMetrics), "GET", "/management/aggregate-metrics", "Get Aggregate Metrics", - s"""Returns aggregated metrics. Requires CanReadAggregateMetrics role. + s"""Returns aggregate metrics on api usage eg. total count, response time (in ms), etc. | - |${userAuthenticationMessage(true)}""", + |Should be able to filter on the following fields + | + |eg: /management/aggregate-metrics?from_date=$DateWithMsExampleString&to_date=$DateWithMsExampleString&consumer_id=5 + |&user_id=66214b8e-259e-44ad-8868-3eb47be70646&implemented_by_partial_function=getTransactionsForBankAccount + |&implemented_in_version=v3.0.0&url=/obp/v3.0.0/banks/gh.29.uk/accounts/8ca8a7e4-6d02-48e3-a029-0b2bf89de9f0/owner/transactions + |&verb=GET&anon=false&app_name=MapperPostman + |&exclude_app_names=API-EXPLORER,API-Manager,SOFI,null + | + |1 from_date (defaults to the day before the current date): eg:from_date=$DateWithMsExampleString + | + |2 to_date (defaults to the current date) eg:to_date=$DateWithMsExampleString + | + |3 consumer_id (if null ignore) + | + |4 user_id (if null ignore) + | + |5 anon (if null ignore) only support two value : true (return where user_id is null.) or false (return where user_id is not null.) + | + |6 url (if null ignore), note: can not contain '&'. + | + |7 app_name (if null ignore) + | + |8 implemented_by_partial_function (if null ignore), + | + |9 implemented_in_version (if null ignore) + | + |10 verb (if null ignore) + | + |11 correlation_id (if null ignore) + | + |12 include_app_names (if null ignore).eg: &include_app_names=API-EXPLORER,API-Manager,SOFI,null + | + |13 include_url_patterns (if null ignore).you can design you own SQL LIKE pattern. eg: &include_url_patterns=%management/metrics%,%management/aggregate-metrics% + | + |14 include_implemented_by_partial_functions (if null ignore).eg: &include_implemented_by_partial_functions=getMetrics,getConnectorMetrics,getAggregateMetrics + | + |15 http_status_code (if null ignore) - Filter by HTTP status code. eg: http_status_code=200 returns only successful calls, http_status_code=500 returns server errors + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, EmptyBody, aggregateMetricsJSONV300, List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagMetric, apiTagAggregateMetrics), @@ -504,9 +545,16 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(getAtm), "GET", "/banks/BANK_ID/atms/ATM_ID", "Get Bank ATM", - s"""Returns information about ATM for a single bank specified by BANK_ID and ATM_ID. - | - |${userAuthenticationMessage(!getAtmsIsPublic)}""", + s"""Returns information about ATM for a single bank specified by BANK_ID and ATM_ID including: + | + |* Address + |* Geo Location + |* License the data under this endpoint is released under + |* ATM Attributes + | + | + | + |${userAuthenticationMessage(!getAtmsIsPublic)}""".stripMargin, EmptyBody, atmJsonV510, List(AuthenticatedUserIsRequired, BankNotFound, AtmNotFoundByAtmId, UnknownError), List(apiTagATM), @@ -586,7 +634,7 @@ object Http4s510 { nameOf(createConsumer), "POST", "/management/consumers", - "Create Consumer", + "Create a Consumer", s"""Create a Consumer (Authenticated access). | |A Consumer represents an application that uses the Open Bank Project API. Each Consumer has: @@ -722,11 +770,19 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(getConsumers), "GET", "/management/consumers", "Get Consumers", - s"""Get all Consumers. - | - |${userAuthenticationMessage(true)}""", + s"""Get the all Consumers. + | + |${userAuthenticationMessage(true)} + | + |${urlParametersDocument(true, true)} + | + |""", EmptyBody, consumersJsonV510, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), List(apiTagConsumer), Some(List(canGetConsumers)), authMode = UserOrApplication, @@ -768,7 +824,30 @@ object Http4s510 { null, implementedInApiVersion, nameOf(getTransactionRequests), "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-requests", "Get Transaction Requests.", - "Returns transaction requests for account, with attribute filter support.", + """Returns transaction requests for account specified by ACCOUNT_ID at bank specified by BANK_ID. + | + |The VIEW_ID specified must be 'owner' and the user must have access to this view. + | + |Version 2.0.0 now returns charge information. + | + |Transaction Requests serve to initiate transactions that may or may not proceed. They contain information including: + | + |* Transaction Request Id + |* Type + |* Status (INITIATED, COMPLETED) + |* Challenge (in order to confirm the request) + |* From Bank / Account + |* Details including Currency, Value, Description and other initiation information specific to each type. (Could potentialy include a list of future transactions.) + |* Related Transactions + | + |PSD2 Context: PSD2 requires transparency of charges to the customer. + |This endpoint provides the charge that would be applied if the Transaction Request proceeds - and a record of that charge there after. + |The customer can proceed with the Transaction by answering the security challenge. + | + |We support query transaction request by attribute + |URL params example:/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-requests?invoiceNumber=123&referenceNumber=456 + | + """.stripMargin, EmptyBody, transactionRequestWithChargeJSONs210, List(AuthenticatedUserIsRequired, BankNotFound, BankAccountNotFound, UserNoPermissionAccessView, ViewDoesNotPermitAccess, @@ -829,7 +908,7 @@ object Http4s510 { nameOf(getAllBankAccountBalances), "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/balances", - "Get Account Balances", + "Get All Bank Account Balances", s"""Get all Balances for a Bank Account. | |${userAuthenticationMessage(true)} @@ -1031,9 +1110,10 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(deleteRegulatedEntity), "DELETE", "/regulated-entities/REGULATED_ENTITY_ID", "Delete Regulated Entity", - s"""Delete Regulated Entity specified by REGULATED_ENTITY_ID. - | - |${userAuthenticationMessage(true)}""", + s"""Delete Regulated Entity specified by REGULATED_ENTITY_ID + | + |${userAuthenticationMessage(true)} + |""".stripMargin, EmptyBody, EmptyBody, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidConnectorResponse, UnknownError), List(apiTagDirectory, apiTagApi), @@ -1996,9 +2076,24 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(getWebUiProps), "GET", "/webui-props", "Get WebUiProps", - "Get all WebUiProps key/values. ?active=true also includes implicit (default) props.", + s""" + | + |Get the all WebUiProps key values, those props key with "webui_" can be stored in DB, this endpoint get all from DB. + | + |url query parameter: + |active: It must be a boolean string. and If active = true, it will show + | combination of explicit (inserted) + implicit (default) method_routings. + | + |eg: + |${getObpApiRoot}/v5.1.0/webui-props + |${getObpApiRoot}/v5.1.0/webui-props?active=true + | + |""", EmptyBody, - ListResult("webui-props", List(WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com", Some("web-ui-props-id")))), + ListResult( + "webui-props", + (List(WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com", Some("web-ui-props-id")))) + ), List(UserHasMissingRoles, UnknownError), List(apiTagWebUiProps), None, @@ -2060,7 +2155,10 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(deleteNonPersonalUserAttribute), "DELETE", "/users/USER_ID/non-personal/attributes/USER_ATTRIBUTE_ID", "Delete Non Personal User Attribute", - s"Delete the Non Personal User Attribute.\n\n${userAuthenticationMessage(true)}", + s"""Delete the Non Personal User Attribute specified by ENTITLEMENT_REQUEST_ID for a user specified by USER_ID + | + |${userAuthenticationMessage(true)} + |""".stripMargin, EmptyBody, EmptyBody, List(AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidConnectorResponse, UnknownError), List(apiTagUser), @@ -2081,7 +2179,10 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(getNonPersonalUserAttributes), "GET", "/users/USER_ID/non-personal/attributes", "Get Non Personal User Attributes", - s"Get Non Personal User Attributes for a user.\n\n${userAuthenticationMessage(true)}", + s"""Get Non Personal User Attribute for a user specified by USER_ID + | + |${userAuthenticationMessage(true)} + |""".stripMargin, EmptyBody, EmptyBody, List(AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidConnectorResponse, UnknownError), List(apiTagUser), @@ -2181,7 +2282,7 @@ object Http4s510 { nameOf(getUserByProviderAndUsername), "GET", "/users/provider/PROVIDER/username/USERNAME", - "Get User by Provider and Username", + "Get User by USERNAME", s"""Get user by PROVIDER and USERNAME | |Get a User by their authentication provider and username. @@ -2228,7 +2329,11 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(getUserLockStatus), "GET", "/users/PROVIDER/USERNAME/lock-status", "Get User Lock Status", - s"Get User Login Status.\n\n${userAuthenticationMessage(true)}", + s""" + |Get User Login Status. + |${userAuthenticationMessage(true)} + | + |""".stripMargin, EmptyBody, badLoginStatusJson, List(AuthenticatedUserIsRequired, UserNotFoundByProviderAndUsername, UserHasMissingRoles, UnknownError), List(apiTagUser), @@ -2253,7 +2358,14 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(unlockUserByProviderAndUsername), "PUT", "/users/PROVIDER/USERNAME/lock-status", "Unlock the user", - s"Unlock a User (e.g. after multiple failed login attempts).\n\n${userAuthenticationMessage(true)}", + s""" + |Unlock a User. + | + |(Perhaps the user was locked due to multiple failed login attempts) + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, EmptyBody, badLoginStatusJson, List(AuthenticatedUserIsRequired, UserNotFoundByProviderAndUsername, UserHasMissingRoles, UnknownError), List(apiTagUser), @@ -2517,7 +2629,12 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(getCustomersByLegalName), "POST", "/banks/BANK_ID/customers/legal-name", "Get Customers by Legal Name", - s"Gets the Customers specified by Legal Name.\n\n${userAuthenticationMessage(true)}", + s"""Gets the Customers specified by Legal Name. + | + | + |${userAuthenticationMessage(true)} + | + |""", postCustomerLegalNameJsonV510, customerJsonV310, List(AuthenticatedUserIsRequired, UserCustomerLinksNotFoundForUser, UnknownError), List(apiTagCustomer, apiTagKyc), @@ -3710,7 +3827,24 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(createCustomView), "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID/target-views", "Create Custom View", - "Create a custom view on bank account. Name MUST start with `_`.", + s"""Create a custom view on bank account + | + | ${userAuthenticationMessage(true)} and the user needs to have access to the owner view. + | The 'alias' field in the JSON can take one of three values: + | + | * _public_: to use the public alias if there is one specified for the other account. + | * _private_: to use the private alias if there is one specified for the other account. + | + | * _''(empty string)_: to use no alias; the view shows the real name of the other account. + | + | The 'hide_metadata_if_alias_used' field in the JSON can take boolean values. If it is set to `true` and there is an alias on the other account then the other accounts' metadata (like more_info, url, image_url, open_corporates_url, etc.) will be hidden. Otherwise the metadata will be shown. + | + | The 'allowed_actions' field is a list containing the name of the actions allowed on this view, all the actions contained will be set to `true` on the view creation, the rest will be set to `false`. + | + | The 'metadata_view' field determines where metadata (comments, tags, images, where tags) for transactions are stored and retrieved. If set to another view's ID (e.g. 'owner'), metadata added through this view will be shared with all other views that also use the same metadata_view value. If left empty, metadata is stored under this view's own ID and is not shared with other views. + | + | You MUST use a leading _ (underscore) in the view name because other view names are reserved for OBP [system views](/index#group-View-System). + | """, createCustomViewJson, customViewJsonV510, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, $UserNoPermissionAccessView, InvalidJsonFormat, UnknownError), List(apiTagView, apiTagAccount), @@ -3744,7 +3878,12 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(updateCustomView), "PUT", "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID/target-views/TARGET_VIEW_ID", "Update Custom View", - "Update an existing custom view on a bank account.", + s"""Update an existing custom view on a bank account + | + |${userAuthenticationMessage(true)} and the user needs to have access to the owner view. + | + |The json sent is the same as during view creation (above), with one difference: the 'name' field + |of a view is not editable (it is only set when a view is created)""", updateCustomViewJson, customViewJsonV510, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, $UserNoPermissionAccessView, InvalidJsonFormat, UnknownError), List(apiTagView, apiTagAccount), @@ -4000,7 +4139,7 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(addSystemViewPermission), "POST", "/system-views/VIEW_ID/permissions", "Add Permission to a System View", - "Add Permission to a System View.", + """Add Permission to a System View.""", createViewPermissionJson, entitlementJSON, List($AuthenticatedUserIsRequired, InvalidJsonFormat, IncorrectRoleName, EntitlementAlreadyExists, UnknownError), List(apiTagSystemView), @@ -4023,7 +4162,8 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(deleteSystemViewPermission), "DELETE", "/system-views/VIEW_ID/permissions/PERMISSION_NAME", "Delete Permission to a System View", - "Delete Permission to a System View.", + """Delete Permission to a System View + """.stripMargin, EmptyBody, EmptyBody, List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagSystemView), @@ -4509,6 +4649,64 @@ object Http4s510 { http4sPartialFunction = Some(selfRevokeConsent) ) + private val generalObpConsentText: String = + s""" + | + |An OBP Consent allows the holder of the Consent to call one or more endpoints. + | + |Consents must be created and authorisied using SCA (Strong Customer Authentication). + | + |That is, Consents can be created by an authorised User via the OBP REST API but they must be confirmed via an out of band (OOB) mechanism such as a code sent to a mobile phone. + | + |Each Consent has one of the following states: ${ConsentStatus.values.toList.sorted.mkString(", ")}. + | + |Each Consent is bound to a consumer i.e. you need to identify yourself over request header value Consumer-Key. + | + |Examples: + | + |For example: + |GET /obp/v4.0.0/users/current HTTP/1.1 + |Host: 127.0.0.1:8080 + |Consent-JWT: eyJhbGciOiJIUzI1NiJ9.eyJlbnRpdGxlbWVudHMiOlt7InJvbGVfbmFtZSI6IkNhbkdldEFueVVzZXIiLCJiYW5rX2lkIjoiIn + |1dLCJjcmVhdGVkQnlVc2VySWQiOiJhYjY1MzlhOS1iMTA1LTQ0ODktYTg4My0wYWQ4ZDZjNjE2NTciLCJzdWIiOiIzNDc1MDEzZi03YmY5LTQyNj + |EtOWUxYy0xZTdlNWZjZTJlN2UiLCJhdWQiOiI4MTVhMGVmMS00YjZhLTQyMDUtYjExMi1lNDVmZDZmNGQzYWQiLCJuYmYiOjE1ODA3NDE2NjcsIml + |zcyI6Imh0dHA6XC9cLzEyNy4wLjAuMTo4MDgwIiwiZXhwIjoxNTgwNzQ1MjY3LCJpYXQiOjE1ODA3NDE2NjcsImp0aSI6ImJkYzVjZTk5LTE2ZTY + |tNDM4Yi1hNjllLTU3MTAzN2RhMTg3OCIsInZpZXdzIjpbXX0.L3fEEEhdCVr3qnmyRKBBUaIQ7dk1VjiFaEBW8hUNjfg + | + |Consumer-Key: ejznk505d132ryomnhbx1qmtohurbsbb0kijajsk + |cache-control: no-cache + | + |Maximum time to live of the token is specified over props value consents.max_time_to_live. In case isn't defined default value is 3600 seconds. + | + |Example of POST JSON: + |{ + | "everything": false, + | "views": [ + | { + | "bank_id": "GENODEM1GLS", + | "account_id": "8ca8a7e4-6d02-40e3-a129-0b2bf89de9f0", + | "view_id": "${Constant.SYSTEM_OWNER_VIEW_ID}" + | } + | ], + | "entitlements": [ + | { + | "bank_id": "GENODEM1GLS", + | "role_name": "CanGetCustomersAtOneBank" + | } + | ], + | "consumer_id": "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + | "email": "eveline@example.com", + | "valid_from": "2020-02-07T08:43:34Z", + | "time_to_live": 3600 + |} + |Please note that only optional fields are: consumer_id, valid_from and time_to_live. + |In case you omit they the default values are used: + |consumer_id = consumer of current user + |valid_from = current time + |time_to_live = consents.max_time_to_live + | + """.stripMargin + // ─── createConsent (IMPLICIT alias) — handles SCA: EMAIL/SMS/IMPLICIT ── val revokeMyConsent: HttpRoutes[IO] = HttpRoutes.of[IO] { @@ -4530,7 +4728,22 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(revokeMyConsent), "DELETE", "/my/consents/CONSENT_ID", "Revoke My Consent", - "Revoke a Consent for the current user, specified by CONSENT_ID.", + s""" + |Revoke Consent for current user specified by CONSENT_ID + | + |There are a few reasons you might need to revoke an application’s access to a user’s account: + | - The user explicitly wishes to revoke the application’s access + | - You as the service provider have determined an application is compromised or malicious, and want to disable it + | - etc. + | + |Please note that this endpoint only supports the case:: "The user explicitly wishes to revoke the application’s access" + | + |OBP as a resource server stores access tokens in a database, then it is relatively easy to revoke some token that belongs to a particular user. + |The status of the token is changed to "REVOKED" so the next time the revoked client makes a request, their token will fail to validate. + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, EmptyBody, revokedConsentJsonV310, List($AuthenticatedUserIsRequired, UnknownError), List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2), @@ -4651,7 +4864,59 @@ object Http4s510 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(createConsent), "POST", "/my/consents/IMPLICIT", "Create Consent (IMPLICIT)", - "Create a Consent in INITIATED state. SCA challenge is sent OOB based on SCA_METHOD.", + s""" + | + |This endpoint starts the process of creating a Consent. + | + |The Consent is created in an ${ConsentStatus.INITIATED} state. + | + |A One Time Password (OTP) (AKA security challenge) is sent Out of Band (OOB) to the User via the transport defined in SCA_METHOD + |SCA_METHOD is typically "SMS","EMAIL" or "IMPLICIT". "EMAIL" is used for testing purposes. OBP mapped mode "IMPLICIT" is "EMAIL". + |Other mode, bank can decide it in the connector method 'getConsentImplicitSCA'. + | + |When the Consent is created, OBP (or a backend system) stores the challenge so it can be checked later against the value supplied by the User with the Answer Consent Challenge endpoint. + | + |$generalObpConsentText + | + |${userAuthenticationMessage(true)} + | + |Example 1: + |{ + | "everything": true, + | "views": [], + | "entitlements": [], + | "consumer_id": "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + |} + | + |Please note that consumer_id is optional field + |Example 2: + |{ + | "everything": true, + | "views": [], + | "entitlements": [], + |} + | + |Please note if everything=false you need to explicitly specify views and entitlements + |Example 3: + |{ + | "everything": false, + | "views": [ + | { + | "bank_id": "GENODEM1GLS", + | "account_id": "8ca8a7e4-6d02-40e3-a129-0b2bf89de9f0", + | "view_id": "${Constant.SYSTEM_OWNER_VIEW_ID}" + | } + | ], + | "entitlements": [ + | { + | "bank_id": "GENODEM1GLS", + | "role_name": "CanGetCustomersAtOneBank" + | } + | ], + | "consumer_id": "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + |} + | + |""", postConsentImplicitJsonV310, consentJsonV310, List(AuthenticatedUserIsRequired, BankNotFound, InvalidJsonFormat, ConsentAllowedScaMethods, RolesAllowedInConsent, ViewsAllowedInConsent, ConsumerNotFoundByConsumerId, ConsumerIsDisabled, From 27f48af7262ff7e6a22d33301e3d24d77d5bf3b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 13:13:06 +0200 Subject: [PATCH 06/14] Revert dead-comment edits from v6.0.0 / v5.1.0 ResourceDoc cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commits d95c1df01 (v6.0.0) and 6154bf2cc (v5.1.0) I edited dead Lift ResourceDoc comments in APIMethods600.scala / APIMethods510.scala to align them with renames / improvements on the http4s side, so the parity audit would report 0 diffs. That had the comparison running backwards: the audit is supposed to verify that http4s matches the Lift source-of-truth, not to rewrite the source-of-truth so http4s looks right. Restore the two files to their pre-edit state. The http4s-side normalisations from the original commits (e.g. dropping the `$` prefix on `AuthenticatedUserIsRequired` in two v6 endpoints, restoring v5.1 descriptions verbatim, adding `generalObpConsentText`) are kept — those are legitimate "make http4s match Lift" changes. Expected effect: the parity audit will once again flag the intentional drifts (placeholder renames like `COUNTERPARTY_ID_PARAM`, `SYS_VIEW_ID`, `EMOJI_REACTION`; the upstream `AccountRoutingJsonV121` shape change; v5.1's `"DELETE"` verb casing; the `createConsent` vs `createConsentImplicit` rename). Those will be addressed by either fixing http4s to match Lift or by documenting them as known intentional drift at the http4s site — not by rewriting the Lift comments. --- .../scala/code/api/v5_1_0/APIMethods510.scala | 6 ++--- .../scala/code/api/v6_0_0/APIMethods600.scala | 24 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala index fcafa55612..16a9fa37f4 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala @@ -2277,7 +2277,7 @@ trait APIMethods510 // revokeMyConsent, // implementedInApiVersion, // nameOf(revokeMyConsent), -// "DELETE", +// "Delete", // "/my/consents/CONSENT_ID", // "Revoke My Consent", // s""" @@ -2382,9 +2382,9 @@ trait APIMethods510 // """.stripMargin // // staticResourceDocs += ResourceDoc( -// createConsent, +// createConsentImplicit, // implementedInApiVersion, -// nameOf(createConsent), +// nameOf(createConsentImplicit), // "POST", // "/my/consents/IMPLICIT", // "Create Consent (IMPLICIT)", diff --git a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala index d311af0f95..5fcefe4328 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala @@ -196,7 +196,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(createTransactionRequestHold), // "POST", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-request-types/HOLD/transaction-requests", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/owner/transaction-request-types/HOLD/transaction-requests", // "Create Transaction Request (HOLD)", // s""" // | @@ -2083,7 +2083,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(createTransactionRequestCardano), // "POST", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-request-types/CARDANO/transaction-requests", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/owner/transaction-request-types/CARDANO/transaction-requests", // "Create Transaction Request (CARDANO)", // s""" // | @@ -5106,7 +5106,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(getSystemViewById), // "GET", -// "/management/system-views/SYS_VIEW_ID", +// "/management/system-views/VIEW_ID", // "Get System View", // s"""Get a single system view by its ID. // | @@ -5232,7 +5232,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(updateSystemView), // "PUT", -// "/system-views/UPD_VIEW_ID", +// "/system-views/VIEW_ID", // "Update System View", // s"""Update an existing system view. // | @@ -11444,7 +11444,7 @@ trait APIMethods600 // account_number = "123456789", // account_type = "CURRENT", // branch_id = "BRANCH_1", -// account_routings = List(AccountRoutingJsonV121(scheme = "OBP", address = ExampleValue.accountIdExample.value)), +// account_routings = List(FastFirehoseRoutings(bank_id = ExampleValue.bankIdExample.value, account_id = ExampleValue.accountIdExample.value)), // account_attributes = List(FastFirehoseAttributes(`type` = "STRING", code = "OVERDRAFT_LIMIT", value = "1000")), // view_ids = List("owner") // )) @@ -12695,7 +12695,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(createCounterpartyAttribute), // "POST", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID/attributes", // "Create Counterparty Attribute", // s""" // | Create a new Counterparty Attribute for a given COUNTERPARTY_ID. @@ -12746,7 +12746,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(deleteCounterpartyAttribute), // "DELETE", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes/COUNTERPARTY_ATTRIBUTE_ID", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID/attributes/COUNTERPARTY_ATTRIBUTE_ID", // "Delete Counterparty Attribute", // s""" // | Delete a Counterparty Attribute specified by COUNTERPARTY_ATTRIBUTE_ID. @@ -12778,7 +12778,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(getCounterpartyAttributeById), // "GET", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes/COUNTERPARTY_ATTRIBUTE_ID", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID/attributes/COUNTERPARTY_ATTRIBUTE_ID", // "Get Counterparty Attribute By ID", // s""" // | Get a specific Counterparty Attribute by its COUNTERPARTY_ATTRIBUTE_ID. @@ -12810,7 +12810,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(getAllCounterpartyAttributes), // "GET", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID/attributes", // "Get All Counterparty Attributes", // s""" // | Get all attributes for the specified Counterparty. @@ -12842,7 +12842,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(updateCounterpartyAttribute), // "PUT", -// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID_PARAM/attributes/COUNTERPARTY_ATTRIBUTE_ID", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/counterparties/COUNTERPARTY_ID/attributes/COUNTERPARTY_ATTRIBUTE_ID", // "Update Counterparty Attribute", // s""" // | Update an existing Counterparty Attribute specified by COUNTERPARTY_ATTRIBUTE_ID. @@ -16239,7 +16239,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(removeBankReaction), // "DELETE", -// "/banks/BANK_ID/chat-rooms/CHAT_ROOM_ID/messages/CHAT_MESSAGE_ID/reactions/EMOJI_REACTION", +// "/banks/BANK_ID/chat-rooms/CHAT_ROOM_ID/messages/CHAT_MESSAGE_ID/reactions/EMOJI", // "Remove Bank Reaction", // s"""Remove your own reaction from a message. // | @@ -16303,7 +16303,7 @@ trait APIMethods600 // implementedInApiVersion, // nameOf(removeSystemReaction), // "DELETE", -// "/chat-rooms/CHAT_ROOM_ID/messages/CHAT_MESSAGE_ID/reactions/EMOJI_REACTION", +// "/chat-rooms/CHAT_ROOM_ID/messages/CHAT_MESSAGE_ID/reactions/EMOJI", // "Remove System Reaction", // s"""Remove your own reaction from a message in a system-level chat room. // | From 19ece37d095abf9ff32f01f789fbae3ae8c05c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 13:21:23 +0200 Subject: [PATCH 07/14] docs: APIMethodsXYZ.scala (Lift) files are source-of-truth for migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a working-style rule capturing the principle the recent commits got wrong: when the parity audit (scripts/check_lift_http4s_resource_doc_parity.py) flags a diff between Lift and http4s, the fix is on the http4s side (either bring it back in line with Lift, or document the intentional drift at the http4s site). Never rewrite the dead Lift comments to silence the audit — that runs the comparison backwards and erases the historical record we're migrating from. The d95c1df01 (v6.0.0) and 6154bf2cc (v5.1.0) commits violated this and were reverted in 27f48af72. Memorialise the rule so the next session doesn't make the same mistake. --- CLAUDE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CLAUDE.md b/CLAUDE.md index f03fae5336..a8ece6c322 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,6 +5,7 @@ - Never add `Co-Authored-By` trailers to commit messages. - **Goal is full http4s migration** — eliminate Lift Web and all deprecated libraries entirely. Treat Lift code as temporary scaffolding to be removed, not maintained. When fixing bugs or adding features, always prefer the http4s path. - **Versioning is tech-agnostic** — API version numbers reflect API signature changes (new/changed fields, new behaviour), never the underlying framework. A framework migration (Lift → http4s) happens in-place at the existing version; it does not justify a version bump. +- **`APIMethodsXYZ.scala` (Lift) files are the source of truth for migration.** The commented-out Lift ResourceDocs and endpoints inside each `APIMethodsXYZ.scala` are the canonical reference for what the http4s version should match: URL templates, verb casing, summaries, descriptions, example bodies, error lists, tags. **Do NOT edit these files to make the parity audit pass.** The audit compares http4s against the Lift source-of-truth — when it flags a diff, the fix is to either (a) update http4s to match Lift, or (b) document the difference at the http4s site as a known intentional drift (e.g. a placeholder rename for `ResourceDocMatcher` middleware, or an upstream-driven case-class shape change). Rewriting the Lift comments to match http4s runs the comparison backwards and destroys the historical record. See `scripts/check_lift_http4s_resource_doc_parity.py` for the audit, and `scripts/rehydrate_resource_docs.py` / `scripts/restore_resource_doc_bodies.py` for the canonical Lift → http4s restoration tools. ## Architecture (Onboarding) From e283195e1c7137fb72502abd4358db593f84c779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 13:23:08 +0200 Subject: [PATCH 08/14] scripts: evaluate chained .replace() in endpoint_name Some http4s ResourceDoc registrations derive a name programmatically, e.g. v5.0.0 Http4s500.scala:1353 uses nameOf(createConsentByConsentRequestId).replace("Id", "IdEmail") to derive the doc name `createConsentByConsentRequestIdEmail` (matching the Lift partial function of that name) without declaring a separate `lazy val`. The parity audit and the restoration tool both used to treat that whole expression as the endpoint name, which made the http4s entry impossible to match against its Lift counterpart. Extend `endpoint_name` in both scripts to evaluate any chain of `.replace("a", "b")` calls following a `nameOf(...)` or string literal base, mirroring what Scala's runtime does. After this, the 3 v5.0.0 SCA-variant docs (Email / Sms / Implicit) become directly comparable to their Lift originals. --- .../check_lift_http4s_resource_doc_parity.py | 35 +++++++++++++++---- scripts/restore_resource_doc_bodies.py | 27 +++++++++++--- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/scripts/check_lift_http4s_resource_doc_parity.py b/scripts/check_lift_http4s_resource_doc_parity.py index 43f0ad24ff..352e5e421c 100755 --- a/scripts/check_lift_http4s_resource_doc_parity.py +++ b/scripts/check_lift_http4s_resource_doc_parity.py @@ -280,14 +280,37 @@ def parse_resourcedoc(body: str): def endpoint_name(part_fn_name: str) -> str: - """`nameOf(getBanks)` -> `getBanks`. Literal `"root"` -> `root`.""" + """`nameOf(getBanks)` -> `getBanks`. Literal `"root"` -> `root`. + + Also evaluates chained `.replace("a", "b")` calls so e.g. + `nameOf(createConsentByConsentRequestId).replace("Id", "IdEmail")` + becomes `createConsentByConsentRequestIdEmail` — matches what runs at + runtime when http4s derives names for related ResourceDoc entries. + """ s = (part_fn_name or "").strip() - m = re.match(r"^nameOf\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)\s*$", s) + # First extract the base name from `nameOf(...)` or a string literal. + rest = s + m = re.match(r"^nameOf\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)", s) if m: - return m.group(1) - if s.startswith('"') and s.endswith('"'): - return s[1:-1] - return s + base = m.group(1) + rest = s[m.end():] + elif s.startswith('"'): + m2 = re.match(r'^"([^"]*)"', s) + if not m2: + return s + base = m2.group(1) + rest = s[m2.end():] + else: + return s + # Apply any trailing `.replace("a", "b")` calls in order. + rep_re = re.compile(r'^\s*\.\s*replace\s*\(\s*"([^"]*)"\s*,\s*"([^"]*)"\s*\)') + while True: + m = rep_re.match(rest) + if not m: + break + base = base.replace(m.group(1), m.group(2)) + rest = rest[m.end():] + return base def normalize(s: str) -> str: diff --git a/scripts/restore_resource_doc_bodies.py b/scripts/restore_resource_doc_bodies.py index d574977439..e7d3df6235 100644 --- a/scripts/restore_resource_doc_bodies.py +++ b/scripts/restore_resource_doc_bodies.py @@ -204,13 +204,30 @@ def parse_args(body: str): def endpoint_name(part_fn_name: str) -> str: + """Like in check_lift_http4s_resource_doc_parity.py: also evaluate + chained `.replace("a", "b")` calls so derived names match.""" s = (part_fn_name or "").strip() - m = re.match(r"^nameOf\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)\s*$", s) + rest = s + m = re.match(r"^nameOf\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)", s) if m: - return m.group(1) - if s.startswith('"') and s.endswith('"'): - return s[1:-1] - return s + base = m.group(1) + rest = s[m.end():] + elif s.startswith('"'): + m2 = re.match(r'^"([^"]*)"', s) + if not m2: + return s + base = m2.group(1) + rest = s[m2.end():] + else: + return s + rep_re = re.compile(r'^\s*\.\s*replace\s*\(\s*"([^"]*)"\s*,\s*"([^"]*)"\s*\)') + while True: + m = rep_re.match(rest) + if not m: + break + base = base.replace(m.group(1), m.group(2)) + rest = rest[m.end():] + return base def find_pair_for_version(version_dir: Path): From 98084ea8206d182bc3fde469554eb6e046bd0a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 13:23:37 +0200 Subject: [PATCH 09/14] v5.0.0: restore 4 ResourceDoc descriptions from Lift originals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run scripts/restore_resource_doc_bodies.py for v5_0_0 limited to the `description` field. Four endpoints had been migrated with a hand-shortened one-line description that drifted from the canonical Lift text in APIMethods500.scala: - createAccount (PUT /banks/.../accounts/NEW_ACCOUNT_ID) - createConsentByConsentRequestIdEmail (POST .../EMAIL/consents) - createConsentByConsentRequestIdSms (POST .../SMS/consents) - createConsentByConsentRequestIdImplicit (POST .../IMPLICIT/consents) The 3 SCA-variant docs only became matchable after the prior commit's endpoint_name fix (they use `.replace("Id", "IdEmail")` etc. to derive their name from the partial function). Remaining v5.0.0 audit diffs are now structural / functional drifts: the `ACCOUNT_ID` → `NEW_ACCOUNT_ID` placeholder rename on createAccount, the system-view endpoints' richer http4s error lists, and the `createConsentByConsentRequestIdCommonErrors` shared val pattern. These will be handled at the http4s site (either reverted to Lift or documented as intentional) rather than by editing the Lift source. --- .../scala/code/api/v5_0_0/Http4s500.scala | 65 +++++++++++++++++-- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v5_0_0/Http4s500.scala b/obp-api/src/main/scala/code/api/v5_0_0/Http4s500.scala index 23f65fc3d8..878c4d47b6 100644 --- a/obp-api/src/main/scala/code/api/v5_0_0/Http4s500.scala +++ b/obp-api/src/main/scala/code/api/v5_0_0/Http4s500.scala @@ -645,9 +645,17 @@ object Http4s500 { null, implementedInApiVersion, nameOf(createAccount), "PUT", "/banks/BANK_ID/accounts/NEW_ACCOUNT_ID", "Create Account (PUT)", """Create Account at bank specified by BANK_ID with Id specified by ACCOUNT_ID. - | - |The User can create an Account for themself - or - the User specified in the PUT body. - |If the PUT body USER_ID is specified, the logged in user must have the Role canCreateAccount.""".stripMargin, + | + |The User can create an Account for themself - or - the User that has the USER_ID specified in the POST body. + | + |If the PUT body USER_ID *is* specified, the logged in user must have the Role canCreateAccount. Once created, the Account will be owned by the User specified by USER_ID. + | + |If the PUT body USER_ID is *not* specified, the account will be owned by the logged in User. + | + |The 'product_code' field SHOULD be a product_code from Product. + |If the 'product_code' matches a product_code from Product, account attributes will be created that match the Product Attributes. + | + |Note: The Amount MUST be zero.""".stripMargin, createAccountRequestJsonV500, createAccountResponseJsonV310, List(InvalidJsonFormat, BankNotFound, AuthenticatedUserIsRequired, InvalidUserId, InvalidAccountIdFormat, InvalidBankIdFormat, UserNotFoundById, UserHasMissingRoles, @@ -1345,7 +1353,22 @@ object Http4s500 { null, implementedInApiVersion, nameOf(createConsentByConsentRequestId).replace("Id", "IdEmail"), "POST", "/consumer/consent-requests/CONSENT_REQUEST_ID/EMAIL/consents", "Create Consent By CONSENT_REQUEST_ID (EMAIL)", - "Answer a Consent Request and create the resulting Consent, with an EMAIL Strong Customer Authentication challenge.", + s""" + |Answer a Consent Request and create the resulting Consent, with an EMAIL Strong Customer Authentication challenge. + | + |After the TPP has called Create Consent Request (Client Credentials), the User authenticates and answers the request via this endpoint. This creates the Consent (the credential the consumer will use to access OBP on the User's behalf). + | + |An SCA challenge code is sent to the email address that was supplied in the Create Consent Request body. The User then completes SCA via Answer Consent Challenge, which moves the Consent from INITIATED to ACCEPTED. + | + |Pinning: the resulting Consent is pinned to a single consumer at creation. The pinned consumer is taken from the `consumer_id` field of the original Create Consent Request body if present, otherwise from the consumer that created the Request. After creation, only that consumer can present the resulting Consent JWT — any other consumer presenting it gets ConsentNotFound (consumer mismatch). + | + |Each Consent Request can be answered exactly once. A second call returns ConsentRequestIsInvalid. + | + |The Consent's authority is bounded by the answering User's own entitlements — it cannot grant access beyond what that User already has. + | + |Authentication: Any authenticated User may answer a Consent Request whose CONSENT_REQUEST_ID they know. This will be tightened in v6.0.0; until then, treat CONSENT_REQUEST_IDs as sensitive. + | + |""", EmptyBody, consentJsonV500, createConsentByConsentRequestIdCommonErrors, apiTagConsent :: apiTagPSD2AIS :: apiTagPsd2 :: apiTagVrp :: Nil, @@ -1357,7 +1380,22 @@ object Http4s500 { null, implementedInApiVersion, nameOf(createConsentByConsentRequestId).replace("Id", "IdSms"), "POST", "/consumer/consent-requests/CONSENT_REQUEST_ID/SMS/consents", "Create Consent By CONSENT_REQUEST_ID (SMS)", - "Answer a Consent Request and create the resulting Consent, with an SMS Strong Customer Authentication challenge.", + s""" + |Answer a Consent Request and create the resulting Consent, with an SMS Strong Customer Authentication challenge. + | + |After the TPP has called Create Consent Request (Client Credentials), the User authenticates and answers the request via this endpoint. This creates the Consent (the credential the consumer will use to access OBP on the User's behalf). + | + |An SCA challenge code is sent to the phone number that was supplied in the Create Consent Request body. The User then completes SCA via Answer Consent Challenge, which moves the Consent from INITIATED to ACCEPTED. + | + |Pinning: the resulting Consent is pinned to a single consumer at creation. The pinned consumer is taken from the `consumer_id` field of the original Create Consent Request body if present, otherwise from the consumer that created the Request. After creation, only that consumer can present the resulting Consent JWT — any other consumer presenting it gets ConsentNotFound (consumer mismatch). + | + |Each Consent Request can be answered exactly once. A second call returns ConsentRequestIsInvalid. + | + |The Consent's authority is bounded by the answering User's own entitlements — it cannot grant access beyond what that User already has. + | + |Authentication: Any authenticated User may answer a Consent Request whose CONSENT_REQUEST_ID they know. This will be tightened in v6.0.0; until then, treat CONSENT_REQUEST_IDs as sensitive. + | + |""", EmptyBody, consentJsonV500, ConsentRequestIsInvalid :: MissingPropsValueAtThisInstance :: SmsServerNotResponding :: createConsentByConsentRequestIdCommonErrors, apiTagConsent :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, @@ -1369,7 +1407,22 @@ object Http4s500 { null, implementedInApiVersion, nameOf(createConsentByConsentRequestId).replace("Id", "IdImplicit"), "POST", "/consumer/consent-requests/CONSENT_REQUEST_ID/IMPLICIT/consents", "Create Consent By CONSENT_REQUEST_ID (IMPLICIT)", - "Answer a Consent Request and create the resulting Consent without an SCA challenge.", + s""" + |Answer a Consent Request and create the resulting Consent, without a Strong Customer Authentication challenge — the Consent is moved directly from INITIATED to ACCEPTED. + | + |After the TPP has called Create Consent Request (Client Credentials), the User authenticates and answers the request via this endpoint. This creates the Consent (the credential the consumer will use to access OBP on the User's behalf). + | + |IMPLICIT means no SCA challenge is sent. The Consent is immediately ACCEPTED. Use only in flows where the User has already been strongly authenticated by upstream means; for production use behind a public TPP, prefer EMAIL or SMS. + | + |Pinning: the resulting Consent is pinned to a single consumer at creation. The pinned consumer is taken from the `consumer_id` field of the original Create Consent Request body if present, otherwise from the consumer that created the Request. After creation, only that consumer can present the resulting Consent JWT — any other consumer presenting it gets ConsentNotFound (consumer mismatch). + | + |Each Consent Request can be answered exactly once. A second call returns ConsentRequestIsInvalid. + | + |The Consent's authority is bounded by the answering User's own entitlements — it cannot grant access beyond what that User already has. + | + |Authentication: Any authenticated User may answer a Consent Request whose CONSENT_REQUEST_ID they know. This will be tightened in v6.0.0; until then, treat CONSENT_REQUEST_IDs as sensitive. + | + |""", EmptyBody, consentJsonV500, ConsentRequestIsInvalid :: MissingPropsValueAtThisInstance :: SmsServerNotResponding :: createConsentByConsentRequestIdCommonErrors, apiTagConsent :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, From 6ed6dda14ea62403103ed7965fcf86e3737866fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 14:13:26 +0200 Subject: [PATCH 10/14] docs(migration): add ResourceDoc parity (per-version drift from Lift) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New section under "Resource-docs (separate workstream)" capturing the state of http4s vs Lift ResourceDoc parity per version, so reviewers can see what's pending without re-running the audit script. Covers: - The source-of-truth principle (APIMethodsXYZ.scala = canonical) and the verification that the commented stub files are byte-equivalent on ResourceDoc bodies to the pre-stub live Lift code (243/243 in v6, 111/111 in v5.1). - The three scripts in `scripts/` (audit + 2 restoration tools) and what each is good for. - A per-version drift table summarising 377 outstanding mismatches across 956 endpoints. - Detailed fix candidates for v6.0.0 (12 drifts), v5.1.0 (1 drift), and v5.0.0 (8 drifts + 3 only-http4s) — each row tags whether the resolution is "fix http4s to match Lift" or "document the intentional drift at the http4s site". - Strategy summary for the untouched versions (v1.2.1 → v4.0.0). --- LIFT_HTTP4S_MIGRATION.md | 88 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/LIFT_HTTP4S_MIGRATION.md b/LIFT_HTTP4S_MIGRATION.md index 644c10d614..f734d103e3 100644 --- a/LIFT_HTTP4S_MIGRATION.md +++ b/LIFT_HTTP4S_MIGRATION.md @@ -164,6 +164,94 @@ Currently served via a raw Lift `serve { case Req(..., "openapi.yaml", ...) }` b --- +## ResourceDoc parity (per-version drift from Lift) + +Separate from the resource-docs **serving** workstream above, there is a parity workstream covering the **content** of each migrated ResourceDoc declaration. The goal is for every http4s `ResourceDoc(...)` to render identically to its Lift original, so the public API docs aren't silently degraded by migration. + +### Principle + +**`APIMethodsXYZ.scala` (Lift) is the source of truth for migration.** The commented-out Lift ResourceDocs and endpoints inside each `APIMethodsXYZ.scala` are the canonical reference for what the http4s version should render: URL templates, verb casing, summaries, descriptions, example bodies, error lists, tags. **Do NOT edit these files to make the audit pass** — the audit compares http4s against the Lift source-of-truth. When the audit flags a diff, the resolution is either (a) update http4s to match Lift, or (b) document the difference at the http4s site as a known intentional drift (placeholder rename for middleware, upstream-driven case-class shift, etc.). Rewriting the Lift comments runs the comparison backwards and erases the historical record. (Mistakes in commits `d95c1df01` and `6154bf2cc` did this; reverted in `27f48af72`.) + +**Stub fidelity verified.** Commits `810589330` (v6) and `88f46f854` (v5.1) replaced the live Lift code with commented-out stubs. Comparing each stub's uncommented ResourceDoc bodies against the pre-stub live versions: **0 field diffs across 243/243 v6 docs and 111/111 v5.1 docs**. The non-ResourceDoc deltas (imports, etc., ~16KB v6 / ~5KB v5.1) are immaterial. The stubs are an exact preservation of the original Lift ResourceDocs. + +### Tooling (`scripts/`) + +| Script | Role | +|---|---| +| `check_lift_http4s_resource_doc_parity.py` | Read-only audit. Parses both files, matches by `nameOf(...)` (with `.replace("a","b")` evaluation for derived names), reports per-field diffs. `--field=X` to focus, `--list-only` for endpoint-presence summary. | +| `rehydrate_resource_docs.py` | Upstream (simonredfern, `67593ea28`). Lifts positional args 7/8/9 (description, exampleRequestBody, successResponseBody) from commented Lift blocks into http4s. Has a `split-init` subcommand for JVM 64KB method-size workaround. | +| `restore_resource_doc_bodies.py` | Companion to the above. Restores any subset of (summary, description, exampleRequestBody, successResponseBody, errorResponseBodies, tags) from Lift into http4s. Surgical per-field replacement preserves layout. `--fields=X,Y` to scope, `--only=ep` to target one endpoint. | + +### Current drift (audit re-run 2026-05-21 evening) + +| Version | shared | mismatch | only-lift | only-http4s | Status | +|---|---|---|---|---|---| +| v1_2_1 | 70 | 48 | 0 | 0 | not started | +| v1_3_0 | 3 | 0 | 0 | 0 | clean | +| v1_4_0 | 10 | 1 | 0 | 0 | one minor | +| v2_0_0 | 37 | 19 | 0 | 0 | not started | +| v2_1_0 | 23 | 13 | 5 | 2 | not started | +| v2_2_0 | 18 | 13 | 0 | 0 | not started | +| v3_0_0 | 47 | 41 | 0 | 0 | not started | +| v3_1_0 | 102 | 49 | 0 | 0 | not started | +| v4_0_0 | 254 | 172| 2 | 5 | not started | +| v5_0_0 | 39 | 8 | 0 | 3 | descriptions restored; structural/errors remain | +| v5_1_0 | 111 | 1 | 1 | 2 | one verb-casing drift to fix | +| v6_0_0 | 243 | 12 | 0 | 1 | 11 placeholder renames + 1 routing-shape upstream change | +| **Total** | **956** | **377** | | | | + +### v6.0.0 — 12 specific drifts (each is a fix candidate) + +These are the cases where http4s deviates from Lift. Under the source-of-truth rule, the default is to fix http4s; deliberate exceptions need to be documented at the http4s site. + +| Endpoint | Field | Lift | http4s | Resolution | +|---|---|---|---|---| +| `createCounterpartyAttribute` | requestUrl | `…/counterparties/COUNTERPARTY_ID/attributes` | `…/COUNTERPARTY_ID_PARAM/…` | TBD — verify `ResourceDocMatcher` correctly handles `COUNTERPARTY_ID` as a wildcard (the literal set contains `COUNTERPARTY`, but `COUNTERPARTY_ID` is whole-segment-different). If safe, revert to Lift's name. | +| `deleteCounterpartyAttribute` | requestUrl | same | same | same as above | +| `getAllCounterpartyAttributes` | requestUrl | same | same | same as above | +| `getCounterpartyAttributeById` | requestUrl | same | same | same as above | +| `updateCounterpartyAttribute` | requestUrl | same | same | same as above | +| `createTransactionRequestCardano` | requestUrl | `…/ACCOUNT_ID/owner/transaction-request-types/CARDANO/…` | `…/ACCOUNT_ID/VIEW_ID/…/CARDANO/…` | **Functional broadening** — http4s lets any view, Lift hardcoded `owner`. Keep http4s; document at the http4s ResourceDoc site. | +| `createTransactionRequestHold` | requestUrl | `…/owner/…HOLD/…` | `…/VIEW_ID/…HOLD/…` | same as above | +| `getSystemViewById` | requestUrl | `/management/system-views/VIEW_ID` | `/management/system-views/SYS_VIEW_ID` | TBD — disambiguation rename. If `ResourceDocMatcher` handles both fine, revert. | +| `updateSystemView` | requestUrl | `/system-views/VIEW_ID` | `/system-views/UPD_VIEW_ID` | same as above | +| `removeBankReaction` | requestUrl | `…/reactions/EMOJI` | `…/reactions/EMOJI_REACTION` | `EMOJI` is NOT in `literalAllCapsSegments` (only `EMAIL`/`SMS`/`IMPLICIT` of the SCA cluster are). Rename may have been defensive; safe to revert. | +| `removeSystemReaction` | requestUrl | same | same | same as above | +| `getAccountDirectory` | successResponseBody | `FastFirehoseRoutings(bank_id, account_id)` | `AccountRoutingJsonV121(scheme, address)` | **Upstream functional change** (`9e151c524` / `9dc4c4c46` migrated the case class). Cannot revert; document. Also note: the same change broke `mvn test` (pre-existing upstream compile error in `JSONFactory6.0.0.scala:2934`). | + +Also: 1 only-http4s (`createWebUiProps`) — genuinely http4s-only with no Lift counterpart. Document. + +### v5.1.0 — 1 specific drift + +| Endpoint | Field | Lift | http4s | Resolution | +|---|---|---|---|---| +| `revokeMyConsent` | requestVerb | `"Delete"` | `"DELETE"` | Trivial casing fix on the http4s side. | + +Also: +- 1 only-lift (`createConsentImplicit`) + 1 only-http4s (`createConsent`) — Lift had `lazy val createConsentImplicit = createConsent` aliasing and registered the doc under the alias; http4s registers under the canonical name. Fix: in http4s, either rename the partial function to `createConsentImplicit` to match Lift, or register a second `nameOf(createConsentImplicit)` doc for the same handler. +- 1 only-http4s (`getBanks`) — kept in the v5.1.0 layer for metrics attribution (intentional addition; see comment at `Http4s510.scala:288`). Document. + +### v5.0.0 — 8 specific drifts + 3 only-http4s + +| Category | Count | Endpoints | Resolution | +|---|---|---|---| +| requestUrl placeholder rename | 1 | `createAccount` (Lift `ACCOUNT_ID` → http4s `NEW_ACCOUNT_ID` for the PUT-creates pattern) | Verify matcher behavior; may be required for `ACCOUNT_ID` literal handling. | +| errorResponseBodies — SCA val-vs-inline | 3 | `createConsentByConsentRequestIdEmail` / `Sms` / `Implicit` | http4s uses `private val createConsentByConsentRequestIdCommonErrors = List(...)` for DRY; Lift inlined the list. Either inline the val in the 3 doc registrations to match Lift verbatim, or extend the audit script to expand simple `val X = List(...)` references. | +| errorResponseBodies — system-view accuracy | 4 | `createSystemView`, `deleteSystemView`, `getSystemView`, `updateSystemView` | http4s has more accurate errors (`SystemViewNotFound`, `SystemViewCannotBePublicError`, `InvalidSystemViewFormat`). Lift had wrong/legacy errors (`BankAccountNotFound`, `$BankNotFound`, `"user does not have owner access"`). **Genuine improvement** — document at http4s site. | + +Also: 3 only-http4s (`getBanks`, `getProduct`, `getProducts`) — kept in this layer for metrics attribution. Document. + +### Strategy summary + +For each remaining drift on a migrated version: +1. **Default**: fix http4s to match Lift verbatim. Use `restore_resource_doc_bodies.py` for field-level restoration. +2. **Documented exceptions**: where the drift is a deliberate http4s improvement or required by middleware semantics, leave the drift and add a `// Lift had X; we use Y because Z` comment at the http4s ResourceDoc site. +3. **Never**: edit `APIMethodsXYZ.scala` to make the audit pass. The Lift comments are the canonical record. + +Untouched versions (v1_2_1 through v4_0_0, plus v2_1_0) need the same treatment: run `rehydrate_resource_docs.py` then `restore_resource_doc_bodies.py`, then audit and address any residual drifts at the http4s site. + +--- + ## Auth Stack (separate workstream) Token-generation paths — not version-file endpoints. Each `extends RestHelper` and needs to become an http4s route or middleware independently. Can run in parallel with the APIMethods migration. From 2b24811e5156992a3b86cfbd8636542856eeb36f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 14:33:40 +0200 Subject: [PATCH 11/14] v4.0.0: bring ResourceDoc parity from 172 to 20 mismatches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run upstream's rehydrate_resource_docs.py + scripts/restore_resource_doc_bodies.py against APIMethods400.scala (source of truth) to restore the canonical Lift descriptions, request/response examples, error lists, summaries, and tags into Http4s400.scala. 152 fields rewritten across: description: 134 (134 → 0) errorResponseBodies: 70 (70 → 0) successResponseBody: 20 (20 → 0) exampleRequestBody: 9 (9 → 0) tags: 8 (8 → 0) summary: 6 (6 → 0) Supporting code carried over from the pre-stub APIMethods400.scala so the restored descriptions compile: - Imports: getGlossaryItem, ConsumerPostJSON, ConsentChallengeJsonV310, PractiseEndpoint, LocalMappedConnectorInternal._ (for transactionRequestGeneralText), ConsentStatus, the SwaggerDefinitionsJSON object itself (not just the wildcard), the three commons enums AttributeCategory / AttributeType / UserInvitationPurpose, java.util.Date. - Four private vals carried over verbatim (used inside `s"""..."""` doc interpolations): productAttributeGeneralInfo, customerAttributeGeneralInfo, generalWebHookInfo, accountNotificationWebhookInfo. Remaining 20 audit diffs are all structural / functional drifts: requestVerb: 1 — deleteExplicitCounterparty (Lift POST → http4s DELETE, a legitimate REST fix) requestUrl: 20 — placeholder renames for ResourceDocMatcher compatibility / disambiguation: 9× VIEW_ID → GRANT_VIEW_ID (transaction-request variants + the answer-challenge endpoint) 6× DYNAMIC-RESOURCE-DOC-ID → DYNAMIC_RESOURCE_DOC_ID (hyphen→underscore so it matches an ALL_CAPS wildcard segment) 2× COUNTERPARTY_ID → COUNTERPARTY_ID_PARAM (deleteExplicit, getById-for-any-account) 1× COUNTERPARTY_ID → EXPLICIT_COUNTERPARTY_ID (getExplicitCounterpartyById) 1× /banks/BANK_ID/firehose/accounts/views/VIEW_ID → /banks/FIREHOSE_BANK_ID/firehose/accounts/views/FIREHOSE_VIEW_ID (firehose prop-check-before-bank-lookup pattern, see CLAUDE.md firehose gotcha) 1× /banks/BANK_ID/CUSTOMER_ID/attributes/CUSTOMER_ATTRIBUTE_ID → /banks/BANK_ID/customers/attributes/CUSTOMER_ATTRIBUTE_ID (deleteCustomerAttribute — http4s URL fix; Lift's URL was malformed) These 20 will be addressed by either reverting the http4s rename (where ResourceDocMatcher tolerates it) or documenting at the http4s site (where the rename is required for middleware or is a deliberate URL fix). Per the source-of-truth rule, APIMethods400.scala is NOT modified. --- .../scala/code/api/v4_0_0/Http4s400.scala | 5424 +++++++++++++---- 1 file changed, 4077 insertions(+), 1347 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v4_0_0/Http4s400.scala b/obp-api/src/main/scala/code/api/v4_0_0/Http4s400.scala index 801eaaf40f..0c81d21591 100644 --- a/obp-api/src/main/scala/code/api/v4_0_0/Http4s400.scala +++ b/obp-api/src/main/scala/code/api/v4_0_0/Http4s400.scala @@ -3,6 +3,7 @@ package code.api.v4_0_0 import cats.data.{Kleisli, OptionT} import cats.effect._ import code.api.Constant._ +import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ import code.api.util.APIUtil.{EmptyBody, ResourceDoc, _} import code.api.util.ApiRole._ @@ -10,7 +11,15 @@ import code.api.util.ApiTag._ import code.api.util.ErrorMessages._ import code.api.util.ExampleValue._ import code.api.util.Glossary +import code.api.util.Glossary.getGlossaryItem import code.api.Constant +import code.api.v2_1_0.ConsumerPostJSON +import code.api.v3_1_0.ConsentChallengeJsonV310 +import code.api.dynamic.endpoint.helper.practise.PractiseEndpoint +import code.bankconnectors.LocalMappedConnectorInternal._ +import code.consent.ConsentStatus +import com.openbankproject.commons.model.enums.{AttributeCategory, AttributeType, UserInvitationPurpose} +import java.util.Date import code.api.dynamic.endpoint.helper.DynamicEndpointHelper import code.api.dynamic.entity.helper.DynamicEntityInfo import code.api.util.{ApiRole => ApiRoleObj} @@ -96,6 +105,59 @@ object Http4s400 { type HttpF[A] = OptionT[IO, A] + // Local doc-strings carried over from the pre-stub APIMethods400.scala so the + // restored ResourceDoc descriptions compile. Kept verbatim — these are + // referenced inside `s"""..."""` interpolations in the doc text. + private val productAttributeGeneralInfo = + s""" + |Product Attributes are used to describe a financial Product with a list of typed key value pairs. + | + |Each Product Attribute is linked to its Product by PRODUCT_CODE + | + | + """.stripMargin + + private val customerAttributeGeneralInfo = + s""" + |CustomerAttributes are used to enhance the OBP Customer object with Bank specific entities. + | + """.stripMargin + + private val generalWebHookInfo = s""" + |Webhooks are used to call external web services when certain events happen. + | + |For instance, a webhook can be used to notify an external service if a transaction is created on an account. + | + |""" + + private val accountNotificationWebhookInfo = s""" + |When an account notification webhook fires it will POST to the URL you specify during the creation of the webhook. + | + |Inside the payload you will find account_id and transaction_id and also user_ids and customer_ids of the Users / Customers linked to the Account. + | | + |The webhook will POST the following structure to your service: + | + |{ + | "event_name": "OnCreateTransaction", + | "event_id": "9ca9a7e4-6d02-40e3-a129-0b2bf89de9b1", + | "bank_id": "gh.29.uk", + | "account_id": "8ca9a7e4-6d02-40e3-a129-0b2bf89de9b1", + | "transaction_id": "7ca9a7e4-6d02-40e3-a129-0b2bf89de9b1", + | "related_entities": [ + | { + | "user_id": "8ca9a7e4-6d02-40e3-a129-0b2bf89de9b1", + | "customer_ids": ["3ca9a7e4-6d02-40e3-a129-0b2bf89de9b1"] + | } + | ] + |} + | + |Thus, your service should accept the above POST body structure. + | + |In this way, your web service can be informed about an event on an account and act accordingly. + | + |Further information about the account, transaction or related entities can then be retrieved using the standard REST APIs. + |""" + object Implementations4_0_0 { // Expose as a member so ResourceDocsAPIMethods can access it via APIMethods400.Implementations4_0_0.implementedInApiVersion val implementedInApiVersion: com.openbankproject.commons.util.ScannedApiVersion = Http4s400.implementedInApiVersion @@ -113,16 +175,24 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMapperDatabaseInfo), "GET", + null, + implementedInApiVersion, + nameOf(getMapperDatabaseInfo), + "GET", "/database/info", "Get Mapper Database Info", s"""Get basic information about the Mapper Database. | - |${userAuthenticationMessage(true)}""", - EmptyBody, adapterInfoJsonV300, - List(AuthenticatedUserIsRequired, UnknownError), - List(apiTagApi), Some(List(canGetDatabaseInfo)), - http4sPartialFunction = Some(getMapperDatabaseInfo)) + |${userAuthenticationMessage(true)} + | + """.stripMargin, + EmptyBody, + adapterInfoJsonV300, + List($AuthenticatedUserIsRequired, UnknownError), + List(apiTagApi), + Some(List(canGetDatabaseInfo)), + http4sPartialFunction = Some(getMapperDatabaseInfo) + ) // ─── getLogoutLink ──────────────────────────────────────────────────────── @@ -137,16 +207,23 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getLogoutLink), "GET", + null, + implementedInApiVersion, + nameOf(getLogoutLink), + "GET", "/users/current/logout-link", "Get Logout Link", s"""Get the Logout Link | - |${userAuthenticationMessage(true)}""", - EmptyBody, logoutLinkV400, - List(AuthenticatedUserIsRequired, UnknownError), - List(apiTagUser), None, - http4sPartialFunction = Some(getLogoutLink)) + |${userAuthenticationMessage(true)} + """.stripMargin, + EmptyBody, + logoutLinkV400, + List($AuthenticatedUserIsRequired, UnknownError), + List(apiTagUser), + None, + http4sPartialFunction = Some(getLogoutLink) + ) // ─── getBanks ───────────────────────────────────────────────────────────── // v4.0.0 overrides v3.x getBanks — v4 uses createBanksJson which adds attributes. @@ -161,15 +238,26 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBanks), "GET", + null, + implementedInApiVersion, + nameOf(getBanks), + "GET", "/banks", "Get Banks", """Get banks on this API instance - |Returns a list of banks supported on this server.""".stripMargin, - EmptyBody, banksJSON400, + |Returns a list of banks supported on this server: + | + |* ID used as parameter in URLs + |* Short and full name of bank + |* Logo URL + |* Website""", + EmptyBody, + banksJSON400, List(UnknownError), - apiTagBank :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, - http4sPartialFunction = Some(getBanks)) + apiTagBank :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, + None, + http4sPartialFunction = Some(getBanks) + ) // ─── getBank ────────────────────────────────────────────────────────────── // v4.0.0 overrides v3.x getBank — v4 includes bank attributes. @@ -184,14 +272,25 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBank), "GET", + null, + implementedInApiVersion, + nameOf(getBank), + "GET", "/banks/BANK_ID", "Get Bank", - """Get the bank specified by BANK_ID.""".stripMargin, - EmptyBody, bankJson400, + """Get the bank specified by BANK_ID + |Returns information about a single bank specified by BANK_ID including: + | + |* Short and full name of bank + |* Logo URL + |* Website""", + EmptyBody, + bankJson400, List(UnknownError, BankNotFound), - apiTagBank :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, - http4sPartialFunction = Some(getBank)) + apiTagBank :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, + None, + http4sPartialFunction = Some(getBank) + ) // ─── ibanChecker (POST → 200) ───────────────────────────────────────────── @@ -205,14 +304,22 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(ibanChecker), "POST", + null, + implementedInApiVersion, + nameOf(ibanChecker), + "POST", "/account/check/scheme/iban", "Validate and check IBAN", - """Validate and check IBAN for errors""", - ibanCheckerPostJsonV400, ibanCheckerJsonV400, + """Validate and check IBAN for errors + | + |""", + ibanCheckerPostJsonV400, + ibanCheckerJsonV400, List(UnknownError), - apiTagAccount :: Nil, None, - http4sPartialFunction = Some(ibanChecker)) + apiTagAccount :: Nil, + None, + http4sPartialFunction = Some(ibanChecker) + ) // ─── callsLimit (PUT → 200) ─────────────────────────────────────────────── // v4.0.0 overrides v3.1.0 — v4 takes additional api_version / api_name / bank_id fields @@ -241,18 +348,35 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(callsLimit), "PUT", + null, + implementedInApiVersion, + nameOf(callsLimit), + "PUT", "/management/consumers/CONSUMER_ID/consumer/call-limits", "Set Rate Limits / Call Limits per Consumer", - s"""Set the API rate limits / call limits for a Consumer. - | - |${userAuthenticationMessage(true)}""", - callLimitPostJsonV400, callLimitPostJsonV400, + s""" + |Set the API rate limits / call limits for a Consumer: + | + |Rate limiting can be set: + | + |Per Second + |Per Minute + |Per Hour + |Per Week + |Per Month + | + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + callLimitPostJsonV400, + callLimitPostJsonV400, List(AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidConsumerId, - ConsumerNotFoundByConsumerId, UserHasMissingRoles, UpdateConsumerError, UnknownError), + ConsumerNotFoundByConsumerId, UserHasMissingRoles, UpdateConsumerError, UnknownError), List(apiTagConsumer, apiTagRateLimits), Some(List(canUpdateRateLimits)), - http4sPartialFunction = Some(callsLimit)) + http4sPartialFunction = Some(callsLimit) + ) // ─── createBank (POST → 201) ────────────────────────────────────────────── // v4 overrides v2.2.0's createBank — v4 grants CanCreateEntitlementAtOneBank + @@ -315,11 +439,24 @@ object Http4s400 { "/banks", "Create Bank", s"""Create a new bank (Authenticated access). - | - |The user creating this will be automatically assigned the Role CanCreateEntitlementAtOneBank.""", + | + |The user creating this will be automatically assigned the Role CanCreateEntitlementAtOneBank. + |Thus the User can manage the bank they create and assign Roles to other Users. + | + |Only SANDBOX mode (i.e. when connector=mapped in properties file) + |The settlement accounts are automatically created by the system when the bank is created. + |Name and account id are created in accordance to the next rules: + | - Incoming account (name: Default incoming settlement account, Account ID: OBP_DEFAULT_INCOMING_ACCOUNT_ID, currency: EUR) + | - Outgoing account (name: Default outgoing settlement account, Account ID: OBP_DEFAULT_OUTGOING_ACCOUNT_ID, currency: EUR) + | + |""", postBankJson400, bankJson400, - List(InvalidJsonFormat, AuthenticatedUserIsRequired, - InsufficientAuthorisationToCreateBank, UnknownError), + List( + InvalidJsonFormat, + $AuthenticatedUserIsRequired, + InsufficientAuthorisationToCreateBank, + UnknownError + ), List(apiTagBank), Some(List(canCreateBank)), http4sPartialFunction = Some(createBank)) @@ -340,16 +477,26 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(root), "GET", "/root", + null, + implementedInApiVersion, + nameOf(root), + "GET", + "/root", "Get API Info (root)", """Returns information about: - | - |* API version - |* Hosted by information - |* Git Commit""", - EmptyBody, apiInfoJson400, - List(UnknownError, MandatoryPropertyIsNotSet), apiTagApi :: Nil, None, - http4sPartialFunction = Some(root)) + | + |* API version + |* Hosted by information + |* Hosted at information + |* Energy source information + |* Git Commit""", + EmptyBody, + apiInfoJson400, + List(UnknownError, MandatoryPropertyIsNotSet), + apiTagApi :: Nil, + None, + http4sPartialFunction = Some(root) + ) // ─── getAtms (GET) — v4 override; conditional auth via getAtmsIsPublic ─── @@ -378,16 +525,35 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAtms), "GET", + null, + implementedInApiVersion, + nameOf(getAtms), + "GET", "/banks/BANK_ID/atms", "Get Bank ATMS", - s"""Returns information about ATMs for a single bank specified by BANK_ID. - | - |${userAuthenticationMessage(!getAtmsIsPublic)}""".stripMargin, - EmptyBody, atmsJsonV400, - List(AuthenticatedUserIsRequired, BankNotFound, InvalidJsonFormat, UnknownError), - List(apiTagATM), None, - http4sPartialFunction = Some(getAtms)) + s"""Returns information about ATMs for a single bank specified by BANK_ID including: + | + |* Address + |* Geo Location + |* License the data under this endpoint is released under + | + |Pagination: + | + |By default, 100 records are returned. + | + |You can use the url query parameters *limit* and *offset* for pagination + | + |${userAuthenticationMessage(!getAtmsIsPublic)}""".stripMargin, + EmptyBody, + atmsJsonV400, + List( + $BankNotFound, + UnknownError + ), + List(apiTagATM), + None, + http4sPartialFunction = Some(getAtms) + ) // ─── getAtm (GET) — v4 override; conditional auth ──────────────────────── @@ -401,16 +567,30 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAtm), "GET", + null, + implementedInApiVersion, + nameOf(getAtm), + "GET", "/banks/BANK_ID/atms/ATM_ID", "Get Bank ATM", - s"""Returns information about ATM for a single bank specified by BANK_ID and ATM_ID. - | - |${userAuthenticationMessage(!getAtmsIsPublic)}""".stripMargin, - EmptyBody, atmJsonV400, - List(AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagATM), None, - http4sPartialFunction = Some(getAtm)) + s"""Returns information about ATM for a single bank specified by BANK_ID and ATM_ID including: + | + |* Address + |* Geo Location + |* License the data under this endpoint is released under + |${userAuthenticationMessage(!getAtmsIsPublic)} + |""".stripMargin, + EmptyBody, + atmJsonV400, + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + UnknownError + ), + List(apiTagATM), + None, + http4sPartialFunction = Some(getAtm) + ) // ─── getProducts (GET) — v4 override; conditional auth ─────────────────── @@ -428,16 +608,40 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getProducts), "GET", + null, + implementedInApiVersion, + nameOf(getProducts), + "GET", "/banks/BANK_ID/products", "Get Products", - s"""Returns information about the financial products offered by a bank specified by BANK_ID. - | - |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, - EmptyBody, productsJsonV400, - List(AuthenticatedUserIsRequired, BankNotFound, ProductNotFoundByProductCode, UnknownError), - List(apiTagProduct), None, - http4sPartialFunction = Some(getProducts)) + s"""Returns information about the financial products offered by a bank specified by BANK_ID including: + | + |* Name + |* Code + |* Parent Product Code + |* More info URL + |* Terms And Conditions URL + |* Description + |* Terms and Conditions + |* License the data under this endpoint is released under + | + |The combination of bank_id and product_code is unique. + | + |Can filter with attributes name and values. + |URL params example: /banks/some-bank-id/products?&limit=50&offset=1 + | + |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, + EmptyBody, + productsJsonV400, + List( + AuthenticatedUserIsRequired, + BankNotFound, + UnknownError + ), + List(apiTagProduct), + None, + http4sPartialFunction = Some(getProducts) + ) // ─── getProduct (GET) — v4 override; loads attributes + fees ───────────── @@ -455,16 +659,40 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getProduct), "GET", + null, + implementedInApiVersion, + nameOf(getProduct), + "GET", "/banks/BANK_ID/products/PRODUCT_CODE", "Get Bank Product", - s"""Returns information about a financial Product offered by the bank specified by BANK_ID and PRODUCT_CODE. - | - |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, - EmptyBody, productJsonV400, - List(AuthenticatedUserIsRequired, BankNotFound, ProductNotFoundByProductCode, UnknownError), - List(apiTagProduct), None, - http4sPartialFunction = Some(getProduct)) + s"""Returns information about a financial Product offered by the bank specified by BANK_ID and PRODUCT_CODE including: + | + |* Name + |* Code + |* Parent Product Code + |* More info URL + |* Description + |* Terms and Conditions + |* Description + |* Meta + |* Attributes + |* Fees + | + |The combination of bank_id and product_code is unique. + | + |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, + EmptyBody, + productJsonV400, + List( + AuthenticatedUserIsRequired, + $BankNotFound, + ProductNotFoundByProductCode, + UnknownError + ), + List(apiTagProduct), + None, + http4sPartialFunction = Some(getProduct) + ) // ─── createAtm (POST → 201) — v4 override ───────────────────────────────── @@ -502,7 +730,11 @@ object Http4s400 { "Create ATM", s"""Create ATM.""", atmJsonV400, atmJsonV400, - List(AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + UnknownError + ), List(apiTagATM), Some(List(canCreateAtm, canCreateAtmAtAnyBank)), http4sPartialFunction = Some(createAtm)) @@ -548,17 +780,42 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createProduct), "PUT", + null, + implementedInApiVersion, + nameOf(createProduct), + "PUT", "/banks/BANK_ID/products/PRODUCT_CODE", "Create Product", s"""Create or Update Product for the Bank. - | - |${userAuthenticationMessage(true)}""", - putProductJsonV400, productJsonV400.copy(attributes = None, fees = None), - List(AuthenticatedUserIsRequired, BankNotFound, UserHasMissingRoles, UnknownError), + | + | + |Typical Super Family values / Asset classes are: + | + |Debt + |Equity + |FX + |Commodity + |Derivative + | + |$productHiearchyAndCollectionNote + | + | + |${userAuthenticationMessage(true)} + | + | + |""", + putProductJsonV400, + productJsonV400.copy(attributes = None, fees = None), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + UserHasMissingRoles, + UnknownError + ), List(apiTagProduct), Some(List(canCreateProduct, canCreateProductAtAnyBank)), - http4sPartialFunction = Some(createProduct)) + http4sPartialFunction = Some(createProduct) + ) // ─── createProductAttribute (POST → 201) — v4 override ──────────────────── @@ -581,17 +838,44 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createProductAttribute), "POST", + null, + implementedInApiVersion, + nameOf(createProductAttribute), + "POST", "/banks/BANK_ID/products/PRODUCT_CODE/attribute", "Create Product Attribute", - s"""Create a Product Attribute. - | - |${userAuthenticationMessage(true)}""", - productAttributeJsonV400, productAttributeResponseJsonV400, + s""" Create Product Attribute + | + |$productAttributeGeneralInfo + | + |Typical product attributes might be: + | + |ISIN (for International bonds) + |VKN (for German bonds) + |REDCODE (markit short code for credit derivative) + |LOAN_ID (e.g. used for Anacredit reporting) + | + |ISSUE_DATE (When the bond was issued in the market) + |MATURITY_DATE (End of life time of a product) + |TRADABLE + | + |See [FPML](http://www.fpml.org/) for more examples. + | + | + |The type field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + | + | + |${userAuthenticationMessage(true)} + | + |""", + productAttributeJsonV400, + productAttributeResponseJsonV400, List(InvalidJsonFormat, UnknownError), List(apiTagProduct, apiTagProductAttribute, apiTagAttribute), Some(List(canCreateProductAttribute)), - http4sPartialFunction = Some(createProductAttribute)) + http4sPartialFunction = Some(createProductAttribute) + ) // ─── updateProductAttribute (PUT → 200) — v4 override ───────────────────── @@ -614,17 +898,29 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateProductAttribute), "PUT", + null, + implementedInApiVersion, + nameOf(updateProductAttribute), + "PUT", "/banks/BANK_ID/products/PRODUCT_CODE/attributes/PRODUCT_ATTRIBUTE_ID", "Update Product Attribute", - s"""Update one Product Attribute by its id. - | - |${userAuthenticationMessage(true)}""", - productAttributeJsonV400, productAttributeResponseJsonV400, + s""" Update Product Attribute. + | + + |$productAttributeGeneralInfo + | + |Update one Product Attribute by its id. + | + |${userAuthenticationMessage(true)} + | + |""", + productAttributeJsonV400, + productAttributeResponseJsonV400, List(UserHasMissingRoles, UnknownError), List(apiTagProduct, apiTagProductAttribute, apiTagAttribute), Some(List(canUpdateProductAttribute)), - http4sPartialFunction = Some(updateProductAttribute)) + http4sPartialFunction = Some(updateProductAttribute) + ) // ─── getEntitlements (GET /users/USER_ID/entitlements) — v4 override ──── @@ -651,9 +947,12 @@ object Http4s400 { null, implementedInApiVersion, "getEntitlements", "GET", "/users/USER_ID/entitlements", "Get Entitlements for User", - "", + s""" + | + | + """.stripMargin, EmptyBody, entitlementsJsonV400, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagRole, apiTagEntitlement, apiTagUser), Some(List(canGetEntitlementsForAnyUserAtAnyBank)), http4sPartialFunction = Some(getEntitlements)) @@ -689,7 +988,12 @@ object Http4s400 { | |CanGetAnyUser entitlement is required,""", EmptyBody, userJsonV400, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, UserNotFoundByUserId, UnknownError), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UserNotFoundById, + UnknownError + ), List(apiTagUser), Some(List(canGetAnyUser)), http4sPartialFunction = Some(getUserByUserId)) @@ -720,8 +1024,12 @@ object Http4s400 { | |CanGetAnyUser entitlement is required,""", EmptyBody, userJsonV400, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, - UserNotFoundByProviderAndUsername, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UserNotFoundByProviderAndUsername, + UnknownError + ), List(apiTagUser), Some(List(canGetAnyUser)), http4sPartialFunction = Some(getUserByUsername)) @@ -746,7 +1054,12 @@ object Http4s400 { |${userAuthenticationMessage(true)} |CanGetAnyUser entitlement is required,""", EmptyBody, usersJsonV400, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, UserNotFoundByEmail, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UserNotFoundByEmail, + UnknownError + ), List(apiTagUser), Some(List(canGetAnyUser)), http4sPartialFunction = Some(getUsersByEmail)) @@ -776,9 +1089,18 @@ object Http4s400 { | |${userAuthenticationMessage(true)} | - |CanGetAnyUser entitlement is required,""", + |CanGetAnyUser entitlement is required, + | + |${urlParametersDocument(false, false)} + |* locked_status (if null ignore) + | + """.stripMargin, EmptyBody, usersJsonV400, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), List(apiTagUser), Some(List(canGetAnyUser)), http4sPartialFunction = Some(getUsers)) @@ -809,10 +1131,21 @@ object Http4s400 { null, implementedInApiVersion, "getCustomersByAttributes", "GET", "/banks/BANK_ID/customers", "Get Customers by ATTRIBUTES", - "Gets the Customers specified by attributes", + s"""Gets the Customers specified by attributes + | + |URL params example: /banks/some-bank-id/customers?name=John&age=8 + |URL params example: /banks/some-bank-id/customers?&limit=50&offset=1 + | + | + |""", EmptyBody, ListResult("customers", List(customerWithAttributesJsonV310)), - List(AuthenticatedUserIsRequired, BankNotFound, UserCustomerLinksNotFoundForUser, UnknownError), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + UserCustomerLinksNotFoundForUser, + UnknownError + ), List(apiTagCustomer), Some(List(canGetCustomersAtOneBank)), http4sPartialFunction = Some(getCustomersByAttributes)) @@ -845,20 +1178,36 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createCustomer), "POST", + null, + implementedInApiVersion, + nameOf(createCustomer), + "POST", "/banks/BANK_ID/customers", "Create Customer", - s"""The Customer resource stores the customer number (set by backend), legal name, email, phone number, date of birth, etc. - | - |${userAuthenticationMessage(true)}""", - code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.postCustomerJsonV310, - code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.customerJsonV310, - List(AuthenticatedUserIsRequired, BankNotFound, InvalidJsonFormat, - CustomerNumberAlreadyExists, UserNotFoundById, CustomerAlreadyExistsForUser, - CreateCustomerError, UnknownError), + s""" + |The Customer resource stores the customer number (which is set by the backend), legal name, email, phone number, their date of birth, relationship status, education attained, a url for a profile image, KYC status etc. + |Dates need to be in the format 2013-01-21T23:08:00Z + | + |Note: If you need to set a specific customer number, use the Update Customer Number endpoint after this call. + | + |${userAuthenticationMessage(true)} + |""", + postCustomerJsonV310, + customerJsonV310, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + InvalidJsonFormat, + CustomerNumberAlreadyExists, + UserNotFoundById, + CustomerAlreadyExistsForUser, + CreateConsumerError, + UnknownError + ), List(apiTagCustomer, apiTagPerson), Some(List(canCreateCustomer, canCreateCustomerAtAnyBank)), - http4sPartialFunction = Some(createCustomer)) + http4sPartialFunction = Some(createCustomer) + ) // ─── getBankAccountsBalancesForCurrentUser (GET /banks/BANK_ID/balances) — v4 @@ -873,14 +1222,20 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBankAccountsBalancesForCurrentUser), "GET", + null, + implementedInApiVersion, + nameOf(getBankAccountsBalancesForCurrentUser), + "GET", "/banks/BANK_ID/balances", "Get Accounts Balances", - "Get the Balances for the Accounts of the current User at one bank.", - EmptyBody, accountBalancesV400Json, - List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), - apiTagAccount :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, - http4sPartialFunction = Some(getBankAccountsBalancesForCurrentUser)) + """Get the Balances for the Accounts of the current User at one bank.""", + EmptyBody, + accountBalancesV400Json, + List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), + apiTagAccount :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, + None, + http4sPartialFunction = Some(getBankAccountsBalancesForCurrentUser) + ) // ─── getCoreAccountById (GET /my/banks/BANK_ID/accounts/ACCOUNT_ID/account) @@ -903,16 +1258,34 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCoreAccountById), "GET", + null, + implementedInApiVersion, + nameOf(getCoreAccountById), + "GET", "/my/banks/BANK_ID/accounts/ACCOUNT_ID/account", "Get Account by Id (Core)", - s"""Information returned about the account specified by ACCOUNT_ID. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, moderatedCoreAccountJsonV400, - List(AuthenticatedUserIsRequired, BankAccountNotFound, UnknownError), - apiTagAccount :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, - http4sPartialFunction = Some(getCoreAccountById)) + s"""Information returned about the account specified by ACCOUNT_ID: + | + |* Number - The human readable account number given by the bank that identifies the account. + |* Label - A label given by the owner of the account + |* Owners - Users that own this account + |* Type - The type of account + |* Balance - Currency and Value + |* Account Routings - A list that might include IBAN or national account identifiers + |* Account Rules - A list that might include Overdraft and other bank specific rules + |* Tags - A list of Tags assigned to this account + | + |This call returns the owner view and requires access to that view. + | + | + |""".stripMargin, + EmptyBody, + moderatedCoreAccountJsonV400, + List($AuthenticatedUserIsRequired, $BankAccountNotFound, UnknownError), + apiTagAccount :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, + None, + http4sPartialFunction = Some(getCoreAccountById) + ) // ─── getPrivateAccountByIdFull (GET /banks/BANK_ID/.../VIEW_ID/account) ── @@ -935,15 +1308,41 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getPrivateAccountByIdFull), "GET", + null, + implementedInApiVersion, + nameOf(getPrivateAccountByIdFull), + "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/account", "Get Account by Id (Full)", - """Information returned about an account specified by ACCOUNT_ID moderated by the view (VIEW_ID).""", - EmptyBody, moderatedAccountJSON400, - List(AuthenticatedUserIsRequired, BankNotFound, BankAccountNotFound, - UserNoPermissionAccessView, UnknownError), - apiTagAccount :: Nil, None, - http4sPartialFunction = Some(getPrivateAccountByIdFull)) + """Information returned about an account specified by ACCOUNT_ID as moderated by the view (VIEW_ID): + | + |* Number + |* Owners + |* Type + |* Balance + |* IBAN + |* Available views (sorted by short_name) + | + |More details about the data moderation by the view [here](#1_2_1-getViewsForBankAccount). + | + |PSD2 Context: PSD2 requires customers to have access to their account information via third party applications. + |This call provides balance and other account information via delegated authentication using OAuth. + | + |Authentication is required if the 'is_public' field in view (VIEW_ID) is not set to `true`. + |""".stripMargin, + EmptyBody, + moderatedAccountJSON400, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + $BankAccountNotFound, + $UserNoPermissionAccessView, + UnknownError + ), + apiTagAccount :: Nil, + None, + http4sPartialFunction = Some(getPrivateAccountByIdFull) + ) // ─── getPrivateAccountsAtOneBank (GET /banks/BANK_ID/accounts) — v4 override @@ -976,14 +1375,29 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getPrivateAccountsAtOneBank), "GET", + null, + implementedInApiVersion, + nameOf(getPrivateAccountsAtOneBank), + "GET", "/banks/BANK_ID/accounts", "Get Accounts at Bank", - s"""Returns the list of accounts at BANK_ID that the user has access to.""", - EmptyBody, basicAccountsJSON, - List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), - List(apiTagAccount, apiTagPrivateData, apiTagPublicData), None, - http4sPartialFunction = Some(getPrivateAccountsAtOneBank)) + s""" + |Returns the list of accounts at BANK_ID that the user has access to. + |For each account the API returns the account ID and the views available to the user.. + |Each account must have at least one private View. + | + |optional request parameters for filter with attributes + |URL params example: /banks/some-bank-id/accounts?&limit=50&offset=1 + | + | + """.stripMargin, + EmptyBody, + basicAccountsJSON, + List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), + List(apiTagAccount, apiTagPrivateData, apiTagPublicData), + None, + http4sPartialFunction = Some(getPrivateAccountsAtOneBank) + ) // ─── createUserCustomerLinks (POST → 201) — v4 override ───────────────── @@ -1028,9 +1442,17 @@ object Http4s400 { | |${userAuthenticationMessage(true)}""", createUserCustomerLinkJson, userCustomerLinkJson, - List(AuthenticatedUserIsRequired, InvalidBankIdFormat, BankNotFound, InvalidJsonFormat, - CustomerNotFoundByCustomerId, UserHasMissingRoles, CustomerAlreadyExistsForUser, - CreateUserCustomerLinksError, UnknownError), + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + $BankNotFound, + InvalidJsonFormat, + CustomerNotFoundByCustomerId, + UserHasMissingRoles, + CustomerAlreadyExistsForUser, + CreateUserCustomerLinksError, + UnknownError + ), List(apiTagCustomer, apiTagUser), Some(List(canCreateUserCustomerLinkAtAnyBank, canCreateUserCustomerLink)), http4sPartialFunction = Some(createUserCustomerLinks)) @@ -1051,18 +1473,31 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getSystemDynamicEntities), "GET", + null, + implementedInApiVersion, + nameOf(getSystemDynamicEntities), + "GET", "/management/system-dynamic-entities", "Get System Dynamic Entities", s"""Get all System Dynamic Entities. - | - |For more information see ${Glossary.getGlossaryItemLink("Dynamic-Entities")}""", + | + |For more information see ${Glossary.getGlossaryItemLink( + "Dynamic-Entities" + )} """, EmptyBody, - ListResult("dynamic_entities", List(dynamicEntityResponseBodyExample)), - List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + ListResult( + "dynamic_entities", + List(dynamicEntityResponseBodyExample) + ), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), List(apiTagManageDynamicEntity, apiTagApi), Some(List(canGetSystemLevelDynamicEntities)), - http4sPartialFunction = Some(getSystemDynamicEntities)) + http4sPartialFunction = Some(getSystemDynamicEntities) + ) // ─── getBankLevelDynamicEntities ────────────────────────────────────────── @@ -1081,18 +1516,32 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBankLevelDynamicEntities), "GET", + null, + implementedInApiVersion, + nameOf(getBankLevelDynamicEntities), + "GET", "/management/banks/BANK_ID/dynamic-entities", "Get Bank Level Dynamic Entities", s"""Get all the bank level Dynamic Entities for one bank. - | - |For more information see ${Glossary.getGlossaryItemLink("Dynamic-Entities")}""", + | + |For more information see ${Glossary.getGlossaryItemLink( + "Dynamic-Entities" + )}""", EmptyBody, - ListResult("dynamic_entities", List(dynamicEntityResponseBodyExample)), - List(BankNotFound, AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + ListResult( + "dynamic_entities", + List(dynamicEntityResponseBodyExample) + ), + List( + $BankNotFound, + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), List(apiTagManageDynamicEntity, apiTagApi), Some(List(canGetBankLevelDynamicEntities, canGetAnyBankLevelDynamicEntities)), - http4sPartialFunction = Some(getBankLevelDynamicEntities)) + http4sPartialFunction = Some(getBankLevelDynamicEntities) + ) // ─── getMyDynamicEntities ───────────────────────────────────────────────── @@ -1109,17 +1558,30 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMyDynamicEntities), "GET", + null, + implementedInApiVersion, + nameOf(getMyDynamicEntities), + "GET", "/my/dynamic-entities", "Get My Dynamic Entities", - s"""Get all the Dynamic Entities created by the current user. - | - |For more information see ${Glossary.getGlossaryItemLink("Dynamic-Entities")}""", + s"""Get all my Dynamic Entities (definitions I created). + | + |For more information see ${Glossary.getGlossaryItemLink( + "My-Dynamic-Entities" + )}""", EmptyBody, - ListResult("dynamic_entities", List(dynamicEntityResponseBodyExample)), - List(AuthenticatedUserIsRequired, UnknownError), - List(apiTagManageDynamicEntity, apiTagApi), None, - http4sPartialFunction = Some(getMyDynamicEntities)) + ListResult( + "dynamic_entities", + List(dynamicEntityResponseBodyExample) + ), + List( + $AuthenticatedUserIsRequired, + UnknownError + ), + List(apiTagManageDynamicEntity, apiTagApi), + None, + http4sPartialFunction = Some(getMyDynamicEntities) + ) // ─── dynamic-entity shared helpers (ported from APIMethods400) ────────── @@ -1339,17 +1801,30 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteSystemDynamicEntity), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteSystemDynamicEntity), + "DELETE", "/management/system-dynamic-entities/DYNAMIC_ENTITY_ID", "Delete System Level Dynamic Entity", - s"""Delete a system-level DynamicEntity specified by DYNAMIC_ENTITY_ID. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, EmptyBody, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + s"""Delete a DynamicEntity specified by DYNAMIC_ENTITY_ID. + | + |For more information see ${Glossary.getGlossaryItemLink( + "Dynamic-Entities" + )}/ + | + |""", + EmptyBody, + EmptyBody, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), List(apiTagManageDynamicEntity, apiTagApi), Some(List(canDeleteSystemLevelDynamicEntity)), - http4sPartialFunction = Some(deleteSystemDynamicEntity)) + http4sPartialFunction = Some(deleteSystemDynamicEntity) + ) // ─── deleteBankLevelDynamicEntity (200) ────────────────────────────────── @@ -1361,17 +1836,31 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteBankLevelDynamicEntity), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteBankLevelDynamicEntity), + "DELETE", "/management/banks/BANK_ID/dynamic-entities/DYNAMIC_ENTITY_ID", "Delete Bank Level Dynamic Entity", - s"""Delete a bank-level DynamicEntity specified by DYNAMIC_ENTITY_ID. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, EmptyBody, - List(BankNotFound, AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + s"""Delete a Bank Level DynamicEntity specified by DYNAMIC_ENTITY_ID. + | + |For more information see ${Glossary.getGlossaryItemLink( + "Dynamic-Entities" + )}/ + | + |""", + EmptyBody, + EmptyBody, + List( + $BankNotFound, + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), List(apiTagManageDynamicEntity, apiTagApi), Some(List(canDeleteBankLevelDynamicEntity)), - http4sPartialFunction = Some(deleteBankLevelDynamicEntity)) + http4sPartialFunction = Some(deleteBankLevelDynamicEntity) + ) // ─── updateMyDynamicEntity ──────────────────────────────────────────────── @@ -1443,16 +1932,28 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteMyDynamicEntity), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteMyDynamicEntity), + "DELETE", "/my/dynamic-entities/DYNAMIC_ENTITY_ID", "Delete My Dynamic Entity", s"""Delete my DynamicEntity specified by DYNAMIC_ENTITY_ID. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, EmptyBody, - List(AuthenticatedUserIsRequired, InvalidMyDynamicEntityUser, UnknownError), - List(apiTagManageDynamicEntity, apiTagApi), None, - http4sPartialFunction = Some(deleteMyDynamicEntity)) + | + |For more information see ${Glossary.getGlossaryItemLink( + "My-Dynamic-Entities" + )} + |""", + EmptyBody, + EmptyBody, + List( + $AuthenticatedUserIsRequired, + UnknownError + ), + List(apiTagManageDynamicEntity, apiTagApi), + None, + http4sPartialFunction = Some(deleteMyDynamicEntity) + ) // ─── dynamic-endpoint shared helpers (ported from APIMethods400) ──────── @@ -1543,18 +2044,36 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createDynamicEndpoint), "POST", + null, + implementedInApiVersion, + nameOf(createDynamicEndpoint), + "POST", "/management/dynamic-endpoints", "Create Dynamic Endpoint", - s"""Create dynamic endpoints with one json format swagger content. - | - |${userAuthenticationMessage(true)}""", - dynamicEndpointRequestBodyExample, dynamicEndpointResponseBodyExample, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, DynamicEndpointExists, - InvalidJsonFormat, UnknownError), + s"""Create dynamic endpoints. + | + |Create dynamic endpoints with one json format swagger content. + | + |If the host of swagger is `dynamic_entity`, then you need link the swagger fields to the dynamic entity fields, + |please check `Endpoint Mapping` endpoints. + | + |If the host of swagger is `obp_mock`, every dynamic endpoint will return example response of swagger,\n + |when create MethodRouting for given dynamic endpoint, it will be routed to given url. + | + |""", + dynamicEndpointRequestBodyExample, + dynamicEndpointResponseBodyExample, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + DynamicEndpointExists, + InvalidJsonFormat, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), Some(List(canCreateDynamicEndpoint)), - http4sPartialFunction = Some(createDynamicEndpoint)) + http4sPartialFunction = Some(createDynamicEndpoint) + ) // ─── createBankLevelDynamicEndpoint (POST → 201) ───────────────────────── @@ -1574,18 +2093,37 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createBankLevelDynamicEndpoint), "POST", + null, + implementedInApiVersion, + nameOf(createBankLevelDynamicEndpoint), + "POST", "/management/banks/BANK_ID/dynamic-endpoints", "Create Bank Level Dynamic Endpoint", - s"""Create dynamic endpoints with one json format swagger content. - | - |${userAuthenticationMessage(true)}""", - dynamicEndpointRequestBodyExample, dynamicEndpointResponseBodyExample, - List(BankNotFound, AuthenticatedUserIsRequired, UserHasMissingRoles, DynamicEndpointExists, - InvalidJsonFormat, UnknownError), + s"""Create dynamic endpoints. + | + |Create dynamic endpoints with one json format swagger content. + | + |If the host of swagger is `dynamic_entity`, then you need link the swagger fields to the dynamic entity fields, + |please check `Endpoint Mapping` endpoints. + | + |If the host of swagger is `obp_mock`, every dynamic endpoint will return example response of swagger,\n + |when create MethodRouting for given dynamic endpoint, it will be routed to given url. + | + |""", + dynamicEndpointRequestBodyExample, + dynamicEndpointResponseBodyExample, + List( + $BankNotFound, + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + DynamicEndpointExists, + InvalidJsonFormat, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), Some(List(canCreateBankLevelDynamicEndpoint, canCreateDynamicEndpoint)), - http4sPartialFunction = Some(createBankLevelDynamicEndpoint)) + http4sPartialFunction = Some(createBankLevelDynamicEndpoint) + ) // ─── updateDynamicEndpointHost (PUT → 201) ─────────────────────────────── @@ -1602,17 +2140,28 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateDynamicEndpointHost), "PUT", + null, + implementedInApiVersion, + nameOf(updateDynamicEndpointHost), + "PUT", "/management/dynamic-endpoints/DYNAMIC_ENDPOINT_ID/host", " Update Dynamic Endpoint Host", s"""Update dynamic endpoint Host. - |The value can be obp_mock, dynamic_entity, or some service url.""", - dynamicEndpointHostJson400, dynamicEndpointHostJson400, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, - DynamicEntityNotFoundByDynamicEntityId, InvalidJsonFormat, UnknownError), + |The value can be obp_mock, dynamic_entity, or some service url. + |""", + dynamicEndpointHostJson400, + dynamicEndpointHostJson400, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + DynamicEntityNotFoundByDynamicEntityId, + InvalidJsonFormat, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), Some(List(canUpdateDynamicEndpoint)), - http4sPartialFunction = Some(updateDynamicEndpointHost)) + http4sPartialFunction = Some(updateDynamicEndpointHost) + ) // ─── updateBankLevelDynamicEndpointHost (PUT → 201) ────────────────────── @@ -1630,16 +2179,29 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateBankLevelDynamicEndpointHost), "PUT", + null, + implementedInApiVersion, + nameOf(updateBankLevelDynamicEndpointHost), + "PUT", "/management/banks/BANK_ID/dynamic-endpoints/DYNAMIC_ENDPOINT_ID/host", " Update Bank Level Dynamic Endpoint Host", - s"""Update Bank Level dynamic endpoint Host.""", - dynamicEndpointHostJson400, dynamicEndpointHostJson400, - List(BankNotFound, AuthenticatedUserIsRequired, UserHasMissingRoles, - DynamicEntityNotFoundByDynamicEntityId, InvalidJsonFormat, UnknownError), + s"""Update Bank Level dynamic endpoint Host. + |The value can be obp_mock, dynamic_entity, or some service url. + |""", + dynamicEndpointHostJson400, + dynamicEndpointHostJson400, + List( + $BankNotFound, + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + DynamicEntityNotFoundByDynamicEntityId, + InvalidJsonFormat, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), Some(List(canUpdateBankLevelDynamicEndpoint, canUpdateDynamicEndpoint)), - http4sPartialFunction = Some(updateBankLevelDynamicEndpointHost)) + http4sPartialFunction = Some(updateBankLevelDynamicEndpointHost) + ) // ─── getDynamicEndpoint (GET → 200) ────────────────────────────────────── @@ -1651,16 +2213,31 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getDynamicEndpoint), "GET", + null, + implementedInApiVersion, + nameOf(getDynamicEndpoint), + "GET", "/management/dynamic-endpoints/DYNAMIC_ENDPOINT_ID", "Get Dynamic Endpoint", - s"""Get a Dynamic Endpoint by DYNAMIC_ENDPOINT_ID.""", - EmptyBody, dynamicEndpointResponseBodyExample, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, - DynamicEndpointNotFoundByDynamicEndpointId, InvalidJsonFormat, UnknownError), + s"""Get a Dynamic Endpoint. + | + | + |Get one DynamicEndpoint, + | + |""", + EmptyBody, + dynamicEndpointResponseBodyExample, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + DynamicEndpointNotFoundByDynamicEndpointId, + InvalidJsonFormat, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), Some(List(canGetDynamicEndpoint)), - http4sPartialFunction = Some(getDynamicEndpoint)) + http4sPartialFunction = Some(getDynamicEndpoint) + ) // ─── getDynamicEndpoints (GET → 200) ───────────────────────────────────── @@ -1672,15 +2249,32 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getDynamicEndpoints), "GET", + null, + implementedInApiVersion, + nameOf(getDynamicEndpoints), + "GET", "/management/dynamic-endpoints", " Get Dynamic Endpoints", - s"""Get Dynamic Endpoints.""", - EmptyBody, ListResult("dynamic_endpoints", List(dynamicEndpointResponseBodyExample)), - List(AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), + s""" + | + |Get Dynamic Endpoints. + | + |""", + EmptyBody, + ListResult( + "dynamic_endpoints", + List(dynamicEndpointResponseBodyExample) + ), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), Some(List(canGetDynamicEndpoints)), - http4sPartialFunction = Some(getDynamicEndpoints)) + http4sPartialFunction = Some(getDynamicEndpoints) + ) // ─── getBankLevelDynamicEndpoint (GET → 200) ───────────────────────────── @@ -1692,16 +2286,28 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBankLevelDynamicEndpoint), "GET", + null, + implementedInApiVersion, + nameOf(getBankLevelDynamicEndpoint), + "GET", "/management/banks/BANK_ID/dynamic-endpoints/DYNAMIC_ENDPOINT_ID", " Get Bank Level Dynamic Endpoint", - s"""Get a Bank Level Dynamic Endpoint.""", - EmptyBody, dynamicEndpointResponseBodyExample, - List(BankNotFound, AuthenticatedUserIsRequired, UserHasMissingRoles, - DynamicEndpointNotFoundByDynamicEndpointId, InvalidJsonFormat, UnknownError), + s"""Get a Bank Level Dynamic Endpoint. + |""", + EmptyBody, + dynamicEndpointResponseBodyExample, + List( + $BankNotFound, + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + DynamicEndpointNotFoundByDynamicEndpointId, + InvalidJsonFormat, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), Some(List(canGetBankLevelDynamicEndpoint, canGetDynamicEndpoint)), - http4sPartialFunction = Some(getBankLevelDynamicEndpoint)) + http4sPartialFunction = Some(getBankLevelDynamicEndpoint) + ) // ─── getBankLevelDynamicEndpoints (GET → 200) ──────────────────────────── @@ -1713,16 +2319,33 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBankLevelDynamicEndpoints), "GET", + null, + implementedInApiVersion, + nameOf(getBankLevelDynamicEndpoints), + "GET", "/management/banks/BANK_ID/dynamic-endpoints", "Get Bank Level Dynamic Endpoints", - s"""Get Bank Level Dynamic Endpoints.""", - EmptyBody, ListResult("dynamic_endpoints", List(dynamicEndpointResponseBodyExample)), - List(BankNotFound, AuthenticatedUserIsRequired, UserHasMissingRoles, - InvalidJsonFormat, UnknownError), + s""" + | + |Get Bank Level Dynamic Endpoints. + | + |""", + EmptyBody, + ListResult( + "dynamic_endpoints", + List(dynamicEndpointResponseBodyExample) + ), + List( + $BankNotFound, + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), Some(List(canGetBankLevelDynamicEndpoints, canGetDynamicEndpoints)), - http4sPartialFunction = Some(getBankLevelDynamicEndpoints)) + http4sPartialFunction = Some(getBankLevelDynamicEndpoints) + ) // ─── deleteDynamicEndpoint (DELETE → 204) ──────────────────────────────── @@ -1734,15 +2357,24 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteDynamicEndpoint), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteDynamicEndpoint), + "DELETE", "/management/dynamic-endpoints/DYNAMIC_ENDPOINT_ID", " Delete Dynamic Endpoint", - s"""Delete a DynamicEndpoint specified by DYNAMIC_ENDPOINT_ID.""", - EmptyBody, EmptyBody, - List(AuthenticatedUserIsRequired, DynamicEndpointNotFoundByDynamicEndpointId, UnknownError), + s"""Delete a DynamicEndpoint specified by DYNAMIC_ENDPOINT_ID.""".stripMargin, + EmptyBody, + EmptyBody, + List( + $AuthenticatedUserIsRequired, + DynamicEndpointNotFoundByDynamicEndpointId, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), Some(List(canDeleteDynamicEndpoint)), - http4sPartialFunction = Some(deleteDynamicEndpoint)) + http4sPartialFunction = Some(deleteDynamicEndpoint) + ) // ─── deleteBankLevelDynamicEndpoint (DELETE → 204) ─────────────────────── @@ -1754,16 +2386,25 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteBankLevelDynamicEndpoint), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteBankLevelDynamicEndpoint), + "DELETE", "/management/banks/BANK_ID/dynamic-endpoints/DYNAMIC_ENDPOINT_ID", " Delete Bank Level Dynamic Endpoint", - s"""Delete a Bank Level DynamicEndpoint specified by DYNAMIC_ENDPOINT_ID.""", - EmptyBody, EmptyBody, - List(BankNotFound, AuthenticatedUserIsRequired, - DynamicEndpointNotFoundByDynamicEndpointId, UnknownError), + s"""Delete a Bank Level DynamicEndpoint specified by DYNAMIC_ENDPOINT_ID.""".stripMargin, + EmptyBody, + EmptyBody, + List( + $BankNotFound, + $AuthenticatedUserIsRequired, + DynamicEndpointNotFoundByDynamicEndpointId, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), Some(List(canDeleteBankLevelDynamicEndpoint, canDeleteDynamicEndpoint)), - http4sPartialFunction = Some(deleteBankLevelDynamicEndpoint)) + http4sPartialFunction = Some(deleteBankLevelDynamicEndpoint) + ) // ─── getMyDynamicEndpoints (GET → 200) ─────────────────────────────────── @@ -1784,14 +2425,27 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMyDynamicEndpoints), "GET", + null, + implementedInApiVersion, + nameOf(getMyDynamicEndpoints), + "GET", "/my/dynamic-endpoints", "Get My Dynamic Endpoints", - s"""Get My Dynamic Endpoints.""", - EmptyBody, ListResult("dynamic_endpoints", List(dynamicEndpointResponseBodyExample)), - List(AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagManageDynamicEndpoint, apiTagApi), None, - http4sPartialFunction = Some(getMyDynamicEndpoints)) + s"""Get My Dynamic Endpoints.""".stripMargin, + EmptyBody, + ListResult( + "dynamic_endpoints", + List(dynamicEndpointResponseBodyExample) + ), + List( + $AuthenticatedUserIsRequired, + InvalidJsonFormat, + UnknownError + ), + List(apiTagManageDynamicEndpoint, apiTagApi), + None, + http4sPartialFunction = Some(getMyDynamicEndpoints) + ) // ─── deleteMyDynamicEndpoint (DELETE → 204) ────────────────────────────── @@ -1814,7 +2468,11 @@ object Http4s400 { "Delete My Dynamic Endpoint", s"""Delete a DynamicEndpoint specified by DYNAMIC_ENDPOINT_ID.""", EmptyBody, EmptyBody, - List(AuthenticatedUserIsRequired, DynamicEndpointNotFoundByDynamicEndpointId, UnknownError), + List( + $AuthenticatedUserIsRequired, + DynamicEndpointNotFoundByDynamicEndpointId, + UnknownError + ), List(apiTagManageDynamicEndpoint, apiTagApi), None, http4sPartialFunction = Some(deleteMyDynamicEndpoint)) @@ -1832,17 +2490,28 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getProductAttribute), "GET", + null, + implementedInApiVersion, + nameOf(getProductAttribute), + "GET", "/banks/BANK_ID/products/PRODUCT_CODE/attributes/PRODUCT_ATTRIBUTE_ID", "Get Product Attribute", - s"""Get one Product Attribute by its id. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, productAttributeResponseJsonV400, + s""" Get Product Attribute + | + |$productAttributeGeneralInfo + | + |Get one product attribute by its id. + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + productAttributeResponseJsonV400, List(UserHasMissingRoles, UnknownError), List(apiTagProduct, apiTagProductAttribute, apiTagAttribute), Some(List(canGetProductAttribute)), - http4sPartialFunction = Some(getProductAttribute)) + http4sPartialFunction = Some(getProductAttribute) + ) // ─── getScopes (GET /consumers/CONSUMER_ID/scopes) — v4 override of Http4s300 ─ @@ -1867,16 +2536,25 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getScopes), "GET", + null, + implementedInApiVersion, + nameOf(getScopes), + "GET", "/consumers/CONSUMER_ID/scopes", "Get Scopes for Consumer", s"""Get all the scopes for an consumer specified by CONSUMER_ID | - |${userAuthenticationMessage(true)}""", - EmptyBody, scopeJsons, + |${userAuthenticationMessage(true)} + | + | + """.stripMargin, + EmptyBody, + scopeJsons, List(AuthenticatedUserIsRequired, EntitlementNotFound, ConsumerNotFoundByConsumerId, UnknownError), - List(apiTagScope, apiTagConsumer), None, - http4sPartialFunction = Some(getScopes)) + List(apiTagScope, apiTagConsumer), + None, + http4sPartialFunction = Some(getScopes) + ) // ─── addScope (POST /consumers/CONSUMER_ID/scopes → 201) — v4 override ──── @@ -1913,18 +2591,29 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(addScope), "POST", + null, + implementedInApiVersion, + nameOf(addScope), + "POST", "/consumers/CONSUMER_ID/scopes", "Create Scope for a Consumer", """Create Scope. Grant Role to Consumer. - | - |Scopes are used to grant System or Bank level roles to the Consumer (App).""", - createScopeJson, scopeJson, + | + |Scopes are used to grant System or Bank level roles to the Consumer (App). (For Account level privileges, see Views) + | + |For a System level Role (.e.g CanGetAnyUser), set bank_id to an empty string i.e. "bank_id":"" + | + |For a Bank level Role (e.g. CanCreateAccount), set bank_id to a valid value e.g. "bank_id":"my-bank-id" + | + |""", + SwaggerDefinitionsJSON.createScopeJson, + scopeJson, List(AuthenticatedUserIsRequired, ConsumerNotFoundById, InvalidJsonFormat, - IncorrectRoleName, EntitlementIsBankRole, EntitlementIsSystemRole, EntitlementAlreadyExists, UnknownError), + IncorrectRoleName, EntitlementIsBankRole, EntitlementIsSystemRole, EntitlementAlreadyExists, UnknownError), List(apiTagScope, apiTagConsumer), Some(List(canCreateScopeAtAnyBank, canCreateScopeAtOneBank)), - http4sPartialFunction = Some(addScope)) + http4sPartialFunction = Some(addScope) + ) // ─── getConsents (GET /banks/BANK_ID/my/consents) — v4 override of Http4s310 ─ @@ -1951,20 +2640,30 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getConsents), "GET", + null, + implementedInApiVersion, + nameOf(getConsents), + "GET", "/banks/BANK_ID/my/consents", "Get Consents", - s"""This endpoint gets the Consents that the current User created. + s""" + | + |This endpoint gets the Consents that the current User created. | |${userAuthenticationMessage(true)} | |1 limit (for pagination: defaults to 50) eg:limit=200 | - |2 offset (for pagination: zero index, defaults to 0) eg: offset=10""", - EmptyBody, consentsJsonV400, + |2 offset (for pagination: zero index, defaults to 0) eg: offset=10 + | + """.stripMargin, + EmptyBody, + consentsJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), - List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2), None, - http4sPartialFunction = Some(getConsents)) + List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2), + None, + http4sPartialFunction = Some(getConsents) + ) // ─── updateAccountLabel (POST /banks/BANK_ID/accounts/ACCOUNT_ID → 200) — v4 override of Http4s121 ─ @@ -1995,17 +2694,32 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateAccountLabel), "POST", + null, + implementedInApiVersion, + nameOf(updateAccountLabel), + "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID", "Update Account Label", - s"""Update the label for the account. The label is how the account is known to the account owner e.g. 'My savings account'. - | - |${userAuthenticationMessage(true)}""", - updateAccountJsonV400, successMessage, - List(InvalidJsonFormat, $AuthenticatedUserIsRequired, $BankAccountNotFound, - "user does not have access to owner view on account", UnknownError), - List(apiTagAccount), None, - http4sPartialFunction = Some(updateAccountLabel)) + s"""Update the label for the account. The label is how the account is known to the account owner e.g. 'My savings account' + | + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, + updateAccountJsonV400, + successMessage, + List( + InvalidJsonFormat, + $AuthenticatedUserIsRequired, + $BankNotFound, + UnknownError, + $BankAccountNotFound, + "user does not have access to owner view on account" + ), + List(apiTagAccount), + None, + http4sPartialFunction = Some(updateAccountLabel) + ) // ─── getExplicitCounterpartiesForAccount (GET .../counterparties) — v4 override ─ @@ -2035,8 +2749,12 @@ object Http4s400 { "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties", "Get Counterparties (Explicit)", s"""Get the Counterparties that have been explicitly created on the specified Account / View. - | - |${userAuthenticationMessage(true)}""", + | + |For a general introduction to Counterparties in OBP, see ${Glossary + .getGlossaryItemLink("Counterparties")} + | + |${userAuthenticationMessage(true)} + |""".stripMargin, EmptyBody, counterpartiesJson400, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, $UserNoPermissionAccessView, ViewNotFound, UnknownError), @@ -2065,9 +2783,13 @@ object Http4s400 { null, implementedInApiVersion, "getExplicitCounterpartyById", "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties/EXPLICIT_COUNTERPARTY_ID", "Get Counterparty by Id (Explicit)", - s"""This endpoint returns a single Counterparty on an Account View specified by its COUNTERPARTY_ID. - | - |${userAuthenticationMessage(true)}""", + s"""This endpoint returns a single Counterparty on an Account View specified by its COUNTERPARTY_ID: + | + |For a general introduction to Counterparties in OBP, see ${Glossary + .getGlossaryItemLink("Counterparties")} + | + |${userAuthenticationMessage(true)} + |""".stripMargin, EmptyBody, counterpartyWithMetadataJson400, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, $UserNoPermissionAccessView, UnknownError), @@ -2157,14 +2879,29 @@ object Http4s400 { null, implementedInApiVersion, "createCounterparty", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties", "Create Counterparty (Explicit)", - s"""Create Counterparty (Explicit) for an Account. - | - |${userAuthenticationMessage(true)}""", + s"""This endpoint creates an (Explicit) Counterparty for an Account. + | + |For an introduction to Counterparties in OBP see ${Glossary + .getGlossaryItemLink("Counterparties")} + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, postCounterpartyJson400, counterpartyWithMetadataJson400, - List($AuthenticatedUserIsRequired, InvalidAccountIdFormat, InvalidBankIdFormat, - InvalidJsonFormat, NoViewPermission, CounterpartyAlreadyExists, - InvalidValueLength, InvalidISOCurrencyCode, UnknownError), - List(apiTagCounterparty, apiTagPSD2PIS, apiTagPsd2, apiTagAccount), None, + List( + $AuthenticatedUserIsRequired, + InvalidAccountIdFormat, + InvalidBankIdFormat, + $BankNotFound, + $BankAccountNotFound, + $UserNoPermissionAccessView, + InvalidJsonFormat, + InvalidISOCurrencyCode, + ViewNotFound, + CounterpartyAlreadyExists, + UnknownError + ), + List(apiTagCounterparty, apiTagAccount), None, http4sPartialFunction = Some(createExplicitCounterparty)) // ─── getFirehoseAccountsAtOneBank ───────────────────────────────────────── @@ -2223,16 +2960,43 @@ object Http4s400 { } staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getFirehoseAccountsAtOneBank), "GET", + null, + implementedInApiVersion, + nameOf(getFirehoseAccountsAtOneBank), + "GET", "/banks/FIREHOSE_BANK_ID/firehose/accounts/views/FIREHOSE_VIEW_ID", "Get Firehose Accounts at Bank", - s"""Get all Accounts at a Bank that have a Firehose View. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, moderatedFirehoseAccountsJsonV400, - List(AuthenticatedUserIsRequired, AccountFirehoseNotAllowedOnThisInstance, UnknownError), - List(apiTagAccountFirehose, apiTagAccount, apiTagFirehoseData, apiTagAccount), None, - http4sPartialFunction = Some(getFirehoseAccountsAtOneBank)) + s""" + |Get all Accounts at a Bank. + | + |This endpoint allows bulk access to all accounts at the specified bank. + | + |Requires the CanUseFirehoseAtAnyBank Role or CanUseAccountFirehose Role + | + |Returns all accounts at the bank. The VIEW_ID parameter determines what account data fields are visible according to the view's permissions. + | + |The view specified must have is_firehose = true + | + |For VIEW_ID try 'owner' or 'firehose' + | + |Optional request parameters for filtering by account attributes: + |URL params example: + | /banks/some-bank-id/firehose/accounts/views/owner?limit=50&offset=1 + | + |To invalidate browser cache, add timestamp query parameter as follows (the parameter name must be `_timestamp_`): + |URL params example: + | `/banks/some-bank-id/firehose/accounts/views/owner?limit=50&offset=1&_timestamp_=1596762180358` + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + EmptyBody, + moderatedFirehoseAccountsJsonV400, + List($BankNotFound), + List(apiTagAccount, apiTagAccountFirehose, apiTagFirehoseData), + None, + http4sPartialFunction = Some(getFirehoseAccountsAtOneBank) + ) // ─── createTransactionRequest (POST /banks/.../trans-request-types/TYPE/trans-requests → 201) ─ // @@ -2307,15 +3071,32 @@ object Http4s400 { staticResourceDocs += ResourceDoc( null, implementedInApiVersion, "createTransactionRequestAccount", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/GRANT_VIEW_ID/transaction-request-types/TRANSACTION_REQUEST_TYPE/transaction-requests", - "Create Transaction Request", - s"""Create a Transaction Request of the type specified in the URL. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidNumber, NotPositiveAmount, - InvalidTransactionRequestType, InvalidISOCurrencyCode, + "Create Transaction Request (ACCOUNT)", + s"""When using ACCOUNT, the payee is set in the request body. + | + |Money goes into the BANK_ID and ACCOUNT_ID specified in the request body. + | + |$transactionRequestGeneralText + | + """.stripMargin, + transactionRequestBodyJsonV200, transactionRequestWithChargeJSON400, + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + AccountNotFound, + $BankAccountNotFound, InsufficientAuthorisationToCreateTransactionRequest, - InvalidAccountIdFormat, InvalidBankIdFormat, TransactionDisabled, UnknownError), + InvalidTransactionRequestType, + InvalidJsonFormat, + InvalidNumber, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequest)) @@ -2332,14 +3113,31 @@ object Http4s400 { null, implementedInApiVersion, "createTransactionRequestAccountOtp", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/GRANT_VIEW_ID/transaction-request-types/ACCOUNT_OTP/transaction-requests", "Create Transaction Request (ACCOUNT_OTP)", - s"""Create Transaction Request (ACCOUNT_OTP). - | - |${userAuthenticationMessage(true)}""", + s"""When using ACCOUNT, the payee is set in the request body. + | + |Money goes into the BANK_ID and ACCOUNT_ID specified in the request body. + | + |$transactionRequestGeneralText + | + """.stripMargin, transactionRequestBodyJsonV200, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidNumber, NotPositiveAmount, - InvalidTransactionRequestType, InvalidISOCurrencyCode, + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + AccountNotFound, + $BankAccountNotFound, InsufficientAuthorisationToCreateTransactionRequest, - InvalidAccountIdFormat, InvalidBankIdFormat, TransactionDisabled, UnknownError), + InvalidTransactionRequestType, + InvalidJsonFormat, + InvalidNumber, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequest)) @@ -2347,14 +3145,33 @@ object Http4s400 { null, implementedInApiVersion, "createTransactionRequestSepa", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/GRANT_VIEW_ID/transaction-request-types/SEPA/transaction-requests", "Create Transaction Request (SEPA)", - s"""Create Transaction Request (SEPA). - | - |${userAuthenticationMessage(true)}""", + s""" + |Special instructions for SEPA: + | + |When using a SEPA Transaction Request, you specify the IBAN of a Counterparty in the body of the request. + |The routing details (IBAN) of the counterparty will be forwarded to the core banking system for the transfer. + | + |$transactionRequestGeneralText + | + """.stripMargin, transactionRequestBodySEPAJsonV400, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidNumber, NotPositiveAmount, - InvalidTransactionRequestType, InvalidISOCurrencyCode, + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + AccountNotFound, + $BankAccountNotFound, InsufficientAuthorisationToCreateTransactionRequest, - InvalidAccountIdFormat, InvalidBankIdFormat, TransactionDisabled, UnknownError), + InvalidTransactionRequestType, + InvalidJsonFormat, + InvalidNumber, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequest)) @@ -2362,14 +3179,40 @@ object Http4s400 { null, implementedInApiVersion, "createTransactionRequestCounterparty", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/GRANT_VIEW_ID/transaction-request-types/COUNTERPARTY/transaction-requests", "Create Transaction Request (COUNTERPARTY)", - s"""Create Transaction Request (COUNTERPARTY). - | - |${userAuthenticationMessage(true)}""", + s""" + |$transactionRequestGeneralText + | + |When using a COUNTERPARTY to create a Transaction Request, specify the counterparty_id in the body of the request. + |The routing details of the counterparty will be forwarded to the Core Banking System (CBS) for the transfer. + | + |COUNTERPARTY Transaction Requests are used for Variable Recurring Payments (VRP). Use the following ${Glossary + .getApiExplorerLink( + "endpoint", + "OBPv5.1.0-createVRPConsentRequest" + )} to create a consent for VRPs. + | + |For a general introduction to Counterparties in OBP, see ${Glossary + .getGlossaryItemLink("Counterparties")} + | + """.stripMargin, transactionRequestBodyCounterpartyJSON, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidNumber, NotPositiveAmount, - InvalidTransactionRequestType, InvalidISOCurrencyCode, + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + AccountNotFound, + $BankAccountNotFound, InsufficientAuthorisationToCreateTransactionRequest, - InvalidAccountIdFormat, InvalidBankIdFormat, TransactionDisabled, UnknownError), + InvalidTransactionRequestType, + InvalidJsonFormat, + InvalidNumber, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequest)) @@ -2377,14 +3220,40 @@ object Http4s400 { null, implementedInApiVersion, "createTransactionRequestRefund", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/GRANT_VIEW_ID/transaction-request-types/REFUND/transaction-requests", "Create Transaction Request (REFUND)", - s"""Create Transaction Request (REFUND). - | - |${userAuthenticationMessage(true)}""", + s""" + | + |Either the `from` or the `to` field must be filled. Those fields refers to the information about the party that will be refunded. + | + |In case the `from` object is used, it means that the refund comes from the part that sent you a transaction. + |In the `from` object, you have two choices : + |- Use `bank_id` and `account_id` fields if the other account is registered on the OBP-API + |- Use the `counterparty_id` field in case the counterparty account is out of the OBP-API + | + |In case the `to` object is used, it means you send a request to a counterparty to ask for a refund on a previous transaction you sent. + |(This case is not managed by the OBP-API and require an external adapter) + | + | + |$transactionRequestGeneralText + | + """.stripMargin, transactionRequestBodyRefundJsonV400, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidNumber, NotPositiveAmount, - InvalidTransactionRequestType, InvalidISOCurrencyCode, + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + AccountNotFound, + $BankAccountNotFound, InsufficientAuthorisationToCreateTransactionRequest, - InvalidAccountIdFormat, InvalidBankIdFormat, TransactionDisabled, UnknownError), + InvalidTransactionRequestType, + InvalidJsonFormat, + InvalidNumber, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequest)) @@ -2392,14 +3261,27 @@ object Http4s400 { null, implementedInApiVersion, "createTransactionRequestFreeForm", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/GRANT_VIEW_ID/transaction-request-types/FREE_FORM/transaction-requests", "Create Transaction Request (FREE_FORM)", - s"""Create Transaction Request (FREE_FORM). - | - |${userAuthenticationMessage(true)}""", + s"""$transactionRequestGeneralText + | + """.stripMargin, transactionRequestBodyFreeFormJSON, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidNumber, NotPositiveAmount, - InvalidTransactionRequestType, InvalidISOCurrencyCode, + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + AccountNotFound, + $BankAccountNotFound, InsufficientAuthorisationToCreateTransactionRequest, - InvalidAccountIdFormat, InvalidBankIdFormat, TransactionDisabled, UnknownError), + InvalidTransactionRequestType, + InvalidJsonFormat, + InvalidNumber, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), List(apiTagTransactionRequest, apiTagPSD2PIS), Some(List(canCreateAnyTransactionRequest)), http4sPartialFunction = Some(createTransactionRequest)) @@ -2408,14 +3290,32 @@ object Http4s400 { null, implementedInApiVersion, "createTransactionRequestSimple", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/GRANT_VIEW_ID/transaction-request-types/SIMPLE/transaction-requests", "Create Transaction Request (SIMPLE)", - s"""Create Transaction Request (SIMPLE). - | - |${userAuthenticationMessage(true)}""", + s""" + |Special instructions for SIMPLE: + | + |You can transfer money to the Bank Account Number or IBAN directly. + | + |$transactionRequestGeneralText + | + """.stripMargin, transactionRequestBodySimpleJsonV400, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidNumber, NotPositiveAmount, - InvalidTransactionRequestType, InvalidISOCurrencyCode, + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + AccountNotFound, + $BankAccountNotFound, InsufficientAuthorisationToCreateTransactionRequest, - InvalidAccountIdFormat, InvalidBankIdFormat, TransactionDisabled, UnknownError), + InvalidTransactionRequestType, + InvalidJsonFormat, + InvalidNumber, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequest)) @@ -2423,14 +3323,40 @@ object Http4s400 { null, implementedInApiVersion, "createTransactionRequestAgentCashWithDrawal", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/GRANT_VIEW_ID/transaction-request-types/AGENT_CASH_WITHDRAWAL/transaction-requests", "Create Transaction Request (AGENT_CASH_WITHDRAWAL)", - s"""Create Transaction Request (AGENT_CASH_WITHDRAWAL). - | - |${userAuthenticationMessage(true)}""", + s""" + | + |Either the `from` or the `to` field must be filled. Those fields refers to the information about the party that will be refunded. + | + |In case the `from` object is used, it means that the refund comes from the part that sent you a transaction. + |In the `from` object, you have two choices : + |- Use `bank_id` and `account_id` fields if the other account is registered on the OBP-API + |- Use the `counterparty_id` field in case the counterparty account is out of the OBP-API + | + |In case the `to` object is used, it means you send a request to a counterparty to ask for a refund on a previous transaction you sent. + |(This case is not managed by the OBP-API and require an external adapter) + | + | + |$transactionRequestGeneralText + | + """.stripMargin, transactionRequestBodyAgentJsonV400, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidNumber, NotPositiveAmount, - InvalidTransactionRequestType, InvalidISOCurrencyCode, + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + AccountNotFound, + $BankAccountNotFound, InsufficientAuthorisationToCreateTransactionRequest, - InvalidAccountIdFormat, InvalidBankIdFormat, TransactionDisabled, UnknownError), + InvalidTransactionRequestType, + InvalidJsonFormat, + InvalidNumber, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequest)) } @@ -2467,14 +3393,33 @@ object Http4s400 { null, implementedInApiVersion, "createTransactionRequestCard", "POST", "/transaction-request-types/CARD/transaction-requests", "Create Transaction Request (CARD)", - s"""Create Transaction Request (CARD). - | - |${userAuthenticationMessage(true)}""", + s""" + | + |When using CARD, the payee is set in the request body . + | + |Money goes into the Counterparty in the request body. + | + |$transactionRequestGeneralText + | + """.stripMargin, transactionRequestBodyCardJsonV400, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidNumber, NotPositiveAmount, - InvalidTransactionRequestType, InvalidISOCurrencyCode, + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + AccountNotFound, + $BankAccountNotFound, InsufficientAuthorisationToCreateTransactionRequest, - InvalidAccountIdFormat, InvalidBankIdFormat, TransactionDisabled, UnknownError), + InvalidTransactionRequestType, + InvalidJsonFormat, + InvalidNumber, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(createTransactionRequestCard)) @@ -2649,13 +3594,60 @@ object Http4s400 { "/banks/BANK_ID/accounts/ACCOUNT_ID/GRANT_VIEW_ID/transaction-request-types/TRANSACTION_REQUEST_TYPE/transaction-requests/TRANSACTION_REQUEST_ID/challenge", "Answer Transaction Request Challenge", s"""In Sandbox mode, any string that can be converted to a positive integer will be accepted as an answer. - | - |${userAuthenticationMessage(true)}""", - challengeAnswerJson400, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidBankIdFormat, - InvalidAccountIdFormat, InvalidTransactionRequestChallengeId, - AllowedAttemptsUsedUp, TransactionRequestStatusNotInitiatedOrPendingOrForwarded, - TransactionRequestTypeHasChanged, UnknownError), + | + |This endpoint totally depends on createTransactionRequest, it need get the following data from createTransactionRequest response body. + | + |1)`TRANSACTION_REQUEST_TYPE` : is the same as createTransactionRequest request URL . + | + |2)`TRANSACTION_REQUEST_ID` : is the `id` field in createTransactionRequest response body. + | + |3) `id` : is `challenge.id` field in createTransactionRequest response body. + | + |4) `answer` : must be `123` in case that Strong Customer Authentication method for OTP challenge is dummy. + | For instance: SANDBOX_TAN_OTP_INSTRUCTION_TRANSPORT=dummy + | Possible values are dummy,email and sms + | In CBS mode, the answer can be got by phone message or other SCA methods. + | + |Note that each Transaction Request Type can have its own OTP_INSTRUCTION_TRANSPORT method. + |OTP_INSTRUCTION_TRANSPORT methods are set in Props. See sample.props.template for instructions. + | + |Single or Multiple authorisations + | + |OBP allows single or multi party authorisations. + | + |Single party authorisation: + | + |In the case that only one person needs to authorise i.e. answer a security challenge we have the following change of state of a `transaction request`: + | INITIATED => COMPLETED + | + | + |Multiparty authorisation: + | + |In the case that multiple parties (n persons) need to authorise a transaction request i.e. answer security challenges, we have the followings state flow for a `transaction request`: + | INITIATED => NEXT_CHALLENGE_PENDING => ... => NEXT_CHALLENGE_PENDING => COMPLETED + | + |The security challenge is bound to a user i.e. in the case of a correct answer but the user is different than expected the challenge will fail. + | + |Rule for calculating number of security challenges: + |If Product Account attribute REQUIRED_CHALLENGE_ANSWERS=N then create N challenges + |(one for every user that has a View where permission $CAN_ADD_TRANSACTION_REQUEST_TO_ANY_ACCOUNT=true) + |In the case REQUIRED_CHALLENGE_ANSWERS is not defined as an account attribute, the default number of security challenges created is one. + | + """.stripMargin, + challengeAnswerJson400, transactionRequestWithChargeJSON210, + List( + $AuthenticatedUserIsRequired, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + $BankAccountNotFound, + TransactionRequestStatusNotInitiated, + TransactionRequestTypeHasChanged, + AllowedAttemptsUsedUp, + TransactionDisabled, + UnknownError + ), List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), None, http4sPartialFunction = Some(answerTransactionRequestChallenge)) @@ -2850,41 +3842,88 @@ object Http4s400 { private def initBatch8ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCounterpartiesForAnyAccount), "GET", + null, + implementedInApiVersion, + nameOf(getCounterpartiesForAnyAccount), + "GET", "/management/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties", "Get Counterparties for any account (Explicit)", - s"""Get Counterparties for any account.""".stripMargin, - EmptyBody, counterpartiesJson400, - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - ViewNotFound, CreateOrUpdateCounterpartyMetadataError, UnknownError), - List(apiTagCounterparty, apiTagAccount), + s"""This is a management endpoint that gets the Counterparties that have been explicitly created for an Account / View. + | + |For a general introduction to Counterparties in OBP, see ${Glossary + .getGlossaryItemLink("Counterparties")} + | + |${userAuthenticationMessage(true)} + |""".stripMargin, + EmptyBody, + counterpartiesJson400, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + $BankAccountNotFound, + UnknownError + ), + List(apiTagCounterparty, apiTagPSD2PIS, apiTagPsd2, apiTagAccount), Some(List(canGetCounterpartiesAtAnyBank, canGetCounterparties)), - http4sPartialFunction = Some(getCounterpartiesForAnyAccount)) + http4sPartialFunction = Some(getCounterpartiesForAnyAccount) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCounterpartyByIdForAnyAccount), "GET", + null, + implementedInApiVersion, + nameOf(getCounterpartyByIdForAnyAccount), + "GET", "/management/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties/COUNTERPARTY_ID_PARAM", "Get Counterparty by Id for any account (Explicit)", - s"""Get Counterparty by COUNTERPARTY_ID.""".stripMargin, - EmptyBody, counterpartyWithMetadataJson400, + s"""This is a management endpoint that gets information about any single explicitly created Counterparty on an Account / View specified by its COUNTERPARTY_ID", + | + |For a general introduction to Counterparties in OBP, see ${Glossary + .getGlossaryItemLink("Counterparties")} + | + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + EmptyBody, + counterpartyWithMetadataJson400, List($AuthenticatedUserIsRequired, InvalidAccountIdFormat, InvalidBankIdFormat, - $BankNotFound, $BankAccountNotFound, InvalidJsonFormat, ViewNotFound, UnknownError), + $BankNotFound, $BankAccountNotFound, InvalidJsonFormat, ViewNotFound, UnknownError), List(apiTagCounterparty, apiTagAccount), Some(List(canGetCounterpartyAtAnyBank, canGetCounterparty)), - http4sPartialFunction = Some(getCounterpartyByIdForAnyAccount)) + http4sPartialFunction = Some(getCounterpartyByIdForAnyAccount) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCounterpartyByNameForAnyAccount), "GET", + null, + implementedInApiVersion, + nameOf(getCounterpartyByNameForAnyAccount), + "GET", "/management/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparty-names/COUNTERPARTY_NAME", "Get Counterparty by name for any account (Explicit)", - s"""Get Counterparty by COUNTERPARTY_NAME.""".stripMargin, - EmptyBody, counterpartyWithMetadataJson400, - List($AuthenticatedUserIsRequired, InvalidAccountIdFormat, InvalidBankIdFormat, - $BankNotFound, $BankAccountNotFound, InvalidJsonFormat, ViewNotFound, - CounterpartyNotFound, UnknownError), + s"""This is a management endpoint that allows the retrieval of any Counterparty on an Account / View by its Name. + | + |For a general introduction to Counterparties in OBP, see ${Glossary + .getGlossaryItemLink("Counterparties")} + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + EmptyBody, + counterpartyWithMetadataJson400, + List( + $AuthenticatedUserIsRequired, + InvalidAccountIdFormat, + InvalidBankIdFormat, + $BankNotFound, + $BankAccountNotFound, + InvalidJsonFormat, + ViewNotFound, + UnknownError + ), List(apiTagCounterparty, apiTagAccount), Some(List(canGetCounterpartyAtAnyBank, canGetCounterparty)), - http4sPartialFunction = Some(getCounterpartyByNameForAnyAccount)) + http4sPartialFunction = Some(getCounterpartyByNameForAnyAccount) + ) } initBatch8ResourceDocs() @@ -3144,39 +4183,70 @@ object Http4s400 { private def initBatch9ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteExplicitCounterparty), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteExplicitCounterparty), + "DELETE", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties/COUNTERPARTY_ID_PARAM", "Delete Counterparty (Explicit)", - s"""Delete Counterparty (Explicit). - | - |${userAuthenticationMessage(true)}""", - EmptyBody, EmptyBody, - List($AuthenticatedUserIsRequired, $BankAccountNotFound, $BankNotFound, - InvalidAccountIdFormat, InvalidBankIdFormat, NoViewPermission, UnknownError), - List(apiTagCounterparty, apiTagAccount), None, - http4sPartialFunction = Some(deleteExplicitCounterparty)) + s"""This endpoint deletes the Counterparty on the Account / View specified by the COUNTERPARTY_ID. + |It also deletes any related Counterparty Metadata. + | + |The User calling this endpoint must have access to the View specified in the URL and that View must have the permission `can_delete_counterparty`. + | + |For a general introduction to Counterparties in OBP see ${Glossary + .getGlossaryItemLink("Counterparties")} + | | + |${userAuthenticationMessage(true)} + |""".stripMargin, + EmptyBody, + EmptyBody, + List( + $AuthenticatedUserIsRequired, + InvalidAccountIdFormat, + InvalidBankIdFormat, + $BankNotFound, + $BankAccountNotFound, + $UserNoPermissionAccessView, + UnknownError + ), + List(apiTagCounterparty, apiTagAccount), + None, + http4sPartialFunction = Some(deleteExplicitCounterparty) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteCounterpartyForAnyAccount), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteCounterpartyForAnyAccount), + "DELETE", "/management/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties/COUNTERPARTY_ID", "Delete Counterparty for any account (Explicit)", - s"""Delete Counterparty for any account. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, EmptyBody, + s"""This is a management endpoint that enables the deletion of any specified Counterparty along with any related Metadata of that Counterparty. + | + |For a general introduction to Counterparties in OBP, see ${Glossary + .getGlossaryItemLink("Counterparties")} + | + |${userAuthenticationMessage(true)} + |""".stripMargin, + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankAccountNotFound, $BankNotFound, - InvalidAccountIdFormat, InvalidBankIdFormat, UserHasMissingRoles, UnknownError), + InvalidAccountIdFormat, InvalidBankIdFormat, UserHasMissingRoles, UnknownError), List(apiTagCounterparty, apiTagAccount), Some(List(canDeleteCounterparty, canDeleteCounterpartyAtAnyBank)), - http4sPartialFunction = Some(deleteCounterpartyForAnyAccount)) + http4sPartialFunction = Some(deleteCounterpartyForAnyAccount) + ) staticResourceDocs += ResourceDoc( null, implementedInApiVersion, "deleteTagForViewOnAccount", "DELETE", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/metadata/tags/TAG_ID", "Delete a tag on account", - s"""Delete a tag on account. - | - |${userAuthenticationMessage(true)}""", + s"""Deletes the tag TAG_ID about the account ACCOUNT_ID made on [view](#1_2_1-getViewsForBankAccount). + | + |${userAuthenticationMessage(true)} + | + |Authentication is required as the tag is linked with the user.""", EmptyBody, EmptyBody, List(NoViewPermission, ViewNotFound, $AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, $UserNoPermissionAccessView, UnknownError), @@ -3187,9 +4257,10 @@ object Http4s400 { null, implementedInApiVersion, "getTagsForViewOnAccount", "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/metadata/tags", "Get tags on account", - s"""Get tags on account. - | - |${userAuthenticationMessage(true)}""", + s"""Returns the account ACCOUNT_ID tags made on a [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). + |${userAuthenticationMessage(true)} + | + |Authentication is required as the tag is linked with the user.""", EmptyBody, accountTagsJSON, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, NoViewPermission, $UserNoPermissionAccessView, UnknownError), @@ -3200,41 +4271,74 @@ object Http4s400 { null, implementedInApiVersion, "addTagForViewOnAccount", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/metadata/tags", "Create a tag on account", - s"""Create a tag on account. - | - |${userAuthenticationMessage(true)}""", - code.api.v1_2_1.PostTransactionTagJSON("tag-value-example"), + s"""Posts a tag about an account ACCOUNT_ID on a [view](#1_2_1-getViewsForBankAccount) VIEW_ID. + | + |${userAuthenticationMessage(true)} + | + |Authentication is required as the tag is linked with the user.""", + postAccountTagJSON, accountTagJSON, - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - InvalidJsonFormat, NoViewPermission, $UserNoPermissionAccessView, UnknownError), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + $BankAccountNotFound, + $UserNoPermissionAccessView, + InvalidJsonFormat, + NoViewPermission, + $UserNoPermissionAccessView, + UnknownError + ), List(apiTagAccountMetadata, apiTagAccount), None, http4sPartialFunction = Some(addTagForViewOnAccount)) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getDoubleEntryTransaction), "GET", + null, + implementedInApiVersion, + nameOf(getDoubleEntryTransaction), + "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/double-entry-transaction", "Get Double Entry Transaction", - s"""Get Double Entry Transaction. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, doubleEntryTransactionJson, + s"""Get Double Entry Transaction + | + |This endpoint can be used to see the double entry transactions. It returns the `bank_id`, `account_id` and `transaction_id` + |for the debit end the credit transaction. The other side account can be a settlement account or an OBP account. + | + |The endpoint also provide the `transaction_request` object which contains the `bank_id`, `account_id` and + |`transaction_request_id` of the transaction request at the origin of the transaction. Please note that if none + |transaction request is at the origin of the transaction, the `transaction_request` object will be `null`. + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + doubleEntryTransactionJson, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - $UserNoPermissionAccessView, InvalidJsonFormat, UnknownError), + $UserNoPermissionAccessView, InvalidJsonFormat, UnknownError), List(apiTagTransaction), Some(List(canGetDoubleEntryTransactionAtAnyBank, canGetDoubleEntryTransactionAtOneBank)), - http4sPartialFunction = Some(getDoubleEntryTransaction)) + http4sPartialFunction = Some(getDoubleEntryTransaction) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBalancingTransaction), "GET", + null, + implementedInApiVersion, + nameOf(getBalancingTransaction), + "GET", "/transactions/TRANSACTION_ID/balancing-transaction", "Get Balancing Transaction", - s"""Get Balancing Transaction. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, doubleEntryTransactionJson, + s"""Get Balancing Transaction + | + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + doubleEntryTransactionJson, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagTransaction), Some(List()), - http4sPartialFunction = Some(getBalancingTransaction)) + List(apiTagTransaction), + Some(List()), + http4sPartialFunction = Some(getBalancingTransaction) + ) staticResourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(getBankAccountBalancesForCurrentUser), "GET", @@ -3247,63 +4351,137 @@ object Http4s400 { http4sPartialFunction = Some(getBankAccountBalancesForCurrentUser)) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAccountByAccountRouting), "POST", + null, + implementedInApiVersion, + nameOf(getAccountByAccountRouting), + "POST", "/management/accounts/account-routing-query", "Get Account by Account Routing", - """Get Account by Account Routing.""", - bankAccountRoutingJson, moderatedAccountJSON400, + """This endpoint returns the account (if it exists) linked with the provided scheme and address. + | + |The `bank_id` field is optional, but if it's not provided, we don't guarantee that the returned account is unique across all the banks. + | + |Example of account routing scheme: `IBAN`, "OBP", "AccountNumber", ... + |Example of account routing address: `DE17500105178275645584`, "321774cc-fccd-11ea-adc1-0242ac120002", "55897106215", ... + | + |""".stripMargin, + bankAccountRoutingJson, + moderatedAccountJSON400, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - $UserNoPermissionAccessView, UnknownError), - List(apiTagAccount), None, - http4sPartialFunction = Some(getAccountByAccountRouting)) + $UserNoPermissionAccessView, UnknownError), + List(apiTagAccount), + None, + http4sPartialFunction = Some(getAccountByAccountRouting) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAccountsByAccountRoutingRegex), "POST", + null, + implementedInApiVersion, + nameOf(getAccountsByAccountRoutingRegex), + "POST", "/management/accounts/account-routing-regex-query", "Get Accounts by Account Routing Regex", - """Get Accounts by Account Routing Regex.""", - bankAccountRoutingJson, moderatedAccountsJSON400, + """This endpoint returns an array of accounts matching the provided routing scheme and the routing address regex. + | + |The `bank_id` field is optional. + | + |Example of account routing scheme: `IBAN`, `OBP`, `AccountNumber`, ... + |Example of account routing address regex: `DE175.*`, `55897106215-[A-Z]{3}`, ... + | + |This endpoint can be used to retrieve multiples accounts matching a same account routing address pattern. + |For example, if you want to link multiple accounts having different currencies, you can create an account + |with `123456789-EUR` as Account Number and an other account with `123456789-USD` as Account Number. + |So we can identify the Account Number as `123456789`, so to get all the accounts with the same account number + |and the different currencies, we can use this body in the request : + | + |``` + |{ + | "bank_id": "BANK_ID", + | "account_routing": { + | "scheme": "AccountNumber", + | "address": "123456789-[A-Z]{3}" + | } + |} + |``` + | + |This request will returns the accounts matching the routing address regex (`123456789-EUR` and `123456789-USD`). + | + |""".stripMargin, + bankAccountRoutingJson, + moderatedAccountsJSON400, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - $UserNoPermissionAccessView, UnknownError), - List(apiTagAccount), None, - http4sPartialFunction = Some(getAccountsByAccountRoutingRegex)) + $UserNoPermissionAccessView, UnknownError), + List(apiTagAccount), + None, + http4sPartialFunction = Some(getAccountsByAccountRoutingRegex) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(lockUser), "POST", + null, + implementedInApiVersion, + nameOf(lockUser), + "POST", "/users/USERNAME/locks", "Lock the user", - s"""Lock a User. - | - |${userAuthenticationMessage(true)}""", - EmptyBody, userLockStatusJson, + s""" + |Lock a User. + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + EmptyBody, + userLockStatusJson, List($AuthenticatedUserIsRequired, UserNotFoundByProviderAndUsername, - UserHasMissingRoles, UnknownError), + UserHasMissingRoles, UnknownError), List(apiTagUser), Some(List(canLockUser)), - http4sPartialFunction = Some(lockUser)) + http4sPartialFunction = Some(lockUser) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(resetPasswordUrl), "POST", + null, + implementedInApiVersion, + nameOf(resetPasswordUrl), + "POST", "/management/user/reset-password-url", "Create password reset url", - s"""Create password reset url.""", - PostResetPasswordUrlJsonV400("jobloggs", "jo@gmail.com", "74a8ebcc-10e4-4036-bef3-9835922246bf"), - ResetPasswordUrlJsonV400("https://apisandbox.openbankproject.com/user_mgt/reset_password/QOL1CPNJPCZ4BRMPX3Z01DPOX1HMGU3L"), + s"""Create password reset url. + | + |""", + PostResetPasswordUrlJsonV400( + "jobloggs", + "jo@gmail.com", + "74a8ebcc-10e4-4036-bef3-9835922246bf" + ), + ResetPasswordUrlJsonV400( + "https://apisandbox.openbankproject.com/user_mgt/reset_password/QOL1CPNJPCZ4BRMPX3Z01DPOX1HMGU3L" + ), List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagUser), Some(List(canCreateResetPasswordUrl)), - http4sPartialFunction = Some(resetPasswordUrl)) + http4sPartialFunction = Some(resetPasswordUrl) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getSettlementAccounts), "GET", + null, + implementedInApiVersion, + nameOf(getSettlementAccounts), + "GET", "/banks/BANK_ID/settlement-accounts", "Get Settlement accounts at Bank", - """Get Settlement accounts at Bank.""", - EmptyBody, settlementAccountsJson, + """Get settlement accounts on this API instance + |Returns a list of settlement accounts at this Bank + | + |Note: a settlement account is considered as a bank account. + |So you can update it and add account attributes to it using the regular account endpoints + |""", + EmptyBody, + settlementAccountsJson, List($AuthenticatedUserIsRequired, UserHasMissingRoles, $BankNotFound, UnknownError), List(apiTagBank, apiTagPsd2), Some(List(canGetSettlementAccountAtOneBank)), - http4sPartialFunction = Some(getSettlementAccounts)) + http4sPartialFunction = Some(getSettlementAccounts) + ) } initBatch9ResourceDocs() @@ -3556,162 +4734,283 @@ object Http4s400 { private def initBatch10ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createBankAttribute), "POST", + null, + implementedInApiVersion, + nameOf(createBankAttribute), + "POST", "/banks/BANK_ID/attribute", "Create Bank Attribute", - s"""Create Bank Attribute. - | - |${userAuthenticationMessage(true)}""", - bankAttributeJsonV400, bankAttributeResponseJsonV400, + s""" Create Bank Attribute + | + |Typical product attributes might be: + | + |ISIN (for International bonds) + |VKN (for German bonds) + |REDCODE (markit short code for credit derivative) + |LOAN_ID (e.g. used for Anacredit reporting) + | + |ISSUE_DATE (When the bond was issued in the market) + |MATURITY_DATE (End of life time of a product) + |TRADABLE + | + |See [FPML](http://www.fpml.org/) for more examples. + | + | + |The type field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + | + | + |${userAuthenticationMessage(true)} + | + |""", + bankAttributeJsonV400, + bankAttributeResponseJsonV400, List(InvalidJsonFormat, UnknownError), List(apiTagBank, apiTagBankAttribute, apiTagAttribute), Some(List(canCreateBankAttribute)), - http4sPartialFunction = Some(createBankAttribute)) + http4sPartialFunction = Some(createBankAttribute) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateBankAttribute), "PUT", + null, + implementedInApiVersion, + nameOf(updateBankAttribute), + "PUT", "/banks/BANK_ID/attributes/BANK_ATTRIBUTE_ID", "Update Bank Attribute", - s"""Update Bank Attribute. - | - |${userAuthenticationMessage(true)}""", - bankAttributeJsonV400, bankAttributeDefinitionJsonV400, + s""" Update Bank Attribute. + | + |Update one Bak Attribute by its id. + | + |${userAuthenticationMessage(true)} + | + |""", + bankAttributeJsonV400, + bankAttributeDefinitionJsonV400, List(UserHasMissingRoles, UnknownError), List(apiTagBank, apiTagBankAttribute, apiTagAttribute), Some(List(canUpdateBankAttribute)), - http4sPartialFunction = Some(updateBankAttribute)) + http4sPartialFunction = Some(updateBankAttribute) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createCustomerAttribute), "POST", + null, + implementedInApiVersion, + nameOf(createCustomerAttribute), + "POST", "/banks/BANK_ID/customers/CUSTOMER_ID/attribute", "Create Customer Attribute", - s"""Create Customer Attribute. - | - |${userAuthenticationMessage(true)}""", - customerAttributeJsonV400, customerAttributeResponseJson, + s""" Create Customer Attribute + | + | + |The type field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + |${userAuthenticationMessage(true)} + | + |""", + customerAttributeJsonV400, + customerAttributeResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagCustomer, apiTagCustomerAttribute, apiTagAttribute), Some(List(canCreateCustomerAttributeAtOneBank, canCreateCustomerAttributeAtAnyBank)), - http4sPartialFunction = Some(createCustomerAttribute)) + http4sPartialFunction = Some(createCustomerAttribute) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateCustomerAttribute), "PUT", + null, + implementedInApiVersion, + nameOf(updateCustomerAttribute), + "PUT", "/banks/BANK_ID/customers/CUSTOMER_ID/attributes/CUSTOMER_ATTRIBUTE_ID", "Update Customer Attribute", - s"""Update Customer Attribute. - | - |${userAuthenticationMessage(true)}""", - customerAttributeJsonV400, customerAttributeResponseJson, + s""" Update Customer Attribute + | + | + |${userAuthenticationMessage(true)} + | + |""", + customerAttributeJsonV400, + customerAttributeResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagCustomer, apiTagCustomerAttribute, apiTagAttribute), Some(List(canUpdateCustomerAttributeAtOneBank, canUpdateCustomerAttributeAtAnyBank)), - http4sPartialFunction = Some(updateCustomerAttribute)) + http4sPartialFunction = Some(updateCustomerAttribute) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createTransactionAttribute), "POST", + null, + implementedInApiVersion, + nameOf(createTransactionAttribute), + "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/transactions/TRANSACTION_ID/attribute", "Create Transaction Attribute", - s"""Create Transaction Attribute. - | - |${userAuthenticationMessage(true)}""", - transactionAttributeJsonV400, transactionAttributeResponseJson, + s""" Create Transaction Attribute + | + |The type field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + |${userAuthenticationMessage(true)} + | + |""", + transactionAttributeJsonV400, + transactionAttributeResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - InvalidJsonFormat, UnknownError), + InvalidJsonFormat, UnknownError), List(apiTagTransaction, apiTagTransactionAttribute, apiTagAttribute), Some(List(canCreateTransactionAttributeAtOneBank)), - http4sPartialFunction = Some(createTransactionAttribute)) + http4sPartialFunction = Some(createTransactionAttribute) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateTransactionAttribute), "PUT", + null, + implementedInApiVersion, + nameOf(updateTransactionAttribute), + "PUT", "/banks/BANK_ID/accounts/ACCOUNT_ID/transactions/TRANSACTION_ID/attributes/ACCOUNT_ATTRIBUTE_ID", "Update Transaction Attribute", - s"""Update Transaction Attribute. - | - |${userAuthenticationMessage(true)}""", - transactionAttributeJsonV400, transactionAttributeResponseJson, + s""" Update Transaction Attribute + | + | + |${userAuthenticationMessage(true)} + | + |""", + transactionAttributeJsonV400, + transactionAttributeResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - InvalidJsonFormat, UnknownError), + InvalidJsonFormat, UnknownError), List(apiTagTransaction, apiTagTransactionAttribute, apiTagAttribute), Some(List(canUpdateTransactionAttributeAtOneBank)), - http4sPartialFunction = Some(updateTransactionAttribute)) + http4sPartialFunction = Some(updateTransactionAttribute) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createTransactionRequestAttribute), "POST", + null, + implementedInApiVersion, + nameOf(createTransactionRequestAttribute), + "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/transaction-requests/TRANSACTION_REQUEST_ID/attribute", "Create Transaction Request Attribute", - s"""Create Transaction Request Attribute. - | - |${userAuthenticationMessage(true)}""", - transactionRequestAttributeJsonV400, transactionRequestAttributeResponseJson, + s""" Create Transaction Request Attribute + | + |The type field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + |${userAuthenticationMessage(true)} + | + |""", + transactionRequestAttributeJsonV400, + transactionRequestAttributeResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - InvalidJsonFormat, UnknownError), + InvalidJsonFormat, UnknownError), List(apiTagTransactionRequest, apiTagTransactionRequestAttribute, apiTagAttribute), Some(List(canCreateTransactionRequestAttributeAtOneBank)), - http4sPartialFunction = Some(createTransactionRequestAttribute)) + http4sPartialFunction = Some(createTransactionRequestAttribute) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateTransactionRequestAttribute), "PUT", + null, + implementedInApiVersion, + nameOf(updateTransactionRequestAttribute), + "PUT", "/banks/BANK_ID/accounts/ACCOUNT_ID/transaction-requests/TRANSACTION_REQUEST_ID/attributes/ATTRIBUTE_ID", "Update Transaction Request Attribute", - s"""Update Transaction Request Attribute. - | - |${userAuthenticationMessage(true)}""", - transactionRequestAttributeJsonV400, transactionRequestAttributeResponseJson, + s""" Update Transaction Request Attribute + | + |${userAuthenticationMessage(true)} + | + |""", + transactionRequestAttributeJsonV400, + transactionRequestAttributeResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - InvalidJsonFormat, UnknownError), + InvalidJsonFormat, UnknownError), List(apiTagTransactionRequest, apiTagTransactionRequestAttribute, apiTagAttribute), Some(List(canUpdateTransactionRequestAttributeAtOneBank)), - http4sPartialFunction = Some(updateTransactionRequestAttribute)) + http4sPartialFunction = Some(updateTransactionRequestAttribute) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createProductFee), "POST", + null, + implementedInApiVersion, + nameOf(createProductFee), + "POST", "/banks/BANK_ID/products/PRODUCT_CODE/fee", "Create Product Fee", - s"""Create Product Fee. - | - |${userAuthenticationMessage(true)}""", - productFeeJsonV400.copy(product_fee_id = None), productFeeResponseJsonV400, + s"""Create Product Fee + | + |${userAuthenticationMessage(true)} + | + |""", + productFeeJsonV400.copy(product_fee_id = None), + productFeeResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagProduct), Some(List(canCreateProductFee)), - http4sPartialFunction = Some(createProductFee)) + http4sPartialFunction = Some(createProductFee) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateProductFee), "PUT", + null, + implementedInApiVersion, + nameOf(updateProductFee), + "PUT", "/banks/BANK_ID/products/PRODUCT_CODE/fees/PRODUCT_FEE_ID", "Update Product Fee", - s"""Update Product Fee. - | - |${userAuthenticationMessage(true)}""", - productFeeJsonV400.copy(product_fee_id = None), productFeeResponseJsonV400, + s""" Update Product Fee. + | + |Update one Product Fee by its id. + | + |${userAuthenticationMessage(true)} + | + |""", + productFeeJsonV400.copy(product_fee_id = None), + productFeeResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), List(apiTagProduct), Some(List(canUpdateProductFee)), - http4sPartialFunction = Some(updateProductFee)) + http4sPartialFunction = Some(updateProductFee) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createMyPersonalUserAttribute), "POST", + null, + implementedInApiVersion, + nameOf(createMyPersonalUserAttribute), + "POST", "/my/user/attributes", "Create My Personal User Attribute", - s"""Create My Personal User Attribute. - | - |${userAuthenticationMessage(true)}""", - userAttributeJsonV400, userAttributeResponseJson, + s""" Create My Personal User Attribute + | + |The `type` field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + |${userAuthenticationMessage(true)} + | + |""", + userAttributeJsonV400, + userAttributeResponseJson, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagUser), Some(List()), - http4sPartialFunction = Some(createMyPersonalUserAttribute)) + List(apiTagUser), + Some(List()), + http4sPartialFunction = Some(createMyPersonalUserAttribute) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateMyPersonalUserAttribute), "PUT", + null, + implementedInApiVersion, + nameOf(updateMyPersonalUserAttribute), + "PUT", "/my/user/attributes/USER_ATTRIBUTE_ID", "Update My Personal User Attribute", - s"""Update My Personal User Attribute. - | - |${userAuthenticationMessage(true)}""", - userAttributeJsonV400, userAttributeResponseJson, + s"""Update My Personal User Attribute for current user by USER_ATTRIBUTE_ID + | + |The type field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + |${userAuthenticationMessage(true)} + | + |""", + userAttributeJsonV400, + userAttributeResponseJson, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagUser), Some(List()), - http4sPartialFunction = Some(updateMyPersonalUserAttribute)) + List(apiTagUser), + Some(List()), + http4sPartialFunction = Some(updateMyPersonalUserAttribute) + ) } initBatch10ResourceDocs() @@ -3926,22 +5225,41 @@ object Http4s400 { private def initBatch11ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getUserInvitationAnonymous), "POST", + null, + implementedInApiVersion, + nameOf(getUserInvitationAnonymous), + "POST", "/banks/BANK_ID/user-invitations", - "Get User Invitation (Anonymous)", - s"""Get User Invitation.""", - PostUserInvitationAnonymousJsonV400(1L), userInvitationJsonV400, - List($BankNotFound, InvalidJsonFormat, UnknownError), - List(apiTagUserInvitation), None, - http4sPartialFunction = Some(getUserInvitationAnonymous)) + "Get User Invitation Information", + s"""Get User Invitation Information. + | + |${userAuthenticationMessage(false)} + |""", + PostUserInvitationAnonymousJsonV400(secret_key = 5819479115482092878L), + userInvitationJsonV400, + List( + $BankNotFound, + UserCustomerLinksNotFoundForUser, + CannotGetUserInvitation, + CannotFindUserInvitation, + UnknownError + ), + List(apiTagUserInvitation, apiTagKyc), + None, + http4sPartialFunction = Some(getUserInvitationAnonymous) + ) staticResourceDocs += ResourceDoc( null, implementedInApiVersion, "grantUserAccessToView", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/account-access/grant", "Grant User access to View", - s"""Grant User access to View. - | - |${userAuthenticationMessage(true)} and the user needs to be account holder.""", + s"""Grants the User identified by USER_ID access to the view identified by VIEW_ID. + | + |${userAuthenticationMessage( + true + )} and the user needs to be account holder. + | + |""", postAccountAccessJsonV400, viewJsonV300, List($AuthenticatedUserIsRequired, UserLacksPermissionCanGrantAccessToViewForTargetAccount, @@ -3954,9 +5272,13 @@ object Http4s400 { null, implementedInApiVersion, "revokeUserAccessToView", "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/account-access/revoke", "Revoke User access to View", - s"""Revoke User access to View. - | - |${userAuthenticationMessage(true)} and the user needs to be account holder.""", + s"""Revoke the User identified by USER_ID access to the view identified by VIEW_ID. + | + |${userAuthenticationMessage( + true + )} and the user needs to be account holder. + | + |""", postAccountAccessJsonV400, revokedJsonV400, List($AuthenticatedUserIsRequired, UserLacksPermissionCanRevokeAccessToViewForTargetAccount, @@ -3969,9 +5291,13 @@ object Http4s400 { null, implementedInApiVersion, "revokeGrantUserAccessToViews", "PUT", "/banks/BANK_ID/accounts/ACCOUNT_ID/account-access", "Revoke/Grant User access to View", - s"""Revoke/Grant User access to View. - | - |${userAuthenticationMessage(true)} and the user needs to be an account holder or has owner view access.""", + s"""Revoke/Grant the logged in User access to the views identified by json. + | + |${userAuthenticationMessage( + true + )} and the user needs to be an account holder or has owner view access. + | + |""", postRevokeGrantAccountAccessJsonV400, revokedJsonV400, List($AuthenticatedUserIsRequired, UserLacksPermissionCanGrantAccessToViewForTargetAccount, @@ -3981,69 +5307,139 @@ object Http4s400 { http4sPartialFunction = Some(revokeGrantUserAccessToViews)) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createMyApiCollection), "POST", + null, + implementedInApiVersion, + nameOf(createMyApiCollection), + "POST", "/my/api-collections", "Create My Api Collection", - s"""Create My Api Collection. - | - |${userAuthenticationMessage(true)}""", - postApiCollectionJson400, apiCollectionJson400, + s"""Create Api Collection for logged in user. + | + |${userAuthenticationMessage(true)} + |""".stripMargin, + postApiCollectionJson400, + apiCollectionJson400, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UserNotFoundByUserId, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(createMyApiCollection)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(createMyApiCollection) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createMyApiCollectionEndpoint), "POST", + null, + implementedInApiVersion, + nameOf(createMyApiCollectionEndpoint), + "POST", "/my/api-collections/API_COLLECTION_NAME/api-collection-endpoints", "Create My Api Collection Endpoint", - s"""Create My Api Collection Endpoint. - | - |${userAuthenticationMessage(true)}""", - postApiCollectionEndpointJson400, apiCollectionEndpointJson400, + s"""Create Api Collection Endpoint. + | + |${Glossary.getGlossaryItem("API Collections")} + | + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + postApiCollectionEndpointJson400, + apiCollectionEndpointJson400, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(createMyApiCollectionEndpoint)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(createMyApiCollectionEndpoint) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createMyApiCollectionEndpointById), "POST", + null, + implementedInApiVersion, + nameOf(createMyApiCollectionEndpointById), + "POST", "/my/api-collection-ids/API_COLLECTION_ID/api-collection-endpoints", "Create My Api Collection Endpoint By Id", - s"""Create My Api Collection Endpoint By Id. - | - |${userAuthenticationMessage(true)}""", - postApiCollectionEndpointJson400, apiCollectionEndpointJson400, + s"""Create Api Collection Endpoint By Id. + | + |${Glossary.getGlossaryItem("API Collections")} + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + postApiCollectionEndpointJson400, + apiCollectionEndpointJson400, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(createMyApiCollectionEndpointById)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(createMyApiCollectionEndpointById) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateConsentStatus), "PUT", + null, + implementedInApiVersion, + nameOf(updateConsentStatus), + "PUT", "/banks/BANK_ID/consents/CONSENT_ID", "Update Consent Status", - s"""Update Consent Status. - | - |${userAuthenticationMessage(true)}""", + s""" + | + | + |This endpoint is used to update the Status of Consent. + | + |Each Consent has one of the following states: ${ConsentStatus.values.toList.sorted + .mkString(", ")}. + | + |${userAuthenticationMessage(true)} + | + |""", PutConsentStatusJsonV400(status = "AUTHORISED"), - code.api.v3_1_0.ConsentChallengeJsonV310( - "9d429899-24f5-42c8-8565-943ffa6a7945", "...", "AUTHORISED"), + ConsentChallengeJsonV310( + consent_id = "9d429899-24f5-42c8-8565-943ffa6a7945", + jwt = + "eyJhbGciOiJIUzI1NiJ9.eyJlbnRpdGxlbWVudHMiOltdLCJjcmVhdGVkQnlVc2VySWQiOiJhYjY1MzlhOS1iMTA1LTQ0ODktYTg4My0wYWQ4ZDZjNjE2NTciLCJzdWIiOiIyMWUxYzhjYy1mOTE4LTRlYWMtYjhlMy01ZTVlZWM2YjNiNGIiLCJhdWQiOiJlanpuazUwNWQxMzJyeW9tbmhieDFxbXRvaHVyYnNiYjBraWphanNrIiwibmJmIjoxNTUzNTU0ODk5LCJpc3MiOiJodHRwczpcL1wvd3d3Lm9wZW5iYW5rcHJvamVjdC5jb20iLCJleHAiOjE1NTM1NTg0OTksImlhdCI6MTU1MzU1NDg5OSwianRpIjoiMDlmODhkNWYtZWNlNi00Mzk4LThlOTktNjYxMWZhMWNkYmQ1Iiwidmlld3MiOlt7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAxIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifSx7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAyIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifV19.8cc7cBEf2NyQvJoukBCmDLT7LXYcuzTcSYLqSpbxLp4", + status = "AUTHORISED" + ), List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, - InvalidConnectorResponse, UnknownError), - apiTagConsent :: apiTagPSD2AIS :: Nil, None, - http4sPartialFunction = Some(updateConsentStatus)) + InvalidConnectorResponse, UnknownError), + apiTagConsent :: apiTagPSD2AIS :: Nil, + None, + http4sPartialFunction = Some(updateConsentStatus) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(addConsentUser), "PUT", + null, + implementedInApiVersion, + nameOf(addConsentUser), + "PUT", "/banks/BANK_ID/consents/CONSENT_ID/user-update-request", "Add User to a Consent", - s"""Add User to a Consent. - | - |${userAuthenticationMessage(true)}""", - PutConsentUserJsonV400("uuid-user"), - code.api.v3_1_0.ConsentJsonV310("9d429899-24f5-42c8-8565-943ffa6a7945", "...", "AUTHORISED"), - List($AuthenticatedUserIsRequired, $BankNotFound, UserNotFoundByUserId, - ConsentUserAlreadyAdded, InvalidJsonFormat, ConsentNotFound, UnknownError), - apiTagConsent :: apiTagPSD2AIS :: Nil, None, - http4sPartialFunction = Some(addConsentUser)) + s""" + | + | + |This endpoint is used to add the User of Consent. + | + |Each Consent has one of the following states: ${ConsentStatus.values.toList.sorted + .mkString(", ")}. + | + |${userAuthenticationMessage(true)} + | + |""", + PutConsentUserJsonV400(user_id = "ed7a7c01-db37-45cc-ba12-0ae8891c195c"), + ConsentChallengeJsonV310( + consent_id = "9d429899-24f5-42c8-8565-943ffa6a7945", + jwt = + "eyJhbGciOiJIUzI1NiJ9.eyJlbnRpdGxlbWVudHMiOltdLCJjcmVhdGVkQnlVc2VySWQiOiJhYjY1MzlhOS1iMTA1LTQ0ODktYTg4My0wYWQ4ZDZjNjE2NTciLCJzdWIiOiIyMWUxYzhjYy1mOTE4LTRlYWMtYjhlMy01ZTVlZWM2YjNiNGIiLCJhdWQiOiJlanpuazUwNWQxMzJyeW9tbmhieDFxbXRvaHVyYnNiYjBraWphanNrIiwibmJmIjoxNTUzNTU0ODk5LCJpc3MiOiJodHRwczpcL1wvd3d3Lm9wZW5iYW5rcHJvamVjdC5jb20iLCJleHAiOjE1NTM1NTg0OTksImlhdCI6MTU1MzU1NDg5OSwianRpIjoiMDlmODhkNWYtZWNlNi00Mzk4LThlOTktNjYxMWZhMWNkYmQ1Iiwidmlld3MiOlt7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAxIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifSx7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAyIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifV19.8cc7cBEf2NyQvJoukBCmDLT7LXYcuzTcSYLqSpbxLp4", + status = "AUTHORISED" + ), + List( + $AuthenticatedUserIsRequired, + UserNotFoundByUserId, + $BankNotFound, + ConsentUserAlreadyAdded, + InvalidJsonFormat, + ConsentNotFound, + UnknownError + ), + apiTagConsent :: apiTagPSD2AIS :: Nil, + None, + http4sPartialFunction = Some(addConsentUser) + ) } initBatch11ResourceDocs() @@ -4217,87 +5613,180 @@ object Http4s400 { private def initBatch12ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createDirectDebit), "POST", + null, + implementedInApiVersion, + nameOf(createDirectDebit), + "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/direct-debit", "Create Direct Debit", - s"""Create direct debit for an account.""", - postDirectDebitJsonV400, directDebitJsonV400, - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - NoViewPermission, InvalidJsonFormat, CustomerNotFoundByCustomerId, - UserNotFoundByUserId, CounterpartyNotFoundByCounterpartyId, UnknownError), - List(apiTagDirectDebit, apiTagAccount), None, - http4sPartialFunction = Some(createDirectDebit)) + s"""Create direct debit for an account. + | + |""", + postDirectDebitJsonV400, + directDebitJsonV400, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + $BankAccountNotFound, + NoViewPermission, + $UserNoPermissionAccessView, + InvalidJsonFormat, + CustomerNotFoundByCustomerId, + UserNotFoundByUserId, + CounterpartyNotFoundByCounterpartyId, + UnknownError + ), + List(apiTagDirectDebit, apiTagAccount), + None, + http4sPartialFunction = Some(createDirectDebit) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createDirectDebitManagement), "POST", + null, + implementedInApiVersion, + nameOf(createDirectDebitManagement), + "POST", "/management/banks/BANK_ID/accounts/ACCOUNT_ID/direct-debit", "Create Direct Debit (management)", - s"""Create direct debit for an account.""", - postDirectDebitJsonV400, directDebitJsonV400, + s"""Create direct debit for an account. + | + |""", + postDirectDebitJsonV400, + directDebitJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - NoViewPermission, InvalidJsonFormat, CustomerNotFoundByCustomerId, - UserNotFoundByUserId, CounterpartyNotFoundByCounterpartyId, UnknownError), + NoViewPermission, InvalidJsonFormat, CustomerNotFoundByCustomerId, + UserNotFoundByUserId, CounterpartyNotFoundByCounterpartyId, UnknownError), List(apiTagDirectDebit, apiTagAccount), Some(List(canCreateDirectDebitAtOneBank)), - http4sPartialFunction = Some(createDirectDebitManagement)) + http4sPartialFunction = Some(createDirectDebitManagement) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createStandingOrder), "POST", + null, + implementedInApiVersion, + nameOf(createStandingOrder), + "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/standing-order", "Create Standing Order", - s"""Create standing order for an account.""", - postStandingOrderJsonV400, standingOrderJsonV400, - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - NoViewPermission, InvalidJsonFormat, InvalidNumber, InvalidISOCurrencyCode, - CustomerNotFoundByCustomerId, UserNotFoundByUserId, UnknownError), - List(apiTagStandingOrder, apiTagAccount), None, - http4sPartialFunction = Some(createStandingOrder)) + s"""Create standing order for an account. + | + |when -> frequency = {‘YEARLY’,’MONTHLY, ‘WEEKLY’, ‘BI-WEEKLY’, DAILY’} + |when -> detail = { ‘FIRST_MONDAY’, ‘FIRST_DAY’, ‘LAST_DAY’}} + | + |""", + postStandingOrderJsonV400, + standingOrderJsonV400, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + $BankAccountNotFound, + NoViewPermission, + InvalidJsonFormat, + InvalidNumber, + InvalidISOCurrencyCode, + CustomerNotFoundByCustomerId, + UserNotFoundByUserId, + $UserNoPermissionAccessView, + UnknownError + ), + List(apiTagStandingOrder, apiTagAccount), + None, + http4sPartialFunction = Some(createStandingOrder) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createStandingOrderManagement), "POST", + null, + implementedInApiVersion, + nameOf(createStandingOrderManagement), + "POST", "/management/banks/BANK_ID/accounts/ACCOUNT_ID/standing-order", "Create Standing Order (management)", - s"""Create standing order for an account.""", - postStandingOrderJsonV400, standingOrderJsonV400, + s"""Create standing order for an account. + | + |when -> frequency = {‘YEARLY’,’MONTHLY, ‘WEEKLY’, ‘BI-WEEKLY’, DAILY’} + |when -> detail = { ‘FIRST_MONDAY’, ‘FIRST_DAY’, ‘LAST_DAY’}} + | + | + |""", + postStandingOrderJsonV400, + standingOrderJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, - NoViewPermission, InvalidJsonFormat, InvalidNumber, InvalidISOCurrencyCode, - CustomerNotFoundByCustomerId, UserNotFoundByUserId, UnknownError), + NoViewPermission, InvalidJsonFormat, InvalidNumber, InvalidISOCurrencyCode, + CustomerNotFoundByCustomerId, UserNotFoundByUserId, UnknownError), List(apiTagStandingOrder, apiTagAccount), Some(List(canCreateStandingOrderAtOneBank)), - http4sPartialFunction = Some(createStandingOrderManagement)) + http4sPartialFunction = Some(createStandingOrderManagement) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createSystemAccountNotificationWebhook), "POST", + null, + implementedInApiVersion, + nameOf(createSystemAccountNotificationWebhook), + "POST", "/web-hooks/account/notifications/on-create-transaction", - "Create System Level Account Notification Webhook", - s"""Create System Level Account Notification Webhook.""", - accountNotificationWebhookPostJson, systemAccountNotificationWebhookJson, + "Create system level Account Notification Webhook", + s""" + |Create a notification Webhook that will fire for all accounts on the system. + | + |$generalWebHookInfo + | + |$accountNotificationWebhookInfo + | + |""", + accountNotificationWebhookPostJson, + systemAccountNotificationWebhookJson, List(UnknownError), apiTagWebhook :: apiTagBank :: Nil, Some(List(canCreateSystemAccountNotificationWebhook)), - http4sPartialFunction = Some(createSystemAccountNotificationWebhook)) + http4sPartialFunction = Some(createSystemAccountNotificationWebhook) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createBankAccountNotificationWebhook), "POST", + null, + implementedInApiVersion, + nameOf(createBankAccountNotificationWebhook), + "POST", "/banks/BANK_ID/web-hooks/account/notifications/on-create-transaction", "Create bank level Account Notification Webhook", - s"""Create bank level Account Notification Webhook.""", - accountNotificationWebhookPostJson, bankAccountNotificationWebhookJson, + s"""Create a notification Webhook that will fire for all accounts on the specified Bank. + | + |$generalWebHookInfo + | + |$accountNotificationWebhookInfo + | + |""", + accountNotificationWebhookPostJson, + bankAccountNotificationWebhookJson, List(AuthenticatedUserIsRequired, $BankNotFound, UnknownError), apiTagWebhook :: apiTagBank :: Nil, Some(List(canCreateAccountNotificationWebhookAtOneBank)), - http4sPartialFunction = Some(createBankAccountNotificationWebhook)) + http4sPartialFunction = Some(createBankAccountNotificationWebhook) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getFastFirehoseAccountsAtOneBank), "GET", + null, + implementedInApiVersion, + nameOf(getFastFirehoseAccountsAtOneBank), + "GET", "/management/banks/BANK_ID/fast-firehose/accounts", "Get Fast Firehose Accounts at Bank", - s"""Get Fast Firehose Accounts at Bank.""", - EmptyBody, fastFirehoseAccountsJsonV400, + s""" + | + |This endpoint allows bulk access to accounts. + | + |optional pagination parameters for filter with accounts + |${urlParametersDocument(true, false)} + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + EmptyBody, + fastFirehoseAccountsJsonV400, List($BankNotFound), List(apiTagAccount, apiTagAccountFirehose, apiTagFirehoseData), Some(List(canUseAccountFirehoseAtAnyBank, code.api.util.ApiRole.canUseAccountFirehose)), - http4sPartialFunction = Some(getFastFirehoseAccountsAtOneBank)) + http4sPartialFunction = Some(getFastFirehoseAccountsAtOneBank) + ) } initBatch12ResourceDocs() @@ -4389,81 +5878,172 @@ object Http4s400 { private def initBatch7ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createOrUpdateCustomerAttributeAttributeDefinition), "PUT", + null, + implementedInApiVersion, + nameOf(createOrUpdateCustomerAttributeAttributeDefinition), + "PUT", "/banks/BANK_ID/attribute-definitions/customer", "Create or Update Customer Attribute Definition", - s"""Create or Update Customer Attribute Definition.""".stripMargin, - customerAttributeDefinitionJsonV400, customerAttributeDefinitionResponseJsonV400, + s""" Create or Update Customer Attribute Definition + | + |The category field must be one of: ${AttributeCategory.Customer} + | + |The type field must be one of; ${AttributeType.DOUBLE}, ${AttributeType.STRING}, ${AttributeType.INTEGER} and ${AttributeType.DATE_WITH_DAY} + | + |${userAuthenticationMessage(true)} + | + |""", + templateAttributeDefinitionJsonV400, + templateAttributeDefinitionResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagCustomer, apiTagCustomerAttribute, apiTagAttribute), Some(List(canCreateCustomerAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(createOrUpdateCustomerAttributeAttributeDefinition)) + http4sPartialFunction = Some(createOrUpdateCustomerAttributeAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createOrUpdateAccountAttributeDefinition), "PUT", + null, + implementedInApiVersion, + nameOf(createOrUpdateAccountAttributeDefinition), + "PUT", "/banks/BANK_ID/attribute-definitions/account", "Create or Update Account Attribute Definition", - s"""Create or Update Account Attribute Definition.""".stripMargin, - accountAttributeDefinitionJsonV400, accountAttributeDefinitionResponseJsonV400, + s""" Create or Update Account Attribute Definition + | + |The category field must be ${AttributeCategory.Account} + | + |The type field must be one of; ${AttributeType.DOUBLE}, ${AttributeType.STRING}, ${AttributeType.INTEGER} and ${AttributeType.DATE_WITH_DAY} + | + |${userAuthenticationMessage(true)} + | + |""", + accountAttributeDefinitionJsonV400, + accountAttributeDefinitionResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagAccount, apiTagAccountAttribute, apiTagAttribute), Some(List(canCreateAccountAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(createOrUpdateAccountAttributeDefinition)) + http4sPartialFunction = Some(createOrUpdateAccountAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createOrUpdateProductAttributeDefinition), "PUT", + null, + implementedInApiVersion, + nameOf(createOrUpdateProductAttributeDefinition), + "PUT", "/banks/BANK_ID/attribute-definitions/product", "Create or Update Product Attribute Definition", - s"""Create or Update Product Attribute Definition.""".stripMargin, - productAttributeDefinitionJsonV400, productAttributeDefinitionResponseJsonV400, + s""" Create or Update Product Attribute Definition + | + |The category field must be ${AttributeCategory.Product} + | + |The type field must be one of; ${AttributeType.DOUBLE}, ${AttributeType.STRING}, ${AttributeType.INTEGER} and ${AttributeType.DATE_WITH_DAY} + | + |${userAuthenticationMessage(true)} + | + |""", + productAttributeDefinitionJsonV400, + productAttributeDefinitionResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagProduct, apiTagProductAttribute, apiTagAttribute), Some(List(canCreateProductAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(createOrUpdateProductAttributeDefinition)) + http4sPartialFunction = Some(createOrUpdateProductAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createOrUpdateTransactionAttributeDefinition), "PUT", + null, + implementedInApiVersion, + nameOf(createOrUpdateTransactionAttributeDefinition), + "PUT", "/banks/BANK_ID/attribute-definitions/transaction", "Create or Update Transaction Attribute Definition", - s"""Create or Update Transaction Attribute Definition.""".stripMargin, - transactionAttributeDefinitionJsonV400, transactionAttributeDefinitionResponseJsonV400, + s""" Create or Update Transaction Attribute Definition + | + |The category field must be ${AttributeCategory.Transaction} + | + |The type field must be one of; ${AttributeType.DOUBLE}, ${AttributeType.STRING}, ${AttributeType.INTEGER} and ${AttributeType.DATE_WITH_DAY} + | + |${userAuthenticationMessage(true)} + | + |""", + transactionAttributeDefinitionJsonV400, + transactionAttributeDefinitionResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagTransaction, apiTagTransactionAttribute, apiTagAttribute), Some(List(canCreateTransactionAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(createOrUpdateTransactionAttributeDefinition)) + http4sPartialFunction = Some(createOrUpdateTransactionAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createOrUpdateCardAttributeDefinition), "PUT", + null, + implementedInApiVersion, + nameOf(createOrUpdateCardAttributeDefinition), + "PUT", "/banks/BANK_ID/attribute-definitions/card", "Create or Update Card Attribute Definition", - s"""Create or Update Card Attribute Definition.""".stripMargin, - cardAttributeDefinitionJsonV400, cardAttributeDefinitionResponseJsonV400, + s""" Create or Update Card Attribute Definition + | + |The category field must be ${AttributeCategory.Card} + | + |The type field must be one of; ${AttributeType.DOUBLE}, ${AttributeType.STRING}, ${AttributeType.INTEGER} and ${AttributeType.DATE_WITH_DAY} + | + |${userAuthenticationMessage(true)} + | + |""", + cardAttributeDefinitionJsonV400, + cardAttributeDefinitionResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagCard, apiTagCardAttribute, apiTagAttribute), Some(List(canCreateCardAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(createOrUpdateCardAttributeDefinition)) + http4sPartialFunction = Some(createOrUpdateCardAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createOrUpdateTransactionRequestAttributeDefinition), "PUT", + null, + implementedInApiVersion, + nameOf(createOrUpdateTransactionRequestAttributeDefinition), + "PUT", "/banks/BANK_ID/attribute-definitions/transaction-request", "Create or Update Transaction Request Attribute Definition", - s"""Create or Update Transaction Request Attribute Definition.""".stripMargin, - transactionRequestAttributeDefinitionJsonV400, transactionRequestAttributeDefinitionResponseJsonV400, + s""" Create or Update Transaction Request Attribute Definition + | + |The category field must be ${AttributeCategory.TransactionRequest} + | + |The type field must be one of: ${AttributeType.DOUBLE}, ${AttributeType.STRING}, ${AttributeType.INTEGER} and ${AttributeType.DATE_WITH_DAY} + | + |${userAuthenticationMessage(true)} + | + |""", + transactionRequestAttributeDefinitionJsonV400, + transactionRequestAttributeDefinitionResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagTransactionRequest, apiTagTransactionRequestAttribute, apiTagAttribute), Some(List(canCreateTransactionRequestAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(createOrUpdateTransactionRequestAttributeDefinition)) + http4sPartialFunction = Some(createOrUpdateTransactionRequestAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createOrUpdateBankAttributeDefinition), "PUT", + null, + implementedInApiVersion, + nameOf(createOrUpdateBankAttributeDefinition), + "PUT", "/banks/BANK_ID/attribute-definitions/bank", "Create or Update Bank Attribute Definition", - s"""Create or Update Bank Attribute Definition.""".stripMargin, - bankAttributeDefinitionJsonV400, bankAttributeDefinitionResponseJsonV400, + s""" Create or Update Bank Attribute Definition + | + |The category field must be ${AttributeCategory.Bank} + | + |The type field must be one of; ${AttributeType.DOUBLE}, ${AttributeType.STRING}, ${AttributeType.INTEGER} and ${AttributeType.DATE_WITH_DAY} + | + |${userAuthenticationMessage(true)} + | + |""", + bankAttributeDefinitionJsonV400, + bankAttributeDefinitionResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagBank, apiTagBankAttribute, apiTagAttribute), Some(List(canCreateBankAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(createOrUpdateBankAttributeDefinition)) + http4sPartialFunction = Some(createOrUpdateBankAttributeDefinition) + ) } initBatch7ResourceDocs() @@ -4556,75 +6136,122 @@ object Http4s400 { private def initBatch6ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateAtmSupportedCurrencies), "PUT", + null, + implementedInApiVersion, + nameOf(updateAtmSupportedCurrencies), + "PUT", "/banks/BANK_ID/atms/ATM_ID/supported-currencies", "Update ATM Supported Currencies", - s"""Update ATM Supported Currencies.""".stripMargin, - supportedCurrenciesJson, atmSupportedCurrenciesJson, + s"""Update ATM Supported Currencies. + |""", + supportedCurrenciesJson, + atmSupportedCurrenciesJson, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagATM), None, - http4sPartialFunction = Some(updateAtmSupportedCurrencies)) + List(apiTagATM), + None, + http4sPartialFunction = Some(updateAtmSupportedCurrencies) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateAtmSupportedLanguages), "PUT", + null, + implementedInApiVersion, + nameOf(updateAtmSupportedLanguages), + "PUT", "/banks/BANK_ID/atms/ATM_ID/supported-languages", "Update ATM Supported Languages", - s"""Update ATM Supported Languages.""".stripMargin, - supportedLanguagesJson, atmSupportedLanguagesJson, + s"""Update ATM Supported Languages. + |""", + supportedLanguagesJson, + atmSupportedLanguagesJson, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagATM), None, - http4sPartialFunction = Some(updateAtmSupportedLanguages)) + List(apiTagATM), + None, + http4sPartialFunction = Some(updateAtmSupportedLanguages) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateAtmAccessibilityFeatures), "PUT", + null, + implementedInApiVersion, + nameOf(updateAtmAccessibilityFeatures), + "PUT", "/banks/BANK_ID/atms/ATM_ID/accessibility-features", "Update ATM Accessibility Features", - s"""Update ATM Accessibility Features.""".stripMargin, - accessibilityFeaturesJson, atmAccessibilityFeaturesJson, + s"""Update ATM Accessibility Features. + |""", + accessibilityFeaturesJson, + atmAccessibilityFeaturesJson, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagATM), None, - http4sPartialFunction = Some(updateAtmAccessibilityFeatures)) + List(apiTagATM), + None, + http4sPartialFunction = Some(updateAtmAccessibilityFeatures) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateAtmServices), "PUT", + null, + implementedInApiVersion, + nameOf(updateAtmServices), + "PUT", "/banks/BANK_ID/atms/ATM_ID/services", "Update ATM Services", - s"""Update ATM Services.""".stripMargin, - atmServicesJson, atmServicesResponseJson, + s"""Update ATM Services. + |""", + atmServicesJson, + atmServicesResponseJson, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagATM), None, - http4sPartialFunction = Some(updateAtmServices)) + List(apiTagATM), + None, + http4sPartialFunction = Some(updateAtmServices) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateAtmNotes), "PUT", + null, + implementedInApiVersion, + nameOf(updateAtmNotes), + "PUT", "/banks/BANK_ID/atms/ATM_ID/notes", "Update ATM Notes", - s"""Update ATM Notes.""".stripMargin, - atmNotesJson, atmNotesResponseJson, + s"""Update ATM Notes. + |""", + atmNotesJson, + atmNotesResponseJson, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagATM), None, - http4sPartialFunction = Some(updateAtmNotes)) + List(apiTagATM), + None, + http4sPartialFunction = Some(updateAtmNotes) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateAtmLocationCategories), "PUT", + null, + implementedInApiVersion, + nameOf(updateAtmLocationCategories), + "PUT", "/banks/BANK_ID/atms/ATM_ID/location-categories", "Update ATM Location Categories", - s"""Update ATM Location Categories.""".stripMargin, - atmLocationCategoriesJsonV400, atmLocationCategoriesResponseJsonV400, + s"""Update ATM Location Categories. + |""", + atmLocationCategoriesJsonV400, + atmLocationCategoriesResponseJsonV400, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagATM), None, - http4sPartialFunction = Some(updateAtmLocationCategories)) + List(apiTagATM), + None, + http4sPartialFunction = Some(updateAtmLocationCategories) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateAtm), "PUT", + null, + implementedInApiVersion, + nameOf(updateAtm), + "PUT", "/banks/BANK_ID/atms/ATM_ID", - "Update ATM", - s"""Update ATM.""".stripMargin, - atmJsonV400, atmJsonV400, + "UPDATE ATM", + s"""Update ATM.""", + atmJsonV400.copy(id = None), + atmJsonV400, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), List(apiTagATM), Some(List(canUpdateAtm, canCreateAtmAtAnyBank)), - http4sPartialFunction = Some(updateAtm)) + http4sPartialFunction = Some(updateAtm) + ) } initBatch6ResourceDocs() @@ -4824,198 +6451,362 @@ object Http4s400 { private def initBatch5ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getProductFee), "GET", + null, + implementedInApiVersion, + nameOf(getProductFee), + "GET", "/banks/BANK_ID/products/PRODUCT_CODE/fees/PRODUCT_FEE_ID", "Get Product Fee", - s"""Get Product Fee""".stripMargin, - EmptyBody, productFeeResponseJsonV400, + s""" Get Product Fee + | + |Get one product fee by its id. + | + |${userAuthenticationMessage(false)} + | + |""", + EmptyBody, + productFeeResponseJsonV400, List($BankNotFound, UnknownError), - List(apiTagProduct), None, - http4sPartialFunction = Some(getProductFee)) + List(apiTagProduct), + None, + http4sPartialFunction = Some(getProductFee) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getProductFees), "GET", + null, + implementedInApiVersion, + nameOf(getProductFees), + "GET", "/banks/BANK_ID/products/PRODUCT_CODE/fees", "Get Product Fees", - s"""Get Product Fees""".stripMargin, - EmptyBody, productFeesResponseJsonV400, + s"""Get Product Fees + | + |${userAuthenticationMessage(false)} + | + |""", + EmptyBody, + productFeesResponseJsonV400, List($BankNotFound, UnknownError), - List(apiTagProduct), None, - http4sPartialFunction = Some(getProductFees)) + List(apiTagProduct), + None, + http4sPartialFunction = Some(getProductFees) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getTransactionAttributes), "GET", + null, + implementedInApiVersion, + nameOf(getTransactionAttributes), + "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/transactions/TRANSACTION_ID/attributes", "Get Transaction Attributes", - s"""Get Transaction Attributes - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, transactionAttributesResponseJson, + s""" Get Transaction Attributes + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + transactionAttributesResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, InvalidJsonFormat, UnknownError), List(apiTagTransaction, apiTagTransactionAttribute, apiTagAttribute), Some(List(canGetTransactionAttributesAtOneBank)), - http4sPartialFunction = Some(getTransactionAttributes)) + http4sPartialFunction = Some(getTransactionAttributes) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getTransactionAttributeById), "GET", + null, + implementedInApiVersion, + nameOf(getTransactionAttributeById), + "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/transactions/TRANSACTION_ID/attributes/ATTRIBUTE_ID", "Get Transaction Attribute By Id", - s"""Get Transaction Attribute By Id - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, transactionAttributeResponseJson, + s""" Get Transaction Attribute By Id + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + transactionAttributeResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, InvalidJsonFormat, UnknownError), List(apiTagTransaction, apiTagTransactionAttribute, apiTagAttribute), Some(List(canGetTransactionAttributeAtOneBank)), - http4sPartialFunction = Some(getTransactionAttributeById)) + http4sPartialFunction = Some(getTransactionAttributeById) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getTransactionRequestAttributes), "GET", + null, + implementedInApiVersion, + nameOf(getTransactionRequestAttributes), + "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/transaction-requests/TRANSACTION_REQUEST_ID/attributes", "Get Transaction Request Attributes", - s"""Get Transaction Request Attributes - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, transactionRequestAttributesResponseJson, + s""" Get Transaction Request Attributes + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + transactionRequestAttributesResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, InvalidJsonFormat, UnknownError), List(apiTagTransactionRequest, apiTagTransactionRequestAttribute, apiTagAttribute), Some(List(canGetTransactionRequestAttributesAtOneBank)), - http4sPartialFunction = Some(getTransactionRequestAttributes)) + http4sPartialFunction = Some(getTransactionRequestAttributes) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getTransactionRequestAttributeById), "GET", + null, + implementedInApiVersion, + nameOf(getTransactionRequestAttributeById), + "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/transaction-requests/TRANSACTION_REQUEST_ID/attributes/ATTRIBUTE_ID", "Get Transaction Request Attribute By Id", - s"""Get Transaction Request Attribute By Id - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, transactionRequestAttributeResponseJson, + s""" Get Transaction Request Attribute By Id + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + transactionRequestAttributeResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, InvalidJsonFormat, UnknownError), List(apiTagTransactionRequest, apiTagTransactionRequestAttribute, apiTagAttribute), Some(List(canGetTransactionRequestAttributeAtOneBank)), - http4sPartialFunction = Some(getTransactionRequestAttributeById)) + http4sPartialFunction = Some(getTransactionRequestAttributeById) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getTransactionRequestAttributeDefinition), "GET", + null, + implementedInApiVersion, + nameOf(getTransactionRequestAttributeDefinition), + "GET", "/banks/BANK_ID/attribute-definitions/transaction-request", "Get Transaction Request Attribute Definition", - s"""Get Transaction Request Attribute Definition - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, transactionRequestAttributeDefinitionsResponseJsonV400, + s""" Get Transaction Request Attribute Definition + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + transactionRequestAttributeDefinitionsResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagTransactionRequest, apiTagTransactionRequestAttribute, apiTagAttribute), Some(List(canGetTransactionRequestAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(getTransactionRequestAttributeDefinition)) + http4sPartialFunction = Some(getTransactionRequestAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getTransactionRequest), "GET", + null, + implementedInApiVersion, + nameOf(getTransactionRequest), + "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-requests/TRANSACTION_REQUEST_ID", "Get Transaction Request.", - s"""Returns the transaction request specified by TRANSACTION_REQUEST_ID at BANK_ID. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, transactionRequestWithChargeJSON400, - List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, $UserNoPermissionAccessView, UnknownError), - List(apiTagTransactionRequest), None, - http4sPartialFunction = Some(getTransactionRequest)) + """Returns transaction request for transaction specified by TRANSACTION_REQUEST_ID and for account specified by ACCOUNT_ID at bank specified by BANK_ID. + | + |The VIEW_ID specified must be 'owner' and the user must have access to this view. + | + |Version 2.0.0 now returns charge information. + | + |Transaction Requests serve to initiate transactions that may or may not proceed. They contain information including: + | + |* Transaction Request Id + |* Type + |* Status (INITIATED, COMPLETED) + |* Challenge (in order to confirm the request) + |* From Bank / Account + |* Details including Currency, Value, Description and other initiation information specific to each type. (Could potentialy include a list of future transactions.) + |* Related Transactions + | + |PSD2 Context: PSD2 requires transparency of charges to the customer. + |This endpoint provides the charge that would be applied if the Transaction Request proceeds - and a record of that charge there after. + |The customer can proceed with the Transaction by answering the security challenge. + | + """.stripMargin, + EmptyBody, + transactionRequestWithChargeJSON210, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + $BankAccountNotFound, + $UserNoPermissionAccessView, + GetTransactionRequestsException, + UnknownError + ), + List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2), + None, + http4sPartialFunction = Some(getTransactionRequest) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMyCorrelatedEntities), "GET", + null, + implementedInApiVersion, + nameOf(getMyCorrelatedEntities), + "GET", "/my/correlated-entities", "Get Correlated Entities for the current User", s"""Correlated Entities are users and customers linked to the currently authenticated user via User-Customer-Links - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, correlatedUsersResponseJson, + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + correlatedUsersResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), - List(apiTagCustomer), None, - http4sPartialFunction = Some(getMyCorrelatedEntities)) + List(apiTagCustomer), + None, + http4sPartialFunction = Some(getMyCorrelatedEntities) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCorrelatedUsersInfoByCustomerId), "GET", + null, + implementedInApiVersion, + nameOf(getCorrelatedUsersInfoByCustomerId), + "GET", "/banks/BANK_ID/customers/CUSTOMER_ID/correlated-users", "Get Correlated User Info by Customer", s"""Get Correlated User Info by CUSTOMER_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, customerAndUsersWithAttributesResponseJson, + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + customerAndUsersWithAttributesResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagCustomer), Some(List(canGetCorrelatedUsersInfoAtAnyBank, canGetCorrelatedUsersInfo)), - http4sPartialFunction = Some(getCorrelatedUsersInfoByCustomerId)) + http4sPartialFunction = Some(getCorrelatedUsersInfoByCustomerId) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAccountsMinimalByCustomerId), "GET", + null, + implementedInApiVersion, + nameOf(getAccountsMinimalByCustomerId), + "GET", "/customers/CUSTOMER_ID/accounts-minimal", "Get Accounts Minimal for a Customer", - s"""Get Accounts Minimal that are owned by a Customer. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, accountsMinimalJson400, - List($AuthenticatedUserIsRequired, CustomerNotFoundByCustomerId, UnknownError), - List(apiTagCustomer), + s"""Get Accounts Minimal by CUSTOMER_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + accountsMinimalJson400, + List( + $AuthenticatedUserIsRequired, + CustomerNotFound, + UnknownError + ), + List(apiTagAccount), Some(List(canGetAccountsMinimalForCustomerAtOneBank, canGetAccountsMinimalForCustomerAtAnyBank)), - http4sPartialFunction = Some(getAccountsMinimalByCustomerId)) + http4sPartialFunction = Some(getAccountsMinimalByCustomerId) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCustomersByCustomerPhoneNumber), "POST", + null, + implementedInApiVersion, + nameOf(getCustomersByCustomerPhoneNumber), + "POST", "/banks/BANK_ID/search/customers/mobile-phone-number", "Get Customers by MOBILE_PHONE_NUMBER", - s"""Gets the Customers specified by MOBILE_PHONE_NUMBER.""".stripMargin, - postCustomerPhoneNumberJsonV400, customerJsonV310, - List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), - List(apiTagCustomer), + s"""Gets the Customers specified by MOBILE_PHONE_NUMBER. + | + |There are two wildcards often used in conjunction with the LIKE operator: + | % - The percent sign represents zero, one, or multiple characters + | _ - The underscore represents a single character + |For example {"customer_phone_number":"%381%"} lists all numbers which contain 381 sequence + | + |""", + postCustomerPhoneNumberJsonV400, + customerJsonV310, + List( + $AuthenticatedUserIsRequired, + UserCustomerLinksNotFoundForUser, + UnknownError + ), + List(apiTagCustomer, apiTagKyc), Some(List(canGetCustomersAtOneBank)), - http4sPartialFunction = Some(getCustomersByCustomerPhoneNumber)) + http4sPartialFunction = Some(getCustomersByCustomerPhoneNumber) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCustomersAtAnyBank), "GET", + null, + implementedInApiVersion, + nameOf(getCustomersAtAnyBank), + "GET", "/customers", "Get Customers at Any Bank", - s"""Get Customers at Any Bank.""".stripMargin, - EmptyBody, customersJsonV300, + s"""Get Customers at Any Bank. + | + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + customersJsonV300, List(AuthenticatedUserIsRequired, UserCustomerLinksNotFoundForUser, UnknownError), List(apiTagCustomer, apiTagUser), Some(List(canGetCustomersAtAllBanks)), - http4sPartialFunction = Some(getCustomersAtAnyBank)) + http4sPartialFunction = Some(getCustomersAtAnyBank) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCustomersMinimalAtAnyBank), "GET", + null, + implementedInApiVersion, + nameOf(getCustomersMinimalAtAnyBank), + "GET", "/customers-minimal", "Get Customers Minimal at Any Bank", - s"""Get Customers Minimal at Any Bank.""".stripMargin, - EmptyBody, customersMinimalJsonV300, + s"""Get Customers Minimal at Any Bank. + | + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + customersMinimalJsonV300, List(AuthenticatedUserIsRequired, UserCustomerLinksNotFoundForUser, UnknownError), List(apiTagCustomer, apiTagUser), Some(List(canGetCustomersMinimalAtAllBanks)), - http4sPartialFunction = Some(getCustomersMinimalAtAnyBank)) + http4sPartialFunction = Some(getCustomersMinimalAtAnyBank) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getUserInvitation), "GET", + null, + implementedInApiVersion, + nameOf(getUserInvitation), + "GET", "/banks/BANK_ID/user-invitations/SECRET_LINK", "Get User Invitation", - s"""Get User Invitation - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, userInvitationJsonV400, + s""" Get User Invitation + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + userInvitationJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagUserInvitation), Some(List(canGetUserInvitation)), - http4sPartialFunction = Some(getUserInvitation)) + http4sPartialFunction = Some(getUserInvitation) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getUserInvitations), "GET", + null, + implementedInApiVersion, + nameOf(getUserInvitations), + "GET", "/banks/BANK_ID/user-invitations", "Get User Invitations", - s"""Get User Invitations - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, userInvitationJsonV400, + s""" Get User Invitations + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + userInvitationJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagUserInvitation), Some(List(canGetUserInvitation)), - http4sPartialFunction = Some(getUserInvitations)) + http4sPartialFunction = Some(getUserInvitations) + ) } initBatch5ResourceDocs() @@ -5202,165 +6993,333 @@ object Http4s400 { private def initBatch4ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getConsentInfosByBank), "GET", + null, + implementedInApiVersion, + nameOf(getConsentInfosByBank), + "GET", "/banks/BANK_ID/my/consent-infos", "Get My Consents Info At Bank", - s"""This endpoint gets the Consents that the current User created at bank.""".stripMargin, - EmptyBody, consentInfosJsonV400, + s""" + | + |This endpoint gets the Consents that the current User created at bank. + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, + EmptyBody, + consentInfosJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), - List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2), None, - http4sPartialFunction = Some(getConsentInfosByBank)) + List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2), + None, + http4sPartialFunction = Some(getConsentInfosByBank) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getConsentInfos), "GET", + null, + implementedInApiVersion, + nameOf(getConsentInfos), + "GET", "/my/consent-infos", "Get My Consents Info", - s"""This endpoint gets the Consents that the current User created.""".stripMargin, - EmptyBody, consentInfosJsonV400, + s""" + | + |This endpoint gets the Consents that the current User created. + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, + EmptyBody, + consentInfosJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), - List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2), None, - http4sPartialFunction = Some(getConsentInfos)) + List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2), + None, + http4sPartialFunction = Some(getConsentInfos) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMyApiCollectionByName), "GET", + null, + implementedInApiVersion, + nameOf(getMyApiCollectionByName), + "GET", "/my/api-collections/name/API_COLLECTION_NAME", "Get My Api Collection By Name", - s"""Get Api Collection By API_COLLECTION_NAME.""".stripMargin, - EmptyBody, apiCollectionJson400, + s"""Get Api Collection By API_COLLECTION_NAME. + | + |${userAuthenticationMessage(true)} + |""".stripMargin, + EmptyBody, + apiCollectionJson400, List($AuthenticatedUserIsRequired, UserNotFoundByUserId, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(getMyApiCollectionByName)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(getMyApiCollectionByName) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMyApiCollectionById), "GET", + null, + implementedInApiVersion, + nameOf(getMyApiCollectionById), + "GET", "/my/api-collections/API_COLLECTION_ID", "Get My Api Collection By Id", - s"""Get Api Collection By API_COLLECTION_ID.""".stripMargin, - EmptyBody, apiCollectionJson400, + s"""Get Api Collection By API_COLLECTION_ID. + | + |${userAuthenticationMessage(true)} + |""".stripMargin, + EmptyBody, + apiCollectionJson400, List($AuthenticatedUserIsRequired, UserNotFoundByUserId, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(getMyApiCollectionById)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(getMyApiCollectionById) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getSharableApiCollectionById), "GET", + null, + implementedInApiVersion, + nameOf(getSharableApiCollectionById), + "GET", "/api-collections/sharable/API_COLLECTION_ID", "Get Sharable Api Collection By Id", - s"""Get Sharable Api Collection By Id.""".stripMargin, - EmptyBody, apiCollectionJson400, + s"""Get Sharable Api Collection By Id. + |${userAuthenticationMessage(false)} + |""".stripMargin, + EmptyBody, + apiCollectionJson400, List(UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(getSharableApiCollectionById)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(getSharableApiCollectionById) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getApiCollectionsForUser), "GET", + null, + implementedInApiVersion, + nameOf(getApiCollectionsForUser), + "GET", "/users/USER_ID/api-collections", "Get Api Collections for User", - s"""Get Api Collections for User.""".stripMargin, - EmptyBody, apiCollectionsJson400, + s"""Get Api Collections for User. + | + |${userAuthenticationMessage(true)} + |""".stripMargin, + EmptyBody, + apiCollectionsJson400, List(UserNotFoundByUserId, UnknownError), List(apiTagApiCollection), Some(canGetApiCollectionsForUser :: Nil), - http4sPartialFunction = Some(getApiCollectionsForUser)) + http4sPartialFunction = Some(getApiCollectionsForUser) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getFeaturedApiCollections), "GET", + null, + implementedInApiVersion, + nameOf(getFeaturedApiCollections), + "GET", "/api-collections/featured", "Get Featured Api Collections", - s"""Get Featured Api Collections.""".stripMargin, - EmptyBody, apiCollectionsJson400, + s"""Get Featured Api Collections. + | + |${userAuthenticationMessage(false)} + |""".stripMargin, + EmptyBody, + apiCollectionsJson400, List(UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(getFeaturedApiCollections)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(getFeaturedApiCollections) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMyApiCollections), "GET", + null, + implementedInApiVersion, + nameOf(getMyApiCollections), + "GET", "/my/api-collections", "Get My Api Collections", - s"""Get all the apiCollections for logged in user.""".stripMargin, - EmptyBody, apiCollectionsJson400, + s"""Get all the apiCollections for logged in user. + | + |${userAuthenticationMessage(true)} + | + |1 limit (for pagination: defaults to 50) eg:limit=200 + | + |2 offset (for pagination: zero index, defaults to 0) eg: offset=10 + | + |""".stripMargin, + EmptyBody, + apiCollectionsJson400, List($AuthenticatedUserIsRequired, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(getMyApiCollections)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(getMyApiCollections) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMyApiCollectionEndpoint), "GET", + null, + implementedInApiVersion, + nameOf(getMyApiCollectionEndpoint), + "GET", "/my/api-collections/API_COLLECTION_NAME/api-collection-endpoints/OPERATION_ID", "Get My Api Collection Endpoint", - s"""Get Api Collection Endpoint By OPERATION_ID.""".stripMargin, - EmptyBody, apiCollectionEndpointJson400, + s"""Get Api Collection Endpoint By API_COLLECTION_NAME and OPERATION_ID. + | + |${userAuthenticationMessage(false)} + |""".stripMargin, + EmptyBody, + apiCollectionEndpointJson400, List($AuthenticatedUserIsRequired, UserNotFoundByUserId, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(getMyApiCollectionEndpoint)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(getMyApiCollectionEndpoint) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getApiCollectionEndpoints), "GET", + null, + implementedInApiVersion, + nameOf(getApiCollectionEndpoints), + "GET", "/api-collections/API_COLLECTION_ID/api-collection-endpoints", "Get Api Collection Endpoints", - s"""Get Api Collection Endpoints By API_COLLECTION_ID.""".stripMargin, - EmptyBody, apiCollectionEndpointsJson400, + s"""Get Api Collection Endpoints By API_COLLECTION_ID. + | + |${userAuthenticationMessage(false)} + |""".stripMargin, + EmptyBody, + apiCollectionEndpointsJson400, List($AuthenticatedUserIsRequired, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(getApiCollectionEndpoints)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(getApiCollectionEndpoints) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMyApiCollectionEndpoints), "GET", + null, + implementedInApiVersion, + nameOf(getMyApiCollectionEndpoints), + "GET", "/my/api-collections/API_COLLECTION_NAME/api-collection-endpoints", "Get My Api Collection Endpoints", - s"""Get Api Collection Endpoints By API_COLLECTION_NAME.""".stripMargin, - EmptyBody, apiCollectionEndpointsJson400, + s"""Get Api Collection Endpoints By API_COLLECTION_NAME. + | + |${userAuthenticationMessage(true)} + |""".stripMargin, + EmptyBody, + apiCollectionEndpointsJson400, List($AuthenticatedUserIsRequired, UserNotFoundByUserId, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(getMyApiCollectionEndpoints)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(getMyApiCollectionEndpoints) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMyApiCollectionEndpointsById), "GET", + null, + implementedInApiVersion, + nameOf(getMyApiCollectionEndpointsById), + "GET", "/my/api-collection-ids/API_COLLECTION_ID/api-collection-endpoints", "Get My Api Collection Endpoints By Id", - s"""Get Api Collection Endpoints By API_COLLECTION_ID.""".stripMargin, - EmptyBody, apiCollectionEndpointsJson400, + s"""Get Api Collection Endpoints By API_COLLECTION_ID. + | + |${userAuthenticationMessage(true)} + |""".stripMargin, + EmptyBody, + apiCollectionEndpointsJson400, List($AuthenticatedUserIsRequired, UserNotFoundByUserId, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(getMyApiCollectionEndpointsById)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(getMyApiCollectionEndpointsById) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteMyApiCollection), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteMyApiCollection), + "DELETE", "/my/api-collections/API_COLLECTION_ID", "Delete My Api Collection", - s"""Delete Api Collection By API_COLLECTION_ID.""".stripMargin, - EmptyBody, Full(true), + s"""Delete Api Collection By API_COLLECTION_ID + | + |${Glossary.getGlossaryItem("API Collections")} + | + |${userAuthenticationMessage(true)} + | + | + | + |""", + EmptyBody, + Full(true), List($AuthenticatedUserIsRequired, UserNotFoundByUserId, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(deleteMyApiCollection)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(deleteMyApiCollection) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteMyApiCollectionEndpoint), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteMyApiCollectionEndpoint), + "DELETE", "/my/api-collections/API_COLLECTION_NAME/api-collection-endpoints/OPERATION_ID", "Delete My Api Collection Endpoint", - s"""Delete Api Collection Endpoint By OPERATION_ID.""".stripMargin, - EmptyBody, Full(true), + s"""${Glossary.getGlossaryItem("API Collections")} + | + | + |Delete Api Collection Endpoint By OPERATION_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + Full(true), List($AuthenticatedUserIsRequired, UserNotFoundByUserId, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(deleteMyApiCollectionEndpoint)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(deleteMyApiCollectionEndpoint) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteMyApiCollectionEndpointByOperationId), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteMyApiCollectionEndpointByOperationId), + "DELETE", "/my/api-collection-ids/API_COLLECTION_ID/api-collection-endpoints/OPERATION_ID", "Delete My Api Collection Endpoint By Id", - s"""Delete Api Collection Endpoint By OPERATION_ID.""".stripMargin, - EmptyBody, Full(true), + s"""${Glossary.getGlossaryItem("API Collections")} + | + |Delete Api Collection Endpoint By OPERATION_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + Full(true), List($AuthenticatedUserIsRequired, UserNotFoundByUserId, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(deleteMyApiCollectionEndpointByOperationId)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(deleteMyApiCollectionEndpointByOperationId) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteMyApiCollectionEndpointById), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteMyApiCollectionEndpointById), + "DELETE", "/my/api-collection-ids/API_COLLECTION_ID/api-collection-endpoint-ids/API_COLLECTION_ENDPOINT_ID", "Delete My Api Collection Endpoint By Id", - s"""Delete Api Collection Endpoint By Id.""".stripMargin, - EmptyBody, Full(true), + s"""${Glossary.getGlossaryItem("API Collections")} + |Delete Api Collection Endpoint + |Delete Api Collection Endpoint By Id + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + Full(true), List($AuthenticatedUserIsRequired, UserNotFoundByUserId, UnknownError), - List(apiTagApiCollection), None, - http4sPartialFunction = Some(deleteMyApiCollectionEndpointById)) + List(apiTagApiCollection), + None, + http4sPartialFunction = Some(deleteMyApiCollectionEndpointById) + ) } initBatch4ResourceDocs() @@ -5602,173 +7561,270 @@ object Http4s400 { private def initBatch3ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteTransactionAttributeDefinition), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteTransactionAttributeDefinition), + "DELETE", "/banks/BANK_ID/attribute-definitions/ATTRIBUTE_DEFINITION_ID/transaction", "Delete Transaction Attribute Definition", - s"""Delete Transaction Attribute Definition by ATTRIBUTE_DEFINITION_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + s""" Delete Transaction Attribute Definition by ATTRIBUTE_DEFINITION_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagTransaction, apiTagTransactionAttribute, apiTagAttribute), Some(List(canDeleteTransactionAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(deleteTransactionAttributeDefinition)) + http4sPartialFunction = Some(deleteTransactionAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteCustomerAttributeDefinition), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteCustomerAttributeDefinition), + "DELETE", "/banks/BANK_ID/attribute-definitions/ATTRIBUTE_DEFINITION_ID/customer", "Delete Customer Attribute Definition", - s"""Delete Customer Attribute Definition by ATTRIBUTE_DEFINITION_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + s""" Delete Customer Attribute Definition by ATTRIBUTE_DEFINITION_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagCustomer, apiTagCustomerAttribute, apiTagAttribute), Some(List(canDeleteCustomerAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(deleteCustomerAttributeDefinition)) + http4sPartialFunction = Some(deleteCustomerAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteAccountAttributeDefinition), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteAccountAttributeDefinition), + "DELETE", "/banks/BANK_ID/attribute-definitions/ATTRIBUTE_DEFINITION_ID/account", "Delete Account Attribute Definition", - s"""Delete Account Attribute Definition by ATTRIBUTE_DEFINITION_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + s""" Delete Account Attribute Definition by ATTRIBUTE_DEFINITION_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagAccount, apiTagAccountAttribute, apiTagAttribute), Some(List(canDeleteAccountAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(deleteAccountAttributeDefinition)) + http4sPartialFunction = Some(deleteAccountAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteProductAttributeDefinition), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteProductAttributeDefinition), + "DELETE", "/banks/BANK_ID/attribute-definitions/ATTRIBUTE_DEFINITION_ID/product", "Delete Product Attribute Definition", - s"""Delete Product Attribute Definition by ATTRIBUTE_DEFINITION_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + s""" Delete Product Attribute Definition by ATTRIBUTE_DEFINITION_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagProduct, apiTagProductAttribute, apiTagAttribute), Some(List(canDeleteProductAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(deleteProductAttributeDefinition)) + http4sPartialFunction = Some(deleteProductAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteCardAttributeDefinition), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteCardAttributeDefinition), + "DELETE", "/banks/BANK_ID/attribute-definitions/ATTRIBUTE_DEFINITION_ID/card", "Delete Card Attribute Definition", - s"""Delete Card Attribute Definition by ATTRIBUTE_DEFINITION_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + s""" Delete Card Attribute Definition by ATTRIBUTE_DEFINITION_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagCard, apiTagCardAttribute, apiTagAttribute), Some(List(canDeleteCardAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(deleteCardAttributeDefinition)) + http4sPartialFunction = Some(deleteCardAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteTransactionRequestAttributeDefinition), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteTransactionRequestAttributeDefinition), + "DELETE", "/banks/BANK_ID/attribute-definitions/ATTRIBUTE_DEFINITION_ID/transaction-request", "Delete Transaction Request Attribute Definition", - s"""Delete Transaction Request Attribute Definition by ATTRIBUTE_DEFINITION_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, Full(true), + s""" Delete Transaction Request Attribute Definition by ATTRIBUTE_DEFINITION_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + Full(true), List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagTransactionRequest, apiTagTransactionRequestAttribute, apiTagAttribute), Some(List(canDeleteTransactionRequestAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(deleteTransactionRequestAttributeDefinition)) + http4sPartialFunction = Some(deleteTransactionRequestAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteUser), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteUser), + "DELETE", "/users/USER_ID", "Delete a User", s"""Delete a User. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + | + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagUser), Some(List(canDeleteUser)), - http4sPartialFunction = Some(deleteUser)) + http4sPartialFunction = Some(deleteUser) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteUserCustomerLink), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteUserCustomerLink), + "DELETE", "/banks/BANK_ID/user_customer_links/USER_CUSTOMER_LINK_ID", "Delete User Customer Link", - s"""Delete User Customer Link by USER_CUSTOMER_LINK_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + s""" Delete User Customer Link by USER_CUSTOMER_LINK_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), List(apiTagCustomer), Some(List(canDeleteUserCustomerLink)), - http4sPartialFunction = Some(deleteUserCustomerLink)) + http4sPartialFunction = Some(deleteUserCustomerLink) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteTransactionCascade), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteTransactionCascade), + "DELETE", "/management/cascading/banks/BANK_ID/accounts/ACCOUNT_ID/transactions/TRANSACTION_ID", "Delete Transaction Cascade", s"""Delete a Transaction Cascade specified by TRANSACTION_ID. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + | + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, UserHasMissingRoles, UnknownError), List(apiTagTransaction), Some(List(canDeleteTransactionCascade)), - http4sPartialFunction = Some(deleteTransactionCascade)) + http4sPartialFunction = Some(deleteTransactionCascade) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteAccountCascade), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteAccountCascade), + "DELETE", "/management/cascading/banks/BANK_ID/accounts/ACCOUNT_ID", "Delete Account Cascade", s"""Delete an Account Cascade specified by ACCOUNT_ID. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + | + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, UserHasMissingRoles, UnknownError), List(apiTagAccount), Some(List(canDeleteAccountCascade)), - http4sPartialFunction = Some(deleteAccountCascade)) + http4sPartialFunction = Some(deleteAccountCascade) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteBankCascade), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteBankCascade), + "DELETE", "/management/cascading/banks/BANK_ID", "Delete Bank Cascade", s"""Delete a Bank Cascade specified by BANK_ID. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + | + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, UnknownError), List(apiTagBank), Some(List(canDeleteBankCascade)), - http4sPartialFunction = Some(deleteBankCascade)) + http4sPartialFunction = Some(deleteBankCascade) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteProductCascade), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteProductCascade), + "DELETE", "/management/cascading/banks/BANK_ID/products/PRODUCT_CODE", "Delete Product Cascade", s"""Delete a Product Cascade specified by PRODUCT_CODE. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + | + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, $BankAccountNotFound, UserHasMissingRoles, UnknownError), List(apiTagProduct), Some(List(canDeleteProductCascade)), - http4sPartialFunction = Some(deleteProductCascade)) + http4sPartialFunction = Some(deleteProductCascade) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteCustomerCascade), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteCustomerCascade), + "DELETE", "/management/cascading/banks/BANK_ID/customers/CUSTOMER_ID", "Delete Customer Cascade", s"""Delete a Customer Cascade specified by CUSTOMER_ID. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + | + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, $BankNotFound, CustomerNotFoundByCustomerId, UserHasMissingRoles, UnknownError), List(apiTagCustomer), Some(List(canDeleteCustomerCascade)), - http4sPartialFunction = Some(deleteCustomerCascade)) + http4sPartialFunction = Some(deleteCustomerCascade) + ) staticResourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(deleteSystemLevelEndpointTag), "DELETE", @@ -5793,52 +7849,91 @@ object Http4s400 { http4sPartialFunction = Some(deleteBankLevelEndpointTag)) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteAuthenticationTypeValidation), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteAuthenticationTypeValidation), + "DELETE", "/management/authentication-type-validations/OPERATION_ID", "Delete an Authentication Type Validation", - s"""Delete an Authentication Type Validation by operation_id.""", - EmptyBody, BooleanBody(true), + s"""Delete an Authentication Type Validation by operation_id. + | + |""", + EmptyBody, + BooleanBody(true), List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagAuthenticationTypeValidation), Some(List(canDeleteAuthenticationValidation)), - http4sPartialFunction = Some(deleteAuthenticationTypeValidation)) + http4sPartialFunction = Some(deleteAuthenticationTypeValidation) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteJsonSchemaValidation), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteJsonSchemaValidation), + "DELETE", "/management/json-schema-validations/OPERATION_ID", "Delete a JSON Schema Validation", - s"""Delete a JSON Schema Validation by operation_id.""", - EmptyBody, BooleanBody(true), + s"""Delete a JSON Schema Validation by operation_id. + | + |""", + EmptyBody, + BooleanBody(true), List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagJsonSchemaValidation), Some(List(canDeleteJsonSchemaValidation)), - http4sPartialFunction = Some(deleteJsonSchemaValidation)) + http4sPartialFunction = Some(deleteJsonSchemaValidation) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteCustomerAttribute), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteCustomerAttribute), + "DELETE", "/banks/BANK_ID/customers/attributes/CUSTOMER_ATTRIBUTE_ID", "Delete Customer Attribute", - s"""Delete Customer Attribute. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, - List(UserHasMissingRoles, UnknownError), + s""" Delete Customer Attribute + | + |$customerAttributeGeneralInfo + | + |Delete a Customer Attribute by its id. + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + UserHasMissingRoles, + UnknownError + ), List(apiTagCustomer, apiTagCustomerAttribute, apiTagAttribute), Some(List(canDeleteCustomerAttributeAtOneBank, canDeleteCustomerAttributeAtAnyBank)), - http4sPartialFunction = Some(deleteCustomerAttribute)) + http4sPartialFunction = Some(deleteCustomerAttribute) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteBankAttribute), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteBankAttribute), + "DELETE", "/banks/BANK_ID/attributes/BANK_ATTRIBUTE_ID", "Delete Bank Attribute", - s"""Delete Bank Attribute. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, EmptyBody, + s""" Delete Bank Attribute + | + |Delete a Bank Attribute by its id. + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, List(UserHasMissingRoles, BankNotFound, UnknownError), List(apiTagBank, apiTagBankAttribute, apiTagAttribute), Some(List(canDeleteBankAttribute)), - http4sPartialFunction = Some(deleteBankAttribute)) + http4sPartialFunction = Some(deleteBankAttribute) + ) staticResourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(deleteAtm), "DELETE", @@ -5846,43 +7941,74 @@ object Http4s400 { "Delete ATM", s"""Delete ATM.""", EmptyBody, EmptyBody, - List(UserHasMissingRoles, UnknownError), + List( + $AuthenticatedUserIsRequired, + UnknownError + ), List(apiTagATM), Some(List(canDeleteAtm, canDeleteAtmAtAnyBank)), http4sPartialFunction = Some(deleteAtm)) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteProductFee), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteProductFee), + "DELETE", "/banks/BANK_ID/products/PRODUCT_CODE/fees/PRODUCT_FEE_ID", "Delete Product Fee", - s"""Delete Product Fee.""", - EmptyBody, EmptyBody, - List(UserHasMissingRoles, UnknownError), + s"""Delete Product Fee + | + |Delete one product fee by its id. + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + BooleanBody(true), + List( + $AuthenticatedUserIsRequired, + $BankNotFound, + UserHasMissingRoles, + UnknownError + ), List(apiTagProduct), Some(List(canDeleteProductFee)), - http4sPartialFunction = Some(deleteProductFee)) + http4sPartialFunction = Some(deleteProductFee) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteEndpointMapping), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteEndpointMapping), + "DELETE", "/management/endpoint-mappings/ENDPOINT_MAPPING_ID", "Delete Endpoint Mapping", - s"""Delete a Endpoint Mapping.""", - EmptyBody, BooleanBody(true), + s"""Delete a Endpoint Mapping. + |""", + EmptyBody, + BooleanBody(true), List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagEndpointMapping), Some(List(canDeleteEndpointMapping)), - http4sPartialFunction = Some(deleteEndpointMapping)) + http4sPartialFunction = Some(deleteEndpointMapping) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteBankLevelEndpointMapping), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteBankLevelEndpointMapping), + "DELETE", "/management/banks/BANK_ID/endpoint-mappings/ENDPOINT_MAPPING_ID", "Delete Bank Level Endpoint Mapping", - s"""Delete a Bank Level Endpoint Mapping.""", - EmptyBody, BooleanBody(true), + s"""Delete a Bank Level Endpoint Mapping. + |""", + EmptyBody, + BooleanBody(true), List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagEndpointMapping), Some(List(canDeleteBankLevelEndpointMapping, canDeleteEndpointMapping)), - http4sPartialFunction = Some(deleteBankLevelEndpointMapping)) + http4sPartialFunction = Some(deleteBankLevelEndpointMapping) + ) } initBatch3ResourceDocs() @@ -6106,339 +8232,525 @@ object Http4s400 { private def initBatch2ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getEntitlementsForBank), "GET", + null, + implementedInApiVersion, + nameOf(getEntitlementsForBank), + "GET", "/banks/BANK_ID/entitlements", "Get Entitlements for One Bank", - s"""${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, entitlementsJsonV400, - List($AuthenticatedUserIsRequired, BankNotFound, UserHasMissingRoles, UnknownError), - List(apiTagRole, apiTagEntitlement, apiTagUser, apiTagBank), + s""" + | + """.stripMargin, + EmptyBody, + entitlementsJsonV400, + List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), + List(apiTagRole, apiTagEntitlement, apiTagUser), Some(List(canGetEntitlementsForOneBank, canGetEntitlementsForAnyBank)), - http4sPartialFunction = Some(getEntitlementsForBank)) + http4sPartialFunction = Some(getEntitlementsForBank) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMyPersonalUserAttributes), "GET", + null, + implementedInApiVersion, + nameOf(getMyPersonalUserAttributes), + "GET", "/my/user/attributes", - "Get my personal User Attributes", - s"""Get my personal User Attributes - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, userAttributesResponseJson, + "Get My Personal User Attributes", + s"""Get My Personal User Attributes. + | + |${userAuthenticationMessage(true)} + |""".stripMargin, + EmptyBody, + userAttributesResponseJson, List($AuthenticatedUserIsRequired, UnknownError), - List(apiTagUser), None, - http4sPartialFunction = Some(getMyPersonalUserAttributes)) + List(apiTagUser), + None, + http4sPartialFunction = Some(getMyPersonalUserAttributes) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getUserWithAttributes), "GET", + null, + implementedInApiVersion, + nameOf(getUserWithAttributes), + "GET", "/users/USER_ID/attributes", "Get User with Attributes by USER_ID", s"""Get User Attributes for the user defined via USER_ID. - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, userWithAttributesResponseJson, + | + |${userAuthenticationMessage(true)} + |""".stripMargin, + EmptyBody, + userWithAttributesResponseJson, List($AuthenticatedUserIsRequired, UnknownError), List(apiTagUser), Some(canGetUsersWithAttributes :: Nil), - http4sPartialFunction = Some(getUserWithAttributes)) + http4sPartialFunction = Some(getUserWithAttributes) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCustomerAttributes), "GET", + null, + implementedInApiVersion, + nameOf(getCustomerAttributes), + "GET", "/banks/BANK_ID/customers/CUSTOMER_ID/attributes", "Get Customer Attributes", - s"""Get Customer Attributes - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, customerAttributesResponseJson, + s""" Get Customer Attributes + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + customerAttributesResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagCustomer, apiTagCustomerAttribute, apiTagAttribute), Some(List(canGetCustomerAttributesAtOneBank, canGetCustomerAttributesAtAnyBank)), - http4sPartialFunction = Some(getCustomerAttributes)) + http4sPartialFunction = Some(getCustomerAttributes) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCustomerAttributeById), "GET", + null, + implementedInApiVersion, + nameOf(getCustomerAttributeById), + "GET", "/banks/BANK_ID/customers/CUSTOMER_ID/attributes/ATTRIBUTE_ID", "Get Customer Attribute By Id", - s"""Get Customer Attribute By Id - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, customerAttributeResponseJson, + s""" Get Customer Attribute By Id + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + customerAttributeResponseJson, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagCustomer, apiTagCustomerAttribute, apiTagAttribute), Some(List(canGetCustomerAttributeAtOneBank, canGetCustomerAttributeAtAnyBank)), - http4sPartialFunction = Some(getCustomerAttributeById)) + http4sPartialFunction = Some(getCustomerAttributeById) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getProductAttributeDefinition), "GET", + null, + implementedInApiVersion, + nameOf(getProductAttributeDefinition), + "GET", "/banks/BANK_ID/attribute-definitions/product", "Get Product Attribute Definition", - s"""Get Product Attribute Definition - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, productAttributeDefinitionsResponseJsonV400, + s""" Get Product Attribute Definition + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + productAttributeDefinitionsResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagProduct, apiTagProductAttribute, apiTagAttribute), Some(List(canGetProductAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(getProductAttributeDefinition)) + http4sPartialFunction = Some(getProductAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCustomerAttributeDefinition), "GET", + null, + implementedInApiVersion, + nameOf(getCustomerAttributeDefinition), + "GET", "/banks/BANK_ID/attribute-definitions/customer", "Get Customer Attribute Definition", - s"""Get Customer Attribute Definition - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, customerAttributeDefinitionsResponseJsonV400, + s""" Get Customer Attribute Definition + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + customerAttributeDefinitionsResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagCustomer, apiTagCustomerAttribute, apiTagAttribute), Some(List(canGetCustomerAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(getCustomerAttributeDefinition)) + http4sPartialFunction = Some(getCustomerAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAccountAttributeDefinition), "GET", + null, + implementedInApiVersion, + nameOf(getAccountAttributeDefinition), + "GET", "/banks/BANK_ID/attribute-definitions/account", "Get Account Attribute Definition", - s"""Get Account Attribute Definition - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, accountAttributeDefinitionsResponseJsonV400, + s""" Get Account Attribute Definition + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + accountAttributeDefinitionsResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagAccount, apiTagAccountAttribute, apiTagAttribute), Some(List(canGetAccountAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(getAccountAttributeDefinition)) + http4sPartialFunction = Some(getAccountAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getTransactionAttributeDefinition), "GET", + null, + implementedInApiVersion, + nameOf(getTransactionAttributeDefinition), + "GET", "/banks/BANK_ID/attribute-definitions/transaction", "Get Transaction Attribute Definition", - s"""Get Transaction Attribute Definition - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, transactionAttributeDefinitionsResponseJsonV400, + s""" Get Transaction Attribute Definition + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + transactionAttributeDefinitionsResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagTransaction, apiTagTransactionAttribute, apiTagAttribute), Some(List(canGetTransactionAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(getTransactionAttributeDefinition)) + http4sPartialFunction = Some(getTransactionAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCardAttributeDefinition), "GET", + null, + implementedInApiVersion, + nameOf(getCardAttributeDefinition), + "GET", "/banks/BANK_ID/attribute-definitions/card", "Get Card Attribute Definition", - s"""Get Card Attribute Definition - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, cardAttributeDefinitionsResponseJsonV400, + s""" Get Card Attribute Definition + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + cardAttributeDefinitionsResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagCard, apiTagCardAttribute, apiTagAttribute), Some(List(canGetCardAttributeDefinitionAtOneBank)), - http4sPartialFunction = Some(getCardAttributeDefinition)) + http4sPartialFunction = Some(getCardAttributeDefinition) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getJsonSchemaValidation), "GET", + null, + implementedInApiVersion, + nameOf(getJsonSchemaValidation), + "GET", "/management/json-schema-validations/OPERATION_ID", "Get a JSON Schema Validation", - s"""Get a JSON Schema Validation by operation_id.""", - EmptyBody, responseJsonSchema, + s"""Get a JSON Schema Validation by operation_id. + | + |""", + EmptyBody, + responseJsonSchema, List(InvalidJsonFormat, UnknownError), List(apiTagJsonSchemaValidation), Some(List(canGetJsonSchemaValidation)), - http4sPartialFunction = Some(getJsonSchemaValidation)) + http4sPartialFunction = Some(getJsonSchemaValidation) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAllJsonSchemaValidations), "GET", + null, + implementedInApiVersion, + nameOf(getAllJsonSchemaValidations), + "GET", "/management/json-schema-validations", "Get all JSON Schema Validations", - s"""Get all JSON Schema Validations.""", + s"""Get all JSON Schema Validations. + | + |""", EmptyBody, - com.openbankproject.commons.model.ListResult("json_schema_validations", responseJsonSchema :: Nil), + ListResult("json_schema_validations", responseJsonSchema :: Nil), List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagJsonSchemaValidation), Some(List(canGetJsonSchemaValidation)), - http4sPartialFunction = Some(getAllJsonSchemaValidations)) + http4sPartialFunction = Some(getAllJsonSchemaValidations) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAuthenticationTypeValidation), "GET", + null, + implementedInApiVersion, + nameOf(getAuthenticationTypeValidation), + "GET", "/management/authentication-type-validations/OPERATION_ID", "Get an Authentication Type Validation", - s"""Get an Authentication Type Validation by operation_id.""", - EmptyBody, JsonAuthTypeValidation("OBPv4.0.0-updateXxx", List.empty), + s"""Get an Authentication Type Validation by operation_id. + | + |""", + EmptyBody, + JsonAuthTypeValidation("OBPv4.0.0-updateXxx", allowedAuthTypes), List(InvalidJsonFormat, UnknownError), List(apiTagAuthenticationTypeValidation), Some(List(canGetAuthenticationTypeValidation)), - http4sPartialFunction = Some(getAuthenticationTypeValidation)) + http4sPartialFunction = Some(getAuthenticationTypeValidation) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAllAuthenticationTypeValidations), "GET", + null, + implementedInApiVersion, + nameOf(getAllAuthenticationTypeValidations), + "GET", "/management/authentication-type-validations", "Get all Authentication Type Validations", - s"""Get all Authentication Type Validations.""", + s"""Get all Authentication Type Validations. + | + |""", EmptyBody, - com.openbankproject.commons.model.ListResult( + ListResult( "authentication_types_validations", - List(JsonAuthTypeValidation("OBPv4.0.0-updateXxx", List.empty))), + List(JsonAuthTypeValidation("OBPv4.0.0-updateXxx", allowedAuthTypes)) + ), List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagAuthenticationTypeValidation), Some(List(canGetAuthenticationTypeValidation)), - http4sPartialFunction = Some(getAllAuthenticationTypeValidations)) + http4sPartialFunction = Some(getAllAuthenticationTypeValidations) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getConnectorMethod), "GET", + null, + implementedInApiVersion, + nameOf(getConnectorMethod), + "GET", "/management/connector-methods/CONNECTOR_METHOD_ID", "Get Connector Method by Id", - s"""Get an internal connector by CONNECTOR_METHOD_ID.""", - EmptyBody, jsonScalaConnectorMethod, + s"""Get an internal connector by CONNECTOR_METHOD_ID. + | + |""", + EmptyBody, + jsonScalaConnectorMethod, List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagConnectorMethod), Some(List(canGetConnectorMethod)), - http4sPartialFunction = Some(getConnectorMethod)) + http4sPartialFunction = Some(getConnectorMethod) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAllConnectorMethods), "GET", + null, + implementedInApiVersion, + nameOf(getAllConnectorMethods), + "GET", "/management/connector-methods", "Get all Connector Methods", - s"""Get all Connector Methods.""", + s"""Get all Connector Methods. + | + |""", EmptyBody, - com.openbankproject.commons.model.ListResult("connectors_methods", jsonScalaConnectorMethod :: Nil), + ListResult("connectors_methods", jsonScalaConnectorMethod :: Nil), List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagConnectorMethod), Some(List(canGetAllConnectorMethods)), - http4sPartialFunction = Some(getAllConnectorMethods)) + http4sPartialFunction = Some(getAllConnectorMethods) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getUserCustomerLinksByUserId), "GET", + null, + implementedInApiVersion, + nameOf(getUserCustomerLinksByUserId), + "GET", "/banks/BANK_ID/user_customer_links/users/USER_ID", "Get User Customer Links by User", - s"""Get User Customer Links by USER_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, userCustomerLinksJson, + s""" Get User Customer Links by USER_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + userCustomerLinksJson, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagCustomer), Some(List(canGetUserCustomerLink)), - http4sPartialFunction = Some(getUserCustomerLinksByUserId)) + http4sPartialFunction = Some(getUserCustomerLinksByUserId) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getUserCustomerLinksByCustomerId), "GET", + null, + implementedInApiVersion, + nameOf(getUserCustomerLinksByCustomerId), + "GET", "/banks/BANK_ID/user_customer_links/customers/CUSTOMER_ID", "Get User Customer Links by Customer", - s"""Get User Customer Links by CUSTOMER_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, userCustomerLinksJson, + s""" Get User Customer Links by CUSTOMER_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + userCustomerLinksJson, List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagCustomer), Some(List(canGetUserCustomerLink)), - http4sPartialFunction = Some(getUserCustomerLinksByCustomerId)) + http4sPartialFunction = Some(getUserCustomerLinksByCustomerId) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCustomerMessages), "GET", + null, + implementedInApiVersion, + nameOf(getCustomerMessages), + "GET", "/banks/BANK_ID/customers/CUSTOMER_ID/messages", - "Get Messages for Customer", - s"""Get messages for the logged in customer - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, customerMessagesJson, - List($AuthenticatedUserIsRequired, $BankNotFound, UnknownError), + "Get Customer Messages for a Customer", + s"""Get messages for the customer specified by CUSTOMER_ID + ${userAuthenticationMessage(true)} + """, + EmptyBody, + customerMessagesJsonV400, + List(AuthenticatedUserIsRequired, $BankNotFound, UnknownError), List(apiTagMessage, apiTagCustomer), Some(List(canGetCustomerMessages)), - http4sPartialFunction = Some(getCustomerMessages)) + http4sPartialFunction = Some(getCustomerMessages) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createCustomerMessage), "POST", + null, + implementedInApiVersion, + nameOf(createCustomerMessage), + "POST", "/banks/BANK_ID/customers/CUSTOMER_ID/messages", "Create Customer Message", - s"""Create a message for the customer specified by CUSTOMER_ID - |${userAuthenticationMessage(true)}""".stripMargin, - createMessageJsonV400, successMessage, - List($AuthenticatedUserIsRequired, $BankNotFound), + s""" + |Create a message for the customer specified by CUSTOMER_ID + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + createMessageJsonV400, + successMessage, + List( + AuthenticatedUserIsRequired, + $BankNotFound + ), List(apiTagMessage, apiTagCustomer, apiTagPerson), Some(List(canCreateCustomerMessage)), - http4sPartialFunction = Some(createCustomerMessage)) + http4sPartialFunction = Some(createCustomerMessage) + ) } initBatch2ResourceDocs() private def initBatch1ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCallContext), "GET", + null, + implementedInApiVersion, + nameOf(getCallContext), + "GET", "/development/call_context", "Get the Call Context of a current call", - s"""Get the Call Context of the current call.""", - EmptyBody, EmptyBody, + s"""Get the Call Context of the current call. + | + """.stripMargin, + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, UnknownError), List(apiTagApi), Some(List(canGetCallContext)), - http4sPartialFunction = Some(getCallContext)) + http4sPartialFunction = Some(getCallContext) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(verifyRequestSignResponse), "GET", + null, + implementedInApiVersion, + nameOf(verifyRequestSignResponse), + "GET", "/development/echo/jws-verified-request-jws-signed-response", "Verify Request and Sign Response of a current call", - s"""Verify Request and Sign Response of a current call.""", - EmptyBody, EmptyBody, + s"""Verify Request and Sign Response of a current call. + | + """.stripMargin, + EmptyBody, + EmptyBody, List($AuthenticatedUserIsRequired, UnknownError), List(apiTagApi), Some(Nil), - http4sPartialFunction = Some(verifyRequestSignResponse)) + http4sPartialFunction = Some(verifyRequestSignResponse) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getCurrentUserId), "GET", + null, + implementedInApiVersion, + nameOf(getCurrentUserId), + "GET", "/users/current/user_id", "Get User Id (Current)", s"""Get the USER_ID of the logged in user | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, userIdJsonV400, + |${userAuthenticationMessage(true)} + """.stripMargin, + EmptyBody, + userIdJsonV400, List(AuthenticatedUserIsRequired, UnknownError), - List(apiTagUser), None, - http4sPartialFunction = Some(getCurrentUserId)) + List(apiTagUser), + None, + http4sPartialFunction = Some(getCurrentUserId) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getScannedApiVersions), "GET", + null, + implementedInApiVersion, + nameOf(getScannedApiVersions), + "GET", "/api/versions", "Get scanned API Versions", s"""Get all the scanned API Versions.""", EmptyBody, - com.openbankproject.commons.model.ListResult("scanned_api_versions", - List(net.liftweb.json.Extraction.decompose(ApiVersion.v3_1_0))), + ListResult( + "scanned_api_versions", + List(Extraction.decompose(ApiVersion.v3_1_0)) + ), List(UnknownError), List(apiTagDocumentation, apiTagApi), Some(Nil), - http4sPartialFunction = Some(getScannedApiVersions)) + http4sPartialFunction = Some(getScannedApiVersions) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getMySpaces), "GET", + null, + implementedInApiVersion, + nameOf(getMySpaces), + "GET", "/my/spaces", "Get My Spaces", s"""Get My Spaces.""", - EmptyBody, code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.mySpaces, + EmptyBody, + mySpaces, List($AuthenticatedUserIsRequired, UnknownError), - List(apiTagUser), None, - http4sPartialFunction = Some(getMySpaces)) + List(apiTagUser), + None, + http4sPartialFunction = Some(getMySpaces) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBankAttributes), "GET", + null, + implementedInApiVersion, + nameOf(getBankAttributes), + "GET", "/banks/BANK_ID/attributes", "Get Bank Attributes", - s"""Get Bank Attributes - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, bankAttributesResponseJsonV400, + s""" Get Bank Attributes + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + bankAttributesResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagBank, apiTagBankAttribute, apiTagAttribute), Some(List(canGetBankAttribute)), - http4sPartialFunction = Some(getBankAttributes)) + http4sPartialFunction = Some(getBankAttributes) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBankAttribute), "GET", + null, + implementedInApiVersion, + nameOf(getBankAttribute), + "GET", "/banks/BANK_ID/attributes/BANK_ATTRIBUTE_ID", "Get Bank Attribute By BANK_ATTRIBUTE_ID", - s"""Get Bank Attribute By BANK_ATTRIBUTE_ID - | - |${userAuthenticationMessage(true)}""".stripMargin, - EmptyBody, bankAttributeResponseJsonV400, + s""" Get Bank Attribute By BANK_ATTRIBUTE_ID + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + bankAttributeResponseJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagBank, apiTagBankAttribute, apiTagAttribute), Some(List(canGetBankAttribute)), - http4sPartialFunction = Some(getBankAttribute)) + http4sPartialFunction = Some(getBankAttribute) + ) staticResourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(getSystemLevelEndpointTags), "GET", @@ -6463,50 +8775,82 @@ object Http4s400 { http4sPartialFunction = Some(getBankLevelEndpointTags)) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getEndpointMapping), "GET", + null, + implementedInApiVersion, + nameOf(getEndpointMapping), + "GET", "/management/endpoint-mappings/ENDPOINT_MAPPING_ID", "Get Endpoint Mapping by Id", - s"""Get an Endpoint Mapping by ENDPOINT_MAPPING_ID.""", - EmptyBody, endpointMappingResponseBodyExample, + s"""Get an Endpoint Mapping by ENDPOINT_MAPPING_ID. + | + |""", + EmptyBody, + endpointMappingResponseBodyExample, List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagEndpointMapping), Some(List(canGetEndpointMapping)), - http4sPartialFunction = Some(getEndpointMapping)) + http4sPartialFunction = Some(getEndpointMapping) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBankLevelEndpointMapping), "GET", + null, + implementedInApiVersion, + nameOf(getBankLevelEndpointMapping), + "GET", "/management/banks/BANK_ID/endpoint-mappings/ENDPOINT_MAPPING_ID", "Get Bank Level Endpoint Mapping", - s"""Get an Bank Level Endpoint Mapping by ENDPOINT_MAPPING_ID.""", - EmptyBody, endpointMappingResponseBodyExample, + s"""Get an Bank Level Endpoint Mapping by ENDPOINT_MAPPING_ID. + | + |""", + EmptyBody, + endpointMappingResponseBodyExample, List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagEndpointMapping), Some(List(canGetBankLevelEndpointMapping, canGetEndpointMapping)), - http4sPartialFunction = Some(getBankLevelEndpointMapping)) + http4sPartialFunction = Some(getBankLevelEndpointMapping) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAllEndpointMappings), "GET", + null, + implementedInApiVersion, + nameOf(getAllEndpointMappings), + "GET", "/management/endpoint-mappings", "Get all Endpoint Mappings", - s"""Get all Endpoint Mappings.""", + s"""Get all Endpoint Mappings. + | + |""", EmptyBody, - com.openbankproject.commons.model.ListResult("endpoint-mappings", endpointMappingResponseBodyExample :: Nil), + ListResult( + "endpoint-mappings", + endpointMappingResponseBodyExample :: Nil + ), List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagEndpointMapping), Some(List(canGetAllEndpointMappings)), - http4sPartialFunction = Some(getAllEndpointMappings)) + http4sPartialFunction = Some(getAllEndpointMappings) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAllBankLevelEndpointMappings), "GET", + null, + implementedInApiVersion, + nameOf(getAllBankLevelEndpointMappings), + "GET", "/management/banks/BANK_ID/endpoint-mappings", "Get all Bank Level Endpoint Mappings", - s"""Get all Bank Level Endpoint Mappings.""", + s"""Get all Bank Level Endpoint Mappings. + | + |""", EmptyBody, - com.openbankproject.commons.model.ListResult("endpoint-mappings", endpointMappingResponseBodyExample :: Nil), + ListResult( + "endpoint-mappings", + endpointMappingResponseBodyExample :: Nil + ), List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagEndpointMapping), Some(List(canGetAllBankLevelEndpointMappings, canGetAllEndpointMappings)), - http4sPartialFunction = Some(getAllBankLevelEndpointMappings)) + http4sPartialFunction = Some(getAllBankLevelEndpointMappings) + ) } initBatch1ResourceDocs() @@ -6588,54 +8932,76 @@ object Http4s400 { private def initBatch13ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createEndpointMapping), "POST", + null, + implementedInApiVersion, + nameOf(createEndpointMapping), + "POST", "/management/endpoint-mappings", "Create Endpoint Mapping", s"""Create an Endpoint Mapping. - | - |Note: at moment only support the dynamic endpoints - |""", - endpointMappingRequestBodyExample, endpointMappingResponseBodyExample, + | + |Note: at moment only support the dynamic endpoints + |""", + endpointMappingRequestBodyExample, + endpointMappingResponseBodyExample, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagEndpointMapping), Some(List(canCreateEndpointMapping)), - http4sPartialFunction = Some(createEndpointMapping)) + http4sPartialFunction = Some(createEndpointMapping) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateEndpointMapping), "PUT", + null, + implementedInApiVersion, + nameOf(updateEndpointMapping), + "PUT", "/management/endpoint-mappings/ENDPOINT_MAPPING_ID", "Update Endpoint Mapping", - s"""Update an Endpoint Mapping.""", - endpointMappingRequestBodyExample, endpointMappingResponseBodyExample, + s"""Update an Endpoint Mapping. + |""", + endpointMappingRequestBodyExample, + endpointMappingResponseBodyExample, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagEndpointMapping), Some(List(canUpdateEndpointMapping)), - http4sPartialFunction = Some(updateEndpointMapping)) + http4sPartialFunction = Some(updateEndpointMapping) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createBankLevelEndpointMapping), "POST", + null, + implementedInApiVersion, + nameOf(createBankLevelEndpointMapping), + "POST", "/management/banks/BANK_ID/endpoint-mappings", "Create Bank Level Endpoint Mapping", s"""Create an Bank Level Endpoint Mapping. - | - |Note: at moment only support the dynamic endpoints - |""", - endpointMappingRequestBodyExample, endpointMappingResponseBodyExample, + | + |Note: at moment only support the dynamic endpoints + |""", + endpointMappingRequestBodyExample, + endpointMappingResponseBodyExample, List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagEndpointMapping), Some(List(canCreateBankLevelEndpointMapping, canCreateEndpointMapping)), - http4sPartialFunction = Some(createBankLevelEndpointMapping)) + http4sPartialFunction = Some(createBankLevelEndpointMapping) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateBankLevelEndpointMapping), "PUT", + null, + implementedInApiVersion, + nameOf(updateBankLevelEndpointMapping), + "PUT", "/management/banks/BANK_ID/endpoint-mappings/ENDPOINT_MAPPING_ID", "Update Bank Level Endpoint Mapping", - s"""Update an Bank Level Endpoint Mapping.""", - endpointMappingRequestBodyExample, endpointMappingResponseBodyExample, + s"""Update an Bank Level Endpoint Mapping. + |""", + endpointMappingRequestBodyExample, + endpointMappingResponseBodyExample, List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagEndpointMapping), Some(List(canUpdateBankLevelEndpointMapping, canUpdateEndpointMapping)), - http4sPartialFunction = Some(updateBankLevelEndpointMapping)) + http4sPartialFunction = Some(updateBankLevelEndpointMapping) + ) } initBatch13ResourceDocs() @@ -6757,48 +9123,90 @@ object Http4s400 { private def initBatch14ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createSystemLevelEndpointTag), "POST", + null, + implementedInApiVersion, + nameOf(createSystemLevelEndpointTag), + "POST", "/management/endpoints/OPERATION_ID/tags", "Create System Level Endpoint Tag", - s"""Create System Level Endpoint Tag.""", - endpointTagJson400, bankLevelEndpointTagResponseJson400, - List($AuthenticatedUserIsRequired, UserHasMissingRoles, EndpointTagAlreadyExists, InvalidJsonFormat, UnknownError), + s"""Create System Level Endpoint Tag + | + |Note: Resource Docs are cached, TTL is ${CREATE_LOCALISED_RESOURCE_DOC_JSON_TTL} seconds + | + |""".stripMargin, + endpointTagJson400, + bankLevelEndpointTagResponseJson400, + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), List(apiTagApi), Some(List(canCreateSystemLevelEndpointTag)), - http4sPartialFunction = Some(createSystemLevelEndpointTag)) + http4sPartialFunction = Some(createSystemLevelEndpointTag) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateSystemLevelEndpointTag), "PUT", + null, + implementedInApiVersion, + nameOf(updateSystemLevelEndpointTag), + "PUT", "/management/endpoints/OPERATION_ID/tags/ENDPOINT_TAG_ID", "Update System Level Endpoint Tag", - s"""Update System Level Endpoint Tag, you can only update the tag_name here, operation_id can not be updated.""", - endpointTagJson400, bankLevelEndpointTagResponseJson400, + s"""Update System Level Endpoint Tag, you can only update the tag_name here, operation_id can not be updated. + | + |Note: Resource Docs are cached, TTL is ${CREATE_LOCALISED_RESOURCE_DOC_JSON_TTL} seconds + | + |""".stripMargin, + endpointTagJson400, + bankLevelEndpointTagResponseJson400, List($AuthenticatedUserIsRequired, UserHasMissingRoles, EndpointTagNotFoundByEndpointTagId, InvalidJsonFormat, UnknownError), List(apiTagApi), Some(List(canUpdateSystemLevelEndpointTag)), - http4sPartialFunction = Some(updateSystemLevelEndpointTag)) + http4sPartialFunction = Some(updateSystemLevelEndpointTag) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createBankLevelEndpointTag), "POST", + null, + implementedInApiVersion, + nameOf(createBankLevelEndpointTag), + "POST", "/management/banks/BANK_ID/endpoints/OPERATION_ID/tags", "Create Bank Level Endpoint Tag", - s"""Create Bank Level Endpoint Tag""", - endpointTagJson400, bankLevelEndpointTagResponseJson400, + s"""Create Bank Level Endpoint Tag + | + |Note: Resource Docs are cached, TTL is ${CREATE_LOCALISED_RESOURCE_DOC_JSON_TTL} seconds + | + | + |""".stripMargin, + endpointTagJson400, + bankLevelEndpointTagResponseJson400, List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagApi), Some(List(canCreateBankLevelEndpointTag)), - http4sPartialFunction = Some(createBankLevelEndpointTag)) + http4sPartialFunction = Some(createBankLevelEndpointTag) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateBankLevelEndpointTag), "PUT", + null, + implementedInApiVersion, + nameOf(updateBankLevelEndpointTag), + "PUT", "/management/banks/BANK_ID/endpoints/OPERATION_ID/tags/ENDPOINT_TAG_ID", "Update Bank Level Endpoint Tag", - s"""Update Endpoint Tag, you can only update the tag_name here, operation_id can not be updated.""", - endpointTagJson400, bankLevelEndpointTagResponseJson400, + s"""Update Endpoint Tag, you can only update the tag_name here, operation_id can not be updated. + | + |Note: Resource Docs are cached, TTL is ${CREATE_LOCALISED_RESOURCE_DOC_JSON_TTL} seconds + | + |""".stripMargin, + endpointTagJson400, + bankLevelEndpointTagResponseJson400, List($AuthenticatedUserIsRequired, $BankNotFound, UserHasMissingRoles, EndpointTagNotFoundByEndpointTagId, InvalidJsonFormat, UnknownError), List(apiTagApi), Some(List(canUpdateBankLevelEndpointTag)), - http4sPartialFunction = Some(updateBankLevelEndpointTag)) + http4sPartialFunction = Some(updateBankLevelEndpointTag) + ) } initBatch14ResourceDocs() @@ -6943,92 +9351,127 @@ object Http4s400 { private def initBatch15ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createJsonSchemaValidation), "POST", + null, + implementedInApiVersion, + nameOf(createJsonSchemaValidation), + "POST", "/management/json-schema-validations/OPERATION_ID", "Create a JSON Schema Validation", s"""Create a JSON Schema Validation. - | - |Introduction: - |${Glossary.getGlossaryItemSimple("JSON Schema Validation")} - | - |To use this endpoint, please supply a valid json-schema in the request body. - |""", - postOrPutJsonSchemaV400, responseJsonSchema, + | + |Introduction: + |${Glossary.getGlossaryItemSimple("JSON Schema Validation")} + | + |To use this endpoint, please supply a valid json-schema in the request body. + | + |Note: It might take a few minutes for the newly created JSON Schema to take effect! + |""", + postOrPutJsonSchemaV400, + responseJsonSchema, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagJsonSchemaValidation), Some(List(canCreateJsonSchemaValidation)), - http4sPartialFunction = Some(createJsonSchemaValidation)) + http4sPartialFunction = Some(createJsonSchemaValidation) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateJsonSchemaValidation), "PUT", + null, + implementedInApiVersion, + nameOf(updateJsonSchemaValidation), + "PUT", "/management/json-schema-validations/OPERATION_ID", "Update a JSON Schema Validation", s"""Update a JSON Schema Validation. - | - |Introduction: - |${Glossary.getGlossaryItemSimple("JSON Schema Validation")} - | - |To use this endpoint, please supply a valid json-schema in the request body. - |""", - postOrPutJsonSchemaV400, responseJsonSchema, + | + |Introduction: + |${Glossary.getGlossaryItemSimple("JSON Schema Validation")} + | + |To use this endpoint, please supply a valid json-schema in the request body. + | + |""", + postOrPutJsonSchemaV400, + responseJsonSchema, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagJsonSchemaValidation), Some(List(canUpdateJsonSchemaValidation)), - http4sPartialFunction = Some(updateJsonSchemaValidation)) + http4sPartialFunction = Some(updateJsonSchemaValidation) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createAuthenticationTypeValidation), "POST", + null, + implementedInApiVersion, + nameOf(createAuthenticationTypeValidation), + "POST", "/management/authentication-type-validations/OPERATION_ID", "Create an Authentication Type Validation", s"""Create an Authentication Type Validation. - | - |Please supply allowed authentication types.""", + | + |Please supply allowed authentication types. + |""", allowedAuthTypes, JsonAuthTypeValidation("OBPv4.0.0-updateXxx", allowedAuthTypes), List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagAuthenticationTypeValidation), Some(List(canCreateAuthenticationTypeValidation)), - http4sPartialFunction = Some(createAuthenticationTypeValidation)) + http4sPartialFunction = Some(createAuthenticationTypeValidation) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateAuthenticationTypeValidation), "PUT", + null, + implementedInApiVersion, + nameOf(updateAuthenticationTypeValidation), + "PUT", "/management/authentication-type-validations/OPERATION_ID", "Update an Authentication Type Validation", s"""Update an Authentication Type Validation. - | - |Please supply allowed authentication types.""", + | + |Please supply allowed authentication types. + |""", allowedAuthTypes, JsonAuthTypeValidation("OBPv4.0.0-updateXxx", allowedAuthTypes), List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagAuthenticationTypeValidation), Some(List(canUpdateAuthenticationTypeValidation)), - http4sPartialFunction = Some(updateAuthenticationTypeValidation)) + http4sPartialFunction = Some(updateAuthenticationTypeValidation) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createConnectorMethod), "POST", + null, + implementedInApiVersion, + nameOf(createConnectorMethod), + "POST", "/management/connector-methods", "Create Connector Method", s"""Create an internal connector. - | - |The method_body is URL-encoded format String""", - jsonScalaConnectorMethod.copy(connectorMethodId = None), jsonScalaConnectorMethod, + | + |The method_body is URL-encoded format String + |""", + jsonScalaConnectorMethod.copy(connectorMethodId = None), + jsonScalaConnectorMethod, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagConnectorMethod), Some(List(canCreateConnectorMethod)), - http4sPartialFunction = Some(createConnectorMethod)) + http4sPartialFunction = Some(createConnectorMethod) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateConnectorMethod), "PUT", + null, + implementedInApiVersion, + nameOf(updateConnectorMethod), + "PUT", "/management/connector-methods/CONNECTOR_METHOD_ID", "Update Connector Method", s"""Update an internal connector. - | - |The method_body is URL-encoded format String""", - jsonScalaConnectorMethodMethodBody, jsonScalaConnectorMethod, + | + |The method_body is URL-encoded format String + |""", + jsonScalaConnectorMethodMethodBody, + jsonScalaConnectorMethod, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagConnectorMethod), Some(List(canUpdateConnectorMethod)), - http4sPartialFunction = Some(updateConnectorMethod)) + http4sPartialFunction = Some(updateConnectorMethod) + ) } initBatch15ResourceDocs() @@ -7190,124 +9633,186 @@ object Http4s400 { private def initBatch16ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createDynamicResourceDoc), "POST", + null, + implementedInApiVersion, + nameOf(createDynamicResourceDoc), + "POST", "/management/dynamic-resource-docs", "Create Dynamic Resource Doc", s"""Create a Dynamic Resource Doc. - | - |The connector_method_body is URL-encoded format String""", - jsonDynamicResourceDoc.copy(dynamicResourceDocId = None), jsonDynamicResourceDoc, + | + |The connector_method_body is URL-encoded format String + |""", + jsonDynamicResourceDoc.copy(dynamicResourceDocId = None), + jsonDynamicResourceDoc, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicResourceDoc), Some(List(canCreateDynamicResourceDoc)), - http4sPartialFunction = Some(createDynamicResourceDoc)) + http4sPartialFunction = Some(createDynamicResourceDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateDynamicResourceDoc), "PUT", + null, + implementedInApiVersion, + nameOf(updateDynamicResourceDoc), + "PUT", "/management/dynamic-resource-docs/DYNAMIC_RESOURCE_DOC_ID", "Update Dynamic Resource Doc", s"""Update a Dynamic Resource Doc. - | - |The connector_method_body is URL-encoded format String""", - jsonDynamicResourceDoc.copy(dynamicResourceDocId = None), jsonDynamicResourceDoc, + | + |The connector_method_body is URL-encoded format String + |""", + jsonDynamicResourceDoc.copy(dynamicResourceDocId = None), + jsonDynamicResourceDoc, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicResourceDoc), Some(List(canUpdateDynamicResourceDoc)), - http4sPartialFunction = Some(updateDynamicResourceDoc)) + http4sPartialFunction = Some(updateDynamicResourceDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteDynamicResourceDoc), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteDynamicResourceDoc), + "DELETE", "/management/dynamic-resource-docs/DYNAMIC_RESOURCE_DOC_ID", "Delete Dynamic Resource Doc", - s"""Delete a Dynamic Resource Doc.""", - EmptyBody, BooleanBody(true), + s"""Delete a Dynamic Resource Doc. + |""", + EmptyBody, + BooleanBody(true), List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicResourceDoc), Some(List(canDeleteDynamicResourceDoc)), - http4sPartialFunction = Some(deleteDynamicResourceDoc)) + http4sPartialFunction = Some(deleteDynamicResourceDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getDynamicResourceDoc), "GET", + null, + implementedInApiVersion, + nameOf(getDynamicResourceDoc), + "GET", "/management/dynamic-resource-docs/DYNAMIC_RESOURCE_DOC_ID", "Get Dynamic Resource Doc by Id", - s"""Get a Dynamic Resource Doc by DYNAMIC_RESOURCE_DOC_ID.""", - EmptyBody, jsonDynamicResourceDoc, + s"""Get a Dynamic Resource Doc by DYNAMIC-RESOURCE-DOC-ID. + | + |""", + EmptyBody, + jsonDynamicResourceDoc, List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagDynamicResourceDoc), Some(List(canGetDynamicResourceDoc)), - http4sPartialFunction = Some(getDynamicResourceDoc)) + http4sPartialFunction = Some(getDynamicResourceDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAllDynamicResourceDocs), "GET", + null, + implementedInApiVersion, + nameOf(getAllDynamicResourceDocs), + "GET", "/management/dynamic-resource-docs", "Get all Dynamic Resource Docs", - s"""Get all Dynamic Resource Docs.""", + s"""Get all Dynamic Resource Docs. + | + |""", EmptyBody, - com.openbankproject.commons.model.ListResult("dynamic-resource-docs", jsonDynamicResourceDoc :: Nil), + ListResult("dynamic-resource-docs", jsonDynamicResourceDoc :: Nil), List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagDynamicResourceDoc), Some(List(canGetAllDynamicResourceDocs)), - http4sPartialFunction = Some(getAllDynamicResourceDocs)) + http4sPartialFunction = Some(getAllDynamicResourceDocs) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createBankLevelDynamicResourceDoc), "POST", + null, + implementedInApiVersion, + nameOf(createBankLevelDynamicResourceDoc), + "POST", "/management/banks/BANK_ID/dynamic-resource-docs", "Create Bank Level Dynamic Resource Doc", s"""Create a Bank Level Dynamic Resource Doc. - | - |The connector_method_body is URL-encoded format String""", - jsonDynamicResourceDoc.copy(dynamicResourceDocId = None), jsonDynamicResourceDoc, + | + |The connector_method_body is URL-encoded format String + |""", + jsonDynamicResourceDoc.copy(dynamicResourceDocId = None), + jsonDynamicResourceDoc, List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicResourceDoc), Some(List(canCreateBankLevelDynamicResourceDoc)), - http4sPartialFunction = Some(createBankLevelDynamicResourceDoc)) + http4sPartialFunction = Some(createBankLevelDynamicResourceDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateBankLevelDynamicResourceDoc), "PUT", + null, + implementedInApiVersion, + nameOf(updateBankLevelDynamicResourceDoc), + "PUT", "/management/banks/BANK_ID/dynamic-resource-docs/DYNAMIC_RESOURCE_DOC_ID", "Update Bank Level Dynamic Resource Doc", s"""Update a Bank Level Dynamic Resource Doc. - | - |The connector_method_body is URL-encoded format String""", - jsonDynamicResourceDoc.copy(dynamicResourceDocId = None), jsonDynamicResourceDoc, + | + |The connector_method_body is URL-encoded format String + |""", + jsonDynamicResourceDoc.copy(dynamicResourceDocId = None), + jsonDynamicResourceDoc, List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicResourceDoc), Some(List(canUpdateBankLevelDynamicResourceDoc)), - http4sPartialFunction = Some(updateBankLevelDynamicResourceDoc)) + http4sPartialFunction = Some(updateBankLevelDynamicResourceDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteBankLevelDynamicResourceDoc), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteBankLevelDynamicResourceDoc), + "DELETE", "/management/banks/BANK_ID/dynamic-resource-docs/DYNAMIC_RESOURCE_DOC_ID", "Delete Bank Level Dynamic Resource Doc", - s"""Delete a Bank Level Dynamic Resource Doc.""", - EmptyBody, BooleanBody(true), + s"""Delete a Bank Level Dynamic Resource Doc. + |""", + EmptyBody, + BooleanBody(true), List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicResourceDoc), Some(List(canDeleteBankLevelDynamicResourceDoc)), - http4sPartialFunction = Some(deleteBankLevelDynamicResourceDoc)) + http4sPartialFunction = Some(deleteBankLevelDynamicResourceDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBankLevelDynamicResourceDoc), "GET", + null, + implementedInApiVersion, + nameOf(getBankLevelDynamicResourceDoc), + "GET", "/management/banks/BANK_ID/dynamic-resource-docs/DYNAMIC_RESOURCE_DOC_ID", "Get Bank Level Dynamic Resource Doc by Id", - s"""Get a Bank Level Dynamic Resource Doc by DYNAMIC_RESOURCE_DOC_ID.""", - EmptyBody, jsonDynamicResourceDoc, + s"""Get a Bank Level Dynamic Resource Doc by DYNAMIC-RESOURCE-DOC-ID. + | + |""", + EmptyBody, + jsonDynamicResourceDoc, List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagDynamicResourceDoc), Some(List(canGetBankLevelDynamicResourceDoc)), - http4sPartialFunction = Some(getBankLevelDynamicResourceDoc)) + http4sPartialFunction = Some(getBankLevelDynamicResourceDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAllBankLevelDynamicResourceDocs), "GET", + null, + implementedInApiVersion, + nameOf(getAllBankLevelDynamicResourceDocs), + "GET", "/management/banks/BANK_ID/dynamic-resource-docs", "Get all Bank Level Dynamic Resource Docs", - s"""Get all Bank Level Dynamic Resource Docs.""", + s"""Get all Bank Level Dynamic Resource Docs. + | + |""", EmptyBody, - com.openbankproject.commons.model.ListResult("dynamic-resource-docs", jsonDynamicResourceDoc :: Nil), + ListResult("dynamic-resource-docs", jsonDynamicResourceDoc :: Nil), List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagDynamicResourceDoc), Some(List(canGetAllBankLevelDynamicResourceDocs)), - http4sPartialFunction = Some(getAllBankLevelDynamicResourceDocs)) + http4sPartialFunction = Some(getAllBankLevelDynamicResourceDocs) + ) } initBatch16ResourceDocs() @@ -7446,116 +9951,178 @@ object Http4s400 { private def initBatch17ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createDynamicMessageDoc), "POST", + null, + implementedInApiVersion, + nameOf(createDynamicMessageDoc), + "POST", "/management/dynamic-message-docs", "Create Dynamic Message Doc", - s"""Create a Dynamic Message Doc.""", - jsonDynamicMessageDoc.copy(dynamicMessageDocId = None), jsonDynamicMessageDoc, + s"""Create a Dynamic Message Doc. + |""", + jsonDynamicMessageDoc.copy(dynamicMessageDocId = None), + jsonDynamicMessageDoc, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicMessageDoc), Some(List(canCreateDynamicMessageDoc)), - http4sPartialFunction = Some(createDynamicMessageDoc)) + http4sPartialFunction = Some(createDynamicMessageDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateDynamicMessageDoc), "PUT", + null, + implementedInApiVersion, + nameOf(updateDynamicMessageDoc), + "PUT", "/management/dynamic-message-docs/DYNAMIC_MESSAGE_DOC_ID", "Update Dynamic Message Doc", - s"""Update a Dynamic Message Doc.""", - jsonDynamicMessageDoc.copy(dynamicMessageDocId = None), jsonDynamicMessageDoc, + s"""Update a Dynamic Message Doc. + |""", + jsonDynamicMessageDoc.copy(dynamicMessageDocId = None), + jsonDynamicMessageDoc, List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicMessageDoc), Some(List(canUpdateDynamicMessageDoc)), - http4sPartialFunction = Some(updateDynamicMessageDoc)) + http4sPartialFunction = Some(updateDynamicMessageDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteDynamicMessageDoc), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteDynamicMessageDoc), + "DELETE", "/management/dynamic-message-docs/DYNAMIC_MESSAGE_DOC_ID", "Delete Dynamic Message Doc", - s"""Delete a Dynamic Message Doc.""", - EmptyBody, BooleanBody(true), + s"""Delete a Dynamic Message Doc. + |""", + EmptyBody, + BooleanBody(true), List($AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicMessageDoc), Some(List(canDeleteDynamicMessageDoc)), - http4sPartialFunction = Some(deleteDynamicMessageDoc)) + http4sPartialFunction = Some(deleteDynamicMessageDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getDynamicMessageDoc), "GET", + null, + implementedInApiVersion, + nameOf(getDynamicMessageDoc), + "GET", "/management/dynamic-message-docs/DYNAMIC_MESSAGE_DOC_ID", "Get Dynamic Message Doc", - s"""Get a Dynamic Message Doc by DYNAMIC_MESSAGE_DOC_ID.""", - EmptyBody, jsonDynamicMessageDoc, + s"""Get a Dynamic Message Doc by DYNAMIC_MESSAGE_DOC_ID. + | + |""", + EmptyBody, + jsonDynamicMessageDoc, List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagDynamicMessageDoc), Some(List(canGetDynamicMessageDoc)), - http4sPartialFunction = Some(getDynamicMessageDoc)) + http4sPartialFunction = Some(getDynamicMessageDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAllDynamicMessageDocs), "GET", + null, + implementedInApiVersion, + nameOf(getAllDynamicMessageDocs), + "GET", "/management/dynamic-message-docs", "Get all Dynamic Message Docs", - s"""Get all Dynamic Message Docs.""", + s"""Get all Dynamic Message Docs. + | + |""", EmptyBody, - com.openbankproject.commons.model.ListResult("dynamic-message-docs", jsonDynamicMessageDoc :: Nil), + ListResult("dynamic-message-docs", jsonDynamicMessageDoc :: Nil), List($AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagDynamicMessageDoc), Some(List(canGetAllDynamicMessageDocs)), - http4sPartialFunction = Some(getAllDynamicMessageDocs)) + http4sPartialFunction = Some(getAllDynamicMessageDocs) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createBankLevelDynamicMessageDoc), "POST", + null, + implementedInApiVersion, + nameOf(createBankLevelDynamicMessageDoc), + "POST", "/management/banks/BANK_ID/dynamic-message-docs", "Create Bank Level Dynamic Message Doc", - s"""Create a Bank Level Dynamic Message Doc.""", - jsonDynamicMessageDoc.copy(dynamicMessageDocId = None), jsonDynamicMessageDoc, + s"""Create a Bank Level Dynamic Message Doc. + |""", + jsonDynamicMessageDoc.copy(dynamicMessageDocId = None), + jsonDynamicMessageDoc, List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicMessageDoc), Some(List(canCreateBankLevelDynamicMessageDoc)), - http4sPartialFunction = Some(createBankLevelDynamicMessageDoc)) + http4sPartialFunction = Some(createBankLevelDynamicMessageDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(updateBankLevelDynamicMessageDoc), "PUT", + null, + implementedInApiVersion, + nameOf(updateBankLevelDynamicMessageDoc), + "PUT", "/management/banks/BANK_ID/dynamic-message-docs/DYNAMIC_MESSAGE_DOC_ID", "Update Bank Level Dynamic Message Doc", - s"""Update a Bank Level Dynamic Message Doc.""", - jsonDynamicMessageDoc.copy(dynamicMessageDocId = None), jsonDynamicMessageDoc, + s"""Update a Bank Level Dynamic Message Doc. + |""", + jsonDynamicMessageDoc.copy(dynamicMessageDocId = None), + jsonDynamicMessageDoc, List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicMessageDoc), Some(List(canUpdateDynamicMessageDoc)), - http4sPartialFunction = Some(updateBankLevelDynamicMessageDoc)) + http4sPartialFunction = Some(updateBankLevelDynamicMessageDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(deleteBankLevelDynamicMessageDoc), "DELETE", + null, + implementedInApiVersion, + nameOf(deleteBankLevelDynamicMessageDoc), + "DELETE", "/management/banks/BANK_ID/dynamic-message-docs/DYNAMIC_MESSAGE_DOC_ID", "Delete Bank Level Dynamic Message Doc", - s"""Delete a Bank Level Dynamic Message Doc.""", - EmptyBody, BooleanBody(true), + s"""Delete a Bank Level Dynamic Message Doc. + |""", + EmptyBody, + BooleanBody(true), List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagDynamicMessageDoc), Some(List(canDeleteBankLevelDynamicMessageDoc)), - http4sPartialFunction = Some(deleteBankLevelDynamicMessageDoc)) + http4sPartialFunction = Some(deleteBankLevelDynamicMessageDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getBankLevelDynamicMessageDoc), "GET", + null, + implementedInApiVersion, + nameOf(getBankLevelDynamicMessageDoc), + "GET", "/management/banks/BANK_ID/dynamic-message-docs/DYNAMIC_MESSAGE_DOC_ID", "Get Bank Level Dynamic Message Doc", - s"""Get a Bank Level Dynamic Message Doc by DYNAMIC_MESSAGE_DOC_ID.""", - EmptyBody, jsonDynamicMessageDoc, + s"""Get a Bank Level Dynamic Message Doc by DYNAMIC_MESSAGE_DOC_ID. + | + |""", + EmptyBody, + jsonDynamicMessageDoc, List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagDynamicMessageDoc), Some(List(canGetBankLevelDynamicMessageDoc)), - http4sPartialFunction = Some(getBankLevelDynamicMessageDoc)) + http4sPartialFunction = Some(getBankLevelDynamicMessageDoc) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(getAllBankLevelDynamicMessageDocs), "GET", + null, + implementedInApiVersion, + nameOf(getAllBankLevelDynamicMessageDocs), + "GET", "/management/banks/BANK_ID/dynamic-message-docs", "Get all Bank Level Dynamic Message Docs", - s"""Get all Bank Level Dynamic Message Docs.""", + s"""Get all Bank Level Dynamic Message Docs. + | + |""", EmptyBody, - com.openbankproject.commons.model.ListResult("dynamic-message-docs", jsonDynamicMessageDoc :: Nil), + ListResult("dynamic-message-docs", jsonDynamicMessageDoc :: Nil), List($BankNotFound, $AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagDynamicMessageDoc), Some(List(canGetAllDynamicMessageDocs)), - http4sPartialFunction = Some(getAllBankLevelDynamicMessageDocs)) + http4sPartialFunction = Some(getAllBankLevelDynamicMessageDocs) + ) } initBatch17ResourceDocs() @@ -7595,14 +10162,26 @@ object Http4s400 { private def initBatch18ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(buildDynamicEndpointTemplate), "POST", + null, + implementedInApiVersion, + nameOf(buildDynamicEndpointTemplate), + "POST", "/management/dynamic-resource-docs/endpoint-code", "Create Dynamic Resource Doc endpoint code", - s"""Create a Dynamic Resource Doc endpoint code.""", - jsonResourceDocFragment, jsonCodeTemplateJson, + s"""Create a Dynamic Resource Doc endpoint code. + | + |copy the response and past to ${nameOf( + PractiseEndpoint + )}, So you can have the benefits of + |auto compilation and debug + |""", + jsonResourceDocFragment, + jsonCodeTemplateJson, List($AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), - List(apiTagDynamicResourceDoc), None, - http4sPartialFunction = Some(buildDynamicEndpointTemplate)) + List(apiTagDynamicResourceDoc), + None, + http4sPartialFunction = Some(buildDynamicEndpointTemplate) + ) } initBatch18ResourceDocs() @@ -8120,52 +10699,91 @@ object Http4s400 { private def initBatch19ResourceDocs(): Unit = { staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(addAccount), "POST", + null, + implementedInApiVersion, + nameOf(addAccount), + "POST", "/banks/BANK_ID/accounts", "Create Account (POST)", """Create Account at bank specified by BANK_ID. - | - |The User can create an Account for themself - or - the User that has the USER_ID specified in the POST body. - | - |If the POST body USER_ID *is* specified, the logged in user must have the Role CanCreateAccount. Once created, the Account will be owned by the User specified by USER_ID. - | - |If the POST body USER_ID is *not* specified, the account will be owned by the logged in User. - | - |The 'product_code' field SHOULD be a product_code from Product. - |If the product_code matches a product_code from Product, account attributes will be created that match the Product Attributes. - | - |Note: The Amount MUST be zero.""".stripMargin, - createAccountRequestJsonV310, createAccountResponseJsonV310, + | + |The User can create an Account for themself - or - the User that has the USER_ID specified in the POST body. + | + |If the POST body USER_ID *is* specified, the logged in user must have the Role CanCreateAccount. Once created, the Account will be owned by the User specified by USER_ID. + | + |If the POST body USER_ID is *not* specified, the account will be owned by the logged in User. + | + |The 'product_code' field SHOULD be a product_code from Product. + |If the product_code matches a product_code from Product, account attributes will be created that match the Product Attributes. + | + |Note: The Amount MUST be zero.""".stripMargin, + createAccountRequestJsonV310, + createAccountResponseJsonV310, List(InvalidJsonFormat, $AuthenticatedUserIsRequired, UserHasMissingRoles, - InvalidAccountBalanceAmount, InvalidAccountInitialBalance, InitialBalanceMustBeZero, - InvalidAccountBalanceCurrency, UnknownError), + InvalidAccountBalanceAmount, InvalidAccountInitialBalance, InitialBalanceMustBeZero, + InvalidAccountBalanceCurrency, UnknownError), List(apiTagAccount), Some(List(canCreateAccount)), - http4sPartialFunction = Some(addAccount)) + http4sPartialFunction = Some(addAccount) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createSettlementAccount), "POST", + null, + implementedInApiVersion, + nameOf(createSettlementAccount), + "POST", "/banks/BANK_ID/settlement-accounts", "Create Settlement Account", - s"""Create a new settlement account at a bank.""", - settlementAccountRequestJson, settlementAccountResponseJson, + s"""Create a new settlement account at a bank. + | + |The created settlement account id will be the concatenation of the payment system and the account currency. + |For examples: SEPA_SETTLEMENT_ACCOUNT_EUR, CARD_SETTLEMENT_ACCOUNT_USD + | + |By default, when you create a new bank, two settlements accounts are created automatically: OBP_DEFAULT_INCOMING_ACCOUNT_ID and OBP_DEFAULT_OUTGOING_ACCOUNT_ID + |Those two accounts have EUR as default currency. + | + |If you want to create default settlement account for a specific currency, you can fill the `payment_system` field with the `DEFAULT` value. + | + |When a transaction is saved in OBP through the mapped connector, OBP-API look for the account to save the double-entry transaction. + |If no OBP account can be found from the counterparty, the double-entry transaction will be saved on a bank settlement account. + |- First, the mapped connector looks for a settlement account specific to the payment system and currency. E.g SEPA_SETTLEMENT_ACCOUNT_EUR. + |- If we don't find any specific settlement account with the payment system, we look for a default settlement account for the counterparty currency. E.g DEFAULT_SETTLEMENT_ACCOUNT_EUR. + |- Else, we select one of the two OBP default settlement accounts (OBP_DEFAULT_INCOMING_ACCOUNT_ID/OBP_DEFAULT_OUTGOING_ACCOUNT_ID) according to the transaction direction. + | + |If the POST body USER_ID *is* specified, the logged in user must have the Role CanCreateAccount. Once created, the Account will be owned by the User specified by USER_ID. + | + |If the POST body USER_ID is *not* specified, the account will be owned by the logged in User. + | + |Note: The Amount MUST be zero. + |""".stripMargin, + settlementAccountRequestJson, + settlementAccountResponseJson, List(InvalidJsonFormat, $AuthenticatedUserIsRequired, UserHasMissingRoles, - $BankNotFound, InvalidAccountInitialBalance, InitialBalanceMustBeZero, - InvalidISOCurrencyCode, UnknownError), + $BankNotFound, InvalidAccountInitialBalance, InitialBalanceMustBeZero, + InvalidISOCurrencyCode, UnknownError), List(apiTagBank), Some(List(canCreateSettlementAccountAtOneBank)), - http4sPartialFunction = Some(createSettlementAccount)) + http4sPartialFunction = Some(createSettlementAccount) + ) staticResourceDocs += ResourceDoc( null, implementedInApiVersion, "createConsumer", "POST", "/management/consumers", "Post a Consumer", s"""Create a Consumer (Authenticated access).""", - code.api.v2_1_0.ConsumerPostJSON( - "Test", "Web", "Description", "some@email.com", "redirecturl", "createdby", true, new java.util.Date(), + ConsumerPostJSON( + "Test", + "Web", + "Description", + "some@email.com", + "redirecturl", + "createdby", + true, + new Date(), """-----BEGIN CERTIFICATE----- |client_certificate_content - |-----END CERTIFICATE-----""".stripMargin), + |-----END CERTIFICATE-----""".stripMargin + ), consumerJsonV400, List(AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagConsumer), @@ -8176,7 +10794,14 @@ object Http4s400 { null, implementedInApiVersion, "createCounterpartyForAnyAccount", "POST", "/management/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties", "Create Counterparty for any account (Explicit)", - s"""This is a management endpoint that allows the creation of a Counterparty on any Account.""", + s"""This is a management endpoint that allows the creation of a Counterparty on any Account. + | + |For an introduction to Counterparties in OBP, see ${Glossary + .getGlossaryItemLink("Counterparties")} + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, postCounterpartyJson400, counterpartyWithMetadataJson400, List($AuthenticatedUserIsRequired, InvalidAccountIdFormat, InvalidBankIdFormat, $BankNotFound, $BankAccountNotFound, AccountNotFound, InvalidJsonFormat, @@ -8186,52 +10811,157 @@ object Http4s400 { http4sPartialFunction = Some(createCounterpartyForAnyAccount)) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createHistoricalTransactionAtBank), "POST", + null, + implementedInApiVersion, + nameOf(createHistoricalTransactionAtBank), + "POST", "/banks/BANK_ID/management/historical/transactions", "Create Historical Transactions ", - s"""Create historical transactions at one Bank.""", - postHistoricalTransactionAtBankJson, postHistoricalTransactionResponseJson, + s""" + |Create historical transactions at one Bank + | + |Use this endpoint to create transactions between any two accounts at the same bank. + |From account and to account must be at the same bank. + |Example: + |{ + | "from_account_id": "1ca8a7e4-6d02-48e3-a029-0b2bf89de9f0", + | "to_account_id": "2ca8a7e4-6d02-48e3-a029-0b2bf89de9f0", + | "value": { + | "currency": "GBP", + | "amount": "10" + | }, + | "description": "this is for work", + | "posted": "2017-09-19T02:31:05Z", + | "completed": "2017-09-19T02:31:05Z", + | "type": "SANDBOX_TAN", + | "charge_policy": "SHARED" + |} + | + |This call is experimental. + """.stripMargin, + postHistoricalTransactionAtBankJson, + postHistoricalTransactionResponseJson, List(InvalidJsonFormat, BankNotFound, AccountNotFound, CounterpartyNotFoundByCounterpartyId, - InvalidNumber, NotPositiveAmount, InvalidTransactionRequestCurrency, UnknownError), + InvalidNumber, NotPositiveAmount, InvalidTransactionRequestCurrency, UnknownError), List(apiTagTransactionRequest), Some(List(canCreateHistoricalTransactionAtBank)), - http4sPartialFunction = Some(createHistoricalTransactionAtBank)) + http4sPartialFunction = Some(createHistoricalTransactionAtBank) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createUserWithRoles), "POST", + null, + implementedInApiVersion, + nameOf(createUserWithRoles), + "POST", "/user-entitlements", "Create (DAuth) User with Roles", - s"""Create (DAuth) User with Roles.""", - postCreateUserWithRolesJsonV400, entitlementsJsonV400, + s""" + |This endpoint is used as part of the DAuth solution to grant Entitlements for Roles to a smart contract on the blockchain. + | + |Put the smart contract address in username + | + |For provider use "dauth" + | + |This endpoint will create the User with username and provider if the User does not already exist. + | + |Then it will create Entitlements i.e. grant Roles to the User. + | + |Entitlements are used to grant System or Bank level roles to Users. (For Account level privileges, see Views) + | + |i.e. Entitlements are used to create / consume system or bank level resources where as views / account access are used to consume / create customer level resources. + | + |For a System level Role (.e.g CanGetAnyUser), set bank_id to an empty string i.e. "bank_id":"" + | + |For a Bank level Role (e.g. CanCreateAccount), set bank_id to a valid value e.g. "bank_id":"my-bank-id" + | + |Note: The Roles actually granted will depend on the Roles that the calling user has. + | + |If you try to grant Entitlements to a user that already exist (duplicate entitilements) you will get an error. + | + |For information about DAuth see below: + | + |${getGlossaryItem("DAuth")} + | + |""", + postCreateUserWithRolesJsonV400, + entitlementsJsonV400, List(AuthenticatedUserIsRequired, InvalidJsonFormat, IncorrectRoleName, - EntitlementIsBankRole, EntitlementIsSystemRole, EntitlementAlreadyExists, - InvalidUserProvider, UnknownError), + EntitlementIsBankRole, EntitlementIsSystemRole, EntitlementAlreadyExists, + InvalidUserProvider, UnknownError), List(apiTagRole, apiTagEntitlement, apiTagUser, apiTagDAuth), None, - http4sPartialFunction = Some(createUserWithRoles)) + http4sPartialFunction = Some(createUserWithRoles) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createUserWithAccountAccess), "POST", + null, + implementedInApiVersion, + nameOf(createUserWithAccountAccess), + "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/user-account-access", "Create (DAuth) User with Account Access", - s"""Create (DAuth) User with Account Access.""", - postCreateUserAccountAccessJsonV400, List(viewJsonV300), + s"""This endpoint is used as part of the DAuth solution to grant access to account and transaction data to a smart contract on the blockchain. + | + |Put the smart contract address in username + | + |For provider use "dauth" + | + |This endpoint will create the (DAuth) User with username and provider if the User does not already exist. + | + |${userAuthenticationMessage( + true + )} and the logged in user needs to be account holder. + | + |For information about DAuth see below: + | + |${getGlossaryItem("DAuth")} + | + |""", + postCreateUserAccountAccessJsonV400, + List(viewJsonV300), List($AuthenticatedUserIsRequired, UserLacksPermissionCanGrantAccessToViewForTargetAccount, - InvalidJsonFormat, SystemViewNotFound, ViewNotFound, CannotGrantAccountAccess, UnknownError), + InvalidJsonFormat, SystemViewNotFound, ViewNotFound, CannotGrantAccountAccess, UnknownError), List(apiTagAccountAccess, apiTagView, apiTagAccount, apiTagUser, apiTagOwnerRequired, apiTagDAuth), None, - http4sPartialFunction = Some(createUserWithAccountAccess)) + http4sPartialFunction = Some(createUserWithAccountAccess) + ) staticResourceDocs += ResourceDoc( - null, implementedInApiVersion, nameOf(createUserInvitation), "POST", + null, + implementedInApiVersion, + nameOf(createUserInvitation), + "POST", "/banks/BANK_ID/user-invitation", "Create User Invitation", - s"""Create User Invitation.""", - userInvitationPostJsonV400, userInvitationJsonV400, + s"""Create User Invitation. + | + | This endpoint will send an invitation email to the developers, then they can use the link to create the obp user. + | + | purpose filed only support:${UserInvitationPurpose.values + .toString()}. + | + | You can customise the email details use the following webui props: + | + | when purpose == ${UserInvitationPurpose.DEVELOPER.toString} + | webui_developer_user_invitation_email_subject + | webui_developer_user_invitation_email_from + | webui_developer_user_invitation_email_text + | webui_developer_user_invitation_email_html_text + | + | when purpose = == ${UserInvitationPurpose.CUSTOMER.toString} + | webui_customer_user_invitation_email_subject + | webui_customer_user_invitation_email_from + | webui_customer_user_invitation_email_text + | webui_customer_user_invitation_email_html_text + | + |""", + userInvitationPostJsonV400, + userInvitationJsonV400, List($AuthenticatedUserIsRequired, $BankNotFound, UserCustomerLinksNotFoundForUser, UnknownError), List(apiTagUserInvitation, apiTagKyc), Some(canCreateUserInvitation :: Nil), - http4sPartialFunction = Some(createUserInvitation)) + http4sPartialFunction = Some(createUserInvitation) + ) } initBatch19ResourceDocs() From 1647c017aefb2654b2846f2ace110d80b36476aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 14:34:28 +0200 Subject: [PATCH 12/14] =?UTF-8?q?docs(migration):=20v4.0.0=20ResourceDoc?= =?UTF-8?q?=20parity=20=E2=80=94=20update=20table=20+=20fix-candidate=20de?= =?UTF-8?q?tail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit 2b24811e5 dropped v4.0.0 audit mismatches from 172 to 20, update the per-version drift table and add a new "v4.0.0 — 20 specific drifts" subsection with per-endpoint resolution notes. New total across all migrated versions: 225 mismatches (was 377). v4.0.0's residual drifts split into structural-rename buckets (mostly ResourceDocMatcher disambiguation: VIEW_ID → GRANT_VIEW_ID, COUNTERPARTY_ID → COUNTERPARTY_ID_PARAM, hyphen → underscore for DYNAMIC-RESOURCE-DOC-ID, firehose template bypass) plus 1 legitimate REST-correctness fix (deleteExplicitCounterparty POST → DELETE) and 1 Lift URL-bug fix (deleteCustomerAttribute). Also notes the 2 only-lift entries (getAllAuthenticationTypeValidationsPublic / getAllJsonSchemaValidationsPublic) as an outstanding migration gap to port to http4s. --- LIFT_HTTP4S_MIGRATION.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/LIFT_HTTP4S_MIGRATION.md b/LIFT_HTTP4S_MIGRATION.md index f734d103e3..ea33abbded 100644 --- a/LIFT_HTTP4S_MIGRATION.md +++ b/LIFT_HTTP4S_MIGRATION.md @@ -194,11 +194,11 @@ Separate from the resource-docs **serving** workstream above, there is a parity | v2_2_0 | 18 | 13 | 0 | 0 | not started | | v3_0_0 | 47 | 41 | 0 | 0 | not started | | v3_1_0 | 102 | 49 | 0 | 0 | not started | -| v4_0_0 | 254 | 172| 2 | 5 | not started | +| v4_0_0 | 254 | 20 | 2 | 5 | semantic fields restored; 20 structural drifts (placeholder renames + 1 verb fix) remain | | v5_0_0 | 39 | 8 | 0 | 3 | descriptions restored; structural/errors remain | | v5_1_0 | 111 | 1 | 1 | 2 | one verb-casing drift to fix | | v6_0_0 | 243 | 12 | 0 | 1 | 11 placeholder renames + 1 routing-shape upstream change | -| **Total** | **956** | **377** | | | | +| **Total** | **956** | **225** | | | | ### v6.0.0 — 12 specific drifts (each is a fix candidate) @@ -231,6 +231,22 @@ Also: - 1 only-lift (`createConsentImplicit`) + 1 only-http4s (`createConsent`) — Lift had `lazy val createConsentImplicit = createConsent` aliasing and registered the doc under the alias; http4s registers under the canonical name. Fix: in http4s, either rename the partial function to `createConsentImplicit` to match Lift, or register a second `nameOf(createConsentImplicit)` doc for the same handler. - 1 only-http4s (`getBanks`) — kept in the v5.1.0 layer for metrics attribution (intentional addition; see comment at `Http4s510.scala:288`). Document. +### v4.0.0 — 20 specific drifts + 2 only-lift + 5 only-http4s + +After semantic-field restoration (commit `2b24811e5`), the remaining drifts are all structural / functional: + +| Category | Count | Endpoints | Resolution | +|---|---|---|---| +| requestVerb | 1 | `deleteExplicitCounterparty` (Lift `POST` → http4s `DELETE`) | http4s is REST-correct. **Document** as deliberate fix. | +| requestUrl — `VIEW_ID` → `GRANT_VIEW_ID` | 9 | `answerTransactionRequestChallenge` and 8 `createTransactionRequest*` variants (Account/AccountOtp/AgentCashWithDrawal/Counterparty/FreeForm/Refund/Sepa/Simple) | Middleware disambiguation rename. Verify if `VIEW_ID` collides in `ResourceDocMatcher`; if not, revert. If it does, **document**. | +| requestUrl — hyphen→underscore | 6 | `delete`/`get`/`update` × `BankLevelDynamicResourceDoc` / `DynamicResourceDoc` (Lift `DYNAMIC-RESOURCE-DOC-ID` → http4s `DYNAMIC_RESOURCE_DOC_ID`) | The matcher's ALL_CAPS-with-underscores wildcard requires underscores. **Fix Lift**? No — Lift is source-of-truth. **Document** at the http4s site as a required matcher constraint. | +| requestUrl — `COUNTERPARTY_ID` → `COUNTERPARTY_ID_PARAM` | 2 | `deleteExplicitCounterparty`, `getCounterpartyByIdForAnyAccount` | Same as v6's COUNTERPARTY rename family. Verify matcher behavior; revert if safe. | +| requestUrl — `COUNTERPARTY_ID` → `EXPLICIT_COUNTERPARTY_ID` | 1 | `getExplicitCounterpartyById` | Same defensive rename pattern. | +| requestUrl — firehose pattern | 1 | `getFirehoseAccountsAtOneBank` (Lift `BANK_ID/.../VIEW_ID` → http4s `FIREHOSE_BANK_ID/.../FIREHOSE_VIEW_ID`) | Middleware bypass for the prop-check-before-bank-lookup pattern (see CLAUDE.md "Prop check before role check" gotcha). **Document** — required for correctness. | +| requestUrl — Lift URL malformed | 1 | `deleteCustomerAttribute` (Lift `/banks/BANK_ID/CUSTOMER_ID/attributes/.../...` is missing `/customers/`; http4s uses `/banks/BANK_ID/customers/attributes/...`) | Lift URL was buggy. http4s fixed it. **Document** as deliberate URL fix; flag that the Lift comment preserves the original bug as historical record. | + +Also: 2 only-lift (`getAllAuthenticationTypeValidationsPublic`, `getAllJsonSchemaValidationsPublic`) — these endpoints exist in Lift v4 but were not migrated to `Http4s400`. **Migration gap** — port them. 5 only-http4s (`createBankLevelDynamicEntity`, `createSystemDynamicEntity`, `updateBankLevelDynamicEntity`, `updateMyDynamicEntity`, `updateSystemDynamicEntity`) — dynamic-entity overrides added in http4s with no Lift equivalent. Document if intentional, or audit whether they should have Lift counterparts. + ### v5.0.0 — 8 specific drifts + 3 only-http4s | Category | Count | Endpoints | Resolution | From d081ff7a97ce3ef1709269d9952a90ab8e28b639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 14:42:46 +0200 Subject: [PATCH 13/14] v3.1.0: bring ResourceDoc parity from 49 to 5 mismatches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run scripts/restore_resource_doc_bodies.py against APIMethods310.scala (source of truth — fully stubbed, 102 commented `resourceDocs += ResourceDoc` blocks) to restore the canonical Lift descriptions, request/response examples, error lists, summaries, and tags into Http4s310.scala. 66 field rewrites across: description: 46 (46 → 0) successResponseBody: 8 (8 → 0) errorResponseBodies: 6 (6 → 0) exampleRequestBody: 3 (3 → 0) summary: 2 (2 → 0) tags: 1 (1 → 0) Upstream's rehydrate_resource_docs.py reported "0 patched" for v3.1.0 because it only matches non-stub `staticResourceDocs += ResourceDoc` blocks; the v3.1.0 APIMethods file uses `// resourceDocs += ResourceDoc` which my script handles via uncomment(). Supporting code carried over from the commented-out APIMethods310.scala so the restored descriptions compile: - Import: Glossary (the object, not the wildcard). - Four private vals referenced inside `s"""..."""` doc interpolations: productAttributeGeneralInfo, accountAttributeGeneralInfo, supportedConnectorNames, generalObpConsentText. Remaining 5 audit diffs are all structural drifts where http4s renamed the URL placeholder for ResourceDocMatcher / middleware reasons: createAccount ACCOUNT_ID → NEW_ACCOUNT_ID (PUT-creates pattern; middleware would 404 on ACCOUNT_ID lookup) deleteSystemView VIEW_ID → SYS_VIEW_ID (disambiguates from other VIEW_ID usages) getSystemView VIEW_ID → SYS_VIEW_ID (same) updateSystemView VIEW_ID → SYS_VIEW_ID (same) getFirehoseCustomers BANK_ID → FIREHOSE_BANK_ID (firehose middleware bypass — prop check before bank lookup) These are required for middleware correctness; the resolution is to document at the http4s site, not to revert. Per the source-of-truth rule, APIMethods310.scala is NOT modified. --- LIFT_HTTP4S_MIGRATION.md | 18 +- .../scala/code/api/v3_1_0/Http4s310.scala | 1211 ++++++++++++++--- 2 files changed, 1030 insertions(+), 199 deletions(-) diff --git a/LIFT_HTTP4S_MIGRATION.md b/LIFT_HTTP4S_MIGRATION.md index ea33abbded..97cbac5246 100644 --- a/LIFT_HTTP4S_MIGRATION.md +++ b/LIFT_HTTP4S_MIGRATION.md @@ -193,12 +193,12 @@ Separate from the resource-docs **serving** workstream above, there is a parity | v2_1_0 | 23 | 13 | 5 | 2 | not started | | v2_2_0 | 18 | 13 | 0 | 0 | not started | | v3_0_0 | 47 | 41 | 0 | 0 | not started | -| v3_1_0 | 102 | 49 | 0 | 0 | not started | +| v3_1_0 | 102 | 5 | 0 | 0 | semantic fields restored; 5 structural drifts (placeholder renames) remain | | v4_0_0 | 254 | 20 | 2 | 5 | semantic fields restored; 20 structural drifts (placeholder renames + 1 verb fix) remain | | v5_0_0 | 39 | 8 | 0 | 3 | descriptions restored; structural/errors remain | | v5_1_0 | 111 | 1 | 1 | 2 | one verb-casing drift to fix | | v6_0_0 | 243 | 12 | 0 | 1 | 11 placeholder renames + 1 routing-shape upstream change | -| **Total** | **956** | **225** | | | | +| **Total** | **956** | **181** | | | | ### v6.0.0 — 12 specific drifts (each is a fix candidate) @@ -231,6 +231,20 @@ Also: - 1 only-lift (`createConsentImplicit`) + 1 only-http4s (`createConsent`) — Lift had `lazy val createConsentImplicit = createConsent` aliasing and registered the doc under the alias; http4s registers under the canonical name. Fix: in http4s, either rename the partial function to `createConsentImplicit` to match Lift, or register a second `nameOf(createConsentImplicit)` doc for the same handler. - 1 only-http4s (`getBanks`) — kept in the v5.1.0 layer for metrics attribution (intentional addition; see comment at `Http4s510.scala:288`). Document. +### v3.1.0 — 5 specific drifts + +After semantic-field restoration (commit `f4b9bd183`), only middleware-driven placeholder renames remain. + +| Endpoint | Field | Lift | http4s | Resolution | +|---|---|---|---|---| +| `createAccount` | requestUrl | `/banks/BANK_ID/accounts/ACCOUNT_ID` | `…/NEW_ACCOUNT_ID` | PUT-creates-account pattern. Middleware would 404 on `ACCOUNT_ID` lookup before the handler. **Document** — required. | +| `deleteSystemView` | requestUrl | `/system-views/VIEW_ID` | `/SYS_VIEW_ID` | Disambiguation from other VIEW_ID usages. **Document**. | +| `getSystemView` | requestUrl | same | same | same | +| `updateSystemView` | requestUrl | same | same | same | +| `getFirehoseCustomers` | requestUrl | `/banks/BANK_ID/firehose/customers` | `…/FIREHOSE_BANK_ID/…` | Firehose middleware bypass — prop check must run before bank lookup (see CLAUDE.md). **Document** — required. | + +No only-lift or only-http4s entries for v3.1.0. + ### v4.0.0 — 20 specific drifts + 2 only-lift + 5 only-http4s After semantic-field restoration (commit `2b24811e5`), the remaining drifts are all structural / functional: diff --git a/obp-api/src/main/scala/code/api/v3_1_0/Http4s310.scala b/obp-api/src/main/scala/code/api/v3_1_0/Http4s310.scala index eebae85bd5..0d68a70c27 100644 --- a/obp-api/src/main/scala/code/api/v3_1_0/Http4s310.scala +++ b/obp-api/src/main/scala/code/api/v3_1_0/Http4s310.scala @@ -12,7 +12,7 @@ import code.api.util.ApiRole._ import code.api.util.ApiTag._ import code.api.util.ErrorMessages._ import code.api.util.CertificateUtil -import code.api.util.{ApiTrigger, Consent, SecureRandomUtil} +import code.api.util.{ApiTrigger, Consent, Glossary, SecureRandomUtil} import code.api.util.http4s.Http4sRequestAttributes.{EndpointHelpers, RequestOps} import code.api.util.http4s.ResourceDocMiddleware import code.api.util.newstyle.{BalanceNewStyle, ViewNewStyle} @@ -68,6 +68,85 @@ object Http4s310 { type HttpF[A] = OptionT[IO, A] + // Local doc-strings carried over from the commented-out APIMethods310.scala + // so the restored ResourceDoc descriptions compile. Kept verbatim — these + // are referenced inside `s"""..."""` interpolations in the doc text. + private val productAttributeGeneralInfo = + s""" + |Product Attributes are used to describe a financial Product with a list of typed key value pairs. + | + |Each Product Attribute is linked to its Product by PRODUCT_CODE + | + | + """.stripMargin + + private val accountAttributeGeneralInfo = + s""" + |Account Attributes are used to describe a financial Product with a list of typed key value pairs. + | + |Each Account Attribute is linked to its Account by ACCOUNT_ID + | + | + """.stripMargin + + private val supportedConnectorNames = + NewStyle.function.getSupportedConnectorNames().mkString("[", " | ", "]") + + private val generalObpConsentText: String = + s""" + | + |An OBP Consent allows the holder of the Consent to call one or more endpoints. + | + |Consents must be created and authorisied using SCA (Strong Customer Authentication). + | + |That is, Consents can be created by an authorised User via the OBP REST API but they must be confirmed via an out of band (OOB) mechanism such as a code sent to a mobile phone. + | + |Each Consent has one of the following states: ${ConsentStatus.values.toList.sorted.mkString(", ") }. + | + |Each Consent is bound to a consumer i.e. you need to identify yourself over request header value Consumer-Key. + |For example: + |GET /obp/v4.0.0/users/current HTTP/1.1 + |Host: 127.0.0.1:8080 + |Consent-JWT: eyJhbGciOiJIUzI1NiJ9.eyJlbnRpdGxlbWVudHMiOlt7InJvbGVfbmFtZSI6IkNhbkdldEFueVVzZXIiLCJiYW5rX2lkIjoiIn + |1dLCJjcmVhdGVkQnlVc2VySWQiOiJhYjY1MzlhOS1iMTA1LTQ0ODktYTg4My0wYWQ4ZDZjNjE2NTciLCJzdWIiOiIzNDc1MDEzZi03YmY5LTQyNj + |EtOWUxYy0xZTdlNWZjZTJlN2UiLCJhdWQiOiI4MTVhMGVmMS00YjZhLTQyMDUtYjExMi1lNDVmZDZmNGQzYWQiLCJuYmYiOjE1ODA3NDE2NjcsIml + |zcyI6Imh0dHA6XC9cLzEyNy4wLjAuMTo4MDgwIiwiZXhwIjoxNTgwNzQ1MjY3LCJpYXQiOjE1ODA3NDE2NjcsImp0aSI6ImJkYzVjZTk5LTE2ZTY + |tNDM4Yi1hNjllLTU3MTAzN2RhMTg3OCIsInZpZXdzIjpbXX0.L3fEEEhdCVr3qnmyRKBBUaIQ7dk1VjiFaEBW8hUNjfg + | + |Consumer-Key: ejznk505d132ryomnhbx1qmtohurbsbb0kijajsk + |cache-control: no-cache + | + |Maximum time to live of the token is specified over props value consents.max_time_to_live. In case isn't defined default value is 3600 seconds. + | + |Example of POST JSON: + |{ + | "everything": false, + | "views": [ + | { + | "bank_id": "GENODEM1GLS", + | "account_id": "8ca8a7e4-6d02-40e3-a129-0b2bf89de9f0", + | "view_id": "${Constant.SYSTEM_OWNER_VIEW_ID}" + | } + | ], + | "entitlements": [ + | { + | "bank_id": "GENODEM1GLS", + | "role_name": "CanGetCustomersAtOneBank" + | } + | ], + | "consumer_id": "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + | "email": "eveline@example.com", + | "valid_from": "2020-02-07T08:43:34Z", + | "time_to_live": 3600 + |} + |Please note that only optional fields are: consumer_id, valid_from and time_to_live. + |In case you omit they the default values are used: + |consumer_id = consumer of current user + |valid_from = current time + |time_to_live = consents.max_time_to_live + | + """.stripMargin + object Implementations3_1_0 { val prefixPath: Path = Root / ApiPathZero.toString / implementedInApiVersion.toString @@ -170,7 +249,47 @@ object Http4s310 { "Get Top APIs", s"""Get metrics about the most popular APIs. e.g.: total count, response time (in ms), etc. | - |${userAuthenticationMessage(true)}""", + |Should be able to filter on the following fields + | + |eg: /management/metrics/top-apis?from_date=$epochTimeString&to_date=$DefaultToDateString&consumer_id=5 + |&user_id=66214b8e-259e-44ad-8868-3eb47be70646&implemented_by_partial_function=getTransactionsForBankAccount + |&implemented_in_version=v3.0.0&url=/obp/v3.0.0/banks/gh.29.uk/accounts/8ca8a7e4-6d02-48e3-a029-0b2bf89de9f0/owner/transactions + |&verb=GET&anon=false&app_name=MapperPostman + |&exclude_app_names=API-EXPLORER,API-Manager,SOFI,null + | + |1 from_date (defaults to the one year ago): eg:from_date=$epochTimeString + | + |2 to_date (defaults to the current date) eg:to_date=$DefaultToDateString + | + |3 consumer_id (if null ignore) + | + |4 user_id (if null ignore) + | + |5 anon (if null ignore) only support two value : true (return where user_id is null.) or false (return where user_id is not null.) + | + |6 url (if null ignore), note: can not contain '&'. + | + |7 app_name (if null ignore) + | + |8 implemented_by_partial_function (if null ignore), + | + |9 implemented_in_version (if null ignore) + | + |10 verb (if null ignore) + | + |11 correlation_id (if null ignore) + | + |12 duration (if null ignore) non digit chars will be silently omitted + | + |13 exclude_app_names (if null ignore).eg: &exclude_app_names=API-EXPLORER,API-Manager,SOFI,null + | + |14 exclude_url_patterns (if null ignore).you can design you own SQL NOT LIKE pattern. eg: &exclude_url_patterns=%management/metrics%,%management/aggregate-metrics% + | + |15 exclude_implemented_by_partial_functions (if null ignore).eg: &exclude_implemented_by_partial_functions=getMetrics,getConnectorMetrics,getAggregateMetrics + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, EmptyBody, topApisJson, List(AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidFilterParameterFormat, GetTopApisError, UnknownError), @@ -199,7 +318,50 @@ object Http4s310 { "Get Top Consumers", s"""Get metrics about the top consumers of the API usage e.g. total count, consumer_id and app_name. | - |${userAuthenticationMessage(true)}""", + |Should be able to filter on the following fields + | + |e.g.: /management/metrics/top-consumers?from_date=$epochTimeString&to_date=$DefaultToDateString&consumer_id=5 + |&user_id=66214b8e-259e-44ad-8868-3eb47be70646&implemented_by_partial_function=getTransactionsForBankAccount + |&implemented_in_version=v3.0.0&url=/obp/v3.0.0/banks/gh.29.uk/accounts/8ca8a7e4-6d02-48e3-a029-0b2bf89de9f0/owner/transactions + |&verb=GET&anon=false&app_name=MapperPostman + |&exclude_app_names=API-EXPLORER,API-Manager,SOFI,null + |&limit=100 + | + |1 from_date (defaults to the one year ago): eg:from_date=$epochTimeString + | + |2 to_date (defaults to the current date) eg:to_date=$DefaultToDateString + | + |3 consumer_id (if null ignore) + | + |4 user_id (if null ignore) + | + |5 anon (if null ignore) only support two value : true (return where user_id is null.) or false (return where user_id is not null.) + | + |6 url (if null ignore), note: can not contain '&'. + | + |7 app_name (if null ignore) + | + |8 implemented_by_partial_function (if null ignore), + | + |9 implemented_in_version (if null ignore) + | + |10 verb (if null ignore) + | + |11 correlation_id (if null ignore) + | + |12 duration (if null ignore) non digit chars will be silently omitted + | + |13 exclude_app_names (if null ignore).eg: &exclude_app_names=API-EXPLORER,API-Manager,SOFI,null + | + |14 exclude_url_patterns (if null ignore).you can design you own SQL NOT LIKE pattern. eg: &exclude_url_patterns=%management/metrics%,%management/aggregate-metrics% + | + |15 exclude_implemented_by_partial_functions (if null ignore).eg: &exclude_implemented_by_partial_functions=getMetrics,getConnectorMetrics,getAggregateMetrics + | + |16 limit (for pagination: defaults to 50) eg:limit=200 + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, EmptyBody, topConsumersJson, List(AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidFilterParameterFormat, GetMetricsTopConsumersError, UnknownError), @@ -513,7 +675,10 @@ object Http4s310 { |Note: Rate limiting can be set at the Consumer level and also for anonymous calls. | |See the consumer rate limits / call limits endpoints. - |""".stripMargin, + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, EmptyBody, rateLimitingInfoV310, List(UnknownError), List(apiTagApi, apiTagRateLimits), None, @@ -542,8 +707,13 @@ object Http4s310 { |${userAuthenticationMessage(true)} |""", EmptyBody, customerWithAttributesJsonV310, - List(AuthenticatedUserIsRequired, UserCustomerLinksNotFoundForUser, UnknownError), - List(apiTagCustomer, apiTagKyc), Some(List(canGetCustomersAtOneBank)), + List( + AuthenticatedUserIsRequired, + UserHasMissingRoles, + UserCustomerLinksNotFoundForUser, + UnknownError + ), + List(apiTagCustomer), Some(List(canGetCustomersAtOneBank)), http4sPartialFunction = Some(getCustomerByCustomerId)) // ─── getUserAuthContexts ───────────────────────────────────────────────── @@ -672,10 +842,15 @@ object Http4s310 { null, implementedInApiVersion, nameOf(getProductAttribute), "GET", "/banks/BANK_ID/products/PRODUCT_CODE/attributes/PRODUCT_ATTRIBUTE_ID", "Get Product Attribute", - s"""Get one Product Attribute by its id. - | - |${userAuthenticationMessage(true)} - |""", + s""" Get Product Attribute + | + |$productAttributeGeneralInfo + | + |Get one product attribute by its id. + | + |${userAuthenticationMessage(true)} + | + |""", EmptyBody, productAttributeResponseJson, List(UserHasMissingRoles, UnknownError), List(apiTagProduct, apiTagProductAttribute, apiTagAttribute), @@ -880,17 +1055,21 @@ object Http4s310 { "/management/method_routings", "Get MethodRoutings", s"""Get the all MethodRoutings. - | - |Query url parameters: - | - |* method_name: filter with method_name - |* active: if active = true, it will show all the webui_ props. - |""", + | + |Query url parameters: + | + |* method_name: filter with method_name + |* active: if active = true, it will show all the webui_ props. Even if they are set yet, we will return all the default webui_ props + | + |eg: + |${getObpApiRoot}/v3.1.0/management/method_routings?active=true + |${getObpApiRoot}/v3.1.0/management/method_routings?method_name=getBank + | + |""", EmptyBody, ListResult( "method_routings", - List(code.methodrouting.MethodRoutingCommons("getBanks", "rest_vMar2019", false, Some("some_bank_.*"), - List(code.methodrouting.MethodRoutingParam("url", "http://mydomain.com/xxx")), Some("method-routing-id"))) + (List(MethodRoutingCommons("getBanks", "rest_vMar2019", false, Some("some_bank_.*"), List(MethodRoutingParam("url", "http://mydomain.com/xxx")), Some("method-routing-id")))) ), List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagMethodRouting, apiTagApi), Some(List(canGetMethodRoutings)), @@ -916,12 +1095,17 @@ object Http4s310 { null, implementedInApiVersion, nameOf(getSystemView), "GET", "/system-views/SYS_VIEW_ID", "Get System View", - s"""Get System View. + s"""Get System View | - |${userAuthenticationMessage(true)} and the user needs to have access to the $canGetSystemView entitlement. - |""", - EmptyBody, viewJsonV300, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, ViewNotFound, UnknownError), + |${userAuthenticationMessage(true)} + | + """.stripMargin, + EmptyBody, viewJSONV220, + List( + AuthenticatedUserIsRequired, + BankNotFound, + UnknownError + ), List(apiTagSystemView), Some(List(canGetSystemView)), http4sPartialFunction = Some(getSystemView)) @@ -944,9 +1128,16 @@ object Http4s310 { null, implementedInApiVersion, nameOf(getCardsForBank), "GET", "/management/banks/BANK_ID/cards", "Get Cards for the specified bank", - s"""Cards for the specified bank. - | - |${userAuthenticationMessage(true)}""".stripMargin, + s"""Should be able to filter on the following fields + | + |eg:/management/banks/BANK_ID/cards?customer_id=66214b8e-259e-44ad-8868-3eb47be70646&account_id=8ca8a7e4-6d02-48e3-a029-0b2bf89de9f0 + | + |1 customer_id should be valid customer_id, otherwise, it will return an empty card list. + | + |2 account_id should be valid account_id , otherwise, it will return an empty card list. + | + | + |${userAuthenticationMessage(true)}""".stripMargin, EmptyBody, physicalCardsJsonV310, List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), List(apiTagCard), None, @@ -974,9 +1165,12 @@ object Http4s310 { null, implementedInApiVersion, nameOf(getCardForBank), "GET", "/management/banks/BANK_ID/cards/CARD_ID", "Get Card By Id", - s"""Get the details of a card by its id. - | - |${userAuthenticationMessage(true)}""".stripMargin, + s""" + |This will the datails of the card. + |It shows the account infomation which linked the the card. + |Also shows the card attributes of the card. + | + """.stripMargin, EmptyBody, physicalCardWithAttributesJsonV310, List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), List(apiTagCard), Some(List(canGetCardsForBank)), @@ -1080,10 +1274,13 @@ object Http4s310 { null, implementedInApiVersion, nameOf(getTransactionByIdForBankAccount), "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/transaction", "Get Transaction by Id", - s"""Returns one transaction specified by TRANSACTION_ID of the account ACCOUNT_ID and moderated by the view (VIEW_ID). - | - |${userAuthenticationMessage(true)} - |""", + s"""Returns one transaction specified by TRANSACTION_ID of the account ACCOUNT_ID and [moderated](#1_2_1-getViewsForBankAccount) by the view (VIEW_ID). + | + |${userAuthenticationMessage(false)} + |Authentication is required if the view is not public. + | + | + |""", EmptyBody, transactionJsonV300, List(AuthenticatedUserIsRequired, BankAccountNotFound, ViewNotFound, UserNoPermissionAccessView, UnknownError), @@ -1118,7 +1315,24 @@ object Http4s310 { """Returns transaction requests for account specified by ACCOUNT_ID at bank specified by BANK_ID. | |The VIEW_ID specified must be 'owner' and the user must have access to this view. - |""".stripMargin, + | + |Version 2.0.0 now returns charge information. + | + |Transaction Requests serve to initiate transactions that may or may not proceed. They contain information including: + | + |* Transaction Request Id + |* Type + |* Status (INITIATED, COMPLETED) + |* Challenge (in order to confirm the request) + |* From Bank / Account + |* Details including Currency, Value, Description and other initiation information specific to each type. (Could potentialy include a list of future transactions.) + |* Related Transactions + | + |PSD2 Context: PSD2 requires transparency of charges to the customer. + |This endpoint provides the charge that would be applied if the Transaction Request proceeds - and a record of that charge there after. + |The customer can proceed with the Transaction by answering the security challenge. + | + """.stripMargin, EmptyBody, transactionRequestWithChargeJSONs210, List(AuthenticatedUserIsRequired, BankNotFound, BankAccountNotFound, UserNoPermissionAccessView, ViewDoesNotPermitAccess, @@ -1146,9 +1360,20 @@ object Http4s310 { null, implementedInApiVersion, nameOf(getProduct), "GET", "/banks/BANK_ID/products/PRODUCT_CODE", "Get Bank Product", - s"""Returns information about a financial Product offered by the bank specified by BANK_ID and PRODUCT_CODE. - | - |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, + s"""Returns information about a financial Product offered by the bank specified by BANK_ID and PRODUCT_CODE including: + | + |* Name + |* Code + |* Parent Product Code + |* Category + |* Family + |* Super Family + |* More info URL + |* Description + |* Terms and Conditions + |* License the data under this endpoint is released under + | + |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, EmptyBody, productJsonV310, List(AuthenticatedUserIsRequired, ProductNotFoundByProductCode, UnknownError), List(apiTagProduct), None, @@ -1172,9 +1397,24 @@ object Http4s310 { "/banks/BANK_ID/product-tree/PRODUCT_CODE", "Get Product Tree", s"""Returns information about a particular financial product specified by BANK_ID and PRODUCT_CODE - |and it's parent product(s) recursively as specified by parent_product_code. - | - |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, + |and it's parent product(s) recursively as specified by parent_product_code. + | + |Each product includes the following information. + | + |* Name + |* Code + |* Parent Product Code + |* Category + |* Family + |* Super Family + |* More info URL + |* Description + |* Terms and Conditions + |* License: The licence under which this product data is released. Licence can be an Open Data licence such as Open Data Commons Public Domain Dedication and License (PDDL) or Copyright etc. + | + | + | + |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, EmptyBody, childProductTreeJsonV310, List(AuthenticatedUserIsRequired, ProductNotFoundByProductCode, UnknownError), List(apiTagProduct), None, @@ -1197,12 +1437,23 @@ object Http4s310 { null, implementedInApiVersion, "getProducts", "GET", "/banks/BANK_ID/products", "Get Products", - s"""Returns information about the financial products offered by a bank specified by BANK_ID. - | - |Can filter with attributes name and values. - |URL params example: /banks/some-bank-id/products?&limit=50&offset=1 - | - |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, + s"""Returns information about the financial products offered by a bank specified by BANK_ID including: + | + |* Name + |* Code + |* Parent Product Code + |* Category + |* Family + |* Super Family + |* More info URL + |* Description + |* Terms and Conditions + |* License the data under this endpoint is released under + | + |Can filter with attributes name and values. + |URL params example: /banks/some-bank-id/products?&limit=50&offset=1 + | + |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, EmptyBody, productsJsonV310, List(AuthenticatedUserIsRequired, BankNotFound, ProductNotFoundByProductCode, UnknownError), List(apiTagProduct), None, @@ -1224,7 +1475,9 @@ object Http4s310 { null, implementedInApiVersion, nameOf(getProductCollection), "GET", "/banks/BANK_ID/product-collections/COLLECTION_CODE", "Get Product Collection", - """Returns information about the financial Product Collection specified by BANK_ID and COLLECTION_CODE.""", + s"""Returns information about the financial Product Collection specified by BANK_ID and COLLECTION_CODE: + | + """, EmptyBody, productCollectionJsonTreeV310, List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), List(apiTagProductCollection, apiTagProduct), None, @@ -1261,10 +1514,16 @@ object Http4s310 { null, implementedInApiVersion, nameOf(getConsents), "GET", "/banks/BANK_ID/my/consents", "Get Consents", - s"""Get Consents for the current User at the specified bank. + s""" + |This endpoint gets the Consents that the current User created. | |${userAuthenticationMessage(true)} - |""", + | + |1 limit (for pagination: defaults to 50) eg:limit=200 + | + |2 offset (for pagination: zero index, defaults to 0) eg: offset=10 + | + """.stripMargin, EmptyBody, consentsJsonV310, List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2), None, @@ -1293,14 +1552,21 @@ object Http4s310 { "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/account", "Get Account by Id (Full)", """Information returned about an account specified by ACCOUNT_ID as moderated by the view (VIEW_ID): - | - |* Number - |* Owners - |* Type - |* Balance - |* IBAN - |* Available views (sorted by short_name) - |""".stripMargin, + | + |* Number + |* Owners + |* Type + |* Balance + |* IBAN + |* Available views (sorted by short_name) + | + |More details about the data moderation by the view [here](#1_2_1-getViewsForBankAccount). + | + |PSD2 Context: PSD2 requires customers to have access to their account information via third party applications. + |This call provides balance and other account information via delegated authentication using OAuth. + | + |Authentication is required if the 'is_public' field in view (VIEW_ID) is not set to `true`. + |""".stripMargin, EmptyBody, moderatedAccountJSON310, List(BankNotFound, AccountNotFound, ViewNotFound, UserNoPermissionAccessView, UnknownError), apiTagAccount :: Nil, None, @@ -1337,14 +1603,41 @@ object Http4s310 { null, implementedInApiVersion, nameOf(getWebUiProps), "GET", "/management/webui_props", "Get WebUiProps", - s"""Get WebUiProps. - | - |${userAuthenticationMessage(true)} - |""", + s""" + | + |Get WebUiProps - properties that configure the Web UI behavior and appearance. + | + |Properties with names starting with "webui_" can be stored in the database and managed via API. + | + |**Data Sources:** + | + |1. **Explicit WebUiProps (Database)**: Custom values created/updated via the API and stored in the database. + | + |2. **Implicit WebUiProps (Configuration File)**: Default values defined in the `sample.props.template` configuration file. + | + |**Query Parameter:** + | + |* `active` (optional, boolean string, default: "false") + | - If `active=false` or omitted: Returns only explicit props from the database + | - If `active=true`: Returns explicit props + implicit (default) props from configuration file + | - When both sources have the same property name, the database value takes precedence + | - Implicit props are marked with `webUiPropsId = "default"` + | + |**Examples:** + | + |Get only database-stored props: + |${getObpApiRoot}/v3.1.0/management/webui_props + | + |Get database props combined with defaults: + |${getObpApiRoot}/v3.1.0/management/webui_props?active=true + | + |For more details about WebUI Props, including how to set config file defaults and precedence order, see ${Glossary.getGlossaryItemLink("webui_props")}. + | + |""", EmptyBody, ListResult( "webui_props", - List(WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com", Some("web-ui-props-id"))) + (List(WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com", Some("web-ui-props-id")))) ), List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagWebUiProps), Some(List(canGetWebUiProps)), @@ -1472,12 +1765,21 @@ object Http4s310 { null, implementedInApiVersion, nameOf(deleteProductAttribute), "DELETE", "/banks/BANK_ID/products/PRODUCT_CODE/attributes/PRODUCT_ATTRIBUTE_ID", "Delete Product Attribute", - s"""Delete a Product Attribute by its id. - | - |${userAuthenticationMessage(true)} - |""", + s""" Delete Product Attribute + | + |$productAttributeGeneralInfo + | + |Delete a Product Attribute by its id. + | + |${userAuthenticationMessage(true)} + | + |""", EmptyBody, EmptyBody, - List(AuthenticatedUserIsRequired, UserHasMissingRoles, BankNotFound, UnknownError), + List( + UserHasMissingRoles, + BankNotFound, + UnknownError + ), List(apiTagProduct, apiTagProductAttribute, apiTagAttribute), Some(List(canDeleteProductAttribute)), http4sPartialFunction = Some(deleteProductAttribute)) @@ -1637,10 +1939,22 @@ object Http4s310 { null, implementedInApiVersion, "revokeConsent", "GET", "/banks/BANK_ID/my/consents/CONSENT_ID/revoke", "Revoke Consent", - s"""Revoke Consent for current user specified by CONSENT_ID + s""" + |Revoke Consent for current user specified by CONSENT_ID + | + |There are a few reasons you might need to revoke an application’s access to a user’s account: + | - The user explicitly wishes to revoke the application’s access + | - You as the service provider have determined an application is compromised or malicious, and want to disable it + | - etc. + | + |Please note that this endpoint only supports the case:: "The user explicitly wishes to revoke the application’s access" + | + |OBP as a resource server stores access tokens in a database, then it is relatively easy to revoke some token that belongs to a particular user. + |The status of the token is changed to "REVOKED" so the next time the revoked client makes a request, their token will fail to validate. | |${userAuthenticationMessage(true)} - |""".stripMargin, + | + """.stripMargin, EmptyBody, revokedConsentJsonV310, List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2), None, @@ -1757,10 +2071,10 @@ object Http4s310 { null, implementedInApiVersion, nameOf(createUserAuthContext), "POST", "/users/USER_ID/auth-context", "Create User Auth Context", - s"""Create User Auth Context. - | - |${userAuthenticationMessage(true)} - |""", + s"""Create User Auth Context. These key value pairs will be propagated over connector to adapter. Normally used for mapping OBP user and + | Bank User/Customer. + |${userAuthenticationMessage(true)} + |""", postUserAuthContextJson, userAuthContextJson, List(AuthenticatedUserIsRequired, InvalidJsonFormat, CreateUserAuthContextError, UnknownError), List(apiTagUser), Some(List(canCreateUserAuthContext)), @@ -1789,10 +2103,31 @@ object Http4s310 { null, implementedInApiVersion, nameOf(createProductAttribute), "POST", "/banks/BANK_ID/products/PRODUCT_CODE/attribute", "Create Product Attribute", - s"""Create a Product Attribute on a Product. - | - |${userAuthenticationMessage(true)} - |""", + s""" Create Product Attribute + | + |$productAttributeGeneralInfo + | + |Typical product attributes might be: + | + |ISIN (for International bonds) + |VKN (for German bonds) + |REDCODE (markit short code for credit derivative) + |LOAN_ID (e.g. used for Anacredit reporting) + | + |ISSUE_DATE (When the bond was issued in the market) + |MATURITY_DATE (End of life time of a product) + |TRADABLE + | + |See [FPML](http://www.fpml.org/) for more examples. + | + | + |The type field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + | + | + |${userAuthenticationMessage(true)} + | + |""", productAttributeJson, productAttributeResponseJson, List(InvalidJsonFormat, UnknownError), List(apiTagProduct, apiTagProductAttribute, apiTagAttribute), @@ -1912,10 +2247,21 @@ object Http4s310 { null, implementedInApiVersion, nameOf(callsLimit), "PUT", "/management/consumers/CONSUMER_ID/consumer/call-limits", "Set Rate Limits (call limits) per Consumer", - s"""Set the API rate limiting (call limits) per Consumer. - | - |${userAuthenticationMessage(true)} - |""".stripMargin, + s""" + |Set the API rate limiting (call limits) per Consumer: + | + |Rate limits can be set: + | + |Per Second + |Per Minute + |Per Hour + |Per Week + |Per Month + | + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, callLimitPostJson, callLimitPostJson, List(AuthenticatedUserIsRequired, InvalidJsonFormat, InvalidConsumerId, ConsumerNotFoundByConsumerId, UserHasMissingRoles, UpdateConsumerError, UnknownError), @@ -2006,12 +2352,12 @@ object Http4s310 { null, implementedInApiVersion, nameOf(updateSystemView), "PUT", "/system-views/SYS_VIEW_ID", "Update System View", - s"""Update an existing view on a bank account. - | - |${userAuthenticationMessage(true)} and the user needs to have access to the owner view. - | - |The json sent is the same as during view creation, with one difference: the 'name' field - |of a view is not editable (it is only set when a view is created).""", + s"""Update an existing view on a bank account + | + |${userAuthenticationMessage(true)} and the user needs to have access to the owner view. + | + |The json sent is the same as during view creation (above), with one difference: the 'name' field + |of a view is not editable (it is only set when a view is created)""", updateSystemViewJson310, viewJsonV300, List(InvalidJsonFormat, AuthenticatedUserIsRequired, BankAccountNotFound, UnknownError), List(apiTagSystemView), Some(List(canUpdateSystemView)), @@ -2041,10 +2387,16 @@ object Http4s310 { null, implementedInApiVersion, nameOf(updateProductAttribute), "PUT", "/banks/BANK_ID/products/PRODUCT_CODE/attributes/PRODUCT_ATTRIBUTE_ID", "Update Product Attribute", - s"""Update one Product Attribute by its id. - | - |${userAuthenticationMessage(true)} - |""", + s""" Update Product Attribute. + | + + |$productAttributeGeneralInfo + | + |Update one Product Attribute by its id. + | + |${userAuthenticationMessage(true)} + | + |""", productAttributeJson, productAttributeResponseJson, List(UserHasMissingRoles, UnknownError), List(apiTagProduct, apiTagProductAttribute, apiTagAttribute), @@ -2328,10 +2680,12 @@ object Http4s310 { null, implementedInApiVersion, nameOf(updateAccountApplicationStatus), "PUT", "/banks/BANK_ID/account-applications/ACCOUNT_APPLICATION_ID", "Update Account Application Status", - s"""Update an Account Application status. - | - |${userAuthenticationMessage(true)} - |""", + s"""Update an Account Application status + | + | + |${userAuthenticationMessage(true)} + | + |""", accountApplicationUpdateStatusJson, accountApplicationResponseJson, List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagAccountApplication, apiTagAccount), None, @@ -2447,10 +2801,11 @@ object Http4s310 { null, implementedInApiVersion, nameOf(createAccountApplication), "POST", "/banks/BANK_ID/account-applications", "Create Account Application", - s"""Create Account Application. - | - |${userAuthenticationMessage(true)} - |""", + s""" Create Account Application + | + |${userAuthenticationMessage(true)} + | + |""", accountApplicationJson, accountApplicationResponseJson, List(InvalidJsonFormat, UnknownError), List(apiTagAccountApplication, apiTagAccount), None, @@ -2482,10 +2837,28 @@ object Http4s310 { null, implementedInApiVersion, nameOf(createAccountAttribute), "POST", "/banks/BANK_ID/accounts/ACCOUNT_ID/products/PRODUCT_CODE/attribute", "Create Account Attribute", - s"""Create an Account Attribute. - | - |${userAuthenticationMessage(true)} - |""", + s""" Create Account Attribute + | + |$accountAttributeGeneralInfo + | + |Typical account attributes might be: + | + |ISIN (for International bonds) + |VKN (for German bonds) + |REDCODE (markit short code for credit derivative) + |LOAN_ID (e.g. used for Anacredit reporting) + | + |ISSUE_DATE (When the bond was issued in the market) + |MATURITY_DATE (End of life time of a product) + |TRADABLE + | + |See [FPML](http://www.fpml.org/) for more examples. + | + |The type field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + |${userAuthenticationMessage(true)} + | + |""", accountAttributeJson, accountAttributeResponseJson, List(AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), List(apiTagAccount, apiTagAccountAttribute, apiTagAttribute), @@ -2519,10 +2892,26 @@ object Http4s310 { null, implementedInApiVersion, nameOf(updateAccountAttribute), "PUT", "/banks/BANK_ID/accounts/ACCOUNT_ID/products/PRODUCT_CODE/attributes/ACCOUNT_ATTRIBUTE_ID", "Update Account Attribute", - s"""Update an Account Attribute by its id. - | - |${userAuthenticationMessage(true)} - |""", + s""" Update Account Attribute + | + |$accountAttributeGeneralInfo + | + |Typical account attributes might be: + | + |ISIN (for International bonds) + |VKN (for German bonds) + |REDCODE (markit short code for credit derivative) + |LOAN_ID (e.g. used for Anacredit reporting) + | + |ISSUE_DATE (When the bond was issued in the market) + |MATURITY_DATE (End of life time of a product) + |TRADABLE + | + |See [FPML](http://www.fpml.org/) for more examples. + | + |${userAuthenticationMessage(true)} + | + |""", accountAttributeJson, accountAttributeResponseJson, List(AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), List(apiTagAccount, apiTagAccountAttribute, apiTagAttribute), @@ -2567,9 +2956,17 @@ object Http4s310 { "/banks/BANK_ID/meetings", "Create Meeting (video conference/call)", """Create Meeting: Initiate a video conference/call with the bank. + | + |The Meetings resource contains meta data about video/other conference sessions + | + |provider_id determines the provider of the meeting / video chat service. MUST be url friendly (no spaces). + | + |purpose_id explains the purpose of the chat. onboarding | mortgage | complaint etc. MUST be url friendly (no spaces). | |Login is required. - |""".stripMargin, + | + |This call is **experimental**. Currently staff_user_id is not set. Further calls will be needed to correctly set this. + """.stripMargin, createMeetingJsonV310, meetingJsonV310, List(AuthenticatedUserIsRequired, BankNotFound, InvalidJsonFormat, UnknownError), List(apiTagMeeting, apiTagCustomer, apiTagExperimental), None, @@ -2597,10 +2994,24 @@ object Http4s310 { null, implementedInApiVersion, nameOf(createSystemView), "POST", "/system-views", "Create System View", - s"""Create a system view. - | - |${userAuthenticationMessage(true)} and the user needs to have access to the $canCreateSystemView entitlement. - |""", + s"""Create a system view + | + | ${userAuthenticationMessage(true)} and the user needs to have access to the $canCreateSystemView entitlement. + | The 'alias' field in the JSON can take one of two values: + | + | * _public_: to use the public alias if there is one specified for the other account. + | * _private_: to use the private alias if there is one specified for the other account. + | + | * _''(empty string)_: to use no alias; the view shows the real name of the other account. + | + | The 'hide_metadata_if_alias_used' field in the JSON can take boolean values. If it is set to `true` and there is an alias on the other account then the other accounts' metadata (like more_info, url, image_url, open_corporates_url, etc.) will be hidden. Otherwise the metadata will be shown. + | + | The 'allowed_actions' field is a list containing the name of the actions allowed on this view, all the actions contained will be set to `true` on the view creation, the rest will be set to `false`. + | + | The 'metadata_view' field determines where metadata (comments, tags, images, where tags) for transactions are stored and retrieved. If set to another view's ID (e.g. 'owner'), metadata added through this view will be shared with all other views that also use the same metadata_view value. If left empty, metadata is stored under this view's own ID and is not shared with other views. + | + | Please note that system views cannot be public. In case you try to set it you will get the error $SystemViewCannotBePublicError + | """, SwaggerDefinitionsJSON.createSystemViewJsonV300, viewJsonV300, List(AuthenticatedUserIsRequired, InvalidJsonFormat, UnknownError), List(apiTagSystemView), Some(List(canCreateSystemView)), @@ -2634,9 +3045,24 @@ object Http4s310 { "/banks/BANK_ID/product-collections/COLLECTION_CODE", "Create Product Collection", s"""Create or Update a Product Collection at the Bank. - | - |${userAuthenticationMessage(true)} - |""", + | + |Use Product Collections to create Product "Baskets", "Portfolios", "Indices", "Collections", "Underlyings-lists", "Buckets" etc. etc. + | + |There is a many to many relationship between Products and Product Collections: + | + |* A Product can exist in many Collections + | + |* A Collection can contain many Products. + | + |A collection has collection code, one parent Product and one or more child Products. + | + | + |$productHiearchyAndCollectionNote + + |${userAuthenticationMessage(true) } + | + | + |""", putProductCollectionsV310, productCollectionsJsonV310, List(AuthenticatedUserIsRequired, BankNotFound, UserHasMissingRoles, UnknownError), List(apiTagProductCollection, apiTagProduct), Some(List(canMaintainProductCollection)), @@ -2806,10 +3232,17 @@ object Http4s310 { null, implementedInApiVersion, nameOf(createCardAttribute), "POST", "/management/banks/BANK_ID/cards/CARD_ID/attribute", "Create Card Attribute", - s"""Create a Card Attribute. - | - |${userAuthenticationMessage(true)} - |""", + s""" Create Card Attribute + | + |Card Attributes are used to describe a financial Product with a list of typed key value pairs. + | + |Each Card Attribute is linked to its Card by CARD_ID + | + |The type field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + |${userAuthenticationMessage(true)} + | + |""", CardAttributeJson( cardAttributeNameExample.value, CardAttributeType.DOUBLE.toString, @@ -2849,10 +3282,15 @@ object Http4s310 { null, implementedInApiVersion, nameOf(updateCardAttribute), "PUT", "/management/banks/BANK_ID/cards/CARD_ID/attributes/CARD_ATTRIBUTE_ID", "Update Card Attribute", - s"""Update a Card Attribute. - | - |${userAuthenticationMessage(true)} - |""", + s""" Update Card Attribute + | + |Card Attributes are used to describe a financial Product with a list of typed key value pairs. + | + |Each Card Attribute is linked to its Card by CARD_ID + | + |${userAuthenticationMessage(true)} + | + |""", CardAttributeJson( cardAttributeNameExample.value, CardAttributeType.DOUBLE.toString, @@ -2890,11 +3328,48 @@ object Http4s310 { "/management/webui_props", "Create WebUiProps", s"""Create a WebUiProps. - | - |${userAuthenticationMessage(true)} - |""", + | + | + |${userAuthenticationMessage(true)} + | + |Explaination of Fields: + | + |* name is required String value + |* value is required String value + | + |The line break and double quotations should do escape, example: + | + |``` + | + |{"name": "webui_some", "value": "this value + |have "line break" and double quotations."} + | + |``` + |should do escape like this: + | + |``` + | + |{"name": "webui_some", "value": "this value\\nhave \\"line break\\" and double quotations."} + | + |``` + | + |Insert image examples: + | + |``` + |// set width=100 and height=50 + |{"name": "webui_some_pic", "value": "here is a picture ![hello](http://somedomain.com/images/pic.png =100x50)"} + | + |// only set height=50 + |{"name": "webui_some_pic", "value": "here is a picture ![hello](http://somedomain.com/images/pic.png =x50)"} + | + |// only width=20% + |{"name": "webui_some_pic", "value": "here is a picture ![hello](http://somedomain.com/images/pic.png =20%x)"} + | + |``` + | + |""", WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com"), - WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com", Some("web-ui-props-id")), + WebUiPropsCommons( "webui_api_explorer_url", "https://apiexplorer.openbankproject.com", Some("some-web-ui-props-id")), List(AuthenticatedUserIsRequired, UserHasMissingRoles, InvalidJsonFormat, UnknownError), List(apiTagWebUiProps), Some(List(canCreateWebUiProps)), http4sPartialFunction = Some(createWebUiProps)) @@ -2924,8 +3399,12 @@ object Http4s310 { "/banks/BANK_ID/users/current/auth-context-updates/SCA_METHOD", "Create User Auth Context Update Request", s"""Create User Auth Context Update Request. - |${userAuthenticationMessage(true)} - |""", + |${userAuthenticationMessage(true)} + | + |A One Time Password (OTP) (AKA security challenge) is sent Out of Band (OOB) to the User via the transport defined in SCA_METHOD + |SCA_METHOD is typically "SMS" or "EMAIL". "EMAIL" is used for testing purposes. + | + |""", postUserAuthContextJson, userAuthContextUpdateJson, List(AuthenticatedUserIsRequired, InvalidJsonFormat, CreateUserAuthContextError, UnknownError), List(apiTagUser), None, @@ -2989,10 +3468,13 @@ object Http4s310 { null, implementedInApiVersion, nameOf(refreshUser), "POST", "/users/USER_ID/refresh", "Refresh User", - s"""The endpoint is used for updating the accounts, views, account holders for the user. - | - |${userAuthenticationMessage(true)} - |""", + s""" The endpoint is used for updating the accounts, views, account holders for the user. + | As to the Json body, you can leave it as Empty. + | This call will get data from backend, no need to prepare the json body in api side. + | + |${userAuthenticationMessage(true)} + | + |""", EmptyBody, refresUserJson, List(UserHasMissingRoles, UnknownError), List(apiTagUser), Some(List(canRefreshUser)), @@ -3036,9 +3518,23 @@ object Http4s310 { "/banks/BANK_ID/products/PRODUCT_CODE", "Create Product", s"""Create or Update Product for the Bank. - | - |${userAuthenticationMessage(true)} - |""", + | + | + |Typical Super Family values / Asset classes are: + | + |Debt + |Equity + |FX + |Commodity + |Derivative + | + |$productHiearchyAndCollectionNote + | + | + |${userAuthenticationMessage(true) } + | + | + |""", postPutProductJsonV310, productJsonV310, List(AuthenticatedUserIsRequired, BankNotFound, UserHasMissingRoles, UnknownError), List(apiTagProduct), Some(List(canCreateProduct, canCreateProductAtAnyBank)), @@ -3093,9 +3589,42 @@ object Http4s310 { "/management/method_routings", "Create MethodRouting", s"""Create a MethodRouting. - | - |${userAuthenticationMessage(true)} - |""", + | + | + |${userAuthenticationMessage(true)} + | + |Explanation of Fields: + | + |* method_name is required String value, current supported value: $supportedConnectorNames + |* connector_name is required String value + |* is_bank_id_exact_match is required boolean value, if bank_id_pattern is exact bank_id value, this value is true; if bank_id_pattern is null or a regex, this value is false + |* bank_id_pattern is optional String value, it can be null, a exact bank_id or a regex + |* parameters is optional array of key value pairs. You can set some parameters for this method + | + |note and CAVEAT!: + | + |* bank_id_pattern has to be empty for methods that do not take bank_id as a function parameter, otherwise might get empty result + |* methods that aggregate bank objects (e.g. getBankAccountsForUser) have to take any existing method routings for these objects into consideration + |* so if you create e.g. a bank specific method routing for getting an account, make sure that it is also served by endpoints getting ALL accounts for ALL banks + |* if bank_id_pattern is regex, special characters need to do escape, for example: bank_id_pattern = "some\\-id_pattern_\\d+" + | + |If the connector name starts with rest, parameters can contain "outBoundMapping" and "inBoundMapping", convert OutBound and InBound json structure. + |for example: + | outBoundMapping example, convert json from source to target: + |![Snipaste_outBoundMapping](https://user-images.githubusercontent.com/2577334/75248007-33332e00-580e-11ea-8d2a-d1856035fa24.png) + |Build OutBound json value rules: + |1 set cId value with: outboundAdapterCallContext.correlationId value + |2 set bankId value with: concat bankId.value value with string helloworld + |3 set originalJson value with: whole source json, note: the field value expression is $$root + | + | + | inBoundMapping example, convert json from source to target: + |![inBoundMapping](https://user-images.githubusercontent.com/2577334/75248199-a9d02b80-580e-11ea-9238-e073264e9170.png) + |Build InBound json value rules: + |1 and 2 set inboundAdapterCallContext and status value: because field name ends with "$$default", remove "$$default" from field name, not change the value + |3 set fullName value with: concat string full: with result.name value + |4 set bankRoutingScheme value: because source value is Array, but target value is not Array, the mapping field name must ends with [0]. + |""", MethodRoutingCommons("getBank", "rest_vMar2019", false, Some("some_bankId_.*"), List(MethodRoutingParam("url", "http://mydomain.com/xxx"))), MethodRoutingCommons("getBank", "rest_vMar2019", false, Some("some_bankId_.*"), @@ -3155,9 +3684,38 @@ object Http4s310 { "/management/method_routings/METHOD_ROUTING_ID", "Update MethodRouting", s"""Update a MethodRouting. - | - |${userAuthenticationMessage(true)} - |""", + | + | + |${userAuthenticationMessage(true)} + | + |Explaination of Fields: + | + |* method_name is required String value, current supported value: $supportedConnectorNames + |* connector_name is required String value + |* is_bank_id_exact_match is required boolean value, if bank_id_pattern is exact bank_id value, this value is true; if bank_id_pattern is null or a regex, this value is false + |* bank_id_pattern is optional String value, it can be null, a exact bank_id or a regex + |* parameters is optional array of key value pairs. You can set some paremeters for this method + |note: + | + |* if bank_id_pattern is regex, special characters need to do escape, for example: bank_id_pattern = "some\\-id_pattern_\\d+" + | + |If connector name start with rest, parameters can contain "outBoundMapping" and "inBoundMapping", to convert OutBound and InBound json structure. + |for example: + | outBoundMapping example, convert json from source to target: + |![Snipaste_outBoundMapping](https://user-images.githubusercontent.com/2577334/75248007-33332e00-580e-11ea-8d2a-d1856035fa24.png) + |Build OutBound json value rules: + |1 set cId value with: outboundAdapterCallContext.correlationId value + |2 set bankId value with: concat bankId.value value with string helloworld + |3 set originalJson value with: whole source json, note: the field value expression is $$root + | + | + | inBoundMapping example, convert json from source to target: + |![inBoundMapping](https://user-images.githubusercontent.com/2577334/75248199-a9d02b80-580e-11ea-9238-e073264e9170.png) + |Build InBound json value rules: + |1 and 2 set inboundAdapterCallContext and status value: because field name ends with "$$default", remove "$$default" from field name, not change the value + |3 set fullName value with: concat string full: with result.name value + |4 set bankRoutingScheme value: because source value is Array, but target value is not Array, the mapping field name must ends with [0]. + |""", MethodRoutingCommons("getBank", "rest_vMar2019", true, Some("some_bankId"), List(MethodRoutingParam("url", "http://mydomain.com/xxx"))), MethodRoutingCommons("getBank", "rest_vMar2019", true, Some("some_bankId"), @@ -3282,10 +3840,17 @@ object Http4s310 { "/banks/BANK_ID/accounts/NEW_ACCOUNT_ID", "Create Account", """Create Account at bank specified by BANK_ID with Id specified by ACCOUNT_ID. - | - |The User can create an Account for themself - or - the User that has the USER_ID specified in the POST body. - | - |Note: The Amount MUST be zero.""".stripMargin, + | + |The User can create an Account for themself - or - the User that has the USER_ID specified in the POST body. + | + |If the PUT body USER_ID *is* specified, the logged in user must have the Role canCreateAccount. Once created, the Account will be owned by the User specified by USER_ID. + | + |If the PUT body USER_ID is *not* specified, the account will be owned by the logged in User. + | + |The 'product_code' field SHOULD be a product_code from Product. + |If the 'product_code' matches a product_code from Product, account attributes will be created that match the Product Attributes. + | + |Note: The Amount MUST be zero.""".stripMargin, createAccountRequestJsonV310, createAccountResponseJsonV310, List(InvalidJsonFormat, BankNotFound, AuthenticatedUserIsRequired, InvalidUserId, InvalidAccountIdFormat, InvalidBankIdFormat, @@ -3415,18 +3980,77 @@ object Http4s310 { resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(createConsentEmail), "POST", "/banks/BANK_ID/my/consents/EMAIL", - "Create Consent (Email)", - s"""This endpoint starts the process of creating a Consent via Email SCA method. - | - |${userAuthenticationMessage(true)} - |""", - postConsentRequestJsonV310, - ConsentJsonV310( - consent_id = "9d429899-24f5-42c8-8565-943ffa6a7945", - jwt = "eyJ...", - status = "INITIATED"), - List(AuthenticatedUserIsRequired, BankNotFound, InvalidJsonFormat, - ConsentMaxTTL, RolesAllowedInConsent, ViewsAllowedInConsent, UnknownError), + "Create Consent (EMAIL)", + s""" + | + |This endpoint starts the process of creating a Consent. + | + |The Consent is created in an ${ConsentStatus.INITIATED} state. + | + |A One Time Password (OTP) (AKA security challenge) is sent Out of Band (OOB) to the User via the transport defined in SCA_METHOD + |SCA_METHOD is typically "SMS","EMAIL" or "IMPLICIT". "EMAIL" is used for testing purposes. OBP mapped mode "IMPLICIT" is "EMAIL". + |Other mode, bank can decide it in the connector method 'getConsentImplicitSCA'. + | + |When the Consent is created, OBP (or a backend system) stores the challenge so it can be checked later against the value supplied by the User with the Answer Consent Challenge endpoint. + | + |$generalObpConsentText + | + |${userAuthenticationMessage(true)} + | + |Example 1: + |{ + | "everything": true, + | "views": [], + | "entitlements": [], + | "consumer_id": "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + | "phone_number": "+49 170 1234567" + |} + | + |Please note that consumer_id is optional field + |Example 2: + |{ + | "everything": true, + | "views": [], + | "entitlements": [], + | "phone_number": "+49 170 1234567" + |} + | + |Please note if everything=false you need to explicitly specify views and entitlements + |Example 3: + |{ + | "everything": false, + | "views": [ + | { + | "bank_id": "GENODEM1GLS", + | "account_id": "8ca8a7e4-6d02-40e3-a129-0b2bf89de9f0", + | "view_id": "${Constant.SYSTEM_OWNER_VIEW_ID}" + | } + | ], + | "entitlements": [ + | { + | "bank_id": "GENODEM1GLS", + | "role_name": "CanGetCustomersAtOneBank" + | } + | ], + | "consumer_id": "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + | "phone_number": "+49 170 1234567" + |} + | + |""", + postConsentEmailJsonV310, + consentJsonV310, + List( + AuthenticatedUserIsRequired, + BankNotFound, + InvalidJsonFormat, + ConsentAllowedScaMethods, + RolesAllowedInConsent, + ViewsAllowedInConsent, + ConsumerNotFoundByConsumerId, + ConsumerIsDisabled, + InvalidConnectorResponse, + UnknownError + ), apiTagConsent :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, http4sPartialFunction = Some(createConsentEmail)) @@ -3434,35 +4058,154 @@ object Http4s310 { null, implementedInApiVersion, nameOf(createConsentSms), "POST", "/banks/BANK_ID/my/consents/SMS", "Create Consent (SMS)", - s"""This endpoint starts the process of creating a Consent via SMS SCA method. - | - |${userAuthenticationMessage(true)} - |""", - postConsentRequestJsonV310, - ConsentJsonV310( - consent_id = "9d429899-24f5-42c8-8565-943ffa6a7945", - jwt = "eyJ...", - status = "INITIATED"), - List(AuthenticatedUserIsRequired, BankNotFound, InvalidJsonFormat, - ConsentMaxTTL, RolesAllowedInConsent, ViewsAllowedInConsent, UnknownError), + s""" + | + |This endpoint starts the process of creating a Consent. + | + |The Consent is created in an ${ConsentStatus.INITIATED} state. + | + |A One Time Password (OTP) (AKA security challenge) is sent Out of Band (OOB) to the User via the transport defined in SCA_METHOD + |SCA_METHOD is typically "SMS","EMAIL" or "IMPLICIT". "EMAIL" is used for testing purposes. OBP mapped mode "IMPLICIT" is "EMAIL". + |Other mode, bank can decide it in the connector method 'getConsentImplicitSCA'. + | + |When the Consent is created, OBP (or a backend system) stores the challenge so it can be checked later against the value supplied by the User with the Answer Consent Challenge endpoint. + | + |$generalObpConsentText + | + |${userAuthenticationMessage(true)} + | + |Example 1: + |{ + | "everything": true, + | "views": [], + | "entitlements": [], + | "consumer_id": "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + | "email": "eveline@example.com" + |} + | + |Please note that consumer_id is optional field + |Example 2: + |{ + | "everything": true, + | "views": [], + | "entitlements": [], + | "email": "eveline@example.com" + |} + | + |Please note if everything=false you need to explicitly specify views and entitlements + |Example 3: + |{ + | "everything": false, + | "views": [ + | { + | "bank_id": "GENODEM1GLS", + | "account_id": "8ca8a7e4-6d02-40e3-a129-0b2bf89de9f0", + | "view_id": "${Constant.SYSTEM_OWNER_VIEW_ID}" + | } + | ], + | "entitlements": [ + | { + | "bank_id": "GENODEM1GLS", + | "role_name": "CanGetCustomersAtOneBank" + | } + | ], + | "consumer_id": "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + | "email": "eveline@example.com" + |} + | + |""", + postConsentPhoneJsonV310, + consentJsonV310, + List( + AuthenticatedUserIsRequired, + BankNotFound, + InvalidJsonFormat, + ConsentAllowedScaMethods, + RolesAllowedInConsent, + ViewsAllowedInConsent, + ConsumerNotFoundByConsumerId, + ConsumerIsDisabled, + MissingPropsValueAtThisInstance, + SmsServerNotResponding, + InvalidConnectorResponse, + UnknownError + ), apiTagConsent :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, http4sPartialFunction = Some(createConsentSms)) resourceDocs += ResourceDoc( null, implementedInApiVersion, nameOf(createConsentImplicit), "POST", "/banks/BANK_ID/my/consents/IMPLICIT", - "Create Consent (Implicit)", - s"""This endpoint starts the process of creating a Consent via Implicit SCA method. - | - |${userAuthenticationMessage(true)} - |""", - postConsentRequestJsonV310, - ConsentJsonV310( - consent_id = "9d429899-24f5-42c8-8565-943ffa6a7945", - jwt = "eyJ...", - status = "INITIATED"), - List(AuthenticatedUserIsRequired, BankNotFound, InvalidJsonFormat, - ConsentMaxTTL, RolesAllowedInConsent, ViewsAllowedInConsent, UnknownError), + "Create Consent (IMPLICIT)", + s""" + | + |This endpoint starts the process of creating a Consent. + | + |The Consent is created in an ${ConsentStatus.INITIATED} state. + | + |A One Time Password (OTP) (AKA security challenge) is sent Out of Band (OOB) to the User via the transport defined in SCA_METHOD + |SCA_METHOD is typically "SMS","EMAIL" or "IMPLICIT". "EMAIL" is used for testing purposes. OBP mapped mode "IMPLICIT" is "EMAIL". + |Other mode, bank can decide it in the connector method 'getConsentImplicitSCA'. + | + |When the Consent is created, OBP (or a backend system) stores the challenge so it can be checked later against the value supplied by the User with the Answer Consent Challenge endpoint. + | + |$generalObpConsentText + | + |${userAuthenticationMessage(true)} + | + |Example 1: + |{ + | "everything": true, + | "views": [], + | "entitlements": [], + | "consumer_id": "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + |} + | + |Please note that consumer_id is optional field + |Example 2: + |{ + | "everything": true, + | "views": [], + | "entitlements": [], + |} + | + |Please note if everything=false you need to explicitly specify views and entitlements + |Example 3: + |{ + | "everything": false, + | "views": [ + | { + | "bank_id": "GENODEM1GLS", + | "account_id": "8ca8a7e4-6d02-40e3-a129-0b2bf89de9f0", + | "view_id": "${Constant.SYSTEM_OWNER_VIEW_ID}" + | } + | ], + | "entitlements": [ + | { + | "bank_id": "GENODEM1GLS", + | "role_name": "CanGetCustomersAtOneBank" + | } + | ], + | "consumer_id": "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + |} + | + |""", + postConsentImplicitJsonV310, + consentJsonV310, + List( + AuthenticatedUserIsRequired, + BankNotFound, + InvalidJsonFormat, + ConsentAllowedScaMethods, + RolesAllowedInConsent, + ViewsAllowedInConsent, + ConsumerNotFoundByConsumerId, + ConsumerIsDisabled, + MissingPropsValueAtThisInstance, + SmsServerNotResponding, + InvalidConnectorResponse, + UnknownError + ), apiTagConsent :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, http4sPartialFunction = Some(createConsentImplicit)) @@ -3483,14 +4226,24 @@ object Http4s310 { null, implementedInApiVersion, nameOf(answerConsentChallenge), "POST", "/banks/BANK_ID/consents/CONSENT_ID/challenge", "Answer Consent Challenge", - s"""This endpoint is used to confirm a Consent previously created. - | - |The User must supply a code that was sent out of band (OOB) for example via an SMS. - | - |${userAuthenticationMessage(true)} - |""", + s""" + | + |$generalObpConsentText + | + | + |This endpoint is used to confirm a Consent previously created. + | + |The User must supply a code that was sent out of band (OOB) for example via an SMS. + | + |${userAuthenticationMessage(true)} + | + |""", PostConsentChallengeJsonV310(answer = "12345678"), - ConsentJsonV310("9d429899-24f5-42c8-8565-943ffa6a7945", "eyJ...", "INITIATED"), + ConsentChallengeJsonV310( + consent_id = "9d429899-24f5-42c8-8565-943ffa6a7945", + jwt = "eyJhbGciOiJIUzI1NiJ9.eyJlbnRpdGxlbWVudHMiOltdLCJjcmVhdGVkQnlVc2VySWQiOiJhYjY1MzlhOS1iMTA1LTQ0ODktYTg4My0wYWQ4ZDZjNjE2NTciLCJzdWIiOiIyMWUxYzhjYy1mOTE4LTRlYWMtYjhlMy01ZTVlZWM2YjNiNGIiLCJhdWQiOiJlanpuazUwNWQxMzJyeW9tbmhieDFxbXRvaHVyYnNiYjBraWphanNrIiwibmJmIjoxNTUzNTU0ODk5LCJpc3MiOiJodHRwczpcL1wvd3d3Lm9wZW5iYW5rcHJvamVjdC5jb20iLCJleHAiOjE1NTM1NTg0OTksImlhdCI6MTU1MzU1NDg5OSwianRpIjoiMDlmODhkNWYtZWNlNi00Mzk4LThlOTktNjYxMWZhMWNkYmQ1Iiwidmlld3MiOlt7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAxIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifSx7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAyIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifV19.8cc7cBEf2NyQvJoukBCmDLT7LXYcuzTcSYLqSpbxLp4", + status = "INITIATED" + ), List(AuthenticatedUserIsRequired, BankNotFound, InvalidJsonFormat, InvalidConnectorResponse, UnknownError), apiTagConsent :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, @@ -3512,10 +4265,10 @@ object Http4s310 { "/connector/loopback", "Get Connector Status (Loopback)", s"""This endpoint makes a call to the Connector to check the backend transport is reachable. (Deprecated) - | - |${userAuthenticationMessage(false)} - | - |""".stripMargin, + | + |${userAuthenticationMessage(true)} + | + |""", EmptyBody, obpApiLoopbackJson, List(UnknownError), List(apiTagApi, apiTagOAuth, apiTagOIDC), @@ -3632,11 +4385,75 @@ object Http4s310 { null, implementedInApiVersion, nameOf(saveHistoricalTransaction), "POST", "/management/historical/transactions", "Save Historical Transactions", - s"""Import the historical transactions. - | - |The fields bank_id, account_id, counterparty_id in the json body are all optional ones. - | - |This call is experimental.""".stripMargin, + s""" + |Import the historical transactions. + | + |The fields bank_id, account_id, counterparty_id in the json body are all optional ones. + |It support transfer money from account to account, account to counterparty and counterparty to counterparty + |Both bank_id + account_id and counterparty_id can identify the account, so OBP only need one of them to make the payment. + |So: + |When you need the account to account, just omit counterparty_id field.eg: + |{ + | "from": { + | "bank_id": "gh.29.uk", + | "account_id": "1ca8a7e4-6d02-48e3-a029-0b2bf89de9f0", + | }, + | "to": { + | "bank_id": "gh.29.uk", + | "account_id": "2ca8a7e4-6d02-48e3-a029-0b2bf89de9f0", + | }, + | "value": { + | "currency": "GBP", + | "amount": "10" + | }, + | "description": "this is for work", + | "posted": "2017-09-19T02:31:05Z", + | "completed": "2017-09-19T02:31:05Z", + | "type": "SANDBOX_TAN", + | "charge_policy": "SHARED" + |} + | + |When you need the counterparty to counterparty, need to omit bank_id and account_id field.eg: + |{ + | "from": { + | "counterparty_id": "f6392b7d-4218-45ea-b9a7-eaa71c0202f9" + | }, + | "to": { + | "counterparty_id": "26392b7d-4218-45ea-b9a7-eaa71c0202f9" + | }, + | "value": { + | "currency": "GBP", + | "amount": "10" + | }, + | "description": "this is for work", + | "posted": "2017-09-19T02:31:05Z", + | "completed": "2017-09-19T02:31:05Z", + | "type": "SANDBOX_TAN", + | "charge_policy": "SHARED" + |} + | + |or, you can counterparty to account + |{ + | "from": { + | "counterparty_id": "f6392b7d-4218-45ea-b9a7-eaa71c0202f9" + | }, + | "to": { + | "bank_id": "gh.29.uk", + | "account_id": "8ca8a7e4-6d02-48e3-a029-0b2bf89de9f0", + | }, + | "value": { + | "currency": "GBP", + | "amount": "10" + | }, + | "description": "this is for work", + | "posted": "2017-09-19T02:31:05Z", + | "completed": "2017-09-19T02:31:05Z", + | "type": "SANDBOX_TAN", + | "charge_policy": "SHARED" + |} + | + |This call is experimental. + """.stripMargin, postHistoricalTransactionJson, postHistoricalTransactionResponseJson, List(InvalidJsonFormat, BankNotFound, AccountNotFound, CounterpartyNotFoundByCounterpartyId, InvalidNumber, NotPositiveAmount, From 214bfd23b205e508ca02a79bbf6eb3e97571fd8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 21 May 2026 14:47:25 +0200 Subject: [PATCH 14/14] v3.0.0: bring ResourceDoc parity from 41 to 4 mismatches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run scripts/restore_resource_doc_bodies.py against APIMethods300.scala (source of truth) to restore the canonical Lift descriptions, examples, and error lists into Http4s300.scala. 44 field rewrites across: description: 41 (41 → 0) exampleRequestBody: 2 (2 → 0) errorResponseBodies: 1 (1 → 0) Two supporting imports added to Http4s300.scala so the restored doc strings compile: the SwaggerDefinitionsJSON object (not just the wildcard) and AccountsHelper.accountTypeFilterText (used inside several account-listing descriptions). Remaining 4 audit diffs are all middleware-driven URL renames: createViewForBankAccount ACCOUNT_ID → VIEW_ACCOUNT_ID (bypasses middleware account-validation; see CLAUDE.md "Middleware URL template bypass" gotcha) updateViewForBankAccount VIEW_ID → UPD_VIEW_ID (disambiguation) getFirehoseAccountsAtOneBank BANK_ID → FIREHOSE_BANK_ID VIEW_ID → FIREHOSE_VIEW_ID (firehose prop-check-before- bank-lookup bypass) getFirehoseTransactionsForBankAccount same firehose pattern, plus ACCOUNT_ID → FIREHOSE_ACCOUNT_ID All four are required for middleware correctness; the resolution is to document at the http4s site, not to revert. Per the source-of-truth rule, APIMethods300.scala is NOT modified. Also updates LIFT_HTTP4S_MIGRATION.md with v3.0.0's row and the per- endpoint fix-candidate table. --- LIFT_HTTP4S_MIGRATION.md | 17 +- .../scala/code/api/v3_0_0/Http4s300.scala | 572 +++++++++++++++--- 2 files changed, 493 insertions(+), 96 deletions(-) diff --git a/LIFT_HTTP4S_MIGRATION.md b/LIFT_HTTP4S_MIGRATION.md index 97cbac5246..b26fb73b31 100644 --- a/LIFT_HTTP4S_MIGRATION.md +++ b/LIFT_HTTP4S_MIGRATION.md @@ -192,13 +192,13 @@ Separate from the resource-docs **serving** workstream above, there is a parity | v2_0_0 | 37 | 19 | 0 | 0 | not started | | v2_1_0 | 23 | 13 | 5 | 2 | not started | | v2_2_0 | 18 | 13 | 0 | 0 | not started | -| v3_0_0 | 47 | 41 | 0 | 0 | not started | +| v3_0_0 | 47 | 4 | 0 | 0 | semantic fields restored; 4 middleware-driven URL renames remain | | v3_1_0 | 102 | 5 | 0 | 0 | semantic fields restored; 5 structural drifts (placeholder renames) remain | | v4_0_0 | 254 | 20 | 2 | 5 | semantic fields restored; 20 structural drifts (placeholder renames + 1 verb fix) remain | | v5_0_0 | 39 | 8 | 0 | 3 | descriptions restored; structural/errors remain | | v5_1_0 | 111 | 1 | 1 | 2 | one verb-casing drift to fix | | v6_0_0 | 243 | 12 | 0 | 1 | 11 placeholder renames + 1 routing-shape upstream change | -| **Total** | **956** | **181** | | | | +| **Total** | **956** | **144** | | | | ### v6.0.0 — 12 specific drifts (each is a fix candidate) @@ -231,6 +231,19 @@ Also: - 1 only-lift (`createConsentImplicit`) + 1 only-http4s (`createConsent`) — Lift had `lazy val createConsentImplicit = createConsent` aliasing and registered the doc under the alias; http4s registers under the canonical name. Fix: in http4s, either rename the partial function to `createConsentImplicit` to match Lift, or register a second `nameOf(createConsentImplicit)` doc for the same handler. - 1 only-http4s (`getBanks`) — kept in the v5.1.0 layer for metrics attribution (intentional addition; see comment at `Http4s510.scala:288`). Document. +### v3.0.0 — 4 specific drifts + +After semantic-field restoration, only middleware-driven URL renames remain. + +| Endpoint | Field | Lift | http4s | Resolution | +|---|---|---|---|---| +| `createViewForBankAccount` | requestUrl | `…/accounts/ACCOUNT_ID/views` | `…/accounts/VIEW_ACCOUNT_ID/views` | Middleware account-validation bypass (see CLAUDE.md "Middleware URL template bypass" gotcha). **Document** — required. | +| `updateViewForBankAccount` | requestUrl | `…/views/VIEW_ID` | `…/views/UPD_VIEW_ID` | Disambiguation rename. **Document**. | +| `getFirehoseAccountsAtOneBank` | requestUrl | `/banks/BANK_ID/firehose/accounts/views/VIEW_ID` | `/banks/FIREHOSE_BANK_ID/firehose/accounts/views/FIREHOSE_VIEW_ID` | Firehose middleware bypass. **Document**. | +| `getFirehoseTransactionsForBankAccount` | requestUrl | `/banks/BANK_ID/firehose/accounts/ACCOUNT_ID/views/VIEW_ID/transactions` | `/banks/FIREHOSE_BANK_ID/firehose/accounts/FIREHOSE_ACCOUNT_ID/views/FIREHOSE_VIEW_ID/transactions` | Same firehose pattern. **Document**. | + +No only-lift or only-http4s entries for v3.0.0. + ### v3.1.0 — 5 specific drifts After semantic-field restoration (commit `f4b9bd183`), only middleware-driven placeholder renames remain. diff --git a/obp-api/src/main/scala/code/api/v3_0_0/Http4s300.scala b/obp-api/src/main/scala/code/api/v3_0_0/Http4s300.scala index 32aac47370..50f47d13c5 100644 --- a/obp-api/src/main/scala/code/api/v3_0_0/Http4s300.scala +++ b/obp-api/src/main/scala/code/api/v3_0_0/Http4s300.scala @@ -4,7 +4,9 @@ import cats.data.{Kleisli, OptionT} import cats.effect._ import code.api.Constant import code.api.Constant._ +import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ +import code.api.v2_0_0.AccountsHelper.accountTypeFilterText import code.api.util.APIUtil.{EmptyBody, ResourceDoc, _} import code.api.util.{ApiRole, FutureUtil} import code.api.util.ApiRole._ @@ -103,9 +105,30 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getViewsForBankAccount), "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/views", "Get Views for Account", - s"""Returns the list of the views created for account ACCOUNT_ID at BANK_ID. - | - |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", + s"""#Views + | + | + |Views in Open Bank Project provide a mechanism for fine grained access control and delegation to Accounts and Transactions. Account holders use the 'owner' view by default. Delegated access is made through other views for example 'accountants', 'share-holders' or 'tagging-application'. Views can be created via the API and each view has a list of entitlements. + | + |Views on accounts and transactions filter the underlying data to redact certain fields for certain users. For instance the balance on an account may be hidden from the public. The way to know what is possible on a view is determined in the following JSON. + | + |**Data:** When a view moderates a set of data, some fields my contain the value `null` rather than the original value. This indicates either that the user is not allowed to see the original data or the field is empty. + | + |There is currently one exception to this rule; the 'holder' field in the JSON contains always a value which is either an alias or the real name - indicated by the 'is_alias' field. + | + |**Action:** When a user performs an action like trying to post a comment (with POST API call), if he is not allowed, the body response will contain an error message. + | + |**Metadata:** + |Transaction metadata (like images, tags, comments, etc.) will appears *ONLY* on the view where they have been created e.g. comments posted to the public view only appear on the public view. + | + |The other account metadata fields (like image_URL, more_info, etc.) are unique through all the views. Example, if a user edits the 'more_info' field in the 'team' view, then the view 'authorities' will show the new value (if it is allowed to do it). + | + |# All + |*Optional* + | + |Returns the list of the views created for account ACCOUNT_ID at BANK_ID. + | + |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", EmptyBody, viewsJsonV300, List(AuthenticatedUserIsRequired, BankAccountNotFound, UnknownError), List(apiTagView, apiTagAccount), None, @@ -137,10 +160,25 @@ object Http4s300 { null, implementedInApiVersion, nameOf(createViewForBankAccount), "POST", "/banks/BANK_ID/accounts/VIEW_ACCOUNT_ID/views", "Create Custom View", - s"""Create a custom view on bank account. - | - |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", - createViewJsonV300, viewJsonV300, + s"""Create a custom view on bank account + | + | ${userAuthenticationMessage(true)} and the user needs to have access to the owner view. + | The 'alias' field in the JSON can take one of three values: + | + | * _public_: to use the public alias if there is one specified for the other account. + | * _private_: to use the private alias if there is one specified for the other account. + | + | * _''(empty string)_: to use no alias; the view shows the real name of the other account. + | + | The 'hide_metadata_if_alias_used' field in the JSON can take boolean values. If it is set to `true` and there is an alias on the other account then the other accounts' metadata (like more_info, url, image_url, open_corporates_url, etc.) will be hidden. Otherwise the metadata will be shown. + | + | The 'allowed_actions' field is a list containing the name of the actions allowed on this view, all the actions contained will be set to `true` on the view creation, the rest will be set to `false`. + | + | The 'metadata_view' field determines where metadata (comments, tags, images, where tags) for transactions are stored and retrieved. If set to another view's ID (e.g. 'owner'), metadata added through this view will be shared with all other views that also use the same metadata_view value. If left empty, metadata is stored under this view's own ID and is not shared with other views. + | + | You MUST use a leading _ (underscore) in the view name because other view names are reserved for OBP [system views](/index#group-View-System). + | """, + SwaggerDefinitionsJSON.createViewJsonV300, viewJsonV300, List(AuthenticatedUserIsRequired, InvalidJsonFormat, BankAccountNotFound, UnknownError), List(apiTagView, apiTagAccount), None, http4sPartialFunction = Some(createViewForBankAccount)) @@ -187,9 +225,12 @@ object Http4s300 { null, implementedInApiVersion, nameOf(updateViewForBankAccount), "PUT", "/banks/BANK_ID/accounts/ACCOUNT_ID/views/UPD_VIEW_ID", "Update Custom View", - s"""Update an existing custom view on a bank account. - | - |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", + s"""Update an existing custom view on a bank account + | + |${userAuthenticationMessage(true)} and the user needs to have access to the owner view. + | + |The json sent is the same as during view creation (above), with one difference: the 'name' field + |of a view is not editable (it is only set when a view is created)""", updateViewJsonV300, viewJsonV300, List(InvalidJsonFormat, AuthenticatedUserIsRequired, BankAccountNotFound, UnknownError), List(apiTagView, apiTagAccount), None, @@ -248,8 +289,11 @@ object Http4s300 { "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER/PROVIDER_ID", "Get Account access for User", s"""Returns the list of the views at BANK_ID for account ACCOUNT_ID that a user identified by PROVIDER_ID at their provider PROVIDER has access to. - | - |${userAuthenticationMessage(true)}""", + |All url parameters must be [%-encoded](http://en.wikipedia.org/wiki/Percent-encoding), which is often especially relevant for USER_ID and PROVIDER. + | + |${userAuthenticationMessage(true)} + | + |The user needs to have access to the owner view.""", EmptyBody, viewsJsonV300, List(AuthenticatedUserIsRequired, BankNotFound, AccountNotFound, UnknownError), List(apiTagView, apiTagAccount, apiTagUser), None, @@ -270,7 +314,22 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getPrivateAccountById), "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/account", "Get Account by Id (Full)", - """Information returned about an account specified by ACCOUNT_ID as moderated by the view (VIEW_ID).""", + """Information returned about an account specified by ACCOUNT_ID as moderated by the view (VIEW_ID): + | + |* Number + |* Owners + |* Type + |* Balance + |* IBAN + |* Available views (sorted by short_name) + | + |More details about the data moderation by the view [here](#1_2_1-getViewsForBankAccount). + | + |PSD2 Context: PSD2 requires customers to have access to their account information via third party applications. + |This call provides balance and other account information via delegated authentication using OAuth. + | + |Authentication is required if the 'is_public' field in view (VIEW_ID) is not set to `true`. + |""".stripMargin, EmptyBody, moderatedCoreAccountJsonV300, List(BankNotFound, AccountNotFound, ViewNotFound, UserNoPermissionAccessView, UnknownError), apiTagAccount :: Nil, None, @@ -294,9 +353,24 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getPublicAccountById), "GET", "/banks/BANK_ID/public/accounts/ACCOUNT_ID/VIEW_ID/account", "Get Public Account by Id", - s"""Returns information about an account that has a public view. - | - |${userAuthenticationMessage(false)}""", + s""" + |Returns information about an account that has a public view. + | + |The account is specified by ACCOUNT_ID. The information is moderated by the view specified by VIEW_ID. + | + |* Number + |* Owners + |* Type + |* Balance + |* Routing + | + | + |PSD2 Context: PSD2 requires customers to have access to their account information via third party applications. + |This call provides balance and other account information via delegated authentication using OAuth. + | + |${userAuthenticationMessage(false)} + | + |""".stripMargin, EmptyBody, moderatedCoreAccountJsonV300, List(BankNotFound, AccountNotFound, ViewNotFound, UnknownError), apiTagAccountPublic :: apiTagAccount :: Nil, None, @@ -321,9 +395,22 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getCoreAccountById), "GET", "/my/banks/BANK_ID/accounts/ACCOUNT_ID/account", "Get Account by Id (Core)", - s"""Information returned about the account specified by ACCOUNT_ID. - | - |${userAuthenticationMessage(true)}""", + s"""Information returned about the account specified by ACCOUNT_ID: + | + |* Number - The human readable account number given by the bank that identifies the account. + |* Label - A label given by the owner of the account + |* Owners - Users that own this account + |* Type - The type of account + |* Balance - Currency and Value + |* Account Routings - A list that might include IBAN or national account identifiers + |* Account Rules - A list that might include Overdraft and other bank specific rules + | + |This call returns the owner view and requires access to that view. + | + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, EmptyBody, newModeratedCoreAccountJsonV300, List(BankAccountNotFound, UnknownError), apiTagAccount :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, @@ -347,8 +434,12 @@ object Http4s300 { "/my/accounts", "Get Accounts at all Banks (private)", s"""Returns the list of accounts containing private views for the user. - | - |${userAuthenticationMessage(true)}""", + |Each account lists the views available to the user. + | + |${accountTypeFilterText("/my/accounts")} + | + |${userAuthenticationMessage(true)} + |""", EmptyBody, coreAccountsJsonV300, List(AuthenticatedUserIsRequired, UnknownError), List(apiTagAccount, apiTagPSD2AIS, apiTagPrivateData, apiTagPsd2), None, @@ -409,9 +500,30 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getFirehoseAccountsAtOneBank), "GET", "/banks/FIREHOSE_BANK_ID/firehose/accounts/views/FIREHOSE_VIEW_ID", "Get Firehose Accounts at Bank", - s"""Get all Accounts at a Bank that have a Firehose View. - | - |${userAuthenticationMessage(true)}""", + s""" + |Get all Accounts at a Bank. + | + |This endpoint allows bulk access to all accounts at the specified bank. + | + |Requires the CanUseFirehoseAtAnyBank Role or CanUseAccountFirehose Role + | + |Returns all accounts at the bank. The VIEW_ID parameter determines what account data fields are visible according to the view's permissions. + | + |The view specified must have is_firehose = true + | + |For VIEW_ID try 'owner' or 'firehose' + | + |Optional request parameters for filtering by account attributes: + |URL params example: + | /banks/some-bank-id/firehose/accounts/views/owner?limit=50&offset=1 + | + |To invalidate browser cache, add timestamp query parameter as follows (the parameter name must be `_timestamp_`): + |URL params example: + | `/banks/some-bank-id/firehose/accounts/views/owner?limit=50&offset=1&_timestamp_=1596762180358` + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, EmptyBody, moderatedCoreAccountsJsonV300, List(AuthenticatedUserIsRequired, AccountFirehoseNotAllowedOnThisInstance, UnknownError), List(apiTagAccount, apiTagAccountFirehose, apiTagFirehoseData), @@ -464,9 +576,21 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getFirehoseTransactionsForBankAccount), "GET", "/banks/FIREHOSE_BANK_ID/firehose/accounts/FIREHOSE_ACCOUNT_ID/views/FIREHOSE_VIEW_ID/transactions", "Get Firehose Transactions for Account", - s"""Get Transactions for an Account that has a firehose View. - | - |${userAuthenticationMessage(true)}""", + s""" + |Get Transactions for an Account that has a firehose View. + | + |Allows bulk access to an account's transactions. + |User must have the CanUseFirehoseAtAnyBank Role + | + |To find ACCOUNT_IDs, use the getFirehoseAccountsAtOneBank call. + | + |For VIEW_ID try 'owner' + | + |${urlParametersDocument(true, true)} + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, EmptyBody, transactionsJsonV300, List(AuthenticatedUserIsRequired, AccountFirehoseNotAllowedOnThisInstance, UserHasMissingRoles, UnknownError), List(apiTagTransaction, apiTagAccountFirehose, apiTagTransactionFirehose, apiTagFirehoseData), @@ -501,8 +625,12 @@ object Http4s300 { "/my/banks/BANK_ID/accounts/ACCOUNT_ID/transactions", "Get Transactions for Account (Core)", s"""Returns transactions list (Core info) of the account specified by ACCOUNT_ID. - | - |${userAuthenticationMessage(true)}""", + | + |${userAuthenticationMessage(true)} + | + |${urlParametersDocument(true, true)} + | + |""", EmptyBody, coreTransactionsJsonV300, List(FilterSortDirectionError, FilterOffersetError, FilterLimitError, FilterDateFormatError, AuthenticatedUserIsRequired, BankAccountNotFound, ViewNotFound, UnknownError), @@ -535,9 +663,15 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getTransactionsForBankAccount), "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions", "Get Transactions for Account (Full)", - s"""Returns transactions list of the account specified by ACCOUNT_ID and moderated by the view (VIEW_ID). - | - |${userAuthenticationMessage(false)}""", + s"""Returns transactions list of the account specified by ACCOUNT_ID and [moderated](#1_2_1-getViewsForBankAccount) by the view (VIEW_ID). + | + |${userAuthenticationMessage(false)} + | + |Authentication is required if the view is not public. + | + |${urlParametersDocument(true, true)} + | + |""", EmptyBody, transactionsJsonV300, List(FilterSortDirectionError, FilterOffersetError, FilterLimitError, FilterDateFormatError, AuthenticatedUserIsRequired, BankAccountNotFound, ViewNotFound, UnknownError), @@ -581,9 +715,35 @@ object Http4s300 { null, implementedInApiVersion, nameOf(dataWarehouseSearch), "POST", "/search/warehouse/INDEX", "Data Warehouse Search", - s"""Search the data warehouse and get row level results. - | - |${userAuthenticationMessage(true)}""", + s""" + |Search the data warehouse and get row level results. + | + |${userAuthenticationMessage(true)} + | + |CanSearchWarehouse entitlement is required. You can request the Role below. + | + |Elastic (search) is used in the background. See links below for syntax. + | + |Examples of usage: + | + | + |POST /search/warehouse/THE_INDEX_YOU_WANT_TO_USE + | + |POST /search/warehouse/INDEX1,INDEX2 + | + |POST /search/warehouse/ALL + | + |{ Any valid elasticsearch query DSL in the body } + | + | + |[Elasticsearch query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html) + | + |[Elastic simple query](https://www.elastic.co/guide/en/elasticsearch/reference/6.2/search-request-body.html) + | + |[Elastic aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/6.2/search-aggregations.html) + | + | + """, elasticSearchJsonV300, emptyElasticSearch, List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagSearchWarehouse), @@ -625,9 +785,36 @@ object Http4s300 { null, implementedInApiVersion, nameOf(dataWarehouseStatistics), "POST", "/search/warehouse/statistics/INDEX/FIELD", "Data Warehouse Statistics", - s"""Search the data warehouse and get statistical aggregations over a warehouse field. - | - |${userAuthenticationMessage(true)}""", + s""" + |Search the data warehouse and get statistical aggregations over a warehouse field + | + |Does a stats aggregation over some numeric field: + | + |https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-stats-aggregation.html + | + |${userAuthenticationMessage(true)} + | + |CanSearchWarehouseStats Role is required. You can request this below. + | + |Elastic (search) is used in the background. See links below for syntax. + | + |Examples of usage: + | + |POST /search/warehouse/statistics/INDEX/FIELD + | + |POST /search/warehouse/statistics/ALL/FIELD + | + |{ Any valid elasticsearch query DSL in the body } + | + | + |[Elasticsearch query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html) + | + |[Elastic simple query](https://www.elastic.co/guide/en/elasticsearch/reference/6.2/search-request-body.html) + | + |[Elastic aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/6.2/search-aggregations.html) + | + | + """, elasticSearchJsonV300, emptyElasticSearch, List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagSearchWarehouse), @@ -650,9 +837,12 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getUser), "GET", "/users/email/USER_EMAIL/terminator", "Get Users by Email Address", - s"""Get users by email address. + s"""Get users by email address | - |${userAuthenticationMessage(true)}""", + |${userAuthenticationMessage(true)} + |CanGetAnyUser entitlement is required, + | + """.stripMargin, EmptyBody, usersJsonV200, List(AuthenticatedUserIsRequired, UserHasMissingRoles, UserNotFoundByEmail, UnknownError), List(apiTagUser), @@ -678,9 +868,12 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getUserByUserId), "GET", "/users/user_id/USER_ID", "Get User by USER_ID", - s"""Get user by USER_ID. + s"""Get user by USER_ID | - |${userAuthenticationMessage(true)}""", + |${userAuthenticationMessage(true)} + |CanGetAnyUser entitlement is required, + | + """.stripMargin, EmptyBody, usersJsonV200, List(AuthenticatedUserIsRequired, UserHasMissingRoles, UserNotFoundById, UnknownError), List(apiTagUser), @@ -706,9 +899,13 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getUserByUsername), "GET", "/users/username/USERNAME", "Get User by USERNAME", - s"""Get user by USERNAME. + s"""Get user by USERNAME | - |${userAuthenticationMessage(true)}""", + |${userAuthenticationMessage(true)} + | + |CanGetAnyUser entitlement is required, + | + """.stripMargin, EmptyBody, usersJsonV200, List(AuthenticatedUserIsRequired, UserHasMissingRoles, UserNotFoundByProviderAndUsername, UnknownError), List(apiTagUser), @@ -799,9 +996,11 @@ object Http4s300 { null, implementedInApiVersion, nameOf(updateBranch), "PUT", "/banks/BANK_ID/branches/BRANCH_ID", "Update Branch", - s"""Update an existing branch for a bank account. - | - |${userAuthenticationMessage(true)}""", + s"""Update an existing branch for a bank account (Authenticated access). + | + |${userAuthenticationMessage(true) } + | + |""", postBranchJsonV300, branchJsonV300, List(AuthenticatedUserIsRequired, BankNotFound, InsufficientAuthorisationToCreateBranch, UnknownError), List(apiTagBranch), @@ -860,9 +1059,14 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getBranch), "GET", "/banks/BANK_ID/branches/BRANCH_ID", "Get Branch", - s"""Returns information about a single Branch specified by BANK_ID and BRANCH_ID. - | - |${userAuthenticationMessage(!getBranchesIsPublic)}""", + s"""Returns information about a single Branch specified by BANK_ID and BRANCH_ID including: + | + |* Name + |* Address + |* Geo Location + |* License the data under this endpoint is released under. + | + |${userAuthenticationMessage(!getBranchesIsPublic)}""".stripMargin, EmptyBody, branchJsonV300, List(AuthenticatedUserIsRequired, BranchNotFoundByBranchId, UnknownError), List(apiTagBranch, apiTagBank), None, @@ -947,9 +1151,34 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getBranches), "GET", "/banks/BANK_ID/branches", "Get Branches for a Bank", - s"""Returns information about branches for a single bank specified by BANK_ID. - | - |${userAuthenticationMessage(!getBranchesIsPublic)}""", + s"""Returns information about branches for a single bank specified by BANK_ID including: + | + |* Name + |* Address + |* Geo Location + |* License the data under this endpoint is released under + |* Structured opening hours + |* Accessible flag + |* Branch Type + |* More Info + | + |Pagination: + | + |By default, 50 records are returned. + | + |You can use the url query parameters *limit* and *offset* for pagination + |You can also use the follow url query parameters: + | + | - city - string, find Branches those in this city, optional + | + | + | - withinMetersOf - number, find Branches within given meters distance, optional + | - nearLatitude - number, a position of latitude value, cooperate with withMetersOf do query filter, optional + | - nearLongitude - number, a position of longitude value, cooperate with withMetersOf do query filter, optional + | + |note: withinMetersOf, nearLatitude and nearLongitude either all empty or all have value. + | + |${userAuthenticationMessage(!getBranchesIsPublic)}""".stripMargin, EmptyBody, branchesJsonV300, List(AuthenticatedUserIsRequired, BankNotFound, BranchesNotFoundLicense, UnknownError), List(apiTagBranch, apiTagBank), None, @@ -975,9 +1204,15 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getAtm), "GET", "/banks/BANK_ID/atms/ATM_ID", "Get Bank ATM", - s"""Returns information about ATM for a single bank specified by BANK_ID and ATM_ID. - | - |${userAuthenticationMessage(!getAtmsIsPublic)}""", + s"""Returns information about ATM for a single bank specified by BANK_ID and ATM_ID including: + | + |* Address + |* Geo Location + |* License the data under this endpoint is released under + | + | + | + |${userAuthenticationMessage(!getAtmsIsPublic)}""".stripMargin, EmptyBody, atmJsonV300, List(AuthenticatedUserIsRequired, BankNotFound, AtmNotFoundByAtmId, UnknownError), List(apiTagATM), None, @@ -1023,11 +1258,25 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getAtms), "GET", "/banks/BANK_ID/atms", "Get Bank ATMS", - s"""Returns information about ATMs for a single bank specified by BANK_ID. - | - |${userAuthenticationMessage(!getAtmsIsPublic)}""", + s"""Returns information about ATMs for a single bank specified by BANK_ID including: + | + |* Address + |* Geo Location + |* License the data under this endpoint is released under + | + |Pagination: + | + |By default, 100 records are returned. + | + |You can use the url query parameters *limit* and *offset* for pagination + | + |${userAuthenticationMessage(!getAtmsIsPublic)}""".stripMargin, EmptyBody, atmJsonV300, - List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), + List( + AuthenticatedUserIsRequired, + BankNotFound, + "No ATMs available. License may not be set.", + UnknownError), List(apiTagATM), None, http4sPartialFunction = Some(getAtms)) @@ -1049,9 +1298,16 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getUsers), "GET", "/users", "Get all Users", - s"""Get all users. + s"""Get all users | - |${userAuthenticationMessage(true)}""", + |${userAuthenticationMessage(true)} + | + |CanGetAnyUser entitlement is required, + | + |${urlParametersDocument(false, false)} + |* locked_status (if null ignore) + | + """.stripMargin, EmptyBody, usersJsonV200, List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagUser), @@ -1102,9 +1358,10 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getCurrentUser), "GET", "/users/current", "Get User (Current)", - s"""Get the logged in user. + s"""Get the logged in user | - |${userAuthenticationMessage(true)}""", + |${userAuthenticationMessage(true)} + """.stripMargin, EmptyBody, userJsonV300, List(AuthenticatedUserIsRequired, UnknownError), List(apiTagUser), None, @@ -1128,8 +1385,13 @@ object Http4s300 { "/banks/BANK_ID/accounts/private", "Get Accounts at Bank (Minimal)", s"""Returns the minimal list of private accounts at BANK_ID that the user has access to. - | - |${userAuthenticationMessage(true)}""", + |For each account, the API returns the ID, routing addresses and the views available to the current user. + | + |If you want to see more information on the Views, use the Account Detail call. + | + |${accountTypeFilterText("/banks/BANK_ID/accounts/private")} + | + |${userAuthenticationMessage(true)}""".stripMargin, EmptyBody, coreAccountsJsonV300, List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), List(apiTagAccount, apiTagPSD2AIS, apiTagPsd2), None, @@ -1154,8 +1416,16 @@ object Http4s300 { "/banks/BANK_ID/accounts/account_ids/private", "Get Accounts at Bank (IDs only)", s"""Returns only the list of accounts ids at BANK_ID that the user has access to. - | - |${userAuthenticationMessage(true)}""", + | + |Each account must have at least one private View. + | + |For each account the API returns its account ID. + | + |If you want to see more information on the Views, use the Account Detail call. + | + |${accountTypeFilterText("/banks/BANK_ID/accounts/account_ids/private")} + | + |${userAuthenticationMessage(true)}""".stripMargin, EmptyBody, accountsIdsJsonV300, List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), List(apiTagAccount, apiTagPSD2AIS, apiTagPsd2), None, @@ -1177,8 +1447,9 @@ object Http4s300 { "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts", "Get Other Accounts of one Account", s"""Returns data about all the other accounts that have shared at least one transaction with the ACCOUNT_ID at BANK_ID. - | - |${userAuthenticationMessage(false)}""", + |${userAuthenticationMessage(false)} + | + |Authentication is required if the view VIEW_ID is not public.""", EmptyBody, otherAccountsJsonV300, List(AuthenticatedUserIsRequired, BankAccountNotFound, ViewNotFound, InvalidConnectorResponse, UnknownError), List(apiTagCounterparty, apiTagAccount), None, @@ -1200,8 +1471,9 @@ object Http4s300 { "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID", "Get Other Account by Id", s"""Returns data about the Other Account that has shared at least one transaction with ACCOUNT_ID at BANK_ID. - | - |${userAuthenticationMessage(false)}""", + |${userAuthenticationMessage(false)} + | + |Authentication is required if the view is not public.""", EmptyBody, otherAccountJsonV300, List(AuthenticatedUserIsRequired, BankAccountNotFound, ViewNotFound, InvalidConnectorResponse, UnknownError), List(apiTagCounterparty, apiTagAccount), None, @@ -1236,8 +1508,20 @@ object Http4s300 { "/entitlement-requests", "Create Entitlement Request for current User", s"""Create Entitlement Request. - | - |${userAuthenticationMessage(true)}""", + | + |Any logged in User can use this endpoint to request an Entitlement + | + |Entitlements are used to grant System or Bank level roles to Users. (For Account level privileges, see Views) + | + |For a System level Role (.e.g CanGetAnyUser), set bank_id to an empty string i.e. "bank_id":"" + | + |For a Bank level Role (e.g. CanCreateAccount), set bank_id to a valid value e.g. "bank_id":"my-bank-id" + | + | + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createEntitlementJSON, entitlementRequestJSON, List(AuthenticatedUserIsRequired, UserNotFoundById, InvalidJsonFormat, IncorrectRoleName, EntitlementIsBankRole, EntitlementIsSystemRole, EntitlementRequestAlreadyExists, EntitlementRequestCannotBeAdded, UnknownError), @@ -1264,9 +1548,13 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getAllEntitlementRequests), "GET", "/entitlement-requests", "Get all Entitlement Requests", - s"""Get all Entitlement Requests. + s""" + |Get all Entitlement Requests | - |${userAuthenticationMessage(true)}""", + |${urlParametersDocument(true, true)} + | + |${userAuthenticationMessage(true)} + """.stripMargin, EmptyBody, entitlementRequestsJSON, List(AuthenticatedUserIsRequired, InvalidConnectorResponse, UnknownError), List(apiTagRole, apiTagEntitlement, apiTagUser), @@ -1293,8 +1581,12 @@ object Http4s300 { "/users/USER_ID/entitlement-requests", "Get Entitlement Requests for a User", s"""Get Entitlement Requests for a User. - | - |${userAuthenticationMessage(true)}""", + | + |${urlParametersDocument(true, true)} + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, EmptyBody, entitlementRequestsJSON, List(AuthenticatedUserIsRequired, InvalidConnectorResponse, UnknownError), List(apiTagRole, apiTagEntitlement, apiTagUser), @@ -1318,8 +1610,12 @@ object Http4s300 { "/my/entitlement-requests", "Get Entitlement Requests for the current User", s"""Get Entitlement Requests for the current User. - | - |${userAuthenticationMessage(true)}""", + | + |${urlParametersDocument(true, true)} + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, EmptyBody, entitlementRequestsJSON, List(AuthenticatedUserIsRequired, InvalidConnectorResponse, UnknownError), List(apiTagRole, apiTagEntitlement, apiTagUser), None, @@ -1348,9 +1644,11 @@ object Http4s300 { null, implementedInApiVersion, nameOf(deleteEntitlementRequest), "DELETE", "/entitlement-requests/ENTITLEMENT_REQUEST_ID", "Delete Entitlement Request", - s"""Delete the Entitlement Request specified by ENTITLEMENT_REQUEST_ID. + s"""Delete the Entitlement Request specified by ENTITLEMENT_REQUEST_ID for a user specified by USER_ID | - |${userAuthenticationMessage(true)}""", + | + |${userAuthenticationMessage(true)} + """.stripMargin, EmptyBody, EmptyBody, List(AuthenticatedUserIsRequired, InvalidConnectorResponse, UnknownError), List(apiTagRole, apiTagEntitlement, apiTagUser), @@ -1409,7 +1707,19 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getApiGlossary), "GET", "/api/glossary", "Get Glossary of the API", - """Get API Glossary. Returns the glossary of the API.""", + """Get API Glossary + | + |Returns the glossary of the API. + | + |The glossary content is static and only changes when the API is redeployed. + |This endpoint supports HTTP caching: + | + |* The response includes a **Cache-Control** header (max-age=3600) indicating clients should cache for 1 hour. + |* The response includes an **ETag** header. Clients can send **If-None-Match** with the ETag value on subsequent requests to receive a **304 Not Modified** if the content has not changed. + | + |Clients and agents are encouraged to cache the glossary response locally. + | + |""", EmptyBody, glossaryItemsJsonV300, List(UnknownError), apiTagDocumentation :: Nil, None, @@ -1435,8 +1745,14 @@ object Http4s300 { "/banks/BANK_ID/accounts-held", "Get Accounts Held", s"""Get Accounts held by the current User if even the User has not been assigned the owner View yet. - | - |${userAuthenticationMessage(true)}""", + | + |Can be used to onboard the account to the API - since all other account and transaction endpoints require views to be assigned. + | + |${accountTypeFilterText("/banks/BANK_ID/accounts-held")} + | + | + | + """.stripMargin, EmptyBody, coreAccountsHeldJsonV300, List(AuthenticatedUserIsRequired, UnknownError), List(apiTagAccount, apiTagPSD2AIS, apiTagView, apiTagPsd2), None, @@ -1462,9 +1778,49 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getAggregateMetrics), "GET", "/management/aggregate-metrics", "Get Aggregate Metrics", - s"""Returns aggregate metrics on api usage. + s"""Returns aggregate metrics on api usage eg. total count, response time (in ms), etc. | - |${userAuthenticationMessage(true)}""", + |Should be able to filter on the following fields + | + |eg: /management/aggregate-metrics?from_date=$DateWithMsExampleString&to_date=$DateWithMsExampleString&consumer_id=5 + |&user_id=66214b8e-259e-44ad-8868-3eb47be70646&implemented_by_partial_function=getTransactionsForBankAccount + |&implemented_in_version=v3.0.0&url=/obp/v3.0.0/banks/gh.29.uk/accounts/8ca8a7e4-6d02-48e3-a029-0b2bf89de9f0/owner/transactions + |&verb=GET&anon=false&app_name=MapperPostman + |&exclude_app_names=API-EXPLORER,API-Manager,SOFI,null + | + |1 from_date (defaults to the day before the current date): eg:from_date=$DateWithMsExampleString + | + |2 to_date (defaults to the current date) eg:to_date=$DateWithMsExampleString + | + |3 consumer_id (if null ignore) + | + |4 user_id (if null ignore) + | + |5 anon (if null ignore) only support two value : true (return where user_id is null.) or false (return where user_id is not null.) + | + |6 url (if null ignore), note: can not contain '&'. + | + |7 app_name (if null ignore) + | + |8 implemented_by_partial_function (if null ignore), + | + |9 implemented_in_version (if null ignore) + | + |10 verb (if null ignore) + | + |11 correlation_id (if null ignore) + | + |12 duration (if null ignore) non digit chars will be silently omitted + | + |13 exclude_app_names (if null ignore).eg: &exclude_app_names=API-EXPLORER,API-Manager,SOFI,null + | + |14 exclude_url_patterns (if null ignore).you can design you own SQL NOT LIKE pattern. eg: &exclude_url_patterns=%management/metrics%,%management/aggregate-metrics% + | + |15 exclude_implemented_by_partial_functions (if null ignore).eg: &exclude_implemented_by_partial_functions=getMetrics,getConnectorMetrics,getAggregateMetrics + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, EmptyBody, aggregateMetricsJSONV300, List(AuthenticatedUserIsRequired, UserHasMissingRoles, UnknownError), List(apiTagMetric, apiTagAggregateMetrics), @@ -1507,8 +1863,16 @@ object Http4s300 { null, implementedInApiVersion, nameOf(addScope), "POST", "/consumers/CONSUMER_ID/scopes", "Create Scope for a Consumer", - """Create Scope. Grant Role to Consumer.""", - code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createScopeJson, scopeJson, + """Create Scope. Grant Role to Consumer. + | + |Scopes are used to grant System or Bank level roles to the Consumer (App). (For Account level privileges, see Views) + | + |For a System level Role (.e.g CanGetAnyUser), set bank_id to an empty string i.e. "bank_id":"" + | + |For a Bank level Role (e.g. CanCreateAccount), set bank_id to a valid value e.g. "bank_id":"my-bank-id" + | + |""", + SwaggerDefinitionsJSON.createScopeJson, scopeJson, List(AuthenticatedUserIsRequired, ConsumerNotFoundById, InvalidJsonFormat, IncorrectRoleName, EntitlementIsBankRole, EntitlementIsSystemRole, EntitlementAlreadyExists, UnknownError), List(apiTagScope, apiTagConsumer), @@ -1544,7 +1908,13 @@ object Http4s300 { null, implementedInApiVersion, nameOf(deleteScope), "DELETE", "/consumers/CONSUMER_ID/scope/SCOPE_ID", "Delete Consumer Scope", - """Delete Consumer Scope specified by SCOPE_ID for a consumer specified by CONSUMER_ID.""", + """Delete Consumer Scope specified by SCOPE_ID for an consumer specified by CONSUMER_ID + | + |Authentication is required and the user needs to be a Super Admin. + |Super Admins are listed in the Props file. + | + | + """.stripMargin, EmptyBody, EmptyBody, List(AuthenticatedUserIsRequired, EntitlementNotFound, UnknownError), List(apiTagScope, apiTagConsumer), @@ -1572,9 +1942,12 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getScopes), "GET", "/consumers/CONSUMER_ID/scopes", "Get Scopes for Consumer", - s"""Get all the scopes for a consumer specified by CONSUMER_ID. + s"""Get all the scopes for an consumer specified by CONSUMER_ID | - |${userAuthenticationMessage(true)}""", + |${userAuthenticationMessage(true)} + | + | + """.stripMargin, EmptyBody, scopeJsons, List(AuthenticatedUserIsRequired, EntitlementNotFound, UnknownError), List(apiTagScope, apiTagConsumer), None, @@ -1598,7 +1971,13 @@ object Http4s300 { null, implementedInApiVersion, nameOf(getBanks), "GET", "/banks", "Get Banks", - """Get banks on this API instance. Returns a list of banks supported on this server.""", + """Get banks on this API instance + |Returns a list of banks supported on this server: + | + |* ID used as parameter in URLs + |* Short and full name of bank + |* Logo URL + |* Website""", EmptyBody, banksJSON, List(UnknownError), apiTagBank :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None, @@ -1617,7 +1996,12 @@ object Http4s300 { null, implementedInApiVersion, nameOf(bankById), "GET", "/banks/BANK_ID", "Get Bank", - """Get the bank specified by BANK_ID.""", + """Get the bank specified by BANK_ID + |Returns information about a single bank specified by BANK_ID including: + | + |* Short and full name of bank + |* Logo URL + |* Website""", EmptyBody, bankJson400, List(AuthenticatedUserIsRequired, UnknownError, BankNotFound), apiTagBank :: apiTagPSD2AIS :: apiTagPsd2 :: Nil, None,