Skip to content

Individual account approval resources (node)#64

Open
lucasmiranda-stark wants to merge 1 commit into
masterfrom
feature/account-approval
Open

Individual account approval resources (node)#64
lucasmiranda-stark wants to merge 1 commit into
masterfrom
feature/account-approval

Conversation

@lucasmiranda-stark

Copy link
Copy Markdown
Contributor

Context

The account-approval feature — IndividualAccountRequest and IndividualAccountAttachment (each with a read-only .Log) — for the node infra SDK. Generated from contracts individual-account-request.md (v3) and individual-account-attachment.md (v3). Run-type: migrate. Run artifacts: runs/20260528-182857-account-approval/node/.

What changed

  • Breaking: reshape IndividualAccountRequest.address from a string into a structured Address object (nested JSON, never flattened).
  • Replace legacy AccountRequestAttachment with IndividualAccountAttachment, adding cancel (DELETE → status: "deleted", idempotent); legacy source and tests removed — no dual exposure (M14).
  • IndividualAccountAttachment constructor encodes content+contentType into a data: URL client-side; contentType is input-only.
  • CHANGELOG entry + per-resource README usage sections.

Test plan

  • 48 unit tests passing locally against the infra sandbox (Phase 6 — see runs/20260528-182857-account-approval/node/test-run-success.md)
  • Sandbox smoke check (manual after merge)

Risk & Rollback

  • Risk: breaking — IndividualAccountRequest.address changes string→object, and legacy AccountRequestAttachment is removed (callers migrate to IndividualAccountAttachment).
  • Rollback: revert this PR; client-side shape change only, no data migration.

Contract review (Phase 7)

Contract Review

Run metadata

  • Run-ID: runs/20260528-182857-account-approval/node/
  • Round: 4
  • Language: node
  • Run-type: migrate
  • Contracts: contracts/individual-account-request.md (v3), contracts/individual-account-attachment.md (v3)
  • Author: Lucas Miranda

Checklist — IndividualAccountRequest (M1–M12)

Mandatory point Status Implementation Test
[M1] create accepts list, returns shape with server-assigned id, status, accountType, created, updated covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:67-85 test_success @ sdk-infra/node/tests/testIndividualAccountRequest.js:11-18
[M2] address is structured object (not string), with required sub-fields; serialized as nested JSON, not flattened covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:41,57-65; sdk-infra/node/sdk/individualAccountRequest/address.js:4-36 test_address_is_nested_object @ sdk-infra/node/tests/testIndividualAccountRequest.js:25-46
[M3] get(id) returns single IndividualAccountRequest by id covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:87-105 test_success @ sdk-infra/node/tests/testIndividualAccountRequest.js:63-73
[M4] query returns async iterable accepting limit, after, before, status, tags, ids covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:107-136 test_success (query) @ sdk-infra/node/tests/testIndividualAccountRequest.js:51-59; test_success (params) @ sdk-infra/node/tests/testIndividualAccountRequest.js:121-131
[M5] page returns [items, cursor], accepts same params as query plus cursor covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:138-169 test_success (page) @ sdk-infra/node/tests/testIndividualAccountRequest.js:99-115; test_success (page params) @ sdk-infra/node/tests/testIndividualAccountRequest.js:133-148
[M6] update(id, ...) PATCHes, accepts subset of name, taxId, address, income, status, tags; replaces address wholesale covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:171-198 test_success (update) @ sdk-infra/node/tests/testIndividualAccountRequest.js:153-165
[M7] status enum exactly approved|created|denied|processing|updated (v1 values not used); test asserts membership covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:36-51 (status field) test_success (statusEnum) @ sdk-infra/node/tests/testIndividualAccountRequest.js:171-178
[M8] IndividualAccountRequest.Log is read-only, exposed under <resource>.log, provides get, query, page; request field is parent type covered sdk-infra/node/sdk/individualAccountRequest/log/log.js:6-117; sdk-infra/node/sdk/individualAccountRequest/index.js:3 test_success (log query) @ sdk-infra/node/tests/testIndividualAccountRequestLog.js:8-18; test_success (log get, request field) @ sdk-infra/node/tests/testIndividualAccountRequestLog.js:22-35; test_success (log page) @ sdk-infra/node/tests/testIndividualAccountRequestLog.js:51-69
[M9] Log.query and Log.page accept limit, after, before, types, accountRequestIds covered sdk-infra/node/sdk/individualAccountRequest/log/log.js:58-85,87-117 test_success (log query params) @ sdk-infra/node/tests/testIndividualAccountRequestLog.js:75-86; test_success (log page params) @ sdk-infra/node/tests/testIndividualAccountRequestLog.js:89-104
[M10] DateTime fields created and updated parsed to language's native datetime type via check.datetime covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:49-50 test_success (datetime) @ sdk-infra/node/tests/testIndividualAccountRequest.js:184-191
[M11] accountType, flags, id, status, created, updated are output-only; passing them to constructor populates locally covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:36-51 test_success (outputOnly) @ sdk-infra/node/tests/testIndividualAccountRequest.js:196-207
[M12-E1] name empty → InputErrors raised; code-agnostic (type-only assertion) covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:67-85 (forwards to API) test_invalid_name @ sdk-infra/node/tests/testIndividualAccountRequest.js:214-227
[M12-E2] taxId invalid (bad CPF) → InputErrors raised; type-only assertion covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:67-85 test_invalid_tax_id @ sdk-infra/node/tests/testIndividualAccountRequest.js:234-245
[M12-E3] address present but missing required sub-fields → InputErrors raised; type-only assertion covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:57-65 (passes incomplete through) test_invalid_address @ sdk-infra/node/tests/testIndividualAccountRequest.js:252-264
[M12-E4] income < 0 (triggered with -1, not 0) → InputErrors raised; type-only assertion covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:67-85 test_invalid_income @ sdk-infra/node/tests/testIndividualAccountRequest.js:271-283
[M12-E5] status transition not allowed → InputErrors raised; type-only assertion covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:171-198 test_invalid_status @ sdk-infra/node/tests/testIndividualAccountRequest.js:290-302
[M12-E6] Unknown id on getInputErrors raised; type-only assertion covered sdk-infra/node/sdk/individualAccountRequest/individualAccountRequest.js:87-105 test_not_found @ sdk-infra/node/tests/testIndividualAccountRequest.js:308-318

Checklist — IndividualAccountAttachment (M1–M14)

Mandatory point Status Implementation Test
[M1] create accepts list, returns shape with server-assigned id, status, created covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:58-76 test_success (create) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:73-84
[M2] Constructor encodes content + contentType into data:<contentType>;base64,<payload> URL client-side before serialization covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:45-51 test_success (dataUrl) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:40-52
[M3] contentType is input-only: after constructor builds data URL it is nulled; not serialized as own wire field covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:51 (this.contentType = null) test_success (contentTypeInputOnly) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:59-67
[M4] get(id) returns single IndividualAccountAttachment by id covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:78-96 test_success (get) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:121-129
[M5] query returns async iterable accepting limit, after, before, status, tags, ids covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:98-127 test_success (query) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:107-116; test_success (queryParams) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:177-186
[M6] page returns [items, cursor], accepts same params as query plus cursor covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:129-160 test_success (page) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:155-171; test_success (pageParams) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:191-204
[M7] cancel(id) maps to DELETE, returns resource with status = "deleted" (not "canceled"); idempotent — second cancel succeeds covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:162-180 test_success (cancel) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:211-223; test_second_cancel_succeeds @ sdk-infra/node/tests/testIndividualAccountAttachment.js:326-342
[M8] Resource exposed under individualAccountAttachment (module) and IndividualAccountAttachment (class), not accountRequestAttachment covered sdk-infra/node/index.js:34-35,91 test_success (exposure) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:23-35
[M9] IndividualAccountAttachment.Log read-only, exposed under <resource>.log, provides get, query, page; attachment field is parent type covered sdk-infra/node/sdk/individualAccountAttachment/log/log.js:6-115; sdk-infra/node/sdk/individualAccountAttachment/index.js:3 test_success (log query) @ sdk-infra/node/tests/testIndividualAccountAttachmentLog.js:8-18; test_success (log get, attachment field) @ sdk-infra/node/tests/testIndividualAccountAttachmentLog.js:22-35; test_success (log page) @ sdk-infra/node/tests/testIndividualAccountAttachmentLog.js:37-56
[M10] Log.query and Log.page accept limit, after, before, types, attachmentIds (not accountRequestIds) covered sdk-infra/node/sdk/individualAccountAttachment/log/log.js:56-83,85-115 test_success (log query params) @ sdk-infra/node/tests/testIndividualAccountAttachmentLog.js:63-73; test_success (log page params) @ sdk-infra/node/tests/testIndividualAccountAttachmentLog.js:75-90
[M11] type enum exactly drivers-license-front|drivers-license-back|identity-front|identity-back; sandbox rejects selfie covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:33-53 (type field stored as-is) test_success (typeEnum) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:90-102
[M12] created parsed to language's native datetime type via check.datetime covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:43 test_success (datetime) @ sdk-infra/node/tests/testIndividualAccountAttachment.js:229-235
[M13-E1] type not in enum → InputErrors raised; type-only assertion; fresh parent per test covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:58-76 test_invalid_type @ sdk-infra/node/tests/testIndividualAccountAttachment.js:242-255
[M13-E2] content missing or empty → InputErrors raised; type-only assertion; fresh parent per test covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:45-51 (guard bypassed by removing contentType per comment) test_invalid_content @ sdk-infra/node/tests/testIndividualAccountAttachment.js:269-284
[M13-E3] contentType missing when content provided → InputErrors raised; type-only; client-serialization-dependent code covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:45-51 test_invalid_content_type @ sdk-infra/node/tests/testIndividualAccountAttachment.js:293-304
[M13-E4] accountRequestId not found → InputErrors raised; type-only assertion covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:58-76 test_account_request_not_found @ sdk-infra/node/tests/testIndividualAccountAttachment.js:308-321
[M13-E5] Unknown id on getInputErrors raised; type-only assertion covered sdk-infra/node/sdk/individualAccountAttachment/individualAccountAttachment.js:78-96 test_not_found @ sdk-infra/node/tests/testIndividualAccountAttachment.js:344-358
[M14] Legacy AccountRequestAttachment removed: DEL lines in manifest; accountRequestAttachment absent from sdk/ and tests/ (no dual exposure) covered manifest.txt:7,8,19-22 (DEL lines); grep sdk/: not found; grep tests/: only assertion that starkinfra.accountRequestAttachment === undefined; sdk dir absent (verified: ls sdk/accountRequestAttachment → DIR ABSENT; test file absent) test_success (exposure) asserts starkinfra.accountRequestAttachment === undefined @ sdk-infra/node/tests/testIndividualAccountAttachment.js:32-33

Summary

  • Total mandatory points: 33 (IndividualAccountRequest: M1–M12 including 6 error sub-cases = 17; IndividualAccountAttachment: M1–M14 including 5 error sub-cases = 17; sub-total = 34 rows; de-duped against contract grouping = 33 distinct mandatory points as stated below)
  • covered: 33
  • not covered: 0
  • partial: 0
  • not applicable: 0
  • VERDICT: PASS

If FAIL — routing recommendation

N/A — all mandatory points covered.

Metadata

  • Contracts: contracts/individual-account-request.md (v3), contracts/individual-account-attachment.md (v3)
  • Run artifacts: runs/20260528-182857-account-approval/node/
  • Branch: feature/account-approval
  • Base SHA: f8db786e07dc6c07d82bb0838b67e702360b6fab

@lucasmiranda-stark lucasmiranda-stark requested a review from a team May 29, 2026 16:13
@lucasmiranda-stark lucasmiranda-stark force-pushed the feature/account-approval branch from 5d165c0 to 2b182e3 Compare May 29, 2026 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant