@micha.bigler/ui-core-micha 3.14.4 → 4.0.1

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 (341) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +7 -0
  3. package/dist/chat/kitSxRegistry.js +9 -0
  4. package/dist/components/charts/kitSxRegistry.js +6 -0
  5. package/dist/entries/charts.js +6 -0
  6. package/dist/entries/chat.js +8 -0
  7. package/dist/entries/markdown.js +1 -0
  8. package/dist/index.js +0 -14
  9. package/dist/pages/AccountPage.js +1 -2
  10. package/dist/pages/LoginPage.js +1 -2
  11. package/dist/pages/PasswordChangePage.js +1 -2
  12. package/dist/pages/PasswordInvitePage.js +1 -2
  13. package/dist/pages/PasswordResetRequestPage.js +1 -2
  14. package/dist/pages/SignUpPage.js +1 -2
  15. package/dist/pages/SignupConfirmPage.js +1 -2
  16. package/dist/theme/kitSxEntry.js +11 -0
  17. package/dist/theme/kitSxRegistry.js +2 -15
  18. package/package.json +31 -7
  19. package/.github/workflows/ci.yml +0 -35
  20. package/.github/workflows/publish.yml +0 -126
  21. package/DESIGN.md +0 -60
  22. package/WORK_ORDERS.md +0 -150
  23. package/dev/entries.jsx +0 -721
  24. package/dev/fixtures.js +0 -26
  25. package/dev/main.jsx +0 -75
  26. package/dev/mockTransport.jsx +0 -128
  27. package/docs/CHART-LAYOUT.md +0 -157
  28. package/docs/DARK-TOKENS.md +0 -140
  29. package/docs/TYPE-SCALE.md +0 -111
  30. package/docs/messaging-deviations.md +0 -118
  31. package/index.html +0 -12
  32. package/renovate.json +0 -10
  33. package/scripts/chart-api-census.mjs +0 -415
  34. package/src/auth/AuthContext.jsx +0 -158
  35. package/src/auth/ReauthModal.jsx +0 -82
  36. package/src/auth/UserMenu.jsx +0 -121
  37. package/src/auth/apiClient.jsx +0 -232
  38. package/src/auth/authApi.jsx +0 -539
  39. package/src/auth/authConfig.jsx +0 -34
  40. package/src/auth/reauth.js +0 -47
  41. package/src/chat/ChatComposer.jsx +0 -36
  42. package/src/chat/ChatList.jsx +0 -87
  43. package/src/chat/ChatThread.jsx +0 -128
  44. package/src/chat/ChatWorkspace.jsx +0 -244
  45. package/src/chat/MarkdownReply.jsx +0 -22
  46. package/src/chat/ModelPicker.jsx +0 -85
  47. package/src/chat/api.js +0 -18
  48. package/src/chat/useChatSocket.js +0 -32
  49. package/src/chat/wire.js +0 -7
  50. package/src/components/AccessCodeManager.jsx +0 -288
  51. package/src/components/AccessCodeSingleUseToggle.jsx +0 -92
  52. package/src/components/AllowedEmailDomainsManager.jsx +0 -92
  53. package/src/components/AuthFactorRequirementCard.jsx +0 -95
  54. package/src/components/BulkInviteCsvTab.jsx +0 -198
  55. package/src/components/EmptyState.jsx +0 -38
  56. package/src/components/LoginForm.jsx +0 -159
  57. package/src/components/MFAComponent.jsx +0 -350
  58. package/src/components/MfaLoginComponent.jsx +0 -252
  59. package/src/components/MobileBottomNav.jsx +0 -82
  60. package/src/components/PasskeysComponent.jsx +0 -252
  61. package/src/components/PasswordChangeForm.jsx +0 -87
  62. package/src/components/PasswordResetRequestForm.jsx +0 -43
  63. package/src/components/PasswordSetForm.jsx +0 -97
  64. package/src/components/ProfileComponent.jsx +0 -348
  65. package/src/components/QrSignupManager.jsx +0 -404
  66. package/src/components/QrSignupValidityManager.jsx +0 -106
  67. package/src/components/RegistrationMethodsManager.jsx +0 -150
  68. package/src/components/SecurityComponent.jsx +0 -141
  69. package/src/components/SocialLoginButtons.jsx +0 -83
  70. package/src/components/SoftChip.jsx +0 -93
  71. package/src/components/StatTile.jsx +0 -39
  72. package/src/components/SupportRecoveryRequestsTab.jsx +0 -482
  73. package/src/components/TurnstileWidget.jsx +0 -99
  74. package/src/components/UserInviteComponent.jsx +0 -76
  75. package/src/components/UserListComponent.jsx +0 -618
  76. package/src/components/charts/BarChart.jsx +0 -102
  77. package/src/components/charts/ChartFrame.jsx +0 -214
  78. package/src/components/charts/LineChart.jsx +0 -126
  79. package/src/components/charts/ScatterChart.jsx +0 -299
  80. package/src/components/charts/TimeSeriesChart.jsx +0 -300
  81. package/src/components/charts/chartDefaults.js +0 -644
  82. package/src/components/charts/chartLabels.js +0 -36
  83. package/src/components/charts/exportChart.js +0 -258
  84. package/src/components/charts/formatters.js +0 -39
  85. package/src/components/charts/palette.js +0 -33
  86. package/src/components/charts/yearTickInterval.js +0 -7
  87. package/src/i18n/authTranslations.ts +0 -2651
  88. package/src/i18n/chartsTranslations.ts +0 -91
  89. package/src/i18n/chatTranslations.ts +0 -55
  90. package/src/i18n/messagingTranslations.ts +0 -120
  91. package/src/i18n/notificationsTranslations.ts +0 -32
  92. package/src/i18n/onboardingTranslations.ts +0 -29
  93. package/src/i18n/sectionNavTranslations.ts +0 -20
  94. package/src/i18n/uiCoreTranslations.js +0 -29
  95. package/src/i18n/userMenuTranslations.ts +0 -5
  96. package/src/index.js +0 -158
  97. package/src/layout/PageLayout.jsx +0 -36
  98. package/src/layout/SectionNav.jsx +0 -320
  99. package/src/messaging/AttachmentList.jsx +0 -145
  100. package/src/messaging/Composer.jsx +0 -197
  101. package/src/messaging/ConversationLaunchers.jsx +0 -51
  102. package/src/messaging/ConversationList.jsx +0 -109
  103. package/src/messaging/DirectMessageLauncher.jsx +0 -112
  104. package/src/messaging/MessageBubble.jsx +0 -183
  105. package/src/messaging/MessagingProvider.jsx +0 -0
  106. package/src/messaging/MessagingScopeConfig.jsx +0 -24
  107. package/src/messaging/PollCard.jsx +0 -163
  108. package/src/messaging/ReactionBar.jsx +0 -43
  109. package/src/messaging/ReadTicks.jsx +0 -82
  110. package/src/messaging/Thread.jsx +0 -195
  111. package/src/messaging/api.js +0 -48
  112. package/src/messaging/composerImageCompression.js +0 -35
  113. package/src/messaging/linkifyText.jsx +0 -37
  114. package/src/notifications/NotificationBell.jsx +0 -84
  115. package/src/notifications/NotificationSettings.jsx +0 -330
  116. package/src/notifications/NotificationsProvider.jsx +0 -224
  117. package/src/notifications/PopupSurface.jsx +0 -105
  118. package/src/notifications/api.js +0 -55
  119. package/src/notifications/feedApi.js +0 -18
  120. package/src/notifications/realtime.jsx +0 -138
  121. package/src/notifications/serviceWorker/sw.js +0 -50
  122. package/src/onboarding/OnboardingProvider.jsx +0 -326
  123. package/src/onboarding/OnboardingWizard.jsx +0 -61
  124. package/src/onboarding/WizardDialogShell.jsx +0 -51
  125. package/src/onboarding/api.js +0 -13
  126. package/src/onboarding/stepSelection.js +0 -16
  127. package/src/onboarding/steps/BrowserPushStep.jsx +0 -121
  128. package/src/onboarding/steps/CompleteNameStep.jsx +0 -46
  129. package/src/onboarding/steps/CookieConsentStep.jsx +0 -133
  130. package/src/onboarding/steps/PwaInstallStep.jsx +0 -47
  131. package/src/pages/AccountPage.jsx +0 -394
  132. package/src/pages/LoginPage.jsx +0 -343
  133. package/src/pages/PasswordChangePage.jsx +0 -62
  134. package/src/pages/PasswordInvitePage.jsx +0 -177
  135. package/src/pages/PasswordResetRequestPage.jsx +0 -68
  136. package/src/pages/SignUpPage.jsx +0 -268
  137. package/src/pages/SignupConfirmPage.jsx +0 -155
  138. package/src/testing/checkKitIntegration.js +0 -233
  139. package/src/theme/createAppTheme.js +0 -423
  140. package/src/theme/fonts.js +0 -3
  141. package/src/theme/index.js +0 -21
  142. package/src/theme/kitSxRegistry.js +0 -285
  143. package/src/theme/themeCompleteness.js +0 -1045
  144. package/src/theme/tokens.js +0 -478
  145. package/src/utils/auth-errors.js +0 -76
  146. package/src/utils/authService.js +0 -223
  147. package/src/utils/resolveErrorText.js +0 -28
  148. package/src/utils/webauthn.js +0 -51
  149. package/tests/AccountPage.profileStatements.test.jsx +0 -162
  150. package/tests/AccountPage.test.jsx +0 -200
  151. package/tests/AuthContext.test.jsx +0 -129
  152. package/tests/BarChart.test.jsx +0 -112
  153. package/tests/BrowserPushStep.test.jsx +0 -110
  154. package/tests/ChartFrame.test.jsx +0 -336
  155. package/tests/ConversationList.test.jsx +0 -144
  156. package/tests/CookieConsentStep.test.jsx +0 -69
  157. package/tests/EmptyState.test.jsx +0 -62
  158. package/tests/LineChart.test.jsx +0 -80
  159. package/tests/MessagingProvider.test.jsx +0 -50
  160. package/tests/MobileBottomNav.test.jsx +0 -319
  161. package/tests/NotificationBell.test.jsx +0 -60
  162. package/tests/NotificationSettings.test.jsx +0 -276
  163. package/tests/NotificationsProvider.test.jsx +0 -240
  164. package/tests/OnboardingProvider.test.jsx +0 -294
  165. package/tests/OnboardingWizard.test.jsx +0 -143
  166. package/tests/PasswordChangeForm.test.jsx +0 -70
  167. package/tests/PasswordInvitePage.test.jsx +0 -142
  168. package/tests/PasswordSetForm.test.jsx +0 -70
  169. package/tests/PopupSurface.test.jsx +0 -142
  170. package/tests/ProfileComponent.refresh.test.jsx +0 -194
  171. package/tests/QrSignupManager.registrationContext.test.jsx +0 -106
  172. package/tests/QrSignupManagerInfoBox.test.jsx +0 -49
  173. package/tests/ScatterChart.test.jsx +0 -270
  174. package/tests/SectionNav.test.jsx +0 -363
  175. package/tests/SignUpPage.test.jsx +0 -208
  176. package/tests/SoftChip.test.jsx +0 -105
  177. package/tests/StatTile.test.jsx +0 -57
  178. package/tests/Thread.test.jsx +0 -151
  179. package/tests/TimeSeriesChart.test.jsx +0 -367
  180. package/tests/UserListComponent.test.jsx +0 -192
  181. package/tests/UserMenu.test.jsx +0 -171
  182. package/tests/apiClientLanguage.test.js +0 -33
  183. package/tests/apiClientPublicPaths.test.js +0 -178
  184. package/tests/authApiLogin.test.js +0 -42
  185. package/tests/authApiRegistration.test.js +0 -31
  186. package/tests/authErrorCodeRendering.test.jsx +0 -77
  187. package/tests/authErrors.test.js +0 -74
  188. package/tests/authTranslations.test.js +0 -74
  189. package/tests/chart-api-census.test.js +0 -366
  190. package/tests/chartAxisTickBand.test.jsx +0 -95
  191. package/tests/chartDefaults.test.js +0 -902
  192. package/tests/chartLabels.test.js +0 -50
  193. package/tests/chartsPalette.test.js +0 -99
  194. package/tests/chatApi.test.js +0 -48
  195. package/tests/chatDriverNames.test.jsx +0 -71
  196. package/tests/chatExports.test.js +0 -3
  197. package/tests/chatList.test.jsx +0 -84
  198. package/tests/chatPicker.test.jsx +0 -82
  199. package/tests/chatSocket.test.jsx +0 -26
  200. package/tests/chatThread.test.jsx +0 -116
  201. package/tests/chatTranslations.test.js +0 -47
  202. package/tests/chatWorkspace.test.jsx +0 -234
  203. package/tests/checkKitIntegration.test.jsx +0 -219
  204. package/tests/createAppTheme.test.js +0 -132
  205. package/tests/createAppThemeDark.test.js +0 -127
  206. package/tests/createAppThemeLightGuard.test.js +0 -40
  207. package/tests/createAppThemePageContrast.test.js +0 -108
  208. package/tests/createAppThemeTypography.test.js +0 -53
  209. package/tests/errorCallSiteGuard.test.js +0 -32
  210. package/tests/exportChart.test.js +0 -313
  211. package/tests/feedApi.test.js +0 -46
  212. package/tests/fixtures/light-theme-baseline.json +0 -2234
  213. package/tests/i18nAggregate.test.js +0 -120
  214. package/tests/i18nGermanVariant.test.js +0 -65
  215. package/tests/loginPageErrorResolution.test.jsx +0 -102
  216. package/tests/messagingApi.test.js +0 -32
  217. package/tests/messagingChunk6.test.jsx +0 -116
  218. package/tests/messagingCompactBubble.test.jsx +0 -64
  219. package/tests/messagingComposer.test.jsx +0 -136
  220. package/tests/messagingComposerChunk5.test.jsx +0 -113
  221. package/tests/messagingContractConformance.test.js +0 -69
  222. package/tests/messagingDirectMessageLauncher.test.jsx +0 -151
  223. package/tests/messagingExports.test.js +0 -21
  224. package/tests/messagingInteractions.test.jsx +0 -136
  225. package/tests/messagingLastMessagePreview.test.jsx +0 -93
  226. package/tests/messagingLinkify.test.jsx +0 -51
  227. package/tests/messagingMessageActions.test.jsx +0 -163
  228. package/tests/messagingMsg6.test.jsx +0 -105
  229. package/tests/messagingMsg6f.test.jsx +0 -155
  230. package/tests/messagingMsg6g.test.jsx +0 -166
  231. package/tests/messagingMsg6h.test.jsx +0 -136
  232. package/tests/messagingMsg6i.test.jsx +0 -129
  233. package/tests/messagingPollRendering.test.jsx +0 -142
  234. package/tests/messagingReactionMerge.test.jsx +0 -77
  235. package/tests/messagingReadTicksTooltip.test.jsx +0 -36
  236. package/tests/messagingThreadReceipts.test.jsx +0 -178
  237. package/tests/messagingThreadingQuoting.test.jsx +0 -87
  238. package/tests/messagingUnreadLifecycle.test.jsx +0 -78
  239. package/tests/notificationsApi.test.js +0 -41
  240. package/tests/notificationsExports.test.js +0 -34
  241. package/tests/onboardingDescriptors.test.js +0 -132
  242. package/tests/packageTreeShaking.test.js +0 -126
  243. package/tests/realtime.test.jsx +0 -219
  244. package/tests/resolveErrorText.test.js +0 -72
  245. package/tests/stepSelection.test.js +0 -53
  246. package/tests/themeCompleteness.test.js +0 -626
  247. package/tests/timeSeriesLegend.test.js +0 -99
  248. package/tests/userScreenTranslations.test.jsx +0 -218
  249. package/tsconfig.build.json +0 -18
  250. package/vite.config.mjs +0 -6
  251. package/work-orders/AUTH-1.md +0 -74
  252. package/work-orders/AUTH-2.md +0 -74
  253. package/work-orders/AUTH-4.md +0 -183
  254. package/work-orders/AUTH-5.md +0 -154
  255. package/work-orders/AUTH-7.md +0 -181
  256. package/work-orders/AUTH-8.md +0 -184
  257. package/work-orders/CHART-1.md +0 -285
  258. package/work-orders/CHART-2.md +0 -222
  259. package/work-orders/CHART-3.md +0 -163
  260. package/work-orders/CHART-4.md +0 -203
  261. package/work-orders/CHART-5.md +0 -226
  262. package/work-orders/CHART-6.md +0 -428
  263. package/work-orders/CHART-7.md +0 -175
  264. package/work-orders/DX-1.md +0 -169
  265. package/work-orders/DX-2.md +0 -188
  266. package/work-orders/DX-3.md +0 -195
  267. package/work-orders/I18N-1.md +0 -254
  268. package/work-orders/I18N-3.md +0 -207
  269. package/work-orders/MSG-3.md +0 -375
  270. package/work-orders/MSG-3b.md +0 -1002
  271. package/work-orders/MSG-3c.md +0 -378
  272. package/work-orders/MSG-3d.md +0 -268
  273. package/work-orders/MSG-3e.md +0 -164
  274. package/work-orders/MSG-3f.md +0 -391
  275. package/work-orders/MSG-6e.md +0 -308
  276. package/work-orders/MSG-6f.md +0 -214
  277. package/work-orders/MSG-6g.md +0 -244
  278. package/work-orders/MSG-6h.md +0 -238
  279. package/work-orders/MSG-6i.md +0 -271
  280. package/work-orders/MSG-6j.md +0 -117
  281. package/work-orders/NOTIF-12.md +0 -214
  282. package/work-orders/NOTIF-13.md +0 -142
  283. package/work-orders/NOTIF-14.md +0 -151
  284. package/work-orders/PRIM-1.md +0 -177
  285. package/work-orders/SHELL-1.md +0 -255
  286. package/work-orders/SHELL-2.md +0 -197
  287. package/work-orders/SHELL-3.md +0 -359
  288. package/work-orders/SHELL-4.md +0 -351
  289. package/work-orders/SHELL-5.md +0 -345
  290. package/work-orders/SHELL-6.md +0 -210
  291. package/work-orders/THEME-1.md +0 -587
  292. package/work-orders/THEME-10.md +0 -303
  293. package/work-orders/THEME-11.md +0 -208
  294. package/work-orders/THEME-2.md +0 -339
  295. package/work-orders/THEME-3.md +0 -210
  296. package/work-orders/THEME-4.md +0 -271
  297. package/work-orders/THEME-5.md +0 -341
  298. package/work-orders/THEME-6.md +0 -247
  299. package/work-orders/THEME-7.md +0 -82
  300. package/work-orders/THEME-8.md +0 -211
  301. package/work-orders/THEME-9.md +0 -194
  302. package/work-orders/UCM-AUTH-10.md +0 -490
  303. package/work-orders/UCM-AUTH-11.md +0 -185
  304. package/work-orders/UCM-AUTH-12.md +0 -98
  305. package/work-orders/UCM-AUTH-13.md +0 -47
  306. package/work-orders/UCM-AUTH-9.md +0 -207
  307. package/work-orders/UCM-CHART-10.md +0 -150
  308. package/work-orders/UCM-CHART-11.md +0 -132
  309. package/work-orders/UCM-CHART-12.md +0 -348
  310. package/work-orders/UCM-CHART-13.md +0 -122
  311. package/work-orders/UCM-CHART-14.md +0 -198
  312. package/work-orders/UCM-CHART-15.md +0 -187
  313. package/work-orders/UCM-CHART-16.md +0 -169
  314. package/work-orders/UCM-CHART-17.md +0 -195
  315. package/work-orders/UCM-CHART-18.md +0 -200
  316. package/work-orders/UCM-CHART-8.md +0 -147
  317. package/work-orders/UCM-CHART-9.md +0 -265
  318. package/work-orders/UCM-CHAT-1.md +0 -190
  319. package/work-orders/UCM-CHAT-2.md +0 -75
  320. package/work-orders/UCM-CI-1.md +0 -65
  321. package/work-orders/UCM-DEP-1.md +0 -63
  322. package/work-orders/UCM-I18N-4.md +0 -226
  323. package/work-orders/UCM-I18N-5.md +0 -211
  324. package/work-orders/UCM-MSG-20.md +0 -192
  325. package/work-orders/UCM-PRIM-2.md +0 -114
  326. package/work-orders/UCM-SHELL-7.md +0 -134
  327. package/work-orders/UCM-SHELL-8.md +0 -125
  328. package/work-orders/UCM-TEST-1.md +0 -304
  329. package/work-orders/UCM-THEME-13.md +0 -69
  330. package/work-orders/UCM-THEME-14.md +0 -312
  331. package/work-orders/UCM-THEME-15.md +0 -356
  332. package/work-orders/UCM-THEME-16.md +0 -80
  333. package/work-orders/UCM-THEME-17.md +0 -111
  334. package/work-orders/UCM-THEME-18.md +0 -184
  335. package/work-orders/assets/AUTH-4-user-list-card.html +0 -407
  336. package/work-orders/assets/PRIM-1-dashboard-primitives.html +0 -624
  337. package/work-orders/assets/SHELL-2-account-navigation.html +0 -1159
  338. package/work-orders/assets/THEME-1-baseline-reference-sheet.html +0 -1352
  339. package/work-orders/assets/UCM-CHAT-1-ai-chat.html +0 -447
  340. package/work-orders/assets/UCM-THEME-13-dark-prototype.html +0 -390
  341. 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).