Skip to content

Individual account approval resources (java)#74

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

Individual account approval resources (java)#74
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 java infra SDK. Generated from contracts individual-account-request.md (v3) and individual-account-attachment.md (v3). Run-type: generate. Run artifacts: runs/20260528-182857-account-approval/java/.

What changed

  • Add IndividualAccountRequest (create/get/query/page/update + read-only .Log) with a structured Address sub-resource (nested object, never flattened).
  • Add IndividualAccountAttachment (create/get/query/page/cancel + read-only .Log); the constructor encodes content+contentType into a data:<contentType>;base64,… URL client-side; contentType is input-only.
  • CHANGELOG entry + per-resource README usage sections.

Test plan

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

Risk & Rollback

  • Risk: new resources, additive only — no changes to existing public types.
  • Rollback: revert this PR; no data migration.

Contract review (Phase 7)

Contract Review

Checklist

IndividualAccountRequest (M1–M12)

Mandatory point Status Implementation Test
[M1] create accepts list of IndividualAccountRequest, returns same shape with server-assigned id, status, accountType, created, updated populated covered IndividualAccountRequest.java:379–411 (create(List<?>)Rest.post) testCreate @ TestIndividualAccountRequest.java:25–42
[M2] address is a structured object (not a string) with required sub-fields street, number, neighborhood, city, state, zipCode; serialized as nested JSON, never flattened covered IndividualAccountRequest.java:476–535 (Address extends SubResource with all 6 sub-fields) testCreateWithObjectAddress @ TestIndividualAccountRequest.java:48–61
[M3] get(id) returns a single IndividualAccountRequest covered IndividualAccountRequest.java:165–183 (get(String id)Rest.getId) testQueryGet @ TestIndividualAccountRequest.java:67–81
[M4] query returns iterable of IndividualAccountRequest, accepts limit, after, before, status, tags, ids covered IndividualAccountRequest.java:205–262 (query(Map, User)Rest.getStream; params documented at lines 197–202) testQueryGet @ TestIndividualAccountRequest.java:67–81 ; testQueryIds @ TestIndividualAccountRequest.java:85–123
[M5] page returns IndividualAccountRequest.Page (items + cursor), accepts same params as query plus cursor covered IndividualAccountRequest.java:264–365 (Page inner class + page(Map, User)Rest.getPage) testPage @ TestIndividualAccountRequest.java:127–154
[M6] update(id, ...) PATCHes request; accepts any subset of name, taxId, address, income, status, tags; replaces (not deep-merges) address covered IndividualAccountRequest.java:432–458 (update(String id, Map patchData, User)Rest.patch; full field list in Javadoc lines 422–431) testUpdate @ TestIndividualAccountRequest.java:161–175 (name patch) ; testUpdateAddress @ TestIndividualAccountRequest.java:179–201 (whole-object address replace)
[M7] status enum exactly approved | created | denied | processing | updated (v1 success/failed/canceled not used) covered IndividualAccountRequest.java:43–50 (field declared public String status; no enum restriction in Java type system; contract-compliant values enforced by API) testStatusEnum @ TestIndividualAccountRequest.java:207–223 (asserts every fetched status is member of {approved, created, denied, processing, updated})
[M8] IndividualAccountRequest.Log is read-only, exposed under <resource>.Log, provides get, query, page; Log.request is IndividualAccountRequest type covered IndividualAccountRequest.java:537–775 (Log extends Resource with get, query, page statics; public IndividualAccountRequest request at line 543) testLogQueryAndGet @ TestIndividualAccountRequest.java:229–248 (asserts log.request.id populated)
[M9] Log.query and Log.page accept limit, after, before, types, accountRequestIds covered IndividualAccountRequest.java:606–618 (Log.query(Map params) with param docs at lines 609–615); IndividualAccountRequest.java:706–709 (Log.page(Map params)) testLogQueryAndGet @ TestIndividualAccountRequest.java:229–248 (uses types); testLogQueryAccountRequestIds @ TestIndividualAccountRequest.java:252–276 (uses accountRequestIds); testLogPage @ TestIndividualAccountRequest.java:280–307
[M10] DateTime fields (created, updated) parsed to language-native type (Java: String, matching existing SDK pattern per serialization.md:44) covered IndividualAccountRequest.java:51–52 (public String created; public String updated;) testDateTimeParsing @ TestIndividualAccountRequest.java:313–328 (asserts both fields non-null)
[M11] accountType, flags, id, status, created, updated are output-only — Map constructor sets them null and rejects them as unknown params covered IndividualAccountRequest.java:130–138 (Map ctor sets status, accountType, flags, created, updated to null without reading from map; unknown-param check at lines 136–138) testOutputOnlyFieldsRejectedByConstructor @ TestIndividualAccountRequest.java:337–354 (passes status+accountType in map, asserts Unknown parameters used in constructor: exception)
[M12] Each error case has a test asserting com.starkcore.error.InputErrors is raised (code-agnostic): invalidName, invalidTaxId, invalidAddress, invalidIncome, invalidStatus, notFound covered IndividualAccountRequest.java:379–411 (all create/update paths forward to API via Rest.post/Rest.patch/Rest.getId) testCreateInvalidName @ TestIndividualAccountRequest.java:360–376 ; testCreateInvalidTaxId @ TestIndividualAccountRequest.java:381–397 ; testCreateInvalidAddress @ TestIndividualAccountRequest.java:401–422 ; testCreateInvalidIncome @ TestIndividualAccountRequest.java:426–443 ; testUpdateInvalidStatus @ TestIndividualAccountRequest.java:447–464 ; testGetNotFound @ TestIndividualAccountRequest.java:468–479

IndividualAccountAttachment (M1–M14)

Mandatory point Status Implementation Test
[M1] create accepts list of IndividualAccountAttachment, returns same shape with server-assigned id, status, created populated covered IndividualAccountAttachment.java:355–387 (create(List<?>)Rest.post) testCreate @ TestIndividualAccountAttachment.java:28–43
[M2] Constructor encodes content (raw bytes) + contentType (MIME) into data:<contentType>;base64,<payload> URL client-side; callers pass raw bytes, not pre-encoded data URLs covered IndividualAccountAttachment.java:109–113 (Map ctor branch: byte[] content + contentType"data:" + contentType + ";base64," + Base64.encode(content)) testConstructorEncodesDataUrl @ TestIndividualAccountAttachment.java:50–62 (asserts content starts with "data:image/png;base64,")
[M3] contentType is input-only: consumed by constructor to build data URL, NOT serialized as its own wire field; passing contentType in a response-shaped Map throws covered IndividualAccountAttachment.java:99–127 (Map ctor: contentType is only consumed in the byte[]-content branch at line 111; it is never assigned to a field; unknown-param check at lines 124–126 rejects stray keys) testContentTypeIsInputOnly @ TestIndividualAccountAttachment.java:69–91 (passes content as String + contentType → asserts exception mentioning contentType)
[M4] get(id) returns a single IndividualAccountAttachment covered IndividualAccountAttachment.java:141–160 (get(String id, User)Rest.getId) testQueryGet @ TestIndividualAccountAttachment.java:96–113
[M5] query returns iterable of IndividualAccountAttachment, accepts limit, after, before, status, tags, ids covered IndividualAccountAttachment.java:181–238 (query(Map, User)Rest.getStream) testQueryGet @ TestIndividualAccountAttachment.java:96–113 ; testQueryIds @ TestIndividualAccountAttachment.java:116–148
[M6] page returns IndividualAccountAttachment.Page (items + cursor), accepts same params as query plus cursor covered IndividualAccountAttachment.java:240–341 (Page inner class + page(Map, User)Rest.getPage) testPage @ TestIndividualAccountAttachment.java:152–180
[M7] cancel(id) maps to DELETE, returns resource with status = deleted; idempotent (second cancel succeeds without error) covered IndividualAccountAttachment.java:401–420 (cancel(String id, User)Rest.delete) testCancel @ TestIndividualAccountAttachment.java:187–195 (asserts status == "deleted") ; testCancelIdempotent @ TestIndividualAccountAttachment.java:417–431 (second cancel asserts status == "deleted", no exception)
[M8] Resource exposed as IndividualAccountAttachment (not accountRequestAttachment) covered IndividualAccountAttachment.java:16 (public final class IndividualAccountAttachment extends Resource) testCreate @ TestIndividualAccountAttachment.java:28 (imports and uses com.starkinfra.IndividualAccountAttachment; file compiles and runs under the new identifier)
[M9] IndividualAccountAttachment.Log is read-only, exposed under <resource>.Log, provides get, query, page; Log.attachment is IndividualAccountAttachment type covered IndividualAccountAttachment.java:422–660 (Log extends Resource with get, query, page statics; public IndividualAccountAttachment attachment at line 428) testLogQueryAndGet @ TestIndividualAccountAttachment.java:202–219 (asserts log.attachment.id populated)
[M10] Log.query and Log.page accept limit, after, before, types, attachmentIds (parent-id filter named attachmentIds, not accountRequestIds) covered IndividualAccountAttachment.java:502–558 (Log.query(Map params) with param docs listing attachmentIds at line 497); IndividualAccountAttachment.java:591–658 (Log.page(Map, User)) testLogQueryAndGet @ TestIndividualAccountAttachment.java:202–219 (uses types); testLogQueryAttachmentIds @ TestIndividualAccountAttachment.java:223–248 (uses attachmentIds); testLogPage @ TestIndividualAccountAttachment.java:251–279
[M11] type enum exactly drivers-license-front | drivers-license-back | identity-front | identity-back; selfie not valid covered IndividualAccountAttachment.java:40 (public String type;; valid values enforced at API level; no selfie in any fixture or docstring's canonical list at line 29) testTypeEnum @ TestIndividualAccountAttachment.java:285–303 (asserts every fetched type is member of 4-value set, no selfie)
[M12] DateTime field (created) parsed to language-native type (Java: String, matching existing SDK pattern) covered IndividualAccountAttachment.java:45 (public String created;) testDateTimeParsing @ TestIndividualAccountAttachment.java:310–323 (asserts created non-null)
[M13] Each error case has a test asserting InputErrors raised (code-agnostic): type invalid, content empty, contentType missing, accountRequestId not found, unknown id covered IndividualAccountAttachment.java:355–387 (create forwards to API via Rest.post); IndividualAccountAttachment.java:141–160 (get forwards via Rest.getId) testCreateInvalidType @ TestIndividualAccountAttachment.java:329–346 ; testCreateInvalidContent @ TestIndividualAccountAttachment.java:350–367 ; testCreateInvalidContentType @ TestIndividualAccountAttachment.java:372–389 ; testCreateAccountRequestNotFound @ TestIndividualAccountAttachment.java:393–411 ; testGetNotFound @ TestIndividualAccountAttachment.java:436–446
[M14] Legacy AccountRequestAttachment removed (no dual exposure): source file deleted, legacy tests deleted not applicable n/a n/a — run-type is generate; no AccountRequestAttachment source ever existed in sdk-infra/java (grep of entire sdk-infra/java/src returned zero source or test files matching AccountRequestAttachment; confirmed in scaffold-plan.md:3–7; manifest has no DEL lines)

Summary

  • Total mandatory points: 26 (IndividualAccountRequest M1–M12 = 12; IndividualAccountAttachment M1–M14 = 14)
  • covered: 25
  • not covered: 0
  • partial: 0
  • not applicable: 1
  • VERDICT: PASS

If FAIL — routing recommendation

N/A — PASS.

Metadata

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

@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 ff08e06 to f44a152 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