genesis_ruby 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.kiro/specs/f2025112509-add_managed_recurring_api/.config.kiro +1 -0
- data/.kiro/specs/f2025112509-add_managed_recurring_api/design.md +332 -0
- data/.kiro/specs/f2025112509-add_managed_recurring_api/requirements.md +91 -0
- data/.kiro/specs/f2025112509-add_managed_recurring_api/tasks.md +139 -0
- data/.kiro/specs/f2025112603-add_reverify_endpoint_to_payee_account/.config.kiro +1 -0
- data/.kiro/specs/f2025112603-add_reverify_endpoint_to_payee_account/design.md +148 -0
- data/.kiro/specs/f2025112603-add_reverify_endpoint_to_payee_account/requirements.md +81 -0
- data/.kiro/specs/f2025112603-add_reverify_endpoint_to_payee_account/tasks.md +48 -0
- data/.kiro/specs/f2025112606-add_list_payees_trx_request/.config.kiro +1 -0
- data/.kiro/specs/f2025112606-add_list_payees_trx_request/design.md +112 -0
- data/.kiro/specs/f2025112606-add_list_payees_trx_request/requirements.md +74 -0
- data/.kiro/specs/f2025112606-add_list_payees_trx_request/tasks.md +38 -0
- data/.kiro/specs/f2025112609_update_payee_request_params/design.md +86 -0
- data/.kiro/specs/f2025112609_update_payee_request_params/requirements.md +86 -0
- data/.kiro/specs/f2025112609_update_payee_request_params/tasks.md +40 -0
- data/.kiro/specs/f2025112612-add_payee_owner_documents_and_verification_requests/.config.kiro +1 -0
- data/.kiro/specs/f2025112612-add_payee_owner_documents_and_verification_requests/design.md +246 -0
- data/.kiro/specs/f2025112612-add_payee_owner_documents_and_verification_requests/requirements.md +287 -0
- data/.kiro/specs/f2025112612-add_payee_owner_documents_and_verification_requests/tasks.md +76 -0
- data/.kiro/specs/f2025112614-add_money_transfer_payout_attributes_to_payout_rq/design.md +84 -0
- data/.kiro/specs/f2025112614-add_money_transfer_payout_attributes_to_payout_rq/requirements.md +88 -0
- data/.kiro/specs/f2025112614-add_money_transfer_payout_attributes_to_payout_rq/tasks.md +38 -0
- data/.kiro/steering/product.md +15 -0
- data/.kiro/steering/spec-folder-naming.md +16 -0
- data/.kiro/steering/structure.md +96 -0
- data/.kiro/steering/tech.md +66 -0
- data/CHANGELOG.md +23 -0
- data/Gemfile.lock +4 -4
- data/README.md +33 -0
- data/VERSION +1 -1
- data/lib/genesis_ruby/api/constants/non_financial/kyc/address_document_supported_types.rb +81 -0
- data/lib/genesis_ruby/api/constants/non_financial/payee/document_types.rb +57 -0
- data/lib/genesis_ruby/api/constants/non_financial/payee/owner_types.rb +30 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/money_transfer/purpose_of_payments.rb +50 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/money_transfer/sender_account_number_types.rb +50 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/money_transfer/source_of_funds.rb +44 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/money_transfer/types.rb +26 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/non_financial/billing_api/statement_response_fields.rb +37 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/cards/mpi_attributes.rb +0 -10
- data/lib/genesis_ruby/api/mixins/requests/financial/money_transfer_payout_attributes.rb +131 -0
- data/lib/genesis_ruby/api/mixins/requests/non_financial/date_attributes.rb +87 -5
- data/lib/genesis_ruby/api/mixins/requests/non_financial/kyc/business_attributes.rb +42 -0
- data/lib/genesis_ruby/api/mixins/requests/non_financial/kyc/document_attributes.rb +8 -7
- data/lib/genesis_ruby/api/request.rb +15 -9
- data/lib/genesis_ruby/api/requests/base/non_financial/billing_api/base.rb +108 -0
- data/lib/genesis_ruby/api/requests/base/non_financial/payee/base.rb +54 -0
- data/lib/genesis_ruby/api/requests/financial/cards/authorize3d.rb +1 -3
- data/lib/genesis_ruby/api/requests/financial/cards/payout.rb +3 -1
- data/lib/genesis_ruby/api/requests/financial/cards/sale3d.rb +1 -3
- data/lib/genesis_ruby/api/requests/non_financial/billing_api/statement.rb +170 -0
- data/lib/genesis_ruby/api/requests/non_financial/billing_api/transactions.rb +20 -60
- data/lib/genesis_ruby/api/requests/non_financial/kyc/business/create.rb +45 -0
- data/lib/genesis_ruby/api/requests/non_financial/kyc/business/document.rb +60 -0
- data/lib/genesis_ruby/api/requests/non_financial/kyc/business/document_list.rb +59 -0
- data/lib/genesis_ruby/api/requests/non_financial/kyc/business/verification.rb +52 -0
- data/lib/genesis_ruby/api/requests/non_financial/kyc/verifications/address_by_document_proof.rb +92 -0
- data/lib/genesis_ruby/api/requests/non_financial/kyc/verifications/create.rb +4 -1
- data/lib/genesis_ruby/api/requests/non_financial/managed_recurring/cancel.rb +63 -0
- data/lib/genesis_ruby/api/requests/non_financial/managed_recurring/fetch.rb +63 -0
- data/lib/genesis_ruby/api/requests/non_financial/managed_recurring/fetch_all.rb +37 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/account/reverify.rb +61 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/associate_payee_with_owners.rb +105 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/create.rb +37 -7
- data/lib/genesis_ruby/api/requests/non_financial/payee/create_payee_document.rb +61 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/dissociate_payee_with_owners.rb +94 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/list.rb +38 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/list_payee_documents.rb +57 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/list_payee_owners.rb +70 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/owners/associate_owner_with_owners.rb +109 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/owners/create.rb +71 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/owners/create_owner_document.rb +63 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/owners/delete.rb +54 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/owners/dissociate_owners.rb +96 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/owners/list_owner_documents.rb +59 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/owners/list_owners.rb +46 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/owners/retrieve.rb +59 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/owners/retrieve_owner_document.rb +62 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/owners/update.rb +66 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/retrieve_payee_document.rb +60 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/update.rb +34 -4
- data/lib/genesis_ruby/api/requests/non_financial/payee/verifications/create_payee_verification.rb +58 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/verifications/list_payee_verifications.rb +59 -0
- data/lib/genesis_ruby/api/requests/non_financial/payee/verifications/retrieve_payee_verification.rb +62 -0
- data/lib/genesis_ruby/api/requests/non_financial/tokenization/retokenize.rb +45 -0
- data/lib/genesis_ruby/api/requests/wpf/create.rb +19 -0
- data/lib/genesis_ruby/api/response.rb +15 -0
- data/lib/genesis_ruby/dependencies.rb +2 -0
- data/lib/genesis_ruby/network/adapter/net_http_adapter.rb +31 -5
- data/lib/genesis_ruby/network/base_network.rb +5 -0
- data/lib/genesis_ruby/network/net_http.rb +16 -4
- data/lib/genesis_ruby/utils/options/api_config.rb +43 -32
- data/lib/genesis_ruby/utils/options/network_adapter_config.rb +1 -1
- data/lib/genesis_ruby/version.rb +1 -1
- metadata +72 -3
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Requirements Document
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
Update the existing Payee Create and Payee Update request classes in the genesis_ruby SDK to support the full set of request parameters defined in the current Payee API documentation. This includes adding `registration_number`, `date`, `notification_url`, and a nested `address` object with `city`, `street`, `state`, `country`, and `zip_code` fields. The obsolete flat address format and `neighborhood` field must not be emitted.
|
|
6
|
+
|
|
7
|
+
## Glossary
|
|
8
|
+
|
|
9
|
+
- **SDK**: The genesis_ruby Ruby gem that wraps the emerchantpay payment gateway API
|
|
10
|
+
- **Payee_Create**: The `GenesisRuby::Api::Requests::NonFinancial::Payee::Create` class (POST /payee)
|
|
11
|
+
- **Payee_Update**: The `GenesisRuby::Api::Requests::NonFinancial::Payee::Update` class (PATCH /payee/:payee_unique_id)
|
|
12
|
+
- **Nested_Address**: A hash object under the `address` key containing `city`, `street`, `state`, `country`, `zip_code`
|
|
13
|
+
- **Deep_Compact**: The SDK's mechanism that removes nil values and empty hashes from the request structure before serialization
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
### Requirement 1: Payee Create — New Request Parameters
|
|
18
|
+
|
|
19
|
+
**User Story:** As a developer using the SDK, I want to set `registration_number`, `date`, `notification_url`, and nested address fields on Payee Create, so that the JSON payload matches the current Payee API documentation.
|
|
20
|
+
|
|
21
|
+
#### Acceptance Criteria
|
|
22
|
+
|
|
23
|
+
- [x] `payee_date` accessor is available and serialized as `payee.date`
|
|
24
|
+
- [x] `payee_notification_url` accessor is available and serialized as `payee.notification_url`
|
|
25
|
+
- [x] `payee_registration_number` accessor is available and serialized as `payee.registration_number`
|
|
26
|
+
- [x] `payee_address_city` is serialized under `payee.address.city`
|
|
27
|
+
- [x] `payee_address_street` is serialized under `payee.address.street`
|
|
28
|
+
- [x] `payee_address_state` is serialized under `payee.address.state`
|
|
29
|
+
- [x] `payee_address_country` is serialized under `payee.address.country`
|
|
30
|
+
- [x] `payee_address_zip_code` is serialized under `payee.address.zip_code`
|
|
31
|
+
- [x] `payee_address_country` is validated against the ISO country list (optional field)
|
|
32
|
+
- [x] When all address fields are nil, the `address` key is not emitted in the payload
|
|
33
|
+
- [x] The `neighborhood` field is never emitted
|
|
34
|
+
- [x] Existing required fields (`payee_type`, `payee_name`, `payee_country`) remain unchanged
|
|
35
|
+
- [x] All new fields are optional
|
|
36
|
+
|
|
37
|
+
### Requirement 2: Payee Update — New Request Parameters
|
|
38
|
+
|
|
39
|
+
**User Story:** As a developer using the SDK, I want to set `registration_number`, `date`, `notification_url`, and nested address fields on Payee Update, so that the JSON payload matches the current Payee API documentation.
|
|
40
|
+
|
|
41
|
+
#### Acceptance Criteria
|
|
42
|
+
|
|
43
|
+
- [x] `payee_date` accessor is available and serialized as `payee.date`
|
|
44
|
+
- [x] `payee_notification_url` accessor is available and serialized as `payee.notification_url`
|
|
45
|
+
- [x] `payee_registration_number` accessor is available and serialized as `payee.registration_number`
|
|
46
|
+
- [x] `payee_address_city` is serialized under `payee.address.city`
|
|
47
|
+
- [x] `payee_address_street` is serialized under `payee.address.street`
|
|
48
|
+
- [x] `payee_address_state` is serialized under `payee.address.state`
|
|
49
|
+
- [x] `payee_address_country` is serialized under `payee.address.country`
|
|
50
|
+
- [x] `payee_address_zip_code` is serialized under `payee.address.zip_code`
|
|
51
|
+
- [x] `payee_address_country` is validated against the ISO country list (optional field)
|
|
52
|
+
- [x] When all address fields are nil, the `address` key is not emitted in the payload
|
|
53
|
+
- [x] The `neighborhood` field is never emitted
|
|
54
|
+
- [x] HTTP method remains PATCH
|
|
55
|
+
- [x] Only `payee_unique_id` is required; all other fields are optional
|
|
56
|
+
- [x] All new fields are optional
|
|
57
|
+
|
|
58
|
+
### Requirement 3: No Obsolete Fields
|
|
59
|
+
|
|
60
|
+
**User Story:** As a developer using the SDK, I want the Payee requests to not emit obsolete fields, so that the payload is compliant with the current API.
|
|
61
|
+
|
|
62
|
+
#### Acceptance Criteria
|
|
63
|
+
|
|
64
|
+
- [x] No `neighborhood` field is present in any request structure
|
|
65
|
+
- [x] No flat `address` string field (e.g., `payee.address = "123 Main St"`) is used
|
|
66
|
+
- [x] No flat `zip_code` field at the payee root level is used
|
|
67
|
+
|
|
68
|
+
### Requirement 4: Test Coverage
|
|
69
|
+
|
|
70
|
+
**User Story:** As a developer, I want RSpec tests covering all new parameters, so that regressions are caught.
|
|
71
|
+
|
|
72
|
+
#### Acceptance Criteria
|
|
73
|
+
|
|
74
|
+
- [x] Spec for Payee Create verifies full request structure including nested address
|
|
75
|
+
- [x] Spec for Payee Create verifies address is omitted when all address fields are nil
|
|
76
|
+
- [x] Spec for Payee Create verifies no `neighborhood` in address
|
|
77
|
+
- [x] Spec for Payee Create verifies `registration_number` serialization
|
|
78
|
+
- [x] Spec for Payee Create verifies `payee_address_country` validation
|
|
79
|
+
- [x] Spec for Payee Update verifies full request structure including nested address
|
|
80
|
+
- [x] Spec for Payee Update verifies address is omitted when all address fields are nil
|
|
81
|
+
- [x] Spec for Payee Update verifies no `neighborhood` in address
|
|
82
|
+
- [x] Spec for Payee Update verifies `registration_number` serialization
|
|
83
|
+
- [x] Spec for Payee Update verifies `payee_address_country` validation
|
|
84
|
+
- [x] Spec for Payee Update verifies minimum request data (only `payee_unique_id` required)
|
|
85
|
+
- [x] All existing tests continue to pass
|
|
86
|
+
- [x] `bundle exec rake styles` passes with 0 offenses
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Tasks
|
|
2
|
+
|
|
3
|
+
## Task 1: Add new fields to Payee Create request class
|
|
4
|
+
|
|
5
|
+
- [x] Add `attr_accessor` for `payee_date`, `payee_notification_url`, `payee_registration_number`
|
|
6
|
+
- [x] Add `attr_accessor` for `payee_address_city`, `payee_address_street`, `payee_address_state`, `payee_address_country`, `payee_address_zip_code`
|
|
7
|
+
- [x] Add `payee_address_country` to `field_values` for ISO validation
|
|
8
|
+
- [x] Update `request_structure` to include new fields and nested `address`
|
|
9
|
+
- [x] Add private `payee_address_structure` method
|
|
10
|
+
|
|
11
|
+
## Task 2: Add new fields to Payee Update request class
|
|
12
|
+
|
|
13
|
+
- [x] Add `attr_accessor` for `payee_date`, `payee_notification_url`, `payee_registration_number`
|
|
14
|
+
- [x] Add `attr_accessor` for `payee_address_city`, `payee_address_street`, `payee_address_state`, `payee_address_country`, `payee_address_zip_code`
|
|
15
|
+
- [x] Add `payee_address_country` to `field_values` for ISO validation
|
|
16
|
+
- [x] Update `request_structure` to include new fields and nested `address`
|
|
17
|
+
- [x] Add private `payee_address_structure` method
|
|
18
|
+
|
|
19
|
+
## Task 3: Update Payee Create spec
|
|
20
|
+
|
|
21
|
+
- [x] Add new fields to `sample_data` and `request` let blocks
|
|
22
|
+
- [x] Update structure assertion to include all new fields
|
|
23
|
+
- [x] Add context for nested address serialization (present, absent, no neighborhood)
|
|
24
|
+
- [x] Add context for `registration_number`
|
|
25
|
+
- [x] Add test for `payee_address_country` validation
|
|
26
|
+
|
|
27
|
+
## Task 4: Update Payee Update spec
|
|
28
|
+
|
|
29
|
+
- [x] Add new fields to `sample_data` and `request` let blocks
|
|
30
|
+
- [x] Update structure assertion to include all new fields
|
|
31
|
+
- [x] Add context for nested address serialization (present, absent, no neighborhood)
|
|
32
|
+
- [x] Add context for `registration_number`
|
|
33
|
+
- [x] Add test for `payee_address_country` validation
|
|
34
|
+
- [x] Update minimum request data test to nil all new fields
|
|
35
|
+
|
|
36
|
+
## Task 5: Validation
|
|
37
|
+
|
|
38
|
+
- [x] `bundle exec rake test` — 7089 examples, 0 failures
|
|
39
|
+
- [x] `bundle exec rake styles` — 933 files inspected, no offenses detected
|
|
40
|
+
- [x] `git diff --stat` shows only 4 modified files (create.rb, update.rb, create_spec.rb, update_spec.rb)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"specId": "e7536868-191d-4a23-aacb-b036ee65c0bb", "workflowType": "requirements-first", "specType": "feature"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Design Document: Payee Owner, Documents & Verifications
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Extend the genesis_ruby SDK with 20 new non-financial request classes for the Payee API covering Owner management, Document management, and Verification management. Additionally, add HTTP DELETE method infrastructure since the existing codebase only supports POST, GET, PUT, and PATCH.
|
|
6
|
+
|
|
7
|
+
All new request classes follow the established `Base::Versioned` pattern: JSON format, versioned API paths, `attr_accessor` parameters, field validations, request structure hashes, and path placeholder replacement in `process_request_parameters`.
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
The new classes follow the PHP SDK's flat layout — Payee-level operations (documents, owners association) sit directly in the `Payee` module, Owner CRUD and Owner sub-operations go in `Payee::Owners`, and Verifications in `Payee::Verifications`:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
lib/genesis_ruby/api/requests/non_financial/payee/
|
|
15
|
+
├── Account/ (existing)
|
|
16
|
+
│ ├── create.rb, retrieve.rb, update.rb, list.rb
|
|
17
|
+
├── Owners/ (Owner CRUD + Owner sub-operations)
|
|
18
|
+
│ ├── create.rb (POST /payee/owners)
|
|
19
|
+
│ ├── retrieve.rb (GET /payee/owners/:owner_unique_id)
|
|
20
|
+
│ ├── update.rb (PATCH /payee/owners/:owner_unique_id)
|
|
21
|
+
│ ├── delete.rb (DELETE /payee/owners/:owner_unique_id)
|
|
22
|
+
│ ├── list_owners.rb (GET /payee/owners)
|
|
23
|
+
│ ├── associate_owner_with_owners.rb (POST /payee/owners/:owner_unique_id/owners)
|
|
24
|
+
│ ├── dissociate_owners.rb (DELETE /payee/owners/:owner_unique_id/owners)
|
|
25
|
+
│ ├── create_owner_document.rb (POST /payee/owners/:owner_unique_id/documents)
|
|
26
|
+
│ ├── retrieve_owner_document.rb (GET /payee/owners/:owner_unique_id/documents/:document_unique_id)
|
|
27
|
+
│ └── list_owner_documents.rb (GET /payee/owners/:owner_unique_id/documents)
|
|
28
|
+
├── Verifications/
|
|
29
|
+
│ ├── create_payee_verification.rb (POST /payee/:payee_unique_id/verifications)
|
|
30
|
+
│ ├── retrieve_payee_verification.rb (GET /payee/:payee_unique_id/verifications/:verification_unique_id)
|
|
31
|
+
│ └── list_payee_verifications.rb (GET /payee/:payee_unique_id/verifications)
|
|
32
|
+
├── create.rb, retrieve.rb, update.rb (existing Payee CRUD)
|
|
33
|
+
├── list_payees.rb (GET /payee)
|
|
34
|
+
├── list_payee_owners.rb (GET /payee/:payee_unique_id/owners)
|
|
35
|
+
├── associate_payee_with_owners.rb (POST /payee/:payee_unique_id/owners)
|
|
36
|
+
├── dissociate_payee_with_owners.rb (DELETE /payee/:payee_unique_id/owners)
|
|
37
|
+
├── create_payee_document.rb (POST /payee/:payee_unique_id/documents)
|
|
38
|
+
├── retrieve_payee_document.rb (GET /payee/:payee_unique_id/documents/:document_unique_id)
|
|
39
|
+
└── list_payee_documents.rb (GET /payee/:payee_unique_id/documents)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Infrastructure changes for DELETE support:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
Api::Request → METHOD_DELETE constant + init_delete_configuration method
|
|
46
|
+
Utils::Options::ApiConfig → load_delete_config method
|
|
47
|
+
Network::Adapter::NetHttpAdapter → DELETE case in execute
|
|
48
|
+
Utils::Options::NetworkAdapterConfig → DELETE format in fetch_content_type
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Components and Interfaces
|
|
52
|
+
|
|
53
|
+
### 1. HTTP DELETE Infrastructure
|
|
54
|
+
|
|
55
|
+
**`Api::Request`** — Add `METHOD_DELETE = 'DELETE'` constant and `init_delete_configuration` method that delegates to `@api_config.load_delete_config`.
|
|
56
|
+
|
|
57
|
+
**`Utils::Options::ApiConfig`** — Add `load_delete_config` method:
|
|
58
|
+
```ruby
|
|
59
|
+
def load_delete_config
|
|
60
|
+
self.protocol = GenesisRuby::Api::Request::PROTOCOL_HTTPS
|
|
61
|
+
self.port = GenesisRuby::Api::Request::PORT_HTTPS
|
|
62
|
+
self.type = GenesisRuby::Api::Request::METHOD_DELETE
|
|
63
|
+
self.format = Builder::JSON
|
|
64
|
+
self.parser_skip_root_node = false
|
|
65
|
+
self.authorization = GenesisRuby::Api::Request::AUTH_TYPE_BASIC
|
|
66
|
+
self.bearer_token = nil
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**`Network::Adapter::NetHttpAdapter`** — Add DELETE case in `execute`:
|
|
71
|
+
```ruby
|
|
72
|
+
when Api::Request::METHOD_DELETE then @response = @request.delete path, headers
|
|
73
|
+
```
|
|
74
|
+
Note: DELETE requests send headers only (no body), similar to GET. The `headers` method should exclude payload headers for DELETE, same as GET.
|
|
75
|
+
|
|
76
|
+
**`Utils::Options::NetworkAdapterConfig`** — Add `Builder::JSON` handling for DELETE in `fetch_content_type`. Since DELETE uses `Builder::JSON` format, it's already handled by the existing `when Builder::JSON then 'application/json'` case. No change needed here.
|
|
77
|
+
|
|
78
|
+
### 2. Request Class Patterns
|
|
79
|
+
|
|
80
|
+
All 20 request classes follow one of four patterns:
|
|
81
|
+
|
|
82
|
+
**GET (Retrieve)** — `init_get_configuration` in `init_configuration`, empty `request_structure`, placeholder replacement in `process_request_parameters`.
|
|
83
|
+
|
|
84
|
+
**GET (List)** — Same as Retrieve, plus optional query parameter building appended to the URL.
|
|
85
|
+
|
|
86
|
+
**POST (Create/Associate)** — Default POST, `request_structure` returns the JSON body hash, placeholder replacement.
|
|
87
|
+
|
|
88
|
+
**PATCH (Update)** — `init_patch_configuration` in constructor, `request_structure` returns updatable fields, placeholder replacement.
|
|
89
|
+
|
|
90
|
+
**DELETE (Dissociate/Delete)** — `init_delete_configuration` in constructor, `request_structure` returns body (for dissociate) or empty hash (for delete), placeholder replacement.
|
|
91
|
+
|
|
92
|
+
### 3. Constants Module
|
|
93
|
+
|
|
94
|
+
**`Api::Constants::NonFinancial::Payee::OwnerTypes`**:
|
|
95
|
+
```ruby
|
|
96
|
+
COMPANY = 'company'
|
|
97
|
+
PERSON = 'person'
|
|
98
|
+
DIRECTOR = 'director'
|
|
99
|
+
ULTIMATE_BENEFICIAL_OWNER = 'ultimate_beneficial_owner'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**`Api::Constants::NonFinancial::Payee::DocumentTypes`**:
|
|
103
|
+
```ruby
|
|
104
|
+
POI = 'poi'
|
|
105
|
+
PASSPORT = 'passport'
|
|
106
|
+
ID_CARD = 'id_card'
|
|
107
|
+
DRIVING_LICENSE = 'driving_license'
|
|
108
|
+
POA = 'poa'
|
|
109
|
+
UTILITY_BILL = 'utility_bill'
|
|
110
|
+
BANK_STATEMENT = 'bank_statement'
|
|
111
|
+
COMPANY_REGISTRATION = 'company_registration'
|
|
112
|
+
TAX_RETURN = 'tax_return'
|
|
113
|
+
MEMORANDUM_OF_ASSOCIATION = 'memorandum_of_association'
|
|
114
|
+
SHAREHOLDER_REGISTER = 'shareholder_register'
|
|
115
|
+
BOARD_RESOLUTION = 'board_resolution'
|
|
116
|
+
PROOF_OF_ADDRESS = 'proof_of_address'
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Data Models
|
|
120
|
+
|
|
121
|
+
### Request Parameters by Class
|
|
122
|
+
|
|
123
|
+
| Class | Required Fields | Optional Fields | Validated Fields |
|
|
124
|
+
|-------|----------------|-----------------|------------------|
|
|
125
|
+
| ListPayeeOwners | payee_unique_id | type (query param) | — |
|
|
126
|
+
| AssociatePayeeWithOwners | payee_unique_id | owners[] | — |
|
|
127
|
+
| DissociatePayeeWithOwners | payee_unique_id | owners[] | — |
|
|
128
|
+
| CreatePayeeDocument | payee_unique_id, document_type, file | — | document_type |
|
|
129
|
+
| RetrievePayeeDocument | payee_unique_id, document_unique_id | — | — |
|
|
130
|
+
| ListPayeeDocuments | payee_unique_id | — | — |
|
|
131
|
+
| Verifications::CreatePayeeVerification | payee_unique_id | notification_url, redirect_url, with_checks_retry | — |
|
|
132
|
+
| Verifications::RetrievePayeeVerification | payee_unique_id, verification_unique_id | — | — |
|
|
133
|
+
| Verifications::ListPayeeVerifications | payee_unique_id | — | — |
|
|
134
|
+
| Owners::Create | owner_type, owner_name, owner_country | owner_date, notification_url, registration_number, owner_address{}, payees[], owners[] | owner_type, owner_country |
|
|
135
|
+
| Owners::Retrieve | owner_unique_id | — | — |
|
|
136
|
+
| Owners::Update | owner_unique_id | owner_name, owner_country, owner_date, notification_url, registration_number, owner_address{} | owner_country |
|
|
137
|
+
| Owners::Delete | owner_unique_id | — | — |
|
|
138
|
+
| Owners::ListOwners | — | — | — |
|
|
139
|
+
| Owners::AssociateOwnerWithOwners | owner_unique_id | owners[] | — |
|
|
140
|
+
| Owners::DissociateOwners | owner_unique_id | owners[] | — |
|
|
141
|
+
| Owners::CreateOwnerDocument | owner_unique_id, document_type, file | — | document_type |
|
|
142
|
+
| Owners::RetrieveOwnerDocument | owner_unique_id, document_unique_id | — | — |
|
|
143
|
+
| Owners::ListOwnerDocuments | owner_unique_id | — | — |
|
|
144
|
+
|
|
145
|
+
### URL Patterns
|
|
146
|
+
|
|
147
|
+
| Class | HTTP Method | URL Pattern |
|
|
148
|
+
|-------|------------|-------------|
|
|
149
|
+
| ListPayeeOwners | GET | `payee/:payee_unique_id/owners[?type=X]` |
|
|
150
|
+
| AssociatePayeeWithOwners | POST | `payee/:payee_unique_id/owners` |
|
|
151
|
+
| DissociatePayeeWithOwners | DELETE | `payee/:payee_unique_id/owners` |
|
|
152
|
+
| CreatePayeeDocument | POST | `payee/:payee_unique_id/documents` |
|
|
153
|
+
| RetrievePayeeDocument | GET | `payee/:payee_unique_id/documents/:document_unique_id` |
|
|
154
|
+
| ListPayeeDocuments | GET | `payee/:payee_unique_id/documents` |
|
|
155
|
+
| Verifications::CreatePayeeVerification | POST | `payee/:payee_unique_id/verifications` |
|
|
156
|
+
| Verifications::RetrievePayeeVerification | GET | `payee/:payee_unique_id/verifications/:verification_unique_id` |
|
|
157
|
+
| Verifications::ListPayeeVerifications | GET | `payee/:payee_unique_id/verifications` |
|
|
158
|
+
| Owners::Create | POST | `payee/owners` |
|
|
159
|
+
| Owners::Retrieve | GET | `payee/owners/:owner_unique_id` |
|
|
160
|
+
| Owners::Update | PATCH | `payee/owners/:owner_unique_id` |
|
|
161
|
+
| Owners::Delete | DELETE | `payee/owners/:owner_unique_id` |
|
|
162
|
+
| Owners::ListOwners | GET | `payee/owners` |
|
|
163
|
+
| Owners::AssociateOwnerWithOwners | POST | `payee/owners/:owner_unique_id/owners` |
|
|
164
|
+
| Owners::DissociateOwners | DELETE | `payee/owners/:owner_unique_id/owners` |
|
|
165
|
+
| Owners::CreateOwnerDocument | POST | `payee/owners/:owner_unique_id/documents` |
|
|
166
|
+
| Owners::RetrieveOwnerDocument | GET | `payee/owners/:owner_unique_id/documents/:document_unique_id` |
|
|
167
|
+
| Owners::ListOwnerDocuments | GET | `payee/owners/:owner_unique_id/documents` |
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
## Correctness Properties
|
|
171
|
+
|
|
172
|
+
*A property is a characteristic or behavior that should hold true across all valid executions of a system — essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
|
|
173
|
+
|
|
174
|
+
### Property 1: Required field validation rejects nil values
|
|
175
|
+
|
|
176
|
+
*For any* request class and *for any* field declared in `required_fields`, setting that field to `nil` and calling `build_document` SHALL raise a `ParameterError`.
|
|
177
|
+
|
|
178
|
+
**Validates: Requirements 2.3, 3.3, 4.3, 5.3, 6.3, 7.3, 8.3, 9.3, 10.3, 11.3, 12.3, 13.3, 14.3, 16.3, 17.3, 18.3, 19.3, 20.3**
|
|
179
|
+
|
|
180
|
+
### Property 2: Path placeholder replacement produces valid URLs
|
|
181
|
+
|
|
182
|
+
*For any* request class with path placeholders and *for any* valid non-empty ID string, after calling `build_document`, the resulting URL SHALL contain the ID string and SHALL NOT contain any `:placeholder` tokens.
|
|
183
|
+
|
|
184
|
+
**Validates: Requirements 2.6, 3.6, 4.6, 5.6, 6.5, 7.5, 8.6, 9.5, 10.5, 12.5, 13.7, 14.5, 16.6, 17.6, 18.6, 19.5, 20.5, 21.3**
|
|
185
|
+
|
|
186
|
+
### Property 3: Field value validation rejects invalid enum values
|
|
187
|
+
|
|
188
|
+
*For any* request class with `field_values` constraints (owner_type, document_type, country) and *for any* string not in the allowed values list, calling `build_document` SHALL raise a `ParameterError`.
|
|
189
|
+
|
|
190
|
+
**Validates: Requirements 5.4, 11.4, 11.5, 13.5, 18.4, 21.6**
|
|
191
|
+
|
|
192
|
+
### Property 4: Request structure serialization preserves input data
|
|
193
|
+
|
|
194
|
+
*For any* POST/PATCH/DELETE request class with a non-empty body and *for any* set of valid input parameters, the JSON-parsed output of `build_document` SHALL contain all non-nil input values under the correct nesting keys.
|
|
195
|
+
|
|
196
|
+
**Validates: Requirements 3.4, 3.5, 4.4, 4.5, 5.5, 8.5, 11.7, 13.6, 16.4, 16.5, 17.4, 17.5, 18.5**
|
|
197
|
+
|
|
198
|
+
### Property 5: Query parameter URL building for list endpoints
|
|
199
|
+
|
|
200
|
+
*For any* list request class with optional query parameters and *for any* non-nil query parameter value, the resulting URL after `build_document` SHALL contain the parameter as a properly encoded query string. When all query parameters are nil, the URL SHALL NOT contain a `?`.
|
|
201
|
+
|
|
202
|
+
**Validates: Requirements 2.4, 21.5**
|
|
203
|
+
|
|
204
|
+
## Error Handling
|
|
205
|
+
|
|
206
|
+
All request classes use the existing `Base::Versioned` validation framework:
|
|
207
|
+
|
|
208
|
+
- **`ParameterError`** — Raised when required fields are nil/empty or field values don't match allowed lists. Raised during `build_document` → `process_request_parameters` → `check_requirements` → `validate`.
|
|
209
|
+
- **`InvalidArgumentError`** — Raised for invalid API versions or builder interface mismatches.
|
|
210
|
+
- **`BuilderError`** — Raised if the builder interface cannot be configured.
|
|
211
|
+
- **`NetworkError`** — Raised by the network adapter for connection failures, timeouts, or invalid request types (including unrecognized HTTP methods).
|
|
212
|
+
|
|
213
|
+
No new error types are needed. The DELETE infrastructure follows the same error patterns as existing methods.
|
|
214
|
+
|
|
215
|
+
## Testing Strategy
|
|
216
|
+
|
|
217
|
+
### Unit Tests (RSpec)
|
|
218
|
+
|
|
219
|
+
Each of the 20 request classes gets a corresponding `_spec.rb` file following the existing pattern:
|
|
220
|
+
|
|
221
|
+
1. **Config setup** — Standard `let(:config)` with username, password, token, endpoint, environment.
|
|
222
|
+
2. **Sample data** — `let(:sample_data)` with Faker-generated values for all parameters.
|
|
223
|
+
3. **Request setup** — `let(:request)` that creates and populates the request instance.
|
|
224
|
+
4. **Structure test** — Verify `JSON.parse(request.build_document)` matches expected structure.
|
|
225
|
+
5. **URL test** — Verify `request.api_config['url']` contains the correct path with replaced placeholders.
|
|
226
|
+
6. **HTTP method test** — Verify `request.api_config['type']` matches expected method (GET/POST/PATCH/DELETE).
|
|
227
|
+
7. **Token test** — Verify `request.api_config['token']` is nil (include_token: false).
|
|
228
|
+
8. **Validation tests** — Required fields nil → ParameterError, invalid field values → ParameterError.
|
|
229
|
+
9. **Shared examples** — `include_examples 'base request examples'` and `include_examples 'versioned request examples'`.
|
|
230
|
+
|
|
231
|
+
Infrastructure tests:
|
|
232
|
+
- `Api::Request` — Verify `METHOD_DELETE` constant and `init_delete_configuration` method.
|
|
233
|
+
- `Utils::Options::ApiConfig` — Verify `load_delete_config` sets correct attributes.
|
|
234
|
+
- `Network::Adapter::NetHttpAdapter` — Verify DELETE requests are dispatched correctly.
|
|
235
|
+
|
|
236
|
+
### Property-Based Tests
|
|
237
|
+
|
|
238
|
+
Using the `rspec-property` or `rantly` gem, minimum 100 iterations per property:
|
|
239
|
+
|
|
240
|
+
- **Property 1**: Generate random request classes and nil out each required field, verify ParameterError.
|
|
241
|
+
- **Property 2**: Generate random UUID strings for ID fields, verify URL contains them and has no placeholders.
|
|
242
|
+
- **Property 3**: Generate random invalid strings for enum fields, verify ParameterError.
|
|
243
|
+
- **Property 4**: Generate random valid parameter sets, verify JSON output contains all values.
|
|
244
|
+
- **Property 5**: Generate random query param values, verify URL encoding.
|
|
245
|
+
|
|
246
|
+
Each property test tagged with: `# Feature: payee-owner-documents-verifications, Property N: <title>`
|