{"id":"e0ec8673-32e7-4577-b7d3-700129331102","shortId":"p5G8Ay","kind":"skill","title":"integration-e2e-testing","tagline":"Integration and E2E test design principles, ROI calculation, test skeleton specification, and review criteria. Use when designing integration tests, E2E tests, or reviewing test quality.","description":"# Integration and E2E Testing Principles\n\n## References\n\n**E2E test design**: See [references/e2e-design.md](references/e2e-design.md) for UI Spec-driven E2E test candidate selection and browser test architecture. The reference uses Playwright as the default browser harness; substitute the project's standard when different.\n\n## Test Type Definition and Limits\n\n| Test Type | Purpose | Scope | External Deps | Limit per Feature | Implementation Timing |\n|-----------|---------|-------|---------------|-------------------|----------------------|\n| Integration | Verify component interactions in-process | Partial system integration (in-process modules; for UI components, the framework's in-process renderer e.g., RTL+MSW for React/TS) | Mocked or in-process | MAX 3 | Created alongside implementation |\n| fixture-e2e | Verify UI behavior in a browser with deterministic fixtures | Full UI flow with mocked backend / fixture-driven state | Mocked / fixture only — no live services | MAX 3 | Created alongside the UI feature |\n| service-integration-e2e | Verify critical user journeys against a running local stack | Full system across services | Live local services or stubs | MAX 1-2 | Executed only in the final phase |\n\n**Lane selection (E2E only)**:\n- Default lane for user-facing UI journeys is **fixture-e2e** — it runs a real browser against deterministic fixtures, catches the bugs that unit/integration tests miss (button no-op, state never updates, navigation breaks), and runs in CI without infrastructure setup\n- Add **service-integration-e2e** only when the journey's correctness depends on real cross-service behavior (data persistence, transactional consistency, external service contracts) that cannot be faked safely\n\nThe two E2E lanes are budgeted independently — having a fixture-e2e for a journey does not consume the service-integration-e2e budget and vice versa.\n\n## Behavior-First Principle\n\n### Include (High ROI)\n- Business logic correctness (calculations, state transitions, data transformations)\n- Data integrity and persistence behavior\n- User-visible functionality completeness\n- Error handling behavior (what user sees/experiences)\n\n### Redirect to Other Test Types\n- External service connections → Verify via contract/interface tests\n- Performance metrics → Verify via dedicated load testing\n- Implementation details → Verify observable behavior instead\n- UI layout specifics → Verify information availability instead\n\n**Principle**: Test = User-observable behavior verifiable in isolated CI environment\n\n## ROI Calculation\n\nROI is used to **rank candidates within the same test type** (integration candidates against each other, E2E candidates against each other). Cross-type comparison is unnecessary because integration and E2E budgets are selected independently.\n\n```\nROI Score = Business Value × User Frequency + Legal Requirement × 10 + Defect Detection\n              (range: 0–120)\n```\n\nHigher ROI Score = higher priority within its test type. No normalization or capping is applied — the raw score is used directly for ranking. Deduplication is a separate step that removes candidates entirely; it does not modify scores.\n\n### ROI Thresholds by Lane\n\nThe two E2E lanes have very different ownership costs and use independent thresholds.\n\n| Lane | ROI threshold | Rationale |\n|------|---------------|-----------|\n| fixture-e2e | ROI ≥ 20 (beyond reserved slot) | Cost is comparable to integration tests once the harness exists; the floor avoids filling MAX 3 with low-signal tests when fewer would suffice |\n| service-integration-e2e | ROI > 50 (beyond reserved slot) | Creation, execution, and maintenance cost is 3-10× higher than integration; reserve for journeys whose value cannot be proven any other way |\n\nReserved slot rules (see Multi-Step User Journey Definition below) apply per lane and override the threshold (the reserved candidate is emitted regardless of its ROI score). Below-floor candidates beyond the reserved slot are not emitted, leaving budget intentionally unfilled rather than padding with low-value tests.\n\n### ROI Calculation Examples\n\n| Scenario | BV | Freq | Legal | Defect | ROI Score | Test Type | Selection Outcome |\n|----------|----|------|-------|--------|-----------|-----------|-------------------|\n| Core checkout UI flow | 10 | 9 | true | 9 | 109 | fixture-e2e | Selected (reserved slot: user-facing multi-step journey, browser-level verification with fixtures) |\n| Core checkout against live payment service | 10 | 9 | true | 9 | 109 | service-integration-e2e | Selected (real-service correctness above ROI threshold) |\n| Dismiss button updates UI state | 6 | 7 | false | 8 | 50 | fixture-e2e | Selected (rank 2 of 3 fixture-e2e budget) |\n| Payment error message display | 5 | 4 | false | 7 | 27 | fixture-e2e | Selected (rank 3 of 3 fixture-e2e budget) |\n| Optional filter toggle | 3 | 4 | false | 2 | 14 | fixture-e2e | Not selected (rank 4, budget full) |\n| Payment retry against real provider | 8 | 3 | false | 7 | 31 | service-integration-e2e | Below ROI threshold (31 < 50), not selected |\n| DB persistence check | 8 | 8 | false | 8 | 72 | Integration | Selected (rank 1 of 3) |\n| Pure data transformation | 5 | 3 | false | 4 | 19 | Integration | Selected (rank 2 of 3) |\n\n## Multi-Step User Journey Definition\n\nA feature qualifies as containing a **multi-step user journey** when ALL of the following are true:\n\n1. **2+ distinct interaction boundaries** are traversed in sequence to complete a user goal. What counts as a boundary depends on the system type:\n   - Web: distinct routes/pages\n   - Mobile native: distinct screens/views\n   - CLI: distinct command invocations or interactive prompts\n   - API: distinct API calls forming a transaction (e.g., create → confirm → finalize)\n2. **State carries across steps** — data produced or actions taken in one step affect what the next step accepts or displays\n3. **The journey has a completion point** — a final state the user or caller reaches (e.g., confirmation page, saved record, API success response, completed workflow)\n\n### User-Facing vs Service-Internal Journeys\n\nMulti-step journeys are classified for reserved-slot eligibility:\n\n| Classification | Condition | Reserved Slot Eligibility | Example |\n|---|---|---|---|\n| **User-facing** | A human user directly triggers and observes the steps (via UI, CLI, or direct API interaction) | Eligible — defaults to **fixture-e2e** reserved slot. Add a service-integration-e2e reserved slot only when the journey's correctness depends on real cross-service behavior | Web checkout flow, CLI setup wizard, mobile onboarding |\n| **Service-internal** | Steps are triggered by backend services without direct user interaction | Not eligible for reserved slot — use integration tests. Service-integration-e2e through normal ROI > 50 path is still valid when full-system verification is warranted | Async job pipeline, service-to-service saga, scheduled batch processing |\n\nThis classification applies only to the reserved-slot rule and the E2E Gap Check. Other selection follows lane-specific ROI rules above.\n\nUse this definition when evaluating E2E test candidates and E2E gap detection.\n\n## Test Skeleton Specification\n\n### Required Comment Patterns\n\nEach test MUST include the following annotations:\n\n```\nAC: [Original acceptance criteria text]\nBehavior: [Trigger] → [Process] → [Observable Result]\n@category: core-functionality | integration | edge-case | fixture-e2e | service-integration-e2e\n@lane: integration | fixture-e2e | service-integration-e2e\n@dependency: none | [component names] | full-system\n@complexity: low | medium | high\nROI: [score]\n```\n\n**`@lane` selection rule**:\n- `integration` — Component interaction in-process, no browser (e.g., RTL+MSW for React/TS, in-process module/handler integration in any language)\n- `fixture-e2e` — Browser-level UI verification with mocked backend / fixture-driven state\n- `service-integration-e2e` — Browser-level or end-to-end verification against running local services or stubs\n\nUse the project's comment syntax to wrap these annotations (e.g., `//` for C-family, `#` for Python/Ruby/Shell).\n\n### Verification Items (Optional)\n\nWhen verification points need explicit enumeration:\n```\nVerification items:\n- [Item 1]\n- [Item 2]\n```\n\n## EARS Format Mapping\n\n| EARS Keyword | Test Type | Generation Approach |\n|--------------|-----------|---------------------|\n| **When** | Event-driven | Trigger event → verify outcome |\n| **While** | State condition | Setup state → verify behavior |\n| **If-then** | Branch coverage | Both condition paths verified |\n| (none) | Basic functionality | Direct invocation → verify result |\n\n## Test File Naming Convention\n\n- Integration tests: `*.int.test.*` or `*.integration.test.*`\n- fixture-e2e tests: `*.fixture.e2e.test.*` (or organize under `tests/e2e/fixture/`)\n- service-integration-e2e tests: `*.service.e2e.test.*` (or organize under `tests/e2e/service/`)\n\nThe test runner or framework in the project determines the appropriate file extension. Repos that already use a single `*.e2e.test.*` convention may keep it as long as each file declares `@lane:` in its header — the lane annotation is the source of truth for routing and budget accounting.\n\n## Review Criteria\n\n### Skeleton and Implementation Consistency\n\n| Check | Failure Condition |\n|-------|-------------------|\n| Behavior Verification | No assertion for \"observable result\" in skeleton |\n| Verification Item Coverage | Listed items not all covered by assertions |\n| Mock Boundary | Internal components mocked in integration test |\n\n### Implementation Quality\n\n| Check | Failure Condition |\n|-------|-------------------|\n| AAA Structure | Arrange/Act/Assert separation unclear |\n| Independence | State sharing between tests, order dependency |\n| Reproducibility | Date/random dependency, varying results |\n| Readability | Test name doesn't match verification content |\n\n## Quality Standards\n\n### Required\n- Each test verifies one behavior\n- Clear AAA (Arrange-Act-Assert) structure\n- No test interdependencies\n- Deterministic execution","tags":["integration","e2e","testing","claude","code","workflows","shinpr","agent-skills","agentic-ai","ai-agents","automation","claude-code"],"capabilities":["skill","source-shinpr","skill-integration-e2e-testing","topic-agent-skills","topic-agentic-ai","topic-ai-agents","topic-automation","topic-claude-code","topic-claude-code-plugin","topic-code-quality","topic-developer-tools","topic-development-workflow","topic-llm-orchestration","topic-productivity","topic-prompt-engineering"],"categories":["claude-code-workflows"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/shinpr/claude-code-workflows/integration-e2e-testing","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add shinpr/claude-code-workflows","source_repo":"https://github.com/shinpr/claude-code-workflows","install_from":"skills.sh"}},"qualityScore":"0.613","qualityRationale":"deterministic score 0.61 from registry signals: · indexed on github topic:agent-skills · 327 github stars · SKILL.md body (10,073 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-02T18:53:51.809Z","embedding":null,"createdAt":"2026-04-18T22:03:04.735Z","updatedAt":"2026-05-02T18:53:51.809Z","lastSeenAt":"2026-05-02T18:53:51.809Z","tsv":"'-10':528 '-2':185 '0':419 '1':184,751,792,1202 '10':415,612,642 '109':616,646 '120':420 '14':709 '19':761 '2':674,708,765,793,841,1204 '20':483 '27':689 '3':122,155,502,527,676,695,697,705,725,753,758,767,862 '31':728,736 '4':686,706,716,760 '5':685,757 '50':517,668,737,996 '6':664 '7':665,688,727 '72':747 '8':667,724,743,744,746 '9':613,615,643,645 'aaa':1361,1395 'ac':1068 'accept':859,1070 'account':1319 'across':176,844 'act':1398 'action':849 'add':239,939 'affect':854 'alongsid':124,157 'alreadi':1288 'annot':1067,1182,1309 'api':830,832,882,929 'appli':435,554,1021 'approach':1213 'appropri':1283 'architectur':54 'arrang':1397 'arrange-act-assert':1396 'arrange/act/assert':1363 'assert':1332,1347,1399 'async':1008 'avail':357 'avoid':499 'backend':143,975,1149 'basic':1239 'batch':1017 'behavior':131,256,297,315,323,350,364,959,1073,1228,1329,1393 'behavior-first':296 'below-floor':571 'beyond':484,518,575 'boundari':796,810,1349 'branch':1232 'break':231 'browser':52,62,134,212,631,1125,1143,1159 'browser-level':630,1142,1158 'budget':274,292,403,583,680,701,717,1318 'bug':218 'busi':303,409 'button':223,660 'bv':598 'c':1186 'c-famili':1185 'calcul':12,306,371,595 'call':833 'caller':875 'candid':49,377,384,389,451,563,574,1050 'cannot':265,537 'cap':433 'carri':843 'case':1085 'catch':216 'categori':1078 'check':742,1033,1326,1358 'checkout':609,637,961 'ci':235,368 'classif':906,1020 'classifi':900 'clear':1394 'cli':823,926,963 'command':825 'comment':1059,1177 'compar':489 'comparison':396 'complet':320,802,867,885 'complex':1109 'compon':89,103,1104,1119,1351 'condit':907,1224,1235,1328,1360 'confirm':839,878 'connect':334 'consist':260,1325 'consum':286 'contain':778 'content':1385 'contract':263 'contract/interface':337 'convent':1248,1293 'core':608,636,1080 'core-funct':1079 'correct':249,305,655,952 'cost':470,487,525 'count':807 'cover':1345 'coverag':1233,1340 'creat':123,156,838 'creation':521 'criteria':18,1071,1321 'critic':166 'cross':254,394,957 'cross-servic':253,956 'cross-typ':393 'data':257,309,311,755,846 'date/random':1374 'db':740 'declar':1302 'dedic':343 'dedupl':444 'default':61,196,932 'defect':416,601 'definit':73,552,773,1045 'dep':81 'depend':250,811,953,1102,1372,1375 'design':9,21,38 'detail':347 'detect':417,1054 'determin':1281 'determinist':136,214,1404 'differ':70,468 'direct':441,918,928,978,1241 'dismiss':659 'display':684,861 'distinct':794,817,821,824,831 'doesn':1381 'driven':46,146,1152,1217 'e.g':111,837,877,1126,1183 'e2e':3,7,24,32,36,47,128,164,194,207,243,271,280,291,388,402,464,481,515,619,650,671,679,692,700,712,732,936,944,992,1031,1048,1052,1088,1092,1097,1101,1141,1157,1256,1266 'e2e.test':1292 'ear':1205,1208 'edg':1084 'edge-cas':1083 'elig':905,910,931,982 'emit':565,581 'end':1163,1165 'end-to-end':1162 'entir':452 'enumer':1198 'environ':369 'error':321,682 'evalu':1047 'event':1216,1219 'event-driven':1215 'exampl':596,911 'execut':186,522,1405 'exist':496 'explicit':1197 'extens':1285 'extern':80,261,332 'face':201,625,889,914 'failur':1327,1359 'fake':267 'fals':666,687,707,726,745,759 'famili':1187 'featur':84,160,775 'fewer':509 'file':1246,1284,1301 'fill':500 'filter':703 'final':190,840,870 'first':298 'fixtur':127,137,145,149,206,215,279,480,618,635,670,678,691,699,711,935,1087,1096,1140,1151,1255 'fixture-driven':144,1150 'fixture-e2e':126,205,278,479,617,669,677,690,698,710,934,1086,1095,1139,1254 'fixture.e2e.test':1258 'floor':498,573 'flow':140,611,962 'follow':789,1036,1066 'form':834 'format':1206 'framework':105,1277 'freq':599 'frequenc':412 'full':138,174,718,1003,1107 'full-system':1002,1106 'function':319,1081,1240 'gap':1032,1053 'generat':1212 'goal':805 'handl':322 'har':63,495 'header':1306 'high':301,1112 'higher':421,424,529 'human':916 'if-then':1229 'implement':85,125,346,1324,1356 'in-process':91,97,107,118,1121,1131 'includ':300,1064 'independ':275,406,473,1366 'inform':356 'infrastructur':237 'instead':351,358 'int.test':1251 'integr':2,5,22,30,87,96,163,242,290,312,383,400,491,514,531,649,731,748,762,943,987,991,1082,1091,1094,1100,1118,1135,1156,1249,1265,1354 'integration-e2e-testing':1 'integration.test':1253 'intent':584 'interact':90,795,828,930,980,1120 'interdepend':1403 'intern':893,970,1350 'invoc':826,1242 'isol':367 'item':1191,1200,1201,1203,1339,1342 'job':1009 'journey':168,203,247,283,534,551,629,772,784,864,894,898,950 'keep':1295 'keyword':1209 'lane':192,197,272,461,465,475,556,1038,1093,1115,1303,1308 'lane-specif':1037 'languag':1138 'layout':353 'leav':582 'legal':413,600 'level':632,1144,1160 'limit':75,82 'list':1341 'live':152,178,639 'load':344 'local':172,179,1169 'logic':304 'long':1298 'low':505,591,1110 'low-sign':504 'low-valu':590 'mainten':524 'map':1207 'match':1383 'max':121,154,183,501 'may':1294 'medium':1111 'messag':683 'metric':340 'miss':222 'mobil':819,966 'mock':116,142,148,1148,1348,1352 'modifi':456 'modul':100 'module/handler':1134 'msw':113,1128 'multi':548,627,769,781,896 'multi-step':547,626,768,780,895 'must':1063 'name':1105,1247,1380 'nativ':820 'navig':230 'need':1196 'never':228 'next':857 'no-op':224 'none':1103,1238 'normal':431,994 'observ':349,363,921,1076,1334 'onboard':967 'one':852,1392 'op':226 'option':702,1192 'order':1371 'organ':1260,1270 'origin':1069 'outcom':607,1221 'overrid':558 'ownership':469 'pad':588 'page':879 'partial':94 'path':997,1236 'pattern':1060 'payment':640,681,719 'per':83,555 'perform':339 'persist':258,314,741 'phase':191 'pipelin':1010 'playwright':58 'point':868,1195 'principl':10,34,299,359 'prioriti':425 'process':93,99,109,120,1018,1075,1123,1133 'produc':847 'project':66,1175,1280 'prompt':829 'proven':539 'provid':723 'pure':754 'purpos':78 'python/ruby/shell':1189 'qualifi':776 'qualiti':29,1357,1386 'rang':418 'rank':376,443,673,694,715,750,764 'rather':586 'rational':478 'raw':437 'reach':876 'react/ts':115,1130 'readabl':1378 'real':211,252,653,722,955 'real-servic':652 'record':881 'redirect':327 'refer':35,56 'references/e2e-design.md':40,41 'regardless':566 'remov':450 'render':110 'repo':1286 'reproduc':1373 'requir':414,1058,1388 'reserv':485,519,532,543,562,577,621,903,908,937,945,984,1026 'reserved-slot':902,1025 'respons':884 'result':1077,1244,1335,1377 'retri':720 'review':17,27,1320 'roi':11,302,370,372,407,422,458,476,482,516,569,594,602,657,734,995,1040,1113 'rout':1316 'routes/pages':818 'rtl':112,1127 'rule':545,1028,1041,1117 'run':171,209,233,1168 'runner':1275 'safe':268 'saga':1015 'save':880 'scenario':597 'schedul':1016 'scope':79 'score':408,423,438,457,570,603,1114 'screens/views':822 'see':39,546 'sees/experiences':326 'select':50,193,405,606,620,651,672,693,714,739,749,763,1035,1116 'separ':447,1364 'sequenc':800 'servic':153,162,177,180,241,255,262,289,333,513,641,648,654,730,892,942,958,969,976,990,1012,1014,1090,1099,1155,1170,1264 'service-integration-e2e':161,240,288,512,647,729,941,989,1089,1098,1154,1263 'service-intern':891,968 'service-to-servic':1011 'service.e2e.test':1268 'setup':238,964,1225 'share':1368 'signal':506 'singl':1291 'skeleton':14,1056,1322,1337 'skill' 'skill-integration-e2e-testing' 'slot':486,520,544,578,622,904,909,938,946,985,1027 'sourc':1312 'source-shinpr' 'spec':45 'spec-driven':44 'specif':15,354,1039,1057 'stack':173 'standard':68,1387 'state':147,227,307,663,842,871,1153,1223,1226,1367 'step':448,549,628,770,782,845,853,858,897,923,971 'still':999 'structur':1362,1400 'stub':182,1172 'substitut':64 'success':883 'suffic':511 'syntax':1178 'system':95,175,814,1004,1108 'taken':850 'test':4,8,13,23,25,28,33,37,48,53,71,76,221,330,338,345,360,381,428,492,507,593,604,988,1049,1055,1062,1210,1245,1250,1257,1267,1274,1355,1370,1379,1390,1402 'tests/e2e/fixture':1262 'tests/e2e/service':1272 'text':1072 'threshold':459,474,477,560,658,735 'time':86 'toggl':704 'topic-agent-skills' 'topic-agentic-ai' 'topic-ai-agents' 'topic-automation' 'topic-claude-code' 'topic-claude-code-plugin' 'topic-code-quality' 'topic-developer-tools' 'topic-development-workflow' 'topic-llm-orchestration' 'topic-productivity' 'topic-prompt-engineering' 'transact':259,836 'transform':310,756 'transit':308 'travers':798 'trigger':919,973,1074,1218 'true':614,644,791 'truth':1314 'two':270,463 'type':72,77,331,382,395,429,605,815,1211 'ui':43,102,130,139,159,202,352,610,662,925,1145 'unclear':1365 'unfil':585 'unit/integration':220 'unnecessari':398 'updat':229,661 'use':19,57,374,440,472,986,1043,1173,1289 'user':167,200,317,325,362,411,550,624,771,783,804,873,888,913,917,979 'user-fac':199,623,887,912 'user-observ':361 'user-vis':316 'valid':1000 'valu':410,536,592 'vari':1376 'verif':633,1005,1146,1166,1190,1194,1199,1330,1338,1384 'verifi':88,129,165,335,341,348,355,365,1220,1227,1237,1243,1391 'versa':295 'via':336,342,924 'vice':294 'visibl':318 'vs':890 'warrant':1007 'way':542 'web':816,960 'whose':535 'within':378,426 'without':236,977 'wizard':965 'workflow':886 'would':510 'wrap':1180","prices":[{"id":"e90473c8-a651-441c-a8ea-4ba32a30878c","listingId":"e0ec8673-32e7-4577-b7d3-700129331102","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"shinpr","category":"claude-code-workflows","install_from":"skills.sh"},"createdAt":"2026-04-18T22:03:04.735Z"}],"sources":[{"listingId":"e0ec8673-32e7-4577-b7d3-700129331102","source":"github","sourceId":"shinpr/claude-code-workflows/integration-e2e-testing","sourceUrl":"https://github.com/shinpr/claude-code-workflows/tree/main/skills/integration-e2e-testing","isPrimary":false,"firstSeenAt":"2026-04-18T22:03:04.735Z","lastSeenAt":"2026-05-02T18:53:51.809Z"}],"details":{"listingId":"e0ec8673-32e7-4577-b7d3-700129331102","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"shinpr","slug":"integration-e2e-testing","github":{"repo":"shinpr/claude-code-workflows","stars":327,"topics":["agent-skills","agentic-ai","ai-agents","automation","claude-code","claude-code-plugin","code-quality","developer-tools","development-workflow","llm-orchestration","productivity","prompt-engineering","skills"],"license":"mit","html_url":"https://github.com/shinpr/claude-code-workflows","pushed_at":"2026-05-02T15:39:17Z","description":"Production-ready development workflows for Claude Code, powered by specialized AI agents.","skill_md_sha":"801459c16f497d9507b2e797ff35a25b3b317a03","skill_md_path":"skills/integration-e2e-testing/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/shinpr/claude-code-workflows/tree/main/skills/integration-e2e-testing"},"layout":"multi","source":"github","category":"claude-code-workflows","frontmatter":{"name":"integration-e2e-testing","description":"Integration and E2E test design principles, ROI calculation, test skeleton specification, and review criteria. Use when designing integration tests, E2E tests, or reviewing test quality."},"skills_sh_url":"https://skills.sh/shinpr/claude-code-workflows/integration-e2e-testing"},"updatedAt":"2026-05-02T18:53:51.809Z"}}