create-qpq-app 0.1.26 → 0.1.27

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.
Files changed (261) hide show
  1. package/package.json +2 -2
  2. package/template/apps/qpqjs/services/test/models/src/SmokeProbeRecord.ts +3 -0
  3. package/template/apps/qpqjs/services/test/service/src/infrastructure.ts +0 -6
  4. package/template/apps/qpqjs/services/test/service/src/smoke/config/defineSmoke.ts +8 -264
  5. package/template/apps/qpqjs/services/test/service/src/smoke/harness/assert/index.ts +2 -0
  6. package/template/apps/qpqjs/services/test/service/src/smoke/harness/config/defineSmokeHarness.ts +115 -0
  7. package/template/apps/qpqjs/services/test/service/src/smoke/harness/config/index.ts +1 -0
  8. package/template/apps/qpqjs/services/test/service/src/smoke/{constants → harness/constants}/index.ts +0 -2
  9. package/template/apps/qpqjs/services/test/service/src/smoke/harness/index.ts +10 -0
  10. package/template/apps/qpqjs/services/test/service/src/smoke/{logic → harness/logic}/smokeRun/askExecuteSmokeTest.ts +3 -3
  11. package/template/apps/qpqjs/services/test/service/src/smoke/{logic → harness/logic}/smokeRun/askStartSmokeRun.ts +5 -4
  12. package/template/apps/qpqjs/services/test/service/src/smoke/{logic → harness/logic}/smokeRun/index.ts +1 -0
  13. package/template/apps/qpqjs/services/test/service/src/smoke/harness/logic/smokeRun/listSmokeTests.ts +6 -0
  14. package/template/apps/qpqjs/services/test/service/src/smoke/{models → harness/models}/SmokeTestRequestedQueueEvent.ts +1 -1
  15. package/template/apps/qpqjs/services/test/service/src/smoke/harness/models/index.ts +2 -0
  16. package/template/apps/qpqjs/services/test/service/src/smoke/harness/queue/index.ts +1 -0
  17. package/template/apps/qpqjs/services/test/service/src/smoke/harness/types/SmokeSuite.ts +13 -0
  18. package/template/apps/qpqjs/services/test/service/src/smoke/harness/types/index.ts +2 -0
  19. package/template/apps/qpqjs/services/test/service/src/smoke/index.ts +2 -12
  20. package/template/apps/qpqjs/services/test/service/src/smoke/suites/emailReceive/config/defineEmailReceiveSmoke.ts +20 -0
  21. package/template/apps/qpqjs/services/test/service/src/smoke/suites/emailReceive/config/index.ts +1 -0
  22. package/template/apps/qpqjs/services/test/service/src/smoke/suites/emailReceive/constants/SMOKE_EMAIL_RECEIVER.ts +2 -0
  23. package/template/apps/qpqjs/services/test/service/src/smoke/suites/emailReceive/constants/index.ts +1 -0
  24. package/template/apps/qpqjs/services/test/service/src/smoke/suites/emailReceive/emailReceiveSmokeSuite.ts +15 -0
  25. package/template/apps/qpqjs/services/test/service/src/smoke/{email → suites/emailReceive/entry/email}/index.ts +0 -1
  26. package/template/apps/qpqjs/services/test/service/src/smoke/{email → suites/emailReceive/entry/email}/onSmokeEmailReceived.ts +1 -1
  27. package/template/apps/qpqjs/services/test/service/src/smoke/suites/emailReceive/entry/index.ts +1 -0
  28. package/template/apps/qpqjs/services/test/service/src/smoke/suites/emailReceive/index.ts +5 -0
  29. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/emailReceive → suites/emailReceive/logic}/askRunEmailReceiveTest.ts +3 -3
  30. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/emailReceive → suites/emailReceive/logic}/index.ts +1 -0
  31. package/template/apps/qpqjs/services/test/service/src/smoke/suites/encryptedResources/config/defineEncryptedResourcesSmoke.ts +29 -0
  32. package/template/apps/qpqjs/services/test/service/src/smoke/suites/encryptedResources/config/index.ts +1 -0
  33. package/template/apps/qpqjs/services/test/service/src/smoke/suites/encryptedResources/constants/SMOKE_CRYPTO_KEY.ts +5 -0
  34. package/template/apps/qpqjs/services/test/service/src/smoke/suites/encryptedResources/constants/SMOKE_ENCRYPTED_PROBE_DRIVE.ts +2 -0
  35. package/template/apps/qpqjs/services/test/service/src/smoke/suites/encryptedResources/constants/SMOKE_ENCRYPTED_PROBE_STORE.ts +2 -0
  36. package/template/apps/qpqjs/services/test/service/src/smoke/suites/encryptedResources/constants/index.ts +3 -0
  37. package/template/apps/qpqjs/services/test/service/src/smoke/suites/encryptedResources/encryptedResourcesSmokeSuite.ts +9 -0
  38. package/template/apps/qpqjs/services/test/service/src/smoke/suites/encryptedResources/index.ts +4 -0
  39. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/encryptedResources → suites/encryptedResources/logic}/askRunEncryptedResourcesTest.ts +3 -5
  40. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/config/defineEventBusSmoke.ts +21 -0
  41. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/config/index.ts +1 -0
  42. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/constants/SMOKE_PROBE_EVENT_BUS.ts +2 -0
  43. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/constants/SMOKE_PROBE_EVENT_QUEUE.ts +2 -0
  44. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/constants/SMOKE_PROBE_EVENT_TYPE.ts +2 -0
  45. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/constants/index.ts +3 -0
  46. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/entry/index.ts +1 -0
  47. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/entry/queue/index.ts +1 -0
  48. package/template/apps/qpqjs/services/test/service/src/smoke/{queue → suites/eventBus/entry/queue}/onSmokeProbeEvent.ts +1 -1
  49. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/eventBusSmokeSuite.ts +9 -0
  50. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/index.ts +6 -0
  51. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/eventBus → suites/eventBus/logic}/askRunEventBusTest.ts +4 -6
  52. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventBus/models/index.ts +1 -0
  53. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventDoc/config/defineEventDocSmoke.ts +44 -0
  54. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventDoc/config/index.ts +1 -0
  55. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventDoc/constants/index.ts +1 -0
  56. package/template/apps/qpqjs/services/test/service/src/smoke/{constants → suites/eventDoc/constants}/smokeEventDoc.ts +1 -1
  57. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventDoc/entry/index.ts +1 -0
  58. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventDoc/entry/queue/index.ts +1 -0
  59. package/template/apps/qpqjs/services/test/service/src/smoke/{queue → suites/eventDoc/entry/queue}/onSmokeEventDocAppend.ts +3 -3
  60. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventDoc/eventDocSmokeSuite.ts +19 -0
  61. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventDoc/index.ts +7 -0
  62. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/eventDoc → suites/eventDoc/logic}/askAssertContiguousEventIds.ts +1 -1
  63. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/eventDoc → suites/eventDoc/logic}/askAssertSmokeProbeDocState.ts +2 -2
  64. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/eventDoc → suites/eventDoc/logic}/askAwaitSmokeEventDocLog.ts +1 -1
  65. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/eventDoc → suites/eventDoc/logic}/askRunEventDocConcurrentAppendTest.ts +5 -5
  66. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/eventDoc → suites/eventDoc/logic}/askRunEventDocInterleavedBatchAppendTest.ts +4 -4
  67. package/template/apps/qpqjs/services/test/service/src/smoke/suites/eventDoc/models/index.ts +2 -0
  68. package/template/apps/qpqjs/services/test/service/src/smoke/{tests → suites}/index.ts +4 -5
  69. package/template/apps/qpqjs/services/test/service/src/smoke/suites/keyValueStore/index.ts +2 -0
  70. package/template/apps/qpqjs/services/test/service/src/smoke/suites/keyValueStore/keyValueStoreSmokeSuite.ts +14 -0
  71. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/crossService → suites/keyValueStore/logic}/askRunCrossServiceKeyValueStoreTest.ts +1 -1
  72. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/keyValueStore → suites/keyValueStore/logic}/askRunKeyValueStoreTest.ts +1 -1
  73. package/template/apps/qpqjs/services/test/service/src/smoke/suites/keyValueStore/logic/index.ts +2 -0
  74. package/template/apps/qpqjs/services/test/service/src/smoke/suites/keyValueStoreStream/config/defineKeyValueStoreStreamSmoke.ts +30 -0
  75. package/template/apps/qpqjs/services/test/service/src/smoke/suites/keyValueStoreStream/config/index.ts +1 -0
  76. package/template/apps/qpqjs/services/test/service/src/smoke/suites/keyValueStoreStream/constants/SMOKE_STREAM_PROBE_STORE.ts +2 -0
  77. package/template/apps/qpqjs/services/test/service/src/smoke/suites/keyValueStoreStream/constants/index.ts +1 -0
  78. package/template/apps/qpqjs/services/test/service/src/smoke/suites/keyValueStoreStream/entry/index.ts +1 -0
  79. package/template/apps/qpqjs/services/test/service/src/smoke/{kvsStream → suites/keyValueStoreStream/entry/kvsStream}/index.ts +0 -1
  80. package/template/apps/qpqjs/services/test/service/src/smoke/{kvsStream → suites/keyValueStoreStream/entry/kvsStream}/onSmokeStreamRecord.ts +6 -4
  81. package/template/apps/qpqjs/services/test/service/src/smoke/suites/keyValueStoreStream/index.ts +5 -0
  82. package/template/apps/qpqjs/services/test/service/src/smoke/suites/keyValueStoreStream/keyValueStoreStreamSmokeSuite.ts +11 -0
  83. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/keyValueStoreStream → suites/keyValueStoreStream/logic}/askRunKeyValueStoreStreamTest.ts +15 -6
  84. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/keyValueStoreStream → suites/keyValueStoreStream/logic}/index.ts +1 -0
  85. package/template/apps/qpqjs/services/test/service/src/smoke/suites/noop/index.ts +2 -0
  86. package/template/apps/qpqjs/services/test/service/src/smoke/suites/noop/noopSmokeSuite.ts +7 -0
  87. package/template/apps/qpqjs/services/test/service/src/smoke/suites/openApi/config/defineOpenApiSmoke.ts +13 -0
  88. package/template/apps/qpqjs/services/test/service/src/smoke/suites/openApi/config/index.ts +1 -0
  89. package/template/apps/qpqjs/services/test/service/src/smoke/suites/openApi/index.ts +4 -0
  90. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/openApi → suites/openApi/logic}/askRunEchoRoundTripTest.ts +1 -1
  91. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/openApi → suites/openApi/logic}/askRunOpenApiDocumentTest.ts +1 -1
  92. package/template/apps/qpqjs/services/test/service/src/smoke/suites/openApi/openApiSmokeSuite.ts +13 -0
  93. package/template/apps/qpqjs/services/test/service/src/smoke/suites/parameter/config/defineParameterSmoke.ts +11 -0
  94. package/template/apps/qpqjs/services/test/service/src/smoke/suites/parameter/config/index.ts +1 -0
  95. package/template/apps/qpqjs/services/test/service/src/smoke/suites/parameter/constants/SMOKE_PROBE_PARAMETER.ts +2 -0
  96. package/template/apps/qpqjs/services/test/service/src/smoke/suites/parameter/constants/SMOKE_PROBE_PARAMETER_VALUE.ts +2 -0
  97. package/template/apps/qpqjs/services/test/service/src/smoke/suites/parameter/constants/index.ts +2 -0
  98. package/template/apps/qpqjs/services/test/service/src/smoke/suites/parameter/index.ts +4 -0
  99. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/parameter → suites/parameter/logic}/askRunParameterTest.ts +3 -5
  100. package/template/apps/qpqjs/services/test/service/src/smoke/suites/parameter/parameterSmokeSuite.ts +9 -0
  101. package/template/apps/qpqjs/services/test/service/src/{tick/config/defineTick.ts → smoke/suites/schedule/config/defineScheduleSmoke.ts} +1 -1
  102. package/template/apps/qpqjs/services/test/service/src/smoke/suites/schedule/config/index.ts +1 -0
  103. package/template/apps/qpqjs/services/test/service/src/smoke/suites/schedule/entry/index.ts +2 -0
  104. package/template/apps/qpqjs/services/test/service/src/smoke/suites/schedule/index.ts +6 -0
  105. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/schedule → suites/schedule/logic}/askRunScheduleTest.ts +4 -4
  106. package/template/apps/qpqjs/services/test/service/src/smoke/suites/schedule/scheduleSmokeSuite.ts +9 -0
  107. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedKeyValueStore/config/defineScopedKeyValueStoreSmoke.ts +19 -0
  108. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedKeyValueStore/config/index.ts +1 -0
  109. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedKeyValueStore/constants/SMOKE_SCOPED_PROBE_STORE.ts +2 -0
  110. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedKeyValueStore/constants/index.ts +1 -0
  111. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedKeyValueStore/index.ts +4 -0
  112. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedKeyValueStore/logic/askRunScopedKeyValueStoreTest.ts +256 -0
  113. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedKeyValueStore/scopedKeyValueStoreSmokeSuite.ts +11 -0
  114. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedStorageDrive/config/defineScopedStorageDriveSmoke.ts +12 -0
  115. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedStorageDrive/config/index.ts +1 -0
  116. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedStorageDrive/constants/SMOKE_SCOPED_PROBE_DRIVE.ts +2 -0
  117. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedStorageDrive/constants/index.ts +1 -0
  118. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedStorageDrive/index.ts +4 -0
  119. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/scopedStorageDrive → suites/scopedStorageDrive/logic}/askRunScopedStorageDriveTest.ts +2 -2
  120. package/template/apps/qpqjs/services/test/service/src/smoke/suites/scopedStorageDrive/scopedStorageDriveSmokeSuite.ts +9 -0
  121. package/template/apps/qpqjs/services/test/service/src/smoke/suites/secret/config/defineSecretSmoke.ts +8 -0
  122. package/template/apps/qpqjs/services/test/service/src/smoke/suites/secret/config/index.ts +1 -0
  123. package/template/apps/qpqjs/services/test/service/src/smoke/suites/secret/constants/SMOKE_PROBE_SECRET.ts +2 -0
  124. package/template/apps/qpqjs/services/test/service/src/smoke/suites/secret/constants/index.ts +1 -0
  125. package/template/apps/qpqjs/services/test/service/src/smoke/suites/secret/index.ts +4 -0
  126. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/secret → suites/secret/logic}/askRunSecretTest.ts +2 -2
  127. package/template/apps/qpqjs/services/test/service/src/smoke/suites/secret/secretSmokeSuite.ts +9 -0
  128. package/template/apps/qpqjs/services/test/service/src/smoke/suites/signingKey/config/defineSigningKeySmoke.ts +12 -0
  129. package/template/apps/qpqjs/services/test/service/src/smoke/suites/signingKey/config/index.ts +1 -0
  130. package/template/apps/qpqjs/services/test/service/src/smoke/suites/signingKey/index.ts +3 -0
  131. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/crossService → suites/signingKey/logic}/askRunCrossServiceSigningKeyTest.ts +1 -1
  132. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/signingKey → suites/signingKey/logic}/askRunSigningKeyTest.ts +1 -1
  133. package/template/apps/qpqjs/services/test/service/src/smoke/suites/signingKey/logic/index.ts +2 -0
  134. package/template/apps/qpqjs/services/test/service/src/smoke/suites/signingKey/signingKeySmokeSuite.ts +16 -0
  135. package/template/apps/qpqjs/services/test/service/src/smoke/suites/smokeSuites.ts +46 -0
  136. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDrive/index.ts +2 -0
  137. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/crossService → suites/storageDrive/logic}/askRunCrossServiceStorageDriveTest.ts +1 -1
  138. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/storageDrive → suites/storageDrive/logic}/askRunStorageDriveTest.ts +1 -1
  139. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDrive/logic/index.ts +2 -0
  140. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDrive/storageDriveSmokeSuite.ts +14 -0
  141. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDriveEvent/config/defineStorageDriveEventSmoke.ts +27 -0
  142. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDriveEvent/config/index.ts +1 -0
  143. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDriveEvent/constants/SMOKE_FILE_EVENT_DRIVE.ts +2 -0
  144. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDriveEvent/constants/SMOKE_SCOPED_FILE_EVENT_DRIVE.ts +2 -0
  145. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDriveEvent/constants/index.ts +2 -0
  146. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDriveEvent/entry/index.ts +1 -0
  147. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDriveEvent/entry/storageDrive/index.ts +1 -0
  148. package/template/apps/qpqjs/services/test/service/src/smoke/{storageDrive → suites/storageDriveEvent/entry/storageDrive}/onSmokeFileEvent.ts +1 -1
  149. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDriveEvent/index.ts +5 -0
  150. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/storageDriveEvent → suites/storageDriveEvent/logic}/askRunStorageDriveEventTest.ts +7 -9
  151. package/template/apps/qpqjs/services/test/service/src/smoke/{tests/storageDriveEvent → suites/storageDriveEvent/logic}/index.ts +1 -0
  152. package/template/apps/qpqjs/services/test/service/src/smoke/suites/storageDriveEvent/storageDriveEventSmokeSuite.ts +9 -0
  153. package/template/apps/qpqjs/services/testa/models/src/CrossServiceProbePayload.ts +1 -1
  154. package/template/apps/qpqjs/services/testa/service/src/infrastructure.ts +2 -2
  155. package/template/apps/qpqjs/services/testa/service/src/smoke/config/defineSmokeProbes.ts +16 -0
  156. package/template/apps/qpqjs/services/testa/service/src/smoke/config/index.ts +1 -0
  157. package/template/apps/qpqjs/services/{test/service/src/tick → testa/service/src/smoke}/index.ts +1 -0
  158. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/index.ts +3 -0
  159. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/keyValueStore/config/defineKeyValueStoreSmokeProbe.ts +33 -0
  160. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/keyValueStore/config/index.ts +1 -0
  161. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/keyValueStore/entry/serviceFunction/index.ts +1 -0
  162. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/keyValueStore/logic/index.ts +1 -0
  163. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/signingKey/config/defineSigningKeySmokeProbe.ts +28 -0
  164. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/signingKey/config/index.ts +1 -0
  165. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/signingKey/entry/index.ts +1 -0
  166. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/signingKey/entry/serviceFunction/index.ts +1 -0
  167. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/signingKey/index.ts +3 -0
  168. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/signingKey/logic/index.ts +1 -0
  169. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/storageDrive/config/defineStorageDriveSmokeProbe.ts +31 -0
  170. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/storageDrive/config/index.ts +1 -0
  171. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/storageDrive/entry/index.ts +1 -0
  172. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/storageDrive/entry/serviceFunction/index.ts +1 -0
  173. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/storageDrive/index.ts +3 -0
  174. package/template/apps/qpqjs/services/testa/service/src/smoke/suites/storageDrive/logic/index.ts +1 -0
  175. package/template/docusaurus/docs/actions/core/key-value-store/ask-key-value-store-delete.md +1 -1
  176. package/template/docusaurus/docs/actions/core/key-value-store/ask-key-value-store-get-all.md +1 -1
  177. package/template/docusaurus/docs/actions/core/key-value-store/ask-key-value-store-get.md +1 -1
  178. package/template/docusaurus/docs/actions/core/key-value-store/ask-key-value-store-query.md +3 -1
  179. package/template/docusaurus/docs/actions/core/key-value-store/ask-key-value-store-scan.md +1 -1
  180. package/template/docusaurus/docs/actions/core/key-value-store/ask-key-value-store-update.md +1 -1
  181. package/template/docusaurus/docs/actions/core/key-value-store/ask-key-value-store-upsert.md +1 -1
  182. package/template/docusaurus/docs/config/core/key-value-store.md +12 -2
  183. package/template/docusaurus/docs/config/features/event-doc.md +22 -1
  184. package/template/apps/qpqjs/services/test/service/src/echo/config/defineEcho.ts +0 -9
  185. package/template/apps/qpqjs/services/test/service/src/smoke/constants/smokeProbe.ts +0 -39
  186. package/template/apps/qpqjs/services/test/service/src/smoke/models/index.ts +0 -5
  187. package/template/apps/qpqjs/services/test/service/src/smoke/queue/index.ts +0 -3
  188. package/template/apps/qpqjs/services/test/service/src/smoke/storageDrive/index.ts +0 -4
  189. package/template/apps/qpqjs/services/test/service/src/smoke/tests/crossService/index.ts +0 -3
  190. package/template/apps/qpqjs/services/test/service/src/smoke/tests/keyValueStore/index.ts +0 -1
  191. package/template/apps/qpqjs/services/test/service/src/smoke/tests/scopedKeyValueStore/askRunScopedKeyValueStoreTest.ts +0 -102
  192. package/template/apps/qpqjs/services/test/service/src/smoke/tests/signingKey/index.ts +0 -1
  193. package/template/apps/qpqjs/services/test/service/src/smoke/tests/smokeTestRegistry.ts +0 -66
  194. package/template/apps/qpqjs/services/test/service/src/smoke/tests/storageDrive/index.ts +0 -1
  195. package/template/apps/qpqjs/services/test/service/src/tick/config/index.ts +0 -1
  196. package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/config/defineCrossServiceProbe.ts +0 -68
  197. package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/config/index.ts +0 -1
  198. package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/entry/serviceFunction/index.ts +0 -3
  199. package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/logic/index.ts +0 -3
  200. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests → harness/assert}/askSmokeAssert.ts +0 -0
  201. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests → harness/assert}/askSmokePollForMarker.ts +0 -0
  202. /package/template/apps/qpqjs/services/test/service/src/smoke/{constants → harness/constants}/SMOKE_RUNS_STORE.ts +0 -0
  203. /package/template/apps/qpqjs/services/test/service/src/smoke/{constants → harness/constants}/githubOidc.ts +0 -0
  204. /package/template/apps/qpqjs/services/test/service/src/smoke/{constants → harness/constants}/smokeRunQueue.ts +0 -0
  205. /package/template/apps/qpqjs/services/test/service/src/smoke/{controller → harness/controller}/askGetSmokeRun.ts +0 -0
  206. /package/template/apps/qpqjs/services/test/service/src/smoke/{controller → harness/controller}/askRunSmokeTests.ts +0 -0
  207. /package/template/apps/qpqjs/services/test/service/src/smoke/{controller → harness/controller}/index.ts +0 -0
  208. /package/template/apps/qpqjs/services/test/service/src/smoke/{data → harness/data}/askGetSmokeRunById.ts +0 -0
  209. /package/template/apps/qpqjs/services/test/service/src/smoke/{data → harness/data}/askRecordSmokeTestResult.ts +0 -0
  210. /package/template/apps/qpqjs/services/test/service/src/smoke/{data → harness/data}/askSaveSmokeRun.ts +0 -0
  211. /package/template/apps/qpqjs/services/test/service/src/smoke/{data → harness/data}/askSetSmokeRunOutcome.ts +0 -0
  212. /package/template/apps/qpqjs/services/test/service/src/smoke/{data → harness/data}/index.ts +0 -0
  213. /package/template/apps/qpqjs/services/test/service/src/smoke/{logic → harness/logic}/github/index.ts +0 -0
  214. /package/template/apps/qpqjs/services/test/service/src/smoke/{logic → harness/logic}/github/verifyGithubOidcToken.ts +0 -0
  215. /package/template/apps/qpqjs/services/test/service/src/smoke/{logic → harness/logic}/index.ts +0 -0
  216. /package/template/apps/qpqjs/services/test/service/src/smoke/{logic → harness/logic}/smokeRun/askFindSmokeRun.ts +0 -0
  217. /package/template/apps/qpqjs/services/test/service/src/smoke/{logic → harness/logic}/smokeRun/summarizeSmokeRun.ts +0 -0
  218. /package/template/apps/qpqjs/services/test/service/src/smoke/{models → harness/models}/GithubOidcClaims.ts +0 -0
  219. /package/template/apps/qpqjs/services/test/service/src/smoke/{processors → harness/processors}/github/getGithubOidcAuthProcessors.ts +0 -0
  220. /package/template/apps/qpqjs/services/test/service/src/smoke/{processors → harness/processors}/github/index.ts +0 -0
  221. /package/template/apps/qpqjs/services/test/service/src/smoke/{processors → harness/processors}/index.ts +0 -0
  222. /package/template/apps/qpqjs/services/test/service/src/smoke/{queue → harness/queue}/onSmokeTestRequested.ts +0 -0
  223. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests → harness/types}/SmokeTestDefinition.ts +0 -0
  224. /package/template/apps/qpqjs/services/test/service/src/smoke/{email → suites/emailReceive/logic}/smokeEmailMarkerId.ts +0 -0
  225. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/encryptedResources → suites/encryptedResources/logic}/index.ts +0 -0
  226. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/eventBus → suites/eventBus/logic}/index.ts +0 -0
  227. /package/template/apps/qpqjs/services/test/service/src/smoke/{models → suites/eventBus/models}/SmokeProbeEventQueueEvent.ts +0 -0
  228. /package/template/apps/qpqjs/services/test/service/src/smoke/{eventDoc → suites/eventDoc/definition}/index.ts +0 -0
  229. /package/template/apps/qpqjs/services/test/service/src/smoke/{eventDoc → suites/eventDoc/definition}/smokeProbeDocDefinition.ts +0 -0
  230. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/eventDoc → suites/eventDoc/logic}/index.ts +0 -0
  231. /package/template/apps/qpqjs/services/test/service/src/smoke/{models → suites/eventDoc/models}/SmokeEventDocAppendQueueEvent.ts +0 -0
  232. /package/template/apps/qpqjs/services/test/service/src/smoke/{models → suites/eventDoc/models}/SmokeEventDocMark.ts +0 -0
  233. /package/template/apps/qpqjs/services/test/service/src/smoke/{kvsStream → suites/keyValueStoreStream/logic}/smokeStreamMarkerId.ts +0 -0
  234. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/noop → suites/noop/logic}/askRunNoopTest.ts +0 -0
  235. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/noop → suites/noop/logic}/index.ts +0 -0
  236. /package/template/apps/qpqjs/services/test/service/src/{echo → smoke/suites/openApi}/controller/echo.ts +0 -0
  237. /package/template/apps/qpqjs/services/test/service/src/{echo → smoke/suites/openApi}/controller/index.ts +0 -0
  238. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/openApi → suites/openApi/logic}/index.ts +0 -0
  239. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/parameter → suites/parameter/logic}/index.ts +0 -0
  240. /package/template/apps/qpqjs/services/test/service/src/{tick → smoke/suites/schedule}/constants/index.ts +0 -0
  241. /package/template/apps/qpqjs/services/test/service/src/{tick → smoke/suites/schedule}/constants/scheduleTickName.ts +0 -0
  242. /package/template/apps/qpqjs/services/test/service/src/{tick → smoke/suites/schedule}/constants/scheduleTickStore.ts +0 -0
  243. /package/template/apps/qpqjs/services/test/service/src/{tick → smoke/suites/schedule}/entry/kvsStream/index.ts +0 -0
  244. /package/template/apps/qpqjs/services/test/service/src/{tick → smoke/suites/schedule}/entry/kvsStream/onScheduleTickStream.ts +0 -0
  245. /package/template/apps/qpqjs/services/test/service/src/{tick → smoke/suites/schedule}/entry/schedule/index.ts +0 -0
  246. /package/template/apps/qpqjs/services/test/service/src/{tick → smoke/suites/schedule}/entry/schedule/onTick.ts +0 -0
  247. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/schedule → suites/schedule/logic}/index.ts +0 -0
  248. /package/template/apps/qpqjs/services/test/service/src/{tick → smoke/suites/schedule}/models/ScheduleTickRecord.ts +0 -0
  249. /package/template/apps/qpqjs/services/test/service/src/{tick → smoke/suites/schedule}/models/index.ts +0 -0
  250. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/scopedKeyValueStore → suites/scopedKeyValueStore/logic}/index.ts +0 -0
  251. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/scopedStorageDrive → suites/scopedStorageDrive/logic}/index.ts +0 -0
  252. /package/template/apps/qpqjs/services/test/service/src/smoke/{tests/secret → suites/secret/logic}/index.ts +0 -0
  253. /package/template/apps/qpqjs/services/test/service/src/smoke/{storageDrive → suites/storageDriveEvent/logic}/smokeFileEventMarkerId.ts +0 -0
  254. /package/template/apps/qpqjs/services/testa/service/src/{crossServiceProbe → smoke/suites/keyValueStore}/entry/index.ts +0 -0
  255. /package/template/apps/qpqjs/services/testa/service/src/{crossServiceProbe → smoke/suites/keyValueStore}/entry/serviceFunction/smokeCrossServiceKeyValueStoreProbe.ts +0 -0
  256. /package/template/apps/qpqjs/services/testa/service/src/{crossServiceProbe → smoke/suites/keyValueStore}/index.ts +0 -0
  257. /package/template/apps/qpqjs/services/testa/service/src/{crossServiceProbe → smoke/suites/keyValueStore}/logic/askProbeForeignKeyValueStore.ts +0 -0
  258. /package/template/apps/qpqjs/services/testa/service/src/{crossServiceProbe → smoke/suites/signingKey}/entry/serviceFunction/smokeCrossServiceSigningKeyProbe.ts +0 -0
  259. /package/template/apps/qpqjs/services/testa/service/src/{crossServiceProbe → smoke/suites/signingKey}/logic/askProbeForeignSigningKey.ts +0 -0
  260. /package/template/apps/qpqjs/services/testa/service/src/{crossServiceProbe → smoke/suites/storageDrive}/entry/serviceFunction/smokeCrossServiceStorageDriveProbe.ts +0 -0
  261. /package/template/apps/qpqjs/services/testa/service/src/{crossServiceProbe → smoke/suites/storageDrive}/logic/askProbeForeignStorageDrive.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-qpq-app",
3
- "version": "0.1.26",
3
+ "version": "0.1.27",
4
4
  "description": "Scaffold a new quidproquo app: npx create-qpq-app my-app",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -55,7 +55,7 @@
55
55
  },
56
56
  "devDependencies": {
57
57
  "@types/node": "^22.13.13",
58
- "quidproquo-tsconfig": "0.1.26"
58
+ "quidproquo-tsconfig": "0.1.27"
59
59
  },
60
60
  "bin": {
61
61
  "create-qpq-app": "./lib/commonjs/bin/createQpqApp.js"
@@ -12,6 +12,9 @@ export type SmokeProbeRecord = {
12
12
  scope?: string;
13
13
  ambientScope?: string;
14
14
  path?: string;
15
+ // Set by the kvs stream handler: the attribute names on the record's image,
16
+ // so a test can prove no backend bookkeeping attribute reaches a handler.
17
+ imageAttributes?: string[];
15
18
  // Set by the email handler: the provider's spf/dkim verdicts on the message.
16
19
  authentication?: string;
17
20
  };
@@ -3,9 +3,7 @@ import { defineDevServerOptions } from 'quidproquo-dev-server/config';
3
3
  import { QpqjsServiceEnum } from '@qpqjs/constants';
4
4
  import { defineQpqjsService } from '@qpqjs/service-utils';
5
5
 
6
- import { defineEcho } from './echo/config/defineEcho';
7
6
  import { defineSmoke } from './smoke/config/defineSmoke';
8
- import { defineTick } from './tick/config/defineTick';
9
7
 
10
8
  export default [
11
9
  defineDevServerOptions({ port: 3083 }),
@@ -18,8 +16,4 @@ export default [
18
16
  ),
19
17
 
20
18
  defineSmoke(),
21
-
22
- defineEcho(),
23
-
24
- defineTick(),
25
19
  ];
@@ -1,266 +1,10 @@
1
- import {
2
- defineCryptoKey,
3
- defineEmailReceiver,
4
- defineEmailSender,
5
- defineEventBus,
6
- defineKeyValueStore,
7
- defineParameter,
8
- defineQueue,
9
- defineRoute,
10
- defineSecret,
11
- defineSigningKey,
12
- defineStorageDrive,
13
- QPQConfig,
14
- QpqFunctionRuntime,
15
- } from 'quidproquo';
16
- import { defineEventDoc } from 'quidproquo-features';
1
+ import { QPQConfig } from 'quidproquo';
17
2
 
18
- import { z } from 'zod/v4';
19
- import {
20
- SMOKE_PROBE_DRIVE,
21
- SMOKE_PROBE_SIGNING_KEY,
22
- SMOKE_PROBE_STORE,
23
- } from '@qpqjs/constants';
24
- import {
25
- SmokeProbeRecord,
26
- SmokeRunStartedSchema,
27
- SmokeRunWithSummarySchema,
28
- } from '@qpqjs/test-models';
3
+ import { defineSmokeHarness } from '../harness/config/defineSmokeHarness';
4
+ import { smokeSuites } from '../suites/smokeSuites';
29
5
 
30
- import { SMOKE_RUNS_STORE } from '../constants/SMOKE_RUNS_STORE';
31
- import {
32
- SMOKE_EVENT_DOC_APPEND_MESSAGE_TYPE,
33
- SMOKE_EVENT_DOC_APPEND_QUEUE,
34
- SMOKE_EVENT_DOC_BASE_PATH,
35
- } from '../constants/smokeEventDoc';
36
- import {
37
- SMOKE_CRYPTO_KEY,
38
- SMOKE_EMAIL_RECEIVER,
39
- SMOKE_ENCRYPTED_PROBE_DRIVE,
40
- SMOKE_ENCRYPTED_PROBE_STORE,
41
- SMOKE_FILE_EVENT_DRIVE,
42
- SMOKE_PROBE_EVENT_BUS,
43
- SMOKE_PROBE_EVENT_QUEUE,
44
- SMOKE_PROBE_EVENT_TYPE,
45
- SMOKE_PROBE_PARAMETER,
46
- SMOKE_PROBE_PARAMETER_VALUE,
47
- SMOKE_PROBE_SECRET,
48
- SMOKE_SCOPED_PROBE_DRIVE,
49
- SMOKE_SCOPED_PROBE_STORE,
50
- SMOKE_STREAM_PROBE_STORE,
51
- } from '../constants/smokeProbe';
52
- import {
53
- SMOKE_RUN_QUEUE,
54
- SMOKE_TEST_REQUESTED_MESSAGE_TYPE,
55
- } from '../constants/smokeRunQueue';
56
- import { smokeProbeDocDefinition } from '../eventDoc/smokeProbeDocDefinition';
57
-
58
- // Everything the smoke feature needs: the run store, the queue runs execute
59
- // on, and the two routes. Runtimes are located relative to this file, so the
60
- // module can move as a unit.
61
- //
62
- // The routes look public (no user directory, no api keys) but carry a
63
- // per-runtime action processor override that swaps the route auth decode for
64
- // the GitHub OIDC validator - so ONLY a GitHub Actions run of our repo,
65
- // holding an OIDC token with the qpq-smoke audience and matching pinned
66
- // claims, gets past the preamble. Everything else 401s, tokenless included.
67
- export const defineSmoke = (): QPQConfig => {
68
- const githubOidcAuth: QpqFunctionRuntime[] = [
69
- {
70
- basePath: __dirname,
71
- relativePath: '../processors/github/getGithubOidcAuthProcessors',
72
- functionName: 'getGithubOidcAuthProcessors',
73
- },
74
- ];
75
-
76
- const onSmokeFileEvent: QpqFunctionRuntime = {
77
- basePath: __dirname,
78
- relativePath: '../storageDrive/onSmokeFileEvent',
79
- functionName: 'onSmokeFileEvent',
80
- };
81
-
82
- return [
83
- // One record per run, keyed by runId; the queue workers each write their
84
- // own test's entry as it completes and the GET route polls it.
85
- defineKeyValueStore(SMOKE_RUNS_STORE, 'runId'),
86
-
87
- // One message per test per run. Not FIFO and no concurrency cap, so the
88
- // tests of a run fan out and execute in parallel.
89
- defineQueue(SMOKE_RUN_QUEUE, {
90
- [SMOKE_TEST_REQUESTED_MESSAGE_TYPE]: {
91
- basePath: __dirname,
92
- relativePath: '../queue/onSmokeTestRequested',
93
- functionName: 'onSmokeTestRequested',
94
- },
95
- }),
96
-
97
- // Throwaway probe resources, one per kind of owned resource the tag-based
98
- // IAM grants cover. The store's `category` index is what the KVS test
99
- // queries through, proving the `table/*/index/*` half of the grant.
100
- defineKeyValueStore<SmokeProbeRecord>(SMOKE_PROBE_STORE, 'probeId', [], {
101
- indexes: ['category'],
102
- }),
103
- defineParameter(SMOKE_PROBE_PARAMETER, {
104
- value: SMOKE_PROBE_PARAMETER_VALUE,
105
- }),
106
- defineSecret(SMOKE_PROBE_SECRET),
107
- defineStorageDrive(SMOKE_PROBE_DRIVE),
108
- // An owned RSA signing key: kms:Sign + kms:GetPublicKey through the
109
- // alias-conditioned grant. testa declares the same key foreign (see
110
- // defineCrossServiceProbe) for the cross-service verify test.
111
- defineSigningKey(SMOKE_PROBE_SIGNING_KEY),
112
-
113
- // Scoped probe resources: the scope gate in both directions (a scoped
114
- // resource refuses an unscoped call, an unscoped one refuses a scope) and
115
- // partition isolation between two scopes.
116
- defineKeyValueStore<SmokeProbeRecord>(
117
- SMOKE_SCOPED_PROBE_STORE,
118
- 'probeId',
119
- [],
120
- { indexes: ['category'], scoped: true }
121
- ),
122
- defineStorageDrive(SMOKE_SCOPED_PROBE_DRIVE, {
123
- scoped: true,
124
- onEvent: { create: onSmokeFileEvent, delete: onSmokeFileEvent },
125
- }),
126
-
127
- // File event test path: a write or delete on either drive fires the
128
- // handler, which writes a marker into the probe store; the test polls for
129
- // it. The scoped drive's events must arrive with the scope split off.
130
- defineStorageDrive(SMOKE_FILE_EVENT_DRIVE, {
131
- onEvent: { create: onSmokeFileEvent, delete: onSmokeFileEvent },
132
- }),
133
-
134
- // Kvs stream test path: a change on this scoped store streams to the
135
- // handler, which writes a marker into the probe store; the test polls for
136
- // it. The record must carry the scope as its own field with a raw key.
137
- defineKeyValueStore<SmokeProbeRecord>(
138
- SMOKE_STREAM_PROBE_STORE,
139
- 'probeId',
140
- [],
141
- {
142
- scoped: true,
143
- onStream: {
144
- runtime: {
145
- basePath: __dirname,
146
- relativePath: '../kvsStream/onSmokeStreamRecord',
147
- functionName: 'onSmokeStreamRecord',
148
- },
149
- },
150
- }
151
- ),
152
-
153
- // Encrypted probe resources: a drive and a store encrypted with an owned
154
- // crypto key, so the test proves the role's KMS grant covers data at rest.
155
- defineCryptoKey(SMOKE_CRYPTO_KEY),
156
- defineKeyValueStore<SmokeProbeRecord>(
157
- SMOKE_ENCRYPTED_PROBE_STORE,
158
- 'probeId',
159
- [],
160
- { cryptoKeyName: SMOKE_CRYPTO_KEY }
161
- ),
162
- defineStorageDrive(SMOKE_ENCRYPTED_PROBE_DRIVE, {
163
- cryptoKeyName: SMOKE_CRYPTO_KEY,
164
- }),
165
-
166
- // Inbound email test path: the test sends to its own receiving domain, the
167
- // receiver hands the parsed message to onSmokeEmailReceived, which writes a
168
- // marker into the probe store, and the test polls for it. The sender is what
169
- // lets the test send; the receiving domain is a verified identity, so the
170
- // SES sandbox allows it.
171
- defineEmailSender(),
172
- defineEmailReceiver(SMOKE_EMAIL_RECEIVER, {
173
- onEmail: {
174
- basePath: __dirname,
175
- relativePath: '../email/onSmokeEmailReceived',
176
- functionName: 'onSmokeEmailReceived',
177
- },
178
- }),
179
-
180
- // Event bus test path: publish to the bus, the subscribed queue's entry
181
- // writes a marker into the probe store, the test polls for it.
182
- defineEventBus(SMOKE_PROBE_EVENT_BUS),
183
- defineQueue(
184
- SMOKE_PROBE_EVENT_QUEUE,
185
- {
186
- [SMOKE_PROBE_EVENT_TYPE]: {
187
- basePath: __dirname,
188
- relativePath: '../queue/onSmokeProbeEvent',
189
- functionName: 'onSmokeProbeEvent',
190
- },
191
- },
192
- { eventBusSubscriptions: [SMOKE_PROBE_EVENT_BUS] }
193
- ),
194
-
195
- // The event-doc probe collection: a full registered collection (stores, stream
196
- // projector, dynamic functions, routes) so the smoke tests exercise event docs the
197
- // way a real service does. NOTE the routes mount with no auth - the test service
198
- // has no user directory - so the collection is world-writable; it holds nothing
199
- // but throwaway probe docs. The queue fans a test's writers out one invocation
200
- // each, so their appends race across lambdas.
201
- defineEventDoc(
202
- smokeProbeDocDefinition,
203
- {
204
- basePath: __dirname,
205
- relativePath: '../eventDoc/smokeProbeDocDefinition',
206
- functionName: 'smokeProbeDocDefinition',
207
- },
208
- { basePath: SMOKE_EVENT_DOC_BASE_PATH }
209
- ),
210
- // A writer that loses the slot race past the append retry cap fails its message; a
211
- // quick redelivery lets it land instead of vanishing, as a production queue should.
212
- defineQueue(
213
- SMOKE_EVENT_DOC_APPEND_QUEUE,
214
- {
215
- [SMOKE_EVENT_DOC_APPEND_MESSAGE_TYPE]: {
216
- basePath: __dirname,
217
- relativePath: '../queue/onSmokeEventDocAppend',
218
- functionName: 'onSmokeEventDocAppend',
219
- },
220
- },
221
- { maxTries: 3, ttRetryInSeconds: 10 }
222
- ),
223
-
224
- // The zod models double as the routes' published contract, flattened to
225
- // JSON Schema here for the OpenAPI document at /v1/docs.
226
- defineRoute(
227
- 'POST',
228
- '/smoke/run',
229
- {
230
- basePath: __dirname,
231
- relativePath: '../controller/askRunSmokeTests',
232
- functionName: 'askRunSmokeTests',
233
- actionProcessors: githubOidcAuth,
234
- },
235
- {
236
- schema: {
237
- summary: 'Start a smoke run',
238
- description:
239
- 'Queues every registered smoke test and returns the run id to poll. Requires a GitHub Actions OIDC token for this repo.',
240
- tags: ['smoke'],
241
- responseJsonSchema: z.toJSONSchema(SmokeRunStartedSchema),
242
- },
243
- }
244
- ),
245
-
246
- defineRoute(
247
- 'GET',
248
- '/smoke/run/{runId}',
249
- {
250
- basePath: __dirname,
251
- relativePath: '../controller/askGetSmokeRun',
252
- functionName: 'askGetSmokeRun',
253
- actionProcessors: githubOidcAuth,
254
- },
255
- {
256
- schema: {
257
- summary: 'Get a smoke run',
258
- description:
259
- 'The stored run plus pass/fail counts. Poll until status leaves running.',
260
- tags: ['smoke'],
261
- responseJsonSchema: z.toJSONSchema(SmokeRunWithSummarySchema),
262
- },
263
- }
264
- ),
265
- ];
266
- };
6
+ /** The whole smoke feature: the harness plus the resources of every registered suite. */
7
+ export const defineSmoke = (): QPQConfig => [
8
+ defineSmokeHarness(),
9
+ smokeSuites.map((suite) => suite.defineConfig?.() ?? []),
10
+ ];
@@ -0,0 +1,2 @@
1
+ export * from './askSmokeAssert';
2
+ export * from './askSmokePollForMarker';
@@ -0,0 +1,115 @@
1
+ import {
2
+ defineKeyValueStore,
3
+ defineQueue,
4
+ defineRoute,
5
+ defineStorageDrive,
6
+ QPQConfig,
7
+ QpqFunctionRuntime,
8
+ } from 'quidproquo';
9
+
10
+ import { z } from 'zod/v4';
11
+ import { SMOKE_PROBE_DRIVE, SMOKE_PROBE_STORE } from '@qpqjs/constants';
12
+ import {
13
+ SmokeProbeRecord,
14
+ SmokeRunStartedSchema,
15
+ SmokeRunWithSummarySchema,
16
+ } from '@qpqjs/test-models';
17
+
18
+ import { SMOKE_RUNS_STORE } from '../constants/SMOKE_RUNS_STORE';
19
+ import {
20
+ SMOKE_RUN_QUEUE,
21
+ SMOKE_TEST_REQUESTED_MESSAGE_TYPE,
22
+ } from '../constants/smokeRunQueue';
23
+
24
+ /**
25
+ * The part of the smoke feature every suite relies on: the run store, the
26
+ * queue runs execute on, the shared probe store and drive, and the two
27
+ * routes. Knows nothing about individual suites; defineSmoke adds theirs
28
+ * alongside.
29
+ *
30
+ * The routes look public (no user directory, no api keys) but carry a
31
+ * per-runtime action processor override that swaps the route auth decode for
32
+ * the GitHub OIDC validator, so ONLY a GitHub Actions run of our repo holding
33
+ * an OIDC token with the qpq-smoke audience and matching pinned claims gets
34
+ * past the preamble. Everything else 401s, tokenless included.
35
+ */
36
+ export const defineSmokeHarness = (): QPQConfig => {
37
+ const githubOidcAuth: QpqFunctionRuntime[] = [
38
+ {
39
+ basePath: __dirname,
40
+ relativePath: '../processors/github/getGithubOidcAuthProcessors',
41
+ functionName: 'getGithubOidcAuthProcessors',
42
+ },
43
+ ];
44
+
45
+ return [
46
+ // One record per run, keyed by runId; the queue workers each write their
47
+ // own test's entry as it completes and the GET route polls it.
48
+ defineKeyValueStore(SMOKE_RUNS_STORE, 'runId'),
49
+
50
+ // One message per test per run. Not FIFO and no concurrency cap, so the
51
+ // tests of a run fan out and execute in parallel.
52
+ defineQueue(SMOKE_RUN_QUEUE, {
53
+ [SMOKE_TEST_REQUESTED_MESSAGE_TYPE]: {
54
+ basePath: __dirname,
55
+ relativePath: '../queue/onSmokeTestRequested',
56
+ functionName: 'onSmokeTestRequested',
57
+ },
58
+ }),
59
+
60
+ // Every async suite's handler writes its marker here for
61
+ // askSmokePollForMarker. The keyValueStore suite queries its `category`
62
+ // index, proving the `table/*/index/*` half of the tag-conditioned grant,
63
+ // and testa reaches it cross-service.
64
+ defineKeyValueStore<SmokeProbeRecord>(SMOKE_PROBE_STORE, 'probeId', [], {
65
+ indexes: ['category'],
66
+ }),
67
+
68
+ // The unscoped probe drive: the storageDrive suite's subject, testa's
69
+ // cross-service target, and the drive the scopedStorageDrive suite proves
70
+ // refuses a scope.
71
+ defineStorageDrive(SMOKE_PROBE_DRIVE),
72
+
73
+ // The zod models double as the routes' published contract, flattened to
74
+ // JSON Schema here for the OpenAPI document at /v1/docs.
75
+ defineRoute(
76
+ 'POST',
77
+ '/smoke/run',
78
+ {
79
+ basePath: __dirname,
80
+ relativePath: '../controller/askRunSmokeTests',
81
+ functionName: 'askRunSmokeTests',
82
+ actionProcessors: githubOidcAuth,
83
+ },
84
+ {
85
+ schema: {
86
+ summary: 'Start a smoke run',
87
+ description:
88
+ 'Queues every registered smoke test and returns the run id to poll. Requires a GitHub Actions OIDC token for this repo.',
89
+ tags: ['smoke'],
90
+ responseJsonSchema: z.toJSONSchema(SmokeRunStartedSchema),
91
+ },
92
+ }
93
+ ),
94
+
95
+ defineRoute(
96
+ 'GET',
97
+ '/smoke/run/{runId}',
98
+ {
99
+ basePath: __dirname,
100
+ relativePath: '../controller/askGetSmokeRun',
101
+ functionName: 'askGetSmokeRun',
102
+ actionProcessors: githubOidcAuth,
103
+ },
104
+ {
105
+ schema: {
106
+ summary: 'Get a smoke run',
107
+ description:
108
+ 'The stored run plus pass/fail counts. Poll until status leaves running.',
109
+ tags: ['smoke'],
110
+ responseJsonSchema: z.toJSONSchema(SmokeRunWithSummarySchema),
111
+ },
112
+ }
113
+ ),
114
+ ];
115
+ };
@@ -0,0 +1 @@
1
+ export * from './defineSmokeHarness';
@@ -1,5 +1,3 @@
1
1
  export * from './githubOidc';
2
2
  export * from './SMOKE_RUNS_STORE';
3
- export * from './smokeEventDoc';
4
- export * from './smokeProbe';
5
3
  export * from './smokeRunQueue';
@@ -0,0 +1,10 @@
1
+ export * from './assert';
2
+ export * from './config';
3
+ export * from './constants';
4
+ export * from './controller';
5
+ export * from './data';
6
+ export * from './logic';
7
+ export * from './models';
8
+ export * from './processors';
9
+ export * from './queue';
10
+ export * from './types';
@@ -16,8 +16,8 @@ import {
16
16
  import { askGetSmokeRunById } from '../../data/askGetSmokeRunById';
17
17
  import { askRecordSmokeTestResult } from '../../data/askRecordSmokeTestResult';
18
18
  import { askSetSmokeRunOutcome } from '../../data/askSetSmokeRunOutcome';
19
- import { SmokeTestDefinition } from '../../tests/SmokeTestDefinition';
20
- import { smokeTestRegistry } from '../../tests/smokeTestRegistry';
19
+ import { SmokeTestDefinition } from '../../types/SmokeTestDefinition';
20
+ import { listSmokeTests } from './listSmokeTests';
21
21
 
22
22
  // Runs one registered test, returning its completed result entry.
23
23
  function* askRunSmokeTest(
@@ -53,7 +53,7 @@ export function* askExecuteSmokeTest(
53
53
  runId: string,
54
54
  testName: string
55
55
  ): AskResponse<SmokeRun> {
56
- const test = smokeTestRegistry.find((t) => t.name === testName);
56
+ const test = listSmokeTests().find((t) => t.name === testName);
57
57
  if (!test) {
58
58
  return yield* askThrowError(
59
59
  ErrorTypeEnum.NotFound,
@@ -20,8 +20,8 @@ import {
20
20
  } from '../../constants/smokeRunQueue';
21
21
  import { askSaveSmokeRun } from '../../data/askSaveSmokeRun';
22
22
  import { SmokeTestRequestedPayload } from '../../models/SmokeTestRequestedQueueEvent';
23
- import { SmokeTestDefinition } from '../../tests/SmokeTestDefinition';
24
- import { smokeTestRegistry } from '../../tests/smokeTestRegistry';
23
+ import { SmokeTestDefinition } from '../../types/SmokeTestDefinition';
24
+ import { listSmokeTests } from './listSmokeTests';
25
25
 
26
26
  const createInitialResult = (
27
27
  test: SmokeTestDefinition,
@@ -57,7 +57,8 @@ export function* askStartSmokeRun(): AskResponse<SmokeRun> {
57
57
  const shouldSkip = (test: SmokeTestDefinition): boolean =>
58
58
  !!test.deployedOnly && platformName === 'devServer';
59
59
 
60
- const queued = smokeTestRegistry.filter((test) => !shouldSkip(test));
60
+ const smokeTests = listSmokeTests();
61
+ const queued = smokeTests.filter((test) => !shouldSkip(test));
61
62
 
62
63
  const smokeRun: SmokeRun = {
63
64
  runId,
@@ -65,7 +66,7 @@ export function* askStartSmokeRun(): AskResponse<SmokeRun> {
65
66
  queued.length === 0 ? SmokeRunStatus.passed : SmokeRunStatus.running,
66
67
  startedAt,
67
68
  finishedAt: queued.length === 0 ? startedAt : null,
68
- tests: smokeTestRegistry.map((test, index) =>
69
+ tests: smokeTests.map((test, index) =>
69
70
  createInitialResult(test, index, shouldSkip(test))
70
71
  ),
71
72
  };
@@ -1,4 +1,5 @@
1
1
  export * from './askExecuteSmokeTest';
2
2
  export * from './askFindSmokeRun';
3
3
  export * from './askStartSmokeRun';
4
+ export * from './listSmokeTests';
4
5
  export * from './summarizeSmokeRun';
@@ -0,0 +1,6 @@
1
+ import { smokeSuites } from '../../../suites/smokeSuites';
2
+ import { SmokeTestDefinition } from '../../types/SmokeTestDefinition';
3
+
4
+ /** Every registered test across all suites, in list order; a test's 1-based position is its run record id. */
5
+ export const listSmokeTests = (): SmokeTestDefinition[] =>
6
+ smokeSuites.flatMap((suite) => suite.tests);
@@ -1,6 +1,6 @@
1
1
  import { QueueEvent, QueueMessage } from 'quidproquo';
2
2
 
3
- // One registered test of one run. `testName` is the registry's stable key,
3
+ // One registered test of one run. `testName` is the test's stable key,
4
4
  // never the positional id.
5
5
  export type SmokeTestRequestedPayload = {
6
6
  runId: string;
@@ -0,0 +1,2 @@
1
+ export * from './GithubOidcClaims';
2
+ export * from './SmokeTestRequestedQueueEvent';
@@ -0,0 +1 @@
1
+ export * from './onSmokeTestRequested';
@@ -0,0 +1,13 @@
1
+ import { QPQConfig } from 'quidproquo';
2
+
3
+ import { SmokeTestDefinition } from './SmokeTestDefinition';
4
+
5
+ /**
6
+ * One folder under suites/: its tests plus the resources and handlers only
7
+ * they use. Tests that share a resource belong in the same suite, so deleting
8
+ * a suite's folder and its line in smokeSuites removes it completely.
9
+ */
10
+ export type SmokeSuite = {
11
+ tests: SmokeTestDefinition[];
12
+ defineConfig?: () => QPQConfig;
13
+ };
@@ -0,0 +1,2 @@
1
+ export * from './SmokeSuite';
2
+ export * from './SmokeTestDefinition';
@@ -1,13 +1,3 @@
1
1
  export * from './config';
2
- export * from './constants';
3
- export * from './controller';
4
- export * from './data';
5
- export * from './email';
6
- export * from './eventDoc';
7
- export * from './kvsStream';
8
- export * from './logic';
9
- export * from './models';
10
- export * from './processors';
11
- export * from './queue';
12
- export * from './storageDrive';
13
- export * from './tests';
2
+ export * from './harness';
3
+ export * from './suites';
@@ -0,0 +1,20 @@
1
+ import { defineEmailReceiver, defineEmailSender, QPQConfig } from 'quidproquo';
2
+
3
+ import { SMOKE_EMAIL_RECEIVER } from '../constants/SMOKE_EMAIL_RECEIVER';
4
+
5
+ /**
6
+ * The test sends to its own receiving domain, the receiver hands the parsed
7
+ * message to onSmokeEmailReceived, which writes a marker into the probe store,
8
+ * and the test polls for it. The sender is what lets the test send; the
9
+ * receiving domain is a verified identity, so the SES sandbox allows it.
10
+ */
11
+ export const defineEmailReceiveSmoke = (): QPQConfig => [
12
+ defineEmailSender(),
13
+ defineEmailReceiver(SMOKE_EMAIL_RECEIVER, {
14
+ onEmail: {
15
+ basePath: __dirname,
16
+ relativePath: '../entry/email/onSmokeEmailReceived',
17
+ functionName: 'onSmokeEmailReceived',
18
+ },
19
+ }),
20
+ ];
@@ -0,0 +1 @@
1
+ export * from './defineEmailReceiveSmoke';
@@ -0,0 +1,2 @@
1
+ /** The inbound email receiver; its onEmail writes the marker the email test polls for. */
2
+ export const SMOKE_EMAIL_RECEIVER = 'smoke';
@@ -0,0 +1 @@
1
+ export * from './SMOKE_EMAIL_RECEIVER';
@@ -0,0 +1,15 @@
1
+ import { SmokeSuite } from '../../harness/types/SmokeSuite';
2
+ import { defineEmailReceiveSmoke } from './config/defineEmailReceiveSmoke';
3
+ import { askRunEmailReceiveTest } from './logic/askRunEmailReceiveTest';
4
+
5
+ /** Inbound email to our own receiving domain. Deployed only. */
6
+ export const emailReceiveSmokeSuite: SmokeSuite = {
7
+ defineConfig: defineEmailReceiveSmoke,
8
+ tests: [
9
+ {
10
+ name: 'emailReceive',
11
+ askRun: askRunEmailReceiveTest,
12
+ deployedOnly: true,
13
+ },
14
+ ],
15
+ };
@@ -1,2 +1 @@
1
1
  export * from './onSmokeEmailReceived';
2
- export * from './smokeEmailMarkerId';
@@ -8,7 +8,7 @@ import {
8
8
  import { SMOKE_PROBE_STORE } from '@qpqjs/constants';
9
9
  import { SmokeProbeRecord } from '@qpqjs/test-models';
10
10
 
11
- import { smokeEmailMarkerId } from './smokeEmailMarkerId';
11
+ import { smokeEmailMarkerId } from '../../logic/smokeEmailMarkerId';
12
12
 
13
13
  // The smoke receiver's onEmail: one marker per delivered recipient, carrying
14
14
  // the subject and the provider's SPF/DKIM verdicts so the test can check the
@@ -0,0 +1,5 @@
1
+ export * from './config';
2
+ export * from './constants';
3
+ export * from './emailReceiveSmokeSuite';
4
+ export * from './entry';
5
+ export * from './logic';