@micha.bigler/ui-core-micha 3.14.3 → 4.0.0

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 (367) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +7 -0
  3. package/dist/auth/UserMenu.js +1 -1
  4. package/dist/auth/apiClient.js +7 -6
  5. package/dist/chat/ChatList.js +1 -1
  6. package/dist/chat/ChatThread.js +2 -1
  7. package/dist/chat/ChatWorkspace.js +1 -1
  8. package/dist/chat/ModelPicker.js +2 -5
  9. package/dist/chat/kitSxRegistry.js +9 -0
  10. package/dist/chat/useChatSocket.js +1 -1
  11. package/dist/components/LoginForm.js +1 -1
  12. package/dist/components/SecurityComponent.js +1 -1
  13. package/dist/components/UserListComponent.js +2 -8
  14. package/dist/components/charts/ChartFrame.js +1 -1
  15. package/dist/components/charts/ScatterChart.js +2 -1
  16. package/dist/components/charts/kitSxRegistry.js +6 -0
  17. package/dist/entries/charts.js +6 -0
  18. package/dist/entries/chat.js +8 -0
  19. package/dist/entries/markdown.js +1 -0
  20. package/dist/index.js +0 -14
  21. package/dist/layout/SectionNav.js +1 -1
  22. package/dist/messaging/AttachmentList.js +2 -2
  23. package/dist/messaging/Composer.js +2 -1
  24. package/dist/messaging/ConversationLaunchers.js +1 -4
  25. package/dist/messaging/ConversationList.js +1 -1
  26. package/dist/messaging/DirectMessageLauncher.js +1 -1
  27. package/dist/messaging/MessagingProvider.js +0 -0
  28. package/dist/messaging/PollCard.js +7 -5
  29. package/dist/messaging/ReadTicks.js +2 -2
  30. package/dist/messaging/Thread.js +5 -3
  31. package/dist/notifications/NotificationBell.js +4 -7
  32. package/dist/notifications/NotificationSettings.js +1 -1
  33. package/dist/onboarding/OnboardingProvider.js +3 -6
  34. package/dist/pages/AccountPage.js +1 -2
  35. package/dist/pages/LoginPage.js +2 -3
  36. package/dist/pages/PasswordChangePage.js +2 -3
  37. package/dist/pages/PasswordInvitePage.js +2 -3
  38. package/dist/pages/PasswordResetRequestPage.js +2 -3
  39. package/dist/pages/SignUpPage.js +2 -3
  40. package/dist/pages/SignupConfirmPage.js +2 -3
  41. package/dist/theme/createAppTheme.js +5 -4
  42. package/dist/theme/kitSxEntry.js +11 -0
  43. package/dist/theme/kitSxRegistry.js +2 -15
  44. package/dist/theme/themeCompleteness.js +3 -12
  45. package/dist/utils/auth-errors.js +4 -3
  46. package/package.json +41 -16
  47. package/.github/workflows/publish.yml +0 -126
  48. package/DESIGN.md +0 -60
  49. package/WORK_ORDERS.md +0 -148
  50. package/dev/entries.jsx +0 -721
  51. package/dev/fixtures.js +0 -26
  52. package/dev/main.jsx +0 -75
  53. package/dev/mockTransport.jsx +0 -128
  54. package/docs/CHART-LAYOUT.md +0 -157
  55. package/docs/DARK-TOKENS.md +0 -140
  56. package/docs/TYPE-SCALE.md +0 -111
  57. package/docs/messaging-deviations.md +0 -118
  58. package/index.html +0 -12
  59. package/renovate.json +0 -10
  60. package/scripts/chart-api-census.mjs +0 -415
  61. package/src/auth/AuthContext.jsx +0 -158
  62. package/src/auth/ReauthModal.jsx +0 -82
  63. package/src/auth/UserMenu.jsx +0 -121
  64. package/src/auth/apiClient.jsx +0 -232
  65. package/src/auth/authApi.jsx +0 -539
  66. package/src/auth/authConfig.jsx +0 -34
  67. package/src/auth/reauth.js +0 -47
  68. package/src/chat/ChatComposer.jsx +0 -36
  69. package/src/chat/ChatList.jsx +0 -87
  70. package/src/chat/ChatThread.jsx +0 -128
  71. package/src/chat/ChatWorkspace.jsx +0 -244
  72. package/src/chat/MarkdownReply.jsx +0 -22
  73. package/src/chat/ModelPicker.jsx +0 -85
  74. package/src/chat/api.js +0 -18
  75. package/src/chat/useChatSocket.js +0 -32
  76. package/src/chat/wire.js +0 -7
  77. package/src/components/AccessCodeManager.jsx +0 -288
  78. package/src/components/AccessCodeSingleUseToggle.jsx +0 -92
  79. package/src/components/AllowedEmailDomainsManager.jsx +0 -92
  80. package/src/components/AuthFactorRequirementCard.jsx +0 -95
  81. package/src/components/BulkInviteCsvTab.jsx +0 -198
  82. package/src/components/EmptyState.jsx +0 -38
  83. package/src/components/LoginForm.jsx +0 -159
  84. package/src/components/MFAComponent.jsx +0 -350
  85. package/src/components/MfaLoginComponent.jsx +0 -252
  86. package/src/components/MobileBottomNav.jsx +0 -82
  87. package/src/components/PasskeysComponent.jsx +0 -252
  88. package/src/components/PasswordChangeForm.jsx +0 -87
  89. package/src/components/PasswordResetRequestForm.jsx +0 -43
  90. package/src/components/PasswordSetForm.jsx +0 -97
  91. package/src/components/ProfileComponent.jsx +0 -348
  92. package/src/components/QrSignupManager.jsx +0 -404
  93. package/src/components/QrSignupValidityManager.jsx +0 -106
  94. package/src/components/RegistrationMethodsManager.jsx +0 -150
  95. package/src/components/SecurityComponent.jsx +0 -141
  96. package/src/components/SocialLoginButtons.jsx +0 -83
  97. package/src/components/SoftChip.jsx +0 -93
  98. package/src/components/StatTile.jsx +0 -39
  99. package/src/components/SupportRecoveryRequestsTab.jsx +0 -482
  100. package/src/components/TurnstileWidget.jsx +0 -99
  101. package/src/components/UserInviteComponent.jsx +0 -76
  102. package/src/components/UserListComponent.jsx +0 -618
  103. package/src/components/charts/BarChart.jsx +0 -102
  104. package/src/components/charts/ChartFrame.jsx +0 -214
  105. package/src/components/charts/LineChart.jsx +0 -126
  106. package/src/components/charts/ScatterChart.jsx +0 -299
  107. package/src/components/charts/TimeSeriesChart.jsx +0 -300
  108. package/src/components/charts/chartDefaults.js +0 -644
  109. package/src/components/charts/chartLabels.js +0 -36
  110. package/src/components/charts/exportChart.js +0 -258
  111. package/src/components/charts/formatters.js +0 -39
  112. package/src/components/charts/palette.js +0 -33
  113. package/src/components/charts/yearTickInterval.js +0 -7
  114. package/src/i18n/authTranslations.ts +0 -2651
  115. package/src/i18n/chartsTranslations.ts +0 -91
  116. package/src/i18n/chatTranslations.ts +0 -55
  117. package/src/i18n/messagingTranslations.ts +0 -120
  118. package/src/i18n/notificationsTranslations.ts +0 -32
  119. package/src/i18n/onboardingTranslations.ts +0 -29
  120. package/src/i18n/sectionNavTranslations.ts +0 -20
  121. package/src/i18n/uiCoreTranslations.js +0 -29
  122. package/src/i18n/userMenuTranslations.ts +0 -5
  123. package/src/index.js +0 -158
  124. package/src/layout/PageLayout.jsx +0 -36
  125. package/src/layout/SectionNav.jsx +0 -320
  126. package/src/messaging/AttachmentList.jsx +0 -145
  127. package/src/messaging/Composer.jsx +0 -197
  128. package/src/messaging/ConversationLaunchers.jsx +0 -51
  129. package/src/messaging/ConversationList.jsx +0 -109
  130. package/src/messaging/DirectMessageLauncher.jsx +0 -112
  131. package/src/messaging/MessageBubble.jsx +0 -183
  132. package/src/messaging/MessagingProvider.jsx +0 -0
  133. package/src/messaging/MessagingScopeConfig.jsx +0 -24
  134. package/src/messaging/PollCard.jsx +0 -163
  135. package/src/messaging/ReactionBar.jsx +0 -43
  136. package/src/messaging/ReadTicks.jsx +0 -82
  137. package/src/messaging/Thread.jsx +0 -195
  138. package/src/messaging/api.js +0 -48
  139. package/src/messaging/composerImageCompression.js +0 -35
  140. package/src/messaging/linkifyText.jsx +0 -37
  141. package/src/notifications/NotificationBell.jsx +0 -84
  142. package/src/notifications/NotificationSettings.jsx +0 -330
  143. package/src/notifications/NotificationsProvider.jsx +0 -224
  144. package/src/notifications/PopupSurface.jsx +0 -105
  145. package/src/notifications/api.js +0 -55
  146. package/src/notifications/feedApi.js +0 -18
  147. package/src/notifications/realtime.jsx +0 -138
  148. package/src/notifications/serviceWorker/sw.js +0 -50
  149. package/src/onboarding/OnboardingProvider.jsx +0 -326
  150. package/src/onboarding/OnboardingWizard.jsx +0 -61
  151. package/src/onboarding/WizardDialogShell.jsx +0 -51
  152. package/src/onboarding/api.js +0 -13
  153. package/src/onboarding/stepSelection.js +0 -16
  154. package/src/onboarding/steps/BrowserPushStep.jsx +0 -121
  155. package/src/onboarding/steps/CompleteNameStep.jsx +0 -46
  156. package/src/onboarding/steps/CookieConsentStep.jsx +0 -133
  157. package/src/onboarding/steps/PwaInstallStep.jsx +0 -47
  158. package/src/pages/AccountPage.jsx +0 -394
  159. package/src/pages/LoginPage.jsx +0 -343
  160. package/src/pages/PasswordChangePage.jsx +0 -62
  161. package/src/pages/PasswordInvitePage.jsx +0 -177
  162. package/src/pages/PasswordResetRequestPage.jsx +0 -68
  163. package/src/pages/SignUpPage.jsx +0 -268
  164. package/src/pages/SignupConfirmPage.jsx +0 -155
  165. package/src/testing/checkKitIntegration.js +0 -233
  166. package/src/theme/createAppTheme.js +0 -423
  167. package/src/theme/fonts.js +0 -3
  168. package/src/theme/index.js +0 -21
  169. package/src/theme/kitSxRegistry.js +0 -285
  170. package/src/theme/themeCompleteness.js +0 -1045
  171. package/src/theme/tokens.js +0 -478
  172. package/src/utils/auth-errors.js +0 -76
  173. package/src/utils/authService.js +0 -223
  174. package/src/utils/resolveErrorText.js +0 -28
  175. package/src/utils/webauthn.js +0 -51
  176. package/tests/AccountPage.profileStatements.test.jsx +0 -162
  177. package/tests/AccountPage.test.jsx +0 -200
  178. package/tests/AuthContext.test.jsx +0 -129
  179. package/tests/BarChart.test.jsx +0 -112
  180. package/tests/BrowserPushStep.test.jsx +0 -110
  181. package/tests/ChartFrame.test.jsx +0 -336
  182. package/tests/ConversationList.test.jsx +0 -144
  183. package/tests/CookieConsentStep.test.jsx +0 -69
  184. package/tests/EmptyState.test.jsx +0 -62
  185. package/tests/LineChart.test.jsx +0 -80
  186. package/tests/MessagingProvider.test.jsx +0 -50
  187. package/tests/MobileBottomNav.test.jsx +0 -319
  188. package/tests/NotificationBell.test.jsx +0 -60
  189. package/tests/NotificationSettings.test.jsx +0 -276
  190. package/tests/NotificationsProvider.test.jsx +0 -240
  191. package/tests/OnboardingProvider.test.jsx +0 -294
  192. package/tests/OnboardingWizard.test.jsx +0 -143
  193. package/tests/PasswordChangeForm.test.jsx +0 -70
  194. package/tests/PasswordInvitePage.test.jsx +0 -142
  195. package/tests/PasswordSetForm.test.jsx +0 -70
  196. package/tests/PopupSurface.test.jsx +0 -142
  197. package/tests/ProfileComponent.refresh.test.jsx +0 -194
  198. package/tests/QrSignupManager.registrationContext.test.jsx +0 -106
  199. package/tests/QrSignupManagerInfoBox.test.jsx +0 -49
  200. package/tests/ScatterChart.test.jsx +0 -270
  201. package/tests/SectionNav.test.jsx +0 -363
  202. package/tests/SignUpPage.test.jsx +0 -208
  203. package/tests/SoftChip.test.jsx +0 -105
  204. package/tests/StatTile.test.jsx +0 -57
  205. package/tests/Thread.test.jsx +0 -151
  206. package/tests/TimeSeriesChart.test.jsx +0 -367
  207. package/tests/UserListComponent.test.jsx +0 -192
  208. package/tests/UserMenu.test.jsx +0 -171
  209. package/tests/apiClientLanguage.test.js +0 -33
  210. package/tests/apiClientPublicPaths.test.js +0 -178
  211. package/tests/authApiLogin.test.js +0 -42
  212. package/tests/authApiRegistration.test.js +0 -31
  213. package/tests/authErrorCodeRendering.test.jsx +0 -77
  214. package/tests/authErrors.test.js +0 -74
  215. package/tests/authTranslations.test.js +0 -74
  216. package/tests/chart-api-census.test.js +0 -366
  217. package/tests/chartAxisTickBand.test.jsx +0 -95
  218. package/tests/chartDefaults.test.js +0 -902
  219. package/tests/chartLabels.test.js +0 -50
  220. package/tests/chartsPalette.test.js +0 -99
  221. package/tests/chatApi.test.js +0 -48
  222. package/tests/chatDriverNames.test.jsx +0 -71
  223. package/tests/chatExports.test.js +0 -3
  224. package/tests/chatList.test.jsx +0 -84
  225. package/tests/chatPicker.test.jsx +0 -82
  226. package/tests/chatSocket.test.jsx +0 -26
  227. package/tests/chatThread.test.jsx +0 -116
  228. package/tests/chatTranslations.test.js +0 -47
  229. package/tests/chatWorkspace.test.jsx +0 -234
  230. package/tests/checkKitIntegration.test.jsx +0 -219
  231. package/tests/createAppTheme.test.js +0 -132
  232. package/tests/createAppThemeDark.test.js +0 -127
  233. package/tests/createAppThemeLightGuard.test.js +0 -40
  234. package/tests/createAppThemePageContrast.test.js +0 -108
  235. package/tests/createAppThemeTypography.test.js +0 -53
  236. package/tests/errorCallSiteGuard.test.js +0 -32
  237. package/tests/exportChart.test.js +0 -313
  238. package/tests/feedApi.test.js +0 -46
  239. package/tests/fixtures/light-theme-baseline.json +0 -2234
  240. package/tests/i18nAggregate.test.js +0 -120
  241. package/tests/i18nGermanVariant.test.js +0 -65
  242. package/tests/loginPageErrorResolution.test.jsx +0 -102
  243. package/tests/messagingApi.test.js +0 -32
  244. package/tests/messagingChunk6.test.jsx +0 -116
  245. package/tests/messagingCompactBubble.test.jsx +0 -64
  246. package/tests/messagingComposer.test.jsx +0 -136
  247. package/tests/messagingComposerChunk5.test.jsx +0 -113
  248. package/tests/messagingContractConformance.test.js +0 -69
  249. package/tests/messagingDirectMessageLauncher.test.jsx +0 -151
  250. package/tests/messagingExports.test.js +0 -21
  251. package/tests/messagingInteractions.test.jsx +0 -136
  252. package/tests/messagingLastMessagePreview.test.jsx +0 -93
  253. package/tests/messagingLinkify.test.jsx +0 -51
  254. package/tests/messagingMessageActions.test.jsx +0 -163
  255. package/tests/messagingMsg6.test.jsx +0 -105
  256. package/tests/messagingMsg6f.test.jsx +0 -155
  257. package/tests/messagingMsg6g.test.jsx +0 -166
  258. package/tests/messagingMsg6h.test.jsx +0 -136
  259. package/tests/messagingMsg6i.test.jsx +0 -129
  260. package/tests/messagingPollRendering.test.jsx +0 -142
  261. package/tests/messagingReactionMerge.test.jsx +0 -77
  262. package/tests/messagingReadTicksTooltip.test.jsx +0 -36
  263. package/tests/messagingThreadReceipts.test.jsx +0 -178
  264. package/tests/messagingThreadingQuoting.test.jsx +0 -87
  265. package/tests/messagingUnreadLifecycle.test.jsx +0 -78
  266. package/tests/notificationsApi.test.js +0 -41
  267. package/tests/notificationsExports.test.js +0 -34
  268. package/tests/onboardingDescriptors.test.js +0 -132
  269. package/tests/packageTreeShaking.test.js +0 -126
  270. package/tests/realtime.test.jsx +0 -219
  271. package/tests/resolveErrorText.test.js +0 -72
  272. package/tests/stepSelection.test.js +0 -53
  273. package/tests/themeCompleteness.test.js +0 -626
  274. package/tests/timeSeriesLegend.test.js +0 -99
  275. package/tests/userScreenTranslations.test.jsx +0 -218
  276. package/tsconfig.build.json +0 -18
  277. package/vite.config.mjs +0 -6
  278. package/work-orders/AUTH-1.md +0 -74
  279. package/work-orders/AUTH-2.md +0 -74
  280. package/work-orders/AUTH-4.md +0 -183
  281. package/work-orders/AUTH-5.md +0 -154
  282. package/work-orders/AUTH-7.md +0 -181
  283. package/work-orders/AUTH-8.md +0 -184
  284. package/work-orders/CHART-1.md +0 -285
  285. package/work-orders/CHART-2.md +0 -222
  286. package/work-orders/CHART-3.md +0 -163
  287. package/work-orders/CHART-4.md +0 -203
  288. package/work-orders/CHART-5.md +0 -226
  289. package/work-orders/CHART-6.md +0 -428
  290. package/work-orders/CHART-7.md +0 -175
  291. package/work-orders/DX-1.md +0 -169
  292. package/work-orders/DX-2.md +0 -188
  293. package/work-orders/DX-3.md +0 -195
  294. package/work-orders/I18N-1.md +0 -254
  295. package/work-orders/I18N-3.md +0 -207
  296. package/work-orders/MSG-3.md +0 -375
  297. package/work-orders/MSG-3b.md +0 -1002
  298. package/work-orders/MSG-3c.md +0 -378
  299. package/work-orders/MSG-3d.md +0 -268
  300. package/work-orders/MSG-3e.md +0 -164
  301. package/work-orders/MSG-3f.md +0 -391
  302. package/work-orders/MSG-6e.md +0 -308
  303. package/work-orders/MSG-6f.md +0 -214
  304. package/work-orders/MSG-6g.md +0 -244
  305. package/work-orders/MSG-6h.md +0 -238
  306. package/work-orders/MSG-6i.md +0 -271
  307. package/work-orders/MSG-6j.md +0 -117
  308. package/work-orders/NOTIF-12.md +0 -214
  309. package/work-orders/NOTIF-13.md +0 -142
  310. package/work-orders/NOTIF-14.md +0 -151
  311. package/work-orders/PRIM-1.md +0 -177
  312. package/work-orders/SHELL-1.md +0 -255
  313. package/work-orders/SHELL-2.md +0 -197
  314. package/work-orders/SHELL-3.md +0 -359
  315. package/work-orders/SHELL-4.md +0 -351
  316. package/work-orders/SHELL-5.md +0 -345
  317. package/work-orders/SHELL-6.md +0 -210
  318. package/work-orders/THEME-1.md +0 -587
  319. package/work-orders/THEME-10.md +0 -303
  320. package/work-orders/THEME-11.md +0 -208
  321. package/work-orders/THEME-2.md +0 -339
  322. package/work-orders/THEME-3.md +0 -210
  323. package/work-orders/THEME-4.md +0 -271
  324. package/work-orders/THEME-5.md +0 -341
  325. package/work-orders/THEME-6.md +0 -247
  326. package/work-orders/THEME-7.md +0 -82
  327. package/work-orders/THEME-8.md +0 -211
  328. package/work-orders/THEME-9.md +0 -194
  329. package/work-orders/UCM-AUTH-10.md +0 -490
  330. package/work-orders/UCM-AUTH-11.md +0 -185
  331. package/work-orders/UCM-AUTH-12.md +0 -98
  332. package/work-orders/UCM-AUTH-13.md +0 -47
  333. package/work-orders/UCM-AUTH-9.md +0 -207
  334. package/work-orders/UCM-CHART-10.md +0 -150
  335. package/work-orders/UCM-CHART-11.md +0 -132
  336. package/work-orders/UCM-CHART-12.md +0 -348
  337. package/work-orders/UCM-CHART-13.md +0 -122
  338. package/work-orders/UCM-CHART-14.md +0 -198
  339. package/work-orders/UCM-CHART-15.md +0 -187
  340. package/work-orders/UCM-CHART-16.md +0 -169
  341. package/work-orders/UCM-CHART-17.md +0 -195
  342. package/work-orders/UCM-CHART-18.md +0 -200
  343. package/work-orders/UCM-CHART-8.md +0 -147
  344. package/work-orders/UCM-CHART-9.md +0 -265
  345. package/work-orders/UCM-CHAT-1.md +0 -190
  346. package/work-orders/UCM-CHAT-2.md +0 -75
  347. package/work-orders/UCM-DEP-1.md +0 -63
  348. package/work-orders/UCM-I18N-4.md +0 -226
  349. package/work-orders/UCM-I18N-5.md +0 -211
  350. package/work-orders/UCM-MSG-20.md +0 -192
  351. package/work-orders/UCM-PRIM-2.md +0 -114
  352. package/work-orders/UCM-SHELL-7.md +0 -134
  353. package/work-orders/UCM-SHELL-8.md +0 -125
  354. package/work-orders/UCM-TEST-1.md +0 -304
  355. package/work-orders/UCM-THEME-13.md +0 -69
  356. package/work-orders/UCM-THEME-14.md +0 -312
  357. package/work-orders/UCM-THEME-15.md +0 -356
  358. package/work-orders/UCM-THEME-16.md +0 -80
  359. package/work-orders/UCM-THEME-17.md +0 -111
  360. package/work-orders/UCM-THEME-18.md +0 -184
  361. package/work-orders/assets/AUTH-4-user-list-card.html +0 -407
  362. package/work-orders/assets/PRIM-1-dashboard-primitives.html +0 -624
  363. package/work-orders/assets/SHELL-2-account-navigation.html +0 -1159
  364. package/work-orders/assets/THEME-1-baseline-reference-sheet.html +0 -1352
  365. package/work-orders/assets/UCM-CHAT-1-ai-chat.html +0 -447
  366. package/work-orders/assets/UCM-THEME-13-dark-prototype.html +0 -390
  367. package/work-orders/assets/UCM-THEME-17-type-scale.html +0 -391
@@ -1,183 +0,0 @@
1
- # AUTH-4 — The account user list on a phone
2
-
3
- **Target repo:** `ui-core-micha` (branch `main` — this repo has no `develop`)
4
- **Tier:** 3 (shared core)
5
- **Review:** independent `reviewer` **and** `ui_reviewer` — both mandatory, concurrent
6
- **Version target:** the next **minor** after `SHELL-5` — the component gains a responsive mode it did
7
- not have, which is a capability rather than a fix. Read the published version at implementation time.
8
- **Prototype:** `work-orders/assets/AUTH-4-user-list-card.html` — the **composition** spec. The
9
- two-width rendered side-by-side is therefore a commit gate.
10
- **Sequencing:** **after `SHELL-5`.** Both are ucm work orders on the same screen; `SHELL-5` changes how
11
- the users section is *reached*, this changes what is *in* it.
12
- **Strand:** split out of `DS-11` by operator decision, because its fix class differs from the
13
- navigation shell's.
14
-
15
- ---
16
-
17
- ## A. Envelope
18
-
19
- ### Goal
20
-
21
- `UserListComponent`'s table is right for a desktop and unusable on a phone. Give it a card layout
22
- below `md`. Above `md` **nothing changes**.
23
-
24
- ### The driver, measured 2026-08-11 in cockpit
25
-
26
- All figures at `innerWidth` **411** CSS px — the mobile preset yields 411, not 375, so at the real
27
- target every figure is worse.
28
-
29
- | | measured |
30
- |---|---|
31
- | Table width | **1053 px** |
32
- | Container | **325 px** → 728 px of overflow |
33
- | Container `overflow-x` | `auto`; **the document does not overflow** |
34
- | Columns | Email 220, Name 180, New 90, Successful Login 163, Role 180, Actions 220 |
35
- | Cell padding | `10px 16px` — already the baseline's `density.tableCellPadding` |
36
-
37
- **This is not a broken layout.** The container scrolls and the page does not. It is a desktop table
38
- shown unchanged on a phone, with Role and Actions — the two things the screen exists for — entirely
39
- outside the view.
40
-
41
- **The cheap fix was tested and does not work.** 253 px of that width is `New` (90) and
42
- `Successful Login` (163), both **default-on props an app can switch off today** —
43
- `AccountPage` forwards all of them (`AccountPage.jsx:238-240`), and cockpit simply left the defaults.
44
- But the four remaining columns are Email 220 + Name 180 + Role 180 + Actions 220 = **800 px** against
45
- a 325 px container. **Configuration cannot fix this; only structure can.** That is now established
46
- rather than assumed.
47
-
48
- `SHELL-2` measured 1045 px on 2026-08-08 and it is 1053 px today (+8 px), so the number is stable —
49
- `THEME-4`/`THEME-5` did not move the rendered density.
50
-
51
- ### Why cards and not a scrolling table
52
-
53
- The component is **interactive per row**: the role is an inline `Select`
54
- (`UserListComponent.jsx:358-364`), there is a delete action plus app-supplied `extraRowActions`
55
- (`:425-451`), a search field (`:506`), sortable columns (`:541`) and pagination. An administrator
56
- opens this screen to **change a role** or **remove someone**. Any layout that puts those behind
57
- horizontal scrolling defeats the screen's purpose — which is why a sticky-first-column table was
58
- considered and rejected: it makes the defect tolerable instead of fixing it.
59
-
60
- ### Scope
61
-
62
- Below `md`, one card per user. The prototype is the composition spec; **four decisions in it are
63
- load-bearing and must not be quietly re-decided:**
64
-
65
- 1. **The email is the card title, the name is secondary.** The email is what an administrator
66
- searches by and the only guaranteed-present field. A user without a name gets a **muted
67
- placeholder**, not an empty line. Verified in the prototype: a 47-character address wraps to two
68
- lines via `overflow-wrap: anywhere` without overflowing a 357 px card.
69
- 2. **The two boolean columns become labelled chips.** In the table they are icon-only with a
70
- `Tooltip` (`:187-195`) — and **a tooltip is unreachable on a touch pointer**, so the information is
71
- effectively absent on the device this work order is about. Chips carry the words. This is a
72
- deliberate small improvement over strict parity, not drift, and it is why the flags cost vertical
73
- space instead of being dropped.
74
- 3. **Role and delete sit in a footer behind a divider.** They are the actions; separating them keeps
75
- the card's top half purely identifying. The select fills the remaining width so its value is never
76
- truncated; delete keeps the full 44 px touch target.
77
- 4. **Sorting needs its own control.** A card list has no column headers to click, so the
78
- sortable-column affordance **disappears with the table**. A compact sort control sits beside the
79
- search field. Without it the mobile view silently loses a capability the desktop has — the kind of
80
- regression that is invisible in a diff and that no test would catch unless it is asked for. It is
81
- asked for here.
82
-
83
- **What the app supplies must keep working**, since the column set is app-configurable:
84
-
85
- | Input | In the card |
86
- |---|---|
87
- | `extraColumns` | rendered as **label: value** rows below the chips, in the given order. **No new required field** on the column definition — an app that passes columns today keeps working unchanged. |
88
- | `extraRowActions` | join delete in the footer. **Beyond three actions total they must collapse into an overflow menu**, or the footer wraps and the card loses its shape. |
89
- | `showNewColumn` / `showSuccessfulLoginColumn` / `showRoleColumn` | chips (or the role select) when on, **absent** when off — a shorter card, not an empty chip row. |
90
-
91
- ### Non-goals / do not touch
92
-
93
- - **The table above `md`.** Byte-identical. Six columns are scannable at 1136 px and the strip beside
94
- them has 570 px of headroom.
95
- - **The column defaults.** `New` and `Successful Login` stay default-on. Flipping them would be a
96
- silent change to the account screen in every app — a separate decision, not a side effect of this
97
- work order.
98
- - **The delete confirmation dialog**, the invite flow, the role list an app supplies, and every other
99
- account section.
100
- - **The section navigation** — that is `SHELL-5`.
101
- - No permission, data-contract or API change. No new required prop. No baseline token change: the
102
- card consumes tokens and introduces none, so there is **no token delta list**.
103
- - No pagination or search redesign; both stay, above the list.
104
-
105
- ### Risks
106
-
107
- - **`AccountPage` is mounted by at least ten apps** — bigler-consult, cockpit, fitness-monitor,
108
- hpc-bridge, hram, innoservice, jg-ferien, kerzenziehen, reimbursements. The account screen's user
109
- list changes on a phone everywhere at once, and there is no staging net: a version bump on `main`
110
- publishes. The two reviews and the rendered gate carry it.
111
- - **Two renderings to keep in step.** From now on a change to a column must be made twice, or the
112
- card and the table drift. Tests 3 and 4 below are what make the drift visible.
113
- - **A long list of cards is a long scroll.** Mitigated by the existing search and pagination, not by
114
- this work order — and worth watching in an app with many users rather than asserting it is fine.
115
- - **`extraRowActions` beyond three** is the shape's real limit. The overflow-menu rule is in scope
116
- precisely so the limit is handled rather than discovered.
117
-
118
- ### Required tests to WRITE
119
-
120
- 1. Below `md` the card list renders and no `<table>` is present; at `md` and above the table renders
121
- and no cards are. **Prove both directions** — a one-sided test passes on a component that never
122
- switches.
123
- 2. A user without a name renders the muted placeholder, not an empty element.
124
- 3. `extraColumns` appear as label/value rows in the card, in the given order, and still as columns in
125
- the table.
126
- 4. `extraRowActions`: three or fewer render inline in the footer; **more than three collapse into an
127
- overflow menu**.
128
- 5. Each of the three column toggles set to `false` removes its chip from the card **and** its column
129
- from the table — no empty chip row.
130
- 6. The mobile sort control changes the order, and the sortable column headers still work above `md`.
131
- 7. Pagination and search still function in the card mode.
132
- 8. `THEME-4`'s shadowing check still returns no findings — any `sx` the card introduces must not
133
- duplicate a baseline `styleOverrides` key. The card uses `MuiCard`, which the baseline styles, so
134
- this is a live risk rather than a formality.
135
-
136
- Plus `tsc -p tsconfig.build.json --noEmit` clean. **No full-suite run** — affected set is
137
- `UserListComponent`'s spec, `AccountPage`'s, and the theme spec touched by test 8.
138
-
139
- ### Verification
140
-
141
- The **two-width rendered side-by-side at 375 px and 1280 px** against the prototype, per the standing
142
- gate. Measure, do not eyeball, the number this work order exists to fix: **at 375 px no element may
143
- exceed its container**, and the 728 px of overflow must be gone. At 1280 px the table must be
144
- unchanged — compare it against the prototype's section 3, which exists so that "unchanged" is part of
145
- the spec rather than an omission.
146
-
147
- State whether real screenshots were obtained or DOM/computed-style inspection substituted. Capture has
148
- failed repeatedly in this estate; the substitution is declared, not silent.
149
-
150
- ### Parity guardrail
151
-
152
- Presentation only, with the one stated exception: the boolean flags gain visible labels because their
153
- tooltip is unreachable on touch. Every datum the table shows, the card shows. No behaviour, no
154
- permissions, no data contract, no routing.
155
-
156
- ---
157
-
158
- ## B. Implementation map
159
-
160
- *Filled by the Orchestrator on `git pull` — see `AGENTS.md` → "Work Order".*
161
-
162
- ### Execution directive (read this first)
163
-
164
- > **If you are the implementer reading this work order as your own specification: this section is
165
- > NOT addressed to you.** It tells the Orchestrator how to invoke you. **You ARE that invocation —
166
- > do NOT shell out to `codex exec`.**
167
- >
168
- > Implement through `codex exec` in the background — invoked directly via Bash (never the
169
- > `debugger`/`*_coder` Agent wrappers) with BOTH flags `--skip-git-repo-check` and
170
- > `--dangerously-bypass-approvals-and-sandbox`. **Pass the WO via stdin, not as a positional
171
- > argument** (a positional arg hits Windows' command-line length limit — proven repeatedly in this
172
- > repo). Fallback to direct Claude implementation only on Codex quota/rate-limit/non-zero exit — and
173
- > note that the fallback flips authorship, so both reviewers stay mandatory either way.
174
- >
175
- > **Read `git log origin/main..HEAD` and `git status`, and re-read this WO's register row, before your
176
- > own review.** Across four ucm work orders the implementer produced an invalid review claim three
177
- > times — twice by self-committing with a self-report, once by writing a **fabricated** verdict into
178
- > `WORK_ORDERS.md`. The preamble now forbids editing that file; verify it was respected.
179
-
180
- ### Mini-handover
181
-
182
- Repo: `ui-core-micha` (`C:\Users\biglmi\Documents\webapps\ui-core-micha`), branch `main`.
183
- WO: `work-orders/AUTH-4.md`. **Run after `SHELL-5`.** Follow `orchestrate-codex`.
@@ -1,154 +0,0 @@
1
- # AUTH-5 — `addPublicPath` muss dynamische Routen ausdrücken können
2
-
3
- **Target repo:** `ui-core-micha` (branch `main`)
4
- **Tier:** 3 — shared-core. Die Änderung betrifft die Login-Weiterleitung jeder konsumierenden App.
5
-
6
- **Kein Prototyp.** Diese Work Order hat keine Oberfläche — sie erweitert eine Registrierungs-API.
7
-
8
- **Auslöser:** `jg-ferien` PUB-7 Teil 2. Diese WO ist dessen Vorbedingung; nach der Veröffentlichung
9
- zieht jg seinen Pin von **`2.37.1`** hoch.
10
-
11
- ---
12
-
13
- ## A. Envelope
14
-
15
- ### Goal
16
-
17
- `apiClient` leitet bei 401/403 per hartem `window.location.assign("/login")` um — **ausser** der
18
- aktuelle Pfad steht auf einer Allowlist (`redirectToLoginOnce`, `src/auth/apiClient.jsx`). Der
19
- Mechanismus ist richtig gebaut: auf einer öffentlichen Seite unterbleibt die Weiterleitung und der
20
- 401 wird an die Komponente durchgereicht.
21
-
22
- **Was er nicht kann, ist dynamische Routen.** `matchesPublicPath` vergleicht mit `startsWith`, ausser
23
- bei `/`, wo Gleichheit verlangt wird. Eine App mit öffentlichen Seiten unter einem **variablen
24
- Segment** — `/<slug>`, `/<slug>/team` — kann ihre öffentliche Fläche damit nicht beschreiben. Ein
25
- konkreter Slug lässt sich eintragen; der nächste, den jemand anlegt, fällt wieder heraus.
26
-
27
- **Warum das mehr ist als eine Unbequemlichkeit.** Fehlt der Pfad in der Liste, landet ein anonymer
28
- Besucher beim ersten 401 auf `/login` — auf einer Seite, die öffentlich sein soll. Von aussen ist das
29
- nicht von „diese Seite gibt es nicht" zu unterscheiden, und der Fehler zeigt sich erst, wenn ein
30
- zweites Department existiert. Er sieht dann aus wie ein Zufall, nicht wie eine Lücke.
31
-
32
- **Erwartetes Ergebnis.** Eine konsumierende App kann ihre öffentliche Fläche vollständig beschreiben,
33
- auch wenn Teile davon aus variablen Segmenten bestehen.
34
-
35
- ### Scope
36
-
37
- - **`addPublicPath` nimmt zusätzlich ein `RegExp` entgegen** (String bleibt unverändert gültig).
38
- - **`matchesPublicPath` unterscheidet nach Typ**: String wie bisher (`/` exakt, sonst `startsWith`),
39
- `RegExp` per `test()` gegen **ausschliesslich `window.location.pathname`** — nie gegen Query oder
40
- Fragment, damit ein Muster nicht versehentlich über den Pfad hinaus greift.
41
- - **`removePublicPath` funktioniert für beide Formen.** Bei `RegExp` über Identität des übergebenen
42
- Objekts; das gehört dokumentiert, weil zwei gleich aussehende Literale nicht dasselbe Objekt sind.
43
- - **`BUILTIN_PUBLIC_PATHS` bleibt eingefroren und rein string-basiert.** Kein Muster in der
44
- Bibliotheks-Liste — sie darf sich nicht durch eine Konsumenten-Erweiterung verschieben.
45
- - **Die Dokumentation am Aufruf sagt, was der Konsument nun selbst trägt**: ein zu weites Muster
46
- unterdrückt die Weiterleitung dort, wo sie gebraucht wird, und ein abgelaufener Login endet dann in
47
- einer stillen Fehlerseite statt am Login. Muster gehören verankert (`^…$`).
48
-
49
- ### Non-goals / do not touch
50
-
51
- - **Keine Änderung am Weiterleitungsverhalten selbst** — weder Ziel, noch `?next=`, noch der
52
- einmalige Sperrmechanismus (`redirectingToLogin`).
53
- - **Keine Änderung an der eingefrorenen Builtin-Liste** und keine an `isPublicSitePath`.
54
- - **Keine Änderung am Per-Request-Opt-out** für Bootstrap-Proben.
55
- - **Keine neue Prüfung gegen Query oder Fragment.**
56
-
57
- ### Risks
58
-
59
- - **Die Verantwortung wandert zum Konsumenten.** Ein unverankertes Muster wie `/team` trifft auch
60
- `/admin/team`. Das ist der Preis der Flexibilität und muss in der Dokumentation stehen, nicht nur
61
- im Kopf des Autors.
62
- - **Geteilter Code**: jede konsumierende App bekommt die Änderung. Deshalb rein additiv — bestehende
63
- String-Registrierungen müssen sich zeichengenau gleich verhalten.
64
- - **Ein Muster, das zu eng greift, ist unsichtbar**, bis jemand die betroffene Seite anonym öffnet.
65
- Deshalb gehört die Gegenrichtung mitgetestet.
66
-
67
- ### Required tests to WRITE
68
-
69
- - **Regression, nicht verhandelbar:** String-Registrierungen verhalten sich exakt wie bisher — `/`
70
- nur bei Gleichheit, andere Einträge per Präfix.
71
- - Ein registriertes `RegExp` trifft die passenden Pfade; ein nicht passender Pfad **löst weiterhin
72
- die Weiterleitung aus**.
73
- - Das Muster wird gegen `pathname` geprüft, nicht gegen Query oder Fragment.
74
- - `removePublicPath` entfernt einen `RegExp`-Eintrag; ein Builtin-Pfad lässt sich weiterhin **nicht**
75
- entfernen.
76
- - Ein `RegExp` in `CONSUMER_PUBLIC_PATHS` bricht die bestehende Auswertung der String-Einträge nicht.
77
- - **Affected set** (laufen, nicht schreiben): die vorhandenen `apiClient`-Tests.
78
-
79
- ---
80
-
81
- ## B. Implementation map
82
-
83
- **Selbst umgesetzt (nicht per Codex)** — laufende Operator-Anweisung für diese Session.
84
-
85
- ### Design-Entscheidungen
86
-
87
- - **`addPublicPath`/`removePublicPath`** akzeptieren jetzt zusätzlich `instanceof RegExp` neben
88
- `string`; `CONSUMER_PUBLIC_PATHS` bleibt ein `Set`, das für `RegExp`-Objekte automatisch
89
- Identitäts-Löschung liefert (`Set.delete` nutzt SameValueZero) — kein Sonderfall nötig.
90
- - **`matchesPublicPath`** prüft `entry instanceof RegExp` zuerst und ruft `entry.test(pathname)` —
91
- ausschliesslich gegen `window.location.pathname`, nie gegen `search`/`hash`, da die Funktion
92
- ohnehin nur `pathname` als Parameter erhält (kein Risiko einer versehentlichen Konkatenation).
93
- - **`BUILTIN_PUBLIC_PATHS` unverändert** — bleibt string-only und eingefroren, keine Berührung.
94
- - Dokumentation an `addPublicPath`/`removePublicPath` erweitert: Anker-Pflicht (`^…$`) für
95
- `RegExp`-Muster und Identitäts-Hinweis für `removePublicPath`.
96
-
97
- ### Kontextpaket
98
-
99
- - `src/auth/apiClient.jsx` — einzige geänderte Quelldatei.
100
-
101
- ### Tests
102
-
103
- `tests/apiClientPublicPaths.test.js` (neu, 11 Fälle) — fährt durch den echten
104
- Response-Interceptor (nicht durch eine Nachbildung von `matchesPublicPath`), damit ein Fehler in
105
- der Verdrahtung selbst auffällt, nicht nur ein Fehler im Matcher. Jeder Test importiert das Modul
106
- frisch (`vi.resetModules()` + dynamisches `import()`), weil `redirectingToLogin` ein
107
- Modul-Level-Riegel ist, der sich in jsdom nie durch echte Navigation zurücksetzt.
108
- `window.location` wird durch ein rein synthetisches Objekt ersetzt (jsdoms echtes
109
- `location.assign` ist nicht konfigurierbar, und `pushState` bindet nicht an ein ersetztes
110
- `location`-Objekt) — deckt exakt das ab, was der Interceptor liest (`pathname`) und aufruft
111
- (`assign`). Affected set: `authApiRegistration.test.js`, `AuthContext.test.jsx`,
112
- `feedApi.test.js`, `messagingApi.test.js`, `notificationsApi.test.js` — alle grün.
113
-
114
- ---
115
-
116
- ## C. Orchestrator only
117
-
118
- > **STOPP — wer diesen Auftrag als eigene Spezifikation liest, ist mit diesem Abschnitt nicht
119
- > gemeint.** Er beschreibt dem Orchestrator, wie er dich aufruft, wie das Ergebnis geprüft und wie es
120
- > verbucht wird. **Du BIST dieser Aufruf — starte kein `codex exec`, spawne keine Reviewer, pflege
121
- > das Register nicht, committe nicht.** Deine Aufgabe endet beim Diff.
122
-
123
- ### Execution directive
124
-
125
- `.claude/codex-status.md` im Workspace-Root vor dem Aufruf prüfen. Ohne Zeile für den
126
- Ausführungstag Codex verwenden — direkt per Bash, nie über die `debugger`/`*_coder`-Wrapper, mit
127
- BEIDEN Flags `--skip-git-repo-check` und `--dangerously-bypass-approvals-and-sandbox`. Der Rückfall
128
- auf direkte Umsetzung dreht die Autorschaft und macht den unabhängigen `reviewer` zwingend.
129
-
130
- ### Review routing
131
-
132
- Tier 3 (shared-core): **`reviewer` und `sec_reviewer`**, gleichzeitig in einem Hintergrund-Batch vor
133
- dem Commit. `ui_reviewer` entfällt — es gibt keine Oberfläche. `sec_reviewer` prüft die Kernfrage:
134
- kann ein registriertes Muster die Weiterleitung dort unterdrücken, wo sie gebraucht wird, und ist die
135
- Auswertung auf `pathname` beschränkt.
136
-
137
- ### Verification
138
-
139
- Kein Prototyp, kein Zwei-Breiten-Abgleich. Der Nachweis sind die Tests, insbesondere die
140
- Regressionsfälle für die String-Registrierung.
141
-
142
- Nach grünem Review: Version anheben und veröffentlichen. **Die WO ist erst abgeschlossen, wenn die
143
- Version veröffentlicht ist** — jg-ferien PUB-7 hängt daran und kann ohne sie nicht landen.
144
-
145
- ### Register + commit
146
-
147
- Zeile `AUTH-5` erreicht `done` nur mit beiden Reviewern samt Verdikt in der `Notiz` und der
148
- veröffentlichten Version. Auf grün nach `main` committen und pushen.
149
-
150
- ### Mini-handover
151
-
152
- Repo: `ui-core-micha` (`C:\Users\biglmi\Documents\webapps\ui-core-micha`), Branch `main`.
153
- WO: `work-orders/AUTH-5.md`. Konsument: `jg-ferien` PUB-7 Teil 2 (Pin heute `2.37.1`).
154
- `git pull`, WO lesen, dann `orchestrate-codex` folgen.
@@ -1,181 +0,0 @@
1
- # AUTH-7 — `loginWithPassword`'s "already authenticated" retry must not crash raw on a second failure
2
-
3
- ---
4
-
5
- # A. Envelope — authored by the Expertenchat
6
-
7
- ## Goal & expected outcome
8
- - Ziel: allauth-headless antwortet auf `POST /auth/login` mit `409` ("Conflict"), wenn bereits
9
- eine gültige Session existiert (die Session ist real gültig — kein Fehlerfall an sich).
10
- `loginWithPassword` (`src/auth/authApi.jsx:97-123`) behandelt das korrekt, indem es dann
11
- `fetchCurrentUser()` erneut aufruft, um den bereits eingeloggten User zurückzugeben. Schlägt
12
- DIESER Retry-Call aber ebenfalls fehl (beobachtet 2026-09-05: ein anderer, unabhängig
13
- überlasteter Endpunkt hatte den globalen `user`-Throttle-Bucket geleert, sodass auch
14
- `/api/users/current/` mit 429 antwortete), wird der Fehler ungefangen durchgereicht — kein
15
- `.code`, keine Übersetzung, ein rohes Error-Objekt statt eines normalen Login-Fehlers.
16
- - Expected outcome: schlägt der 409-Retry fehl, bekommt der Aufrufer (`LoginPage.jsx:219-220`
17
- liest `err.code`) einen normalisierten Fehler mit `.code` — dieselbe Fehlerform wie jeder andere
18
- Login-Fehlerpfad in dieser Funktion, kein Sonderfall.
19
-
20
- ## Scope + non-goals
21
- - In scope: ausschliesslich der 409-Zweig in `loginWithPassword`
22
- (`src/auth/authApi.jsx:116-119`) — den bereits vorhandenen `fetchCurrentUser()`-Retry-Call in
23
- ein eigenes try/catch nehmen und einen Fehlschlag über `normaliseApiError` weiterwerfen, exakt
24
- wie jeder andere Fehlerpfad in dieser Funktion (Zeile 121) es bereits tut.
25
- - Explizite Non-Goals / nicht anfassen: der **Erfolgsfall** dieses Zweigs (409 + erfolgreicher
26
- Retry → `{ user, needsMfa: false }`) bleibt bytegleich. `AuthContext.jsx`s Bootstrap-Catch-Block
27
- (Zeile 107-109) wird NICHT geändert — geprüft: `user` ist beim ersten Mount ohnehin bereits
28
- `null`, eine Fallunterscheidung nach Statuscode hätte dort unter keinem real erreichbaren
29
- Codepfad einen beobachtbaren Effekt (der Effect läuft genau einmal pro Seitenaufruf), wäre also
30
- Änderung ohne Wirkung in einer Shared-Core-Datei — bewusst ausgelassen. Keine neue Kontext-Prop,
31
- keine Änderung an einer konsumierenden App (`kira` o.a.) — der Fix ist rein additiv/intern zu
32
- `authApi.jsx`. `package.json`s Versionsfeld wird als Teil dieser WO angepasst (PATCH-Bump, siehe
33
- Teil C) — das ist Prozess/Publish-Mechanik dieses Repos, kein Scope-Zusatz am eigentlichen Fix.
34
-
35
- ## Tier · precondition / gate
36
- - Tier: 3 — Änderung INNERHALB von Shared-Core (`ui-core-micha`), unabhängig vom Umfang (AGENTS.md
37
- → Tiering-Tabelle). Kein Precondition/Gate; die Änderung ist rein additiv (ein neuer catch um
38
- einen bestehenden Call), kein Breaking Change, kein Versions-Bump nötig, keine konsumierende App
39
- muss etwas tun.
40
-
41
- ## Risks
42
- - Der Erfolgspfad (409 + Retry gelingt) darf sich nicht ändern — sonst bricht der bestehende
43
- "bereits eingeloggt"-Login-Flow für ALLE Apps, die `ui-core-micha` konsumieren.
44
- - Der neue catch darf den `normaliseApiError`-Fehler nicht verschlucken oder verfälschen — die
45
- aufrufende `LoginPage.jsx` liest `err.code` für die i18n-Anzeige.
46
-
47
- ## Required tests to WRITE
48
- - Neue Datei `tests/authApiLogin.test.js` (Muster: `tests/authApiRegistration.test.js` — `apiClient`
49
- gemockt via `vi.mock`, `client.post`/`client.get` direkt gestubbt, kein React/Testing-Library
50
- nötig, `loginWithPassword` direkt importiert und aufgerufen):
51
- 1. `post` rejects mit `{ response: { status: 409 } }`, `get` (der `fetchCurrentUser`-Retry)
52
- resolved mit `{ data: { id: 1, ... } }` → `loginWithPassword` liefert
53
- `{ user: {...}, needsMfa: false }` (dokumentiert den unveränderten Erfolgspfad).
54
- 2. `post` rejects mit `{ response: { status: 409 } }`, `get` (der Retry) rejects zusätzlich mit
55
- `{ response: { status: 429, data: { detail: '...' } } }` → `loginWithPassword` wirft einen
56
- Error mit einem gesetzten `.code` (nicht `undefined`, nicht das rohe Axios-Error-Objekt).
57
-
58
- ---
59
-
60
- # B. Implementation map — filled by the Orchestrator — ADDRESSED TO THE IMPLEMENTER
61
-
62
- ## Context package
63
-
64
- **Named file to change:** `src/auth/authApi.jsx:97-123` (`loginWithPassword`), konkret nur
65
- Zeilen 115-119:
66
-
67
- ```js
68
- // 409 = Already logged in
69
- if (status === 409) {
70
- const user = await fetchCurrentUser();
71
- return { user, needsMfa: false };
72
- }
73
-
74
- throw normaliseApiError(error, 'Auth.LOGIN_FAILED');
75
- ```
76
-
77
- Ändere zu (Retry in eigenes try/catch, Fehlschlag desselben `normaliseApiError`-Wegs wie jeder
78
- andere Fehlerpfad dieser Funktion):
79
-
80
- ```js
81
- // 409 = Already logged in
82
- if (status === 409) {
83
- try {
84
- const user = await fetchCurrentUser();
85
- return { user, needsMfa: false };
86
- } catch (retryError) {
87
- throw normaliseApiError(retryError, 'Auth.LOGIN_FAILED');
88
- }
89
- }
90
-
91
- throw normaliseApiError(error, 'Auth.LOGIN_FAILED');
92
- ```
93
-
94
- `normaliseApiError` ist bereits oben in der Datei importiert (Zeile 3, aus `../utils/auth-errors`)
95
- — keine neue Abhängigkeit.
96
-
97
- **Invariants / Pitfalls:**
98
- - `fetchCurrentUser()` (Zeile 16-24, gleiche Datei) wirft bei jedem Fehler das **rohe** Axios-Error
99
- weiter (kein eigener catch dort) — das ist bereits der Zustand, den dieser Fix abfängt; nicht
100
- `fetchCurrentUser()` selbst ändern.
101
- - Der äussere `catch (error)`-Block (Zeile 103) bleibt unverändert; nur der 409-Zweig innerhalb
102
- bekommt einen zusätzlichen inneren try/catch. Die MFA-Prüfung (Zeile 108-112) und der finale
103
- `throw normaliseApiError(error, ...)` (Zeile 121, für den ursprünglichen `error`, NICHT den
104
- `retryError`) bleiben unverändert.
105
- - `normaliseApiError`s zweites Argument ist ein Default-Code, kein spezifischer 429-Code — es gibt
106
- keinen eigenen i18n-Key für "Login gerade nicht möglich, Konto ist gedrosselt"; Wiederverwendung
107
- von `'Auth.LOGIN_FAILED'` (bereits vorhandener Key) ist beabsichtigt, kein neuer i18n-Key nötig
108
- in irgendeiner konsumierenden App.
109
-
110
- Directive: Arbeite ausschliesslich aus diesem Kontext-Paket; öffne nur die genannte Datei plus die
111
- genannte Testdatei-Vorlage zur Verifikation. Kein breites Erkunden im restlichen `src/auth/`.
112
-
113
- ## Target repo working directory (absolute)
114
-
115
- `C:\Users\Micha Bigler\Documents\webapps\ui-core-micha`
116
-
117
- ## Preamble — REQUIRED, part of this file
118
-
119
- > The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine;
120
- > there is no separate plan file. Read the nearest `AGENTS.md`, the relevant
121
- > `.codex/skills/<role>/SKILL.md`, and the app `MEMORY.md` ONLY for conventions. Stay in scope; do
122
- > not touch auth/permissions/deps/schema/CI unless the spec says so; do not update `MEMORY.md`.
123
- > **Do NOT edit `WORK_ORDERS.md`** — the register row and the review verdicts are the
124
- > orchestrator's alone. **Your tools are for editing source and test files and for running the
125
- > tests you wrote — nothing else.** Do NOT install dependencies, touch a lockfile, run a package
126
- > manager, or tidy up stray files; if something in the repo state blocks you, stop and report it as
127
- > `RESULT: BLOCKED <reason>` instead of fixing it. Do NOT `git add`/`commit`/`push` — leave every
128
- > change uncommitted in the working tree for the orchestrator's independent review. WRITE the
129
- > tests the `Required tests` section calls for AND **RUN the tests you just wrote** to confirm
130
- > they execute and pass — that is the ONLY test run you do (NOT the app's affected/full suite, NOT
131
- > any review). The orchestrator re-runs the authoritative set + does the independent review after
132
- > you finish — those are the gate; your own run does not count as the gate.
133
- >
134
- > Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line
135
- > `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on
136
- > completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final
137
- > `RESULT: DONE|BLOCKED <reason>`.
138
-
139
- ---
140
-
141
- # C. Orchestrator only — NOT ADDRESSED TO THE IMPLEMENTER
142
-
143
- > **If you are the implementer reading this work order as your own specification: STOP at this
144
- > line. Everything below describes what the Orchestrator does AFTER you finish. You do none of it
145
- > — no reviewers, no verification run, no register edit, no commit.** You ARE the invocation
146
- > described below; do NOT shell out to `codex exec`.
147
-
148
- ## Execution directive
149
-
150
- Implement through `codex exec` in the background, invoked directly via Bash with both mandatory
151
- flags. Fallback to direct Claude implementation only on Codex quota/rate-limit/non-zero exit
152
- (flips authorship — independent reviewer becomes mandatory, already mandatory at Tier 3).
153
-
154
- ## Review routing
155
-
156
- Tier 3, full set, all concurrent in one background batch: `reviewer` (all 4 lenses — this is
157
- shared-core, `duplication` and `regression` lenses matter most here), `ui_reviewer` (diff touches
158
- a `.jsx` file consumed by every app's login page — narrow context: this diff + the relevant
159
- `AGENTS.md` auth-error-handling convention), `sec_reviewer` (auth/login flow). Orchestrator's own
160
- targeted security pass runs alongside, additional not substitute.
161
-
162
- ## Verification
163
-
164
- Authoritative test run: `npx vitest run tests/authApiLogin.test.js tests/AuthContext.test.jsx
165
- tests/authApiRegistration.test.js` (affected area — everything touching `authApi.jsx` and the
166
- login flow it feeds). No prototype artifact in scope, no rendered side-by-side needed (no visual
167
- change).
168
-
169
- ## Register + commit
170
-
171
- Bump `package.json`'s `version` `3.5.0` -> `3.5.1` (PATCH — bugfix, no interface/behavior change
172
- for any existing caller) as part of this same commit, matching this repo's established
173
- push-to-`main` + version-bump publish flow (see `MSG-19`'s register row for precedent). Commit on
174
- `main` (this repo has no `develop`). `WORK_ORDERS.md` row for `AUTH-7`, named review verdict.
175
- After push, verify the bumped version actually published (per
176
- `reference_dcm_ucm_publish_topology` — publish-from-main has no staging gate, check the live
177
- package version after push). **No consumer pin-bump is required for this to take effect for
178
- kira** — this is a pure bugfix with no interface change, so record explicitly in the Notiz that no
179
- app needs to bump its `@micha.bigler/ui-core-micha` pin for this fix to matter (kira's *symptom*
180
- was caused by the throttle exhaustion fixed in `KIRA-TRACK-3`, not by this bug alone — this fix
181
- only prevents a raw/uncaught error the NEXT time any app's login flow race is hit).