From 608249f00ab3b75abc3e8235203bf5565b4dfe4a Mon Sep 17 00:00:00 2001 From: Alexander Saal Date: Sat, 23 May 2026 15:53:24 +0200 Subject: [PATCH 1/2] =?UTF-8?q?feat(mail):=20mailstandardfilter=20write=20?= =?UTF-8?q?endpoints=20=E2=80=94=20add=20/=20delete?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wires add_mailstandardfilter and delete_mailstandardfilter through the shared kaswrite seam plus the #109 / #131 / #132 CLI plumbing as a vertical slice (Closes #116, part of #13). Both subcommands are gated: the KAS API has no update action, so add replaces the configured filter chain wholesale, and delete removes every configured filter in one shot. - internal/mailfilter/write.go adds Client.Add/Delete (semicolon-joined --filter chain, per-field validation, kaswrite contract). - internal/cli/mail.go wires "mail filters add | delete" with the destructive flag set, a confirm verb that phrases the all-at-once delete explicitly ("remove all standard filters of mail account ") and a Long help that points users at "mail accounts get " → mail_spamfilter for outcome verification. - testdata/response_failed_internal_server_error.xml captures the observed envelope-level PHP sizeof() fault that delete_mailstandardfilter sometimes returns even after the chain was removed; mailfilter.Client.Delete surfaces it verbatim (locked in by TestClientDeleteSurfacesInternalServerFault). docs/usage/ destructive-writes.md documents the quirk + verification path. - testdata/mailfilter/add_mailstandardfilter_{request,response_success}.xml and get_mailstandardfilter_response_success.xml refreshed against the live API by the maintainer; the slice's read tests still pass against the real-shape fixture. Closes #116. --- CHANGELOG.md | 30 +++ docs/cli/kasapi-cli_mail.md | 2 +- docs/cli/kasapi-cli_mail_filters.md | 4 +- docs/cli/kasapi-cli_mail_filters_add.md | 46 ++++ docs/cli/kasapi-cli_mail_filters_delete.md | 48 +++++ docs/cli/kasapi-cli_mail_filters_list.md | 2 +- docs/usage/destructive-writes.md | 1 + internal/cli/mail.go | 75 ++++++- internal/cli/mail_test.go | 96 ++++++++- internal/mailfilter/doc.go | 7 +- internal/mailfilter/fault_test.go | 23 +- internal/mailfilter/mailfilter.go | 37 ++-- internal/mailfilter/write.go | 120 +++++++++++ internal/mailfilter/write_test.go | 202 ++++++++++++++++++ .../add_mailstandardfilter_request.xml | 2 +- ...dd_mailstandardfilter_response_success.xml | 21 +- ...et_mailstandardfilter_response_success.xml | 2 +- .../response_failed_internal_server_error.xml | 9 + 18 files changed, 684 insertions(+), 43 deletions(-) create mode 100644 docs/cli/kasapi-cli_mail_filters_add.md create mode 100644 docs/cli/kasapi-cli_mail_filters_delete.md create mode 100644 internal/mailfilter/write.go create mode 100644 internal/mailfilter/write_test.go create mode 100644 testdata/response_failed_internal_server_error.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f5f084..b71460a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Mail standard filter write endpoints (#116, #13 write slice): + `kasapi-cli mail filters add --filter [--filter + ...]` and `… delete ` wire + `add_mailstandardfilter` / `delete_mailstandardfilter`. Both are + gated by the #109 confirmation prompt: the KAS API has no + `update_mailstandardfilter` action, so `add` *replaces* the configured + filter chain wholesale (items previously set but missing from the new + `--filter` list are dropped), which is destructive to recover from + without a stored copy. Both honour `--dry-run` (#132) and emit a #131 + audit record. Repeatable `--filter` items are joined with `;` on the + wire (the format the captured `add_mailstandardfilter` request + fixture uses); each item is either a bare filter id (e.g. `pdw`) or + `: