@micha.bigler/ui-core-micha 3.14.4 → 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.
- package/CHANGELOG.md +25 -0
- package/README.md +7 -0
- package/dist/chat/kitSxRegistry.js +9 -0
- package/dist/components/charts/kitSxRegistry.js +6 -0
- package/dist/entries/charts.js +6 -0
- package/dist/entries/chat.js +8 -0
- package/dist/entries/markdown.js +1 -0
- package/dist/index.js +0 -14
- package/dist/pages/AccountPage.js +1 -2
- package/dist/pages/LoginPage.js +1 -2
- package/dist/pages/PasswordChangePage.js +1 -2
- package/dist/pages/PasswordInvitePage.js +1 -2
- package/dist/pages/PasswordResetRequestPage.js +1 -2
- package/dist/pages/SignUpPage.js +1 -2
- package/dist/pages/SignupConfirmPage.js +1 -2
- package/dist/theme/kitSxEntry.js +11 -0
- package/dist/theme/kitSxRegistry.js +2 -15
- package/package.json +32 -7
- package/.github/workflows/ci.yml +0 -35
- package/.github/workflows/publish.yml +0 -126
- package/DESIGN.md +0 -60
- package/WORK_ORDERS.md +0 -150
- package/dev/entries.jsx +0 -721
- package/dev/fixtures.js +0 -26
- package/dev/main.jsx +0 -75
- package/dev/mockTransport.jsx +0 -128
- package/docs/CHART-LAYOUT.md +0 -157
- package/docs/DARK-TOKENS.md +0 -140
- package/docs/TYPE-SCALE.md +0 -111
- package/docs/messaging-deviations.md +0 -118
- package/index.html +0 -12
- package/renovate.json +0 -10
- package/scripts/chart-api-census.mjs +0 -415
- package/src/auth/AuthContext.jsx +0 -158
- package/src/auth/ReauthModal.jsx +0 -82
- package/src/auth/UserMenu.jsx +0 -121
- package/src/auth/apiClient.jsx +0 -232
- package/src/auth/authApi.jsx +0 -539
- package/src/auth/authConfig.jsx +0 -34
- package/src/auth/reauth.js +0 -47
- package/src/chat/ChatComposer.jsx +0 -36
- package/src/chat/ChatList.jsx +0 -87
- package/src/chat/ChatThread.jsx +0 -128
- package/src/chat/ChatWorkspace.jsx +0 -244
- package/src/chat/MarkdownReply.jsx +0 -22
- package/src/chat/ModelPicker.jsx +0 -85
- package/src/chat/api.js +0 -18
- package/src/chat/useChatSocket.js +0 -32
- package/src/chat/wire.js +0 -7
- package/src/components/AccessCodeManager.jsx +0 -288
- package/src/components/AccessCodeSingleUseToggle.jsx +0 -92
- package/src/components/AllowedEmailDomainsManager.jsx +0 -92
- package/src/components/AuthFactorRequirementCard.jsx +0 -95
- package/src/components/BulkInviteCsvTab.jsx +0 -198
- package/src/components/EmptyState.jsx +0 -38
- package/src/components/LoginForm.jsx +0 -159
- package/src/components/MFAComponent.jsx +0 -350
- package/src/components/MfaLoginComponent.jsx +0 -252
- package/src/components/MobileBottomNav.jsx +0 -82
- package/src/components/PasskeysComponent.jsx +0 -252
- package/src/components/PasswordChangeForm.jsx +0 -87
- package/src/components/PasswordResetRequestForm.jsx +0 -43
- package/src/components/PasswordSetForm.jsx +0 -97
- package/src/components/ProfileComponent.jsx +0 -348
- package/src/components/QrSignupManager.jsx +0 -404
- package/src/components/QrSignupValidityManager.jsx +0 -106
- package/src/components/RegistrationMethodsManager.jsx +0 -150
- package/src/components/SecurityComponent.jsx +0 -141
- package/src/components/SocialLoginButtons.jsx +0 -83
- package/src/components/SoftChip.jsx +0 -93
- package/src/components/StatTile.jsx +0 -39
- package/src/components/SupportRecoveryRequestsTab.jsx +0 -482
- package/src/components/TurnstileWidget.jsx +0 -99
- package/src/components/UserInviteComponent.jsx +0 -76
- package/src/components/UserListComponent.jsx +0 -618
- package/src/components/charts/BarChart.jsx +0 -102
- package/src/components/charts/ChartFrame.jsx +0 -214
- package/src/components/charts/LineChart.jsx +0 -126
- package/src/components/charts/ScatterChart.jsx +0 -299
- package/src/components/charts/TimeSeriesChart.jsx +0 -300
- package/src/components/charts/chartDefaults.js +0 -644
- package/src/components/charts/chartLabels.js +0 -36
- package/src/components/charts/exportChart.js +0 -258
- package/src/components/charts/formatters.js +0 -39
- package/src/components/charts/palette.js +0 -33
- package/src/components/charts/yearTickInterval.js +0 -7
- package/src/i18n/authTranslations.ts +0 -2651
- package/src/i18n/chartsTranslations.ts +0 -91
- package/src/i18n/chatTranslations.ts +0 -55
- package/src/i18n/messagingTranslations.ts +0 -120
- package/src/i18n/notificationsTranslations.ts +0 -32
- package/src/i18n/onboardingTranslations.ts +0 -29
- package/src/i18n/sectionNavTranslations.ts +0 -20
- package/src/i18n/uiCoreTranslations.js +0 -29
- package/src/i18n/userMenuTranslations.ts +0 -5
- package/src/index.js +0 -158
- package/src/layout/PageLayout.jsx +0 -36
- package/src/layout/SectionNav.jsx +0 -320
- package/src/messaging/AttachmentList.jsx +0 -145
- package/src/messaging/Composer.jsx +0 -197
- package/src/messaging/ConversationLaunchers.jsx +0 -51
- package/src/messaging/ConversationList.jsx +0 -109
- package/src/messaging/DirectMessageLauncher.jsx +0 -112
- package/src/messaging/MessageBubble.jsx +0 -183
- package/src/messaging/MessagingProvider.jsx +0 -0
- package/src/messaging/MessagingScopeConfig.jsx +0 -24
- package/src/messaging/PollCard.jsx +0 -163
- package/src/messaging/ReactionBar.jsx +0 -43
- package/src/messaging/ReadTicks.jsx +0 -82
- package/src/messaging/Thread.jsx +0 -195
- package/src/messaging/api.js +0 -48
- package/src/messaging/composerImageCompression.js +0 -35
- package/src/messaging/linkifyText.jsx +0 -37
- package/src/notifications/NotificationBell.jsx +0 -84
- package/src/notifications/NotificationSettings.jsx +0 -330
- package/src/notifications/NotificationsProvider.jsx +0 -224
- package/src/notifications/PopupSurface.jsx +0 -105
- package/src/notifications/api.js +0 -55
- package/src/notifications/feedApi.js +0 -18
- package/src/notifications/realtime.jsx +0 -138
- package/src/notifications/serviceWorker/sw.js +0 -50
- package/src/onboarding/OnboardingProvider.jsx +0 -326
- package/src/onboarding/OnboardingWizard.jsx +0 -61
- package/src/onboarding/WizardDialogShell.jsx +0 -51
- package/src/onboarding/api.js +0 -13
- package/src/onboarding/stepSelection.js +0 -16
- package/src/onboarding/steps/BrowserPushStep.jsx +0 -121
- package/src/onboarding/steps/CompleteNameStep.jsx +0 -46
- package/src/onboarding/steps/CookieConsentStep.jsx +0 -133
- package/src/onboarding/steps/PwaInstallStep.jsx +0 -47
- package/src/pages/AccountPage.jsx +0 -394
- package/src/pages/LoginPage.jsx +0 -343
- package/src/pages/PasswordChangePage.jsx +0 -62
- package/src/pages/PasswordInvitePage.jsx +0 -177
- package/src/pages/PasswordResetRequestPage.jsx +0 -68
- package/src/pages/SignUpPage.jsx +0 -268
- package/src/pages/SignupConfirmPage.jsx +0 -155
- package/src/testing/checkKitIntegration.js +0 -233
- package/src/theme/createAppTheme.js +0 -423
- package/src/theme/fonts.js +0 -3
- package/src/theme/index.js +0 -21
- package/src/theme/kitSxRegistry.js +0 -285
- package/src/theme/themeCompleteness.js +0 -1045
- package/src/theme/tokens.js +0 -478
- package/src/utils/auth-errors.js +0 -76
- package/src/utils/authService.js +0 -223
- package/src/utils/resolveErrorText.js +0 -28
- package/src/utils/webauthn.js +0 -51
- package/tests/AccountPage.profileStatements.test.jsx +0 -162
- package/tests/AccountPage.test.jsx +0 -200
- package/tests/AuthContext.test.jsx +0 -129
- package/tests/BarChart.test.jsx +0 -112
- package/tests/BrowserPushStep.test.jsx +0 -110
- package/tests/ChartFrame.test.jsx +0 -336
- package/tests/ConversationList.test.jsx +0 -144
- package/tests/CookieConsentStep.test.jsx +0 -69
- package/tests/EmptyState.test.jsx +0 -62
- package/tests/LineChart.test.jsx +0 -80
- package/tests/MessagingProvider.test.jsx +0 -50
- package/tests/MobileBottomNav.test.jsx +0 -319
- package/tests/NotificationBell.test.jsx +0 -60
- package/tests/NotificationSettings.test.jsx +0 -276
- package/tests/NotificationsProvider.test.jsx +0 -240
- package/tests/OnboardingProvider.test.jsx +0 -294
- package/tests/OnboardingWizard.test.jsx +0 -143
- package/tests/PasswordChangeForm.test.jsx +0 -70
- package/tests/PasswordInvitePage.test.jsx +0 -142
- package/tests/PasswordSetForm.test.jsx +0 -70
- package/tests/PopupSurface.test.jsx +0 -142
- package/tests/ProfileComponent.refresh.test.jsx +0 -194
- package/tests/QrSignupManager.registrationContext.test.jsx +0 -106
- package/tests/QrSignupManagerInfoBox.test.jsx +0 -49
- package/tests/ScatterChart.test.jsx +0 -270
- package/tests/SectionNav.test.jsx +0 -363
- package/tests/SignUpPage.test.jsx +0 -208
- package/tests/SoftChip.test.jsx +0 -105
- package/tests/StatTile.test.jsx +0 -57
- package/tests/Thread.test.jsx +0 -151
- package/tests/TimeSeriesChart.test.jsx +0 -367
- package/tests/UserListComponent.test.jsx +0 -192
- package/tests/UserMenu.test.jsx +0 -171
- package/tests/apiClientLanguage.test.js +0 -33
- package/tests/apiClientPublicPaths.test.js +0 -178
- package/tests/authApiLogin.test.js +0 -42
- package/tests/authApiRegistration.test.js +0 -31
- package/tests/authErrorCodeRendering.test.jsx +0 -77
- package/tests/authErrors.test.js +0 -74
- package/tests/authTranslations.test.js +0 -74
- package/tests/chart-api-census.test.js +0 -366
- package/tests/chartAxisTickBand.test.jsx +0 -95
- package/tests/chartDefaults.test.js +0 -902
- package/tests/chartLabels.test.js +0 -50
- package/tests/chartsPalette.test.js +0 -99
- package/tests/chatApi.test.js +0 -48
- package/tests/chatDriverNames.test.jsx +0 -71
- package/tests/chatExports.test.js +0 -3
- package/tests/chatList.test.jsx +0 -84
- package/tests/chatPicker.test.jsx +0 -82
- package/tests/chatSocket.test.jsx +0 -26
- package/tests/chatThread.test.jsx +0 -116
- package/tests/chatTranslations.test.js +0 -47
- package/tests/chatWorkspace.test.jsx +0 -234
- package/tests/checkKitIntegration.test.jsx +0 -219
- package/tests/createAppTheme.test.js +0 -132
- package/tests/createAppThemeDark.test.js +0 -127
- package/tests/createAppThemeLightGuard.test.js +0 -40
- package/tests/createAppThemePageContrast.test.js +0 -108
- package/tests/createAppThemeTypography.test.js +0 -53
- package/tests/errorCallSiteGuard.test.js +0 -32
- package/tests/exportChart.test.js +0 -313
- package/tests/feedApi.test.js +0 -46
- package/tests/fixtures/light-theme-baseline.json +0 -2234
- package/tests/i18nAggregate.test.js +0 -120
- package/tests/i18nGermanVariant.test.js +0 -65
- package/tests/loginPageErrorResolution.test.jsx +0 -102
- package/tests/messagingApi.test.js +0 -32
- package/tests/messagingChunk6.test.jsx +0 -116
- package/tests/messagingCompactBubble.test.jsx +0 -64
- package/tests/messagingComposer.test.jsx +0 -136
- package/tests/messagingComposerChunk5.test.jsx +0 -113
- package/tests/messagingContractConformance.test.js +0 -69
- package/tests/messagingDirectMessageLauncher.test.jsx +0 -151
- package/tests/messagingExports.test.js +0 -21
- package/tests/messagingInteractions.test.jsx +0 -136
- package/tests/messagingLastMessagePreview.test.jsx +0 -93
- package/tests/messagingLinkify.test.jsx +0 -51
- package/tests/messagingMessageActions.test.jsx +0 -163
- package/tests/messagingMsg6.test.jsx +0 -105
- package/tests/messagingMsg6f.test.jsx +0 -155
- package/tests/messagingMsg6g.test.jsx +0 -166
- package/tests/messagingMsg6h.test.jsx +0 -136
- package/tests/messagingMsg6i.test.jsx +0 -129
- package/tests/messagingPollRendering.test.jsx +0 -142
- package/tests/messagingReactionMerge.test.jsx +0 -77
- package/tests/messagingReadTicksTooltip.test.jsx +0 -36
- package/tests/messagingThreadReceipts.test.jsx +0 -178
- package/tests/messagingThreadingQuoting.test.jsx +0 -87
- package/tests/messagingUnreadLifecycle.test.jsx +0 -78
- package/tests/notificationsApi.test.js +0 -41
- package/tests/notificationsExports.test.js +0 -34
- package/tests/onboardingDescriptors.test.js +0 -132
- package/tests/packageTreeShaking.test.js +0 -126
- package/tests/realtime.test.jsx +0 -219
- package/tests/resolveErrorText.test.js +0 -72
- package/tests/stepSelection.test.js +0 -53
- package/tests/themeCompleteness.test.js +0 -626
- package/tests/timeSeriesLegend.test.js +0 -99
- package/tests/userScreenTranslations.test.jsx +0 -218
- package/tsconfig.build.json +0 -18
- package/vite.config.mjs +0 -6
- package/work-orders/AUTH-1.md +0 -74
- package/work-orders/AUTH-2.md +0 -74
- package/work-orders/AUTH-4.md +0 -183
- package/work-orders/AUTH-5.md +0 -154
- package/work-orders/AUTH-7.md +0 -181
- package/work-orders/AUTH-8.md +0 -184
- package/work-orders/CHART-1.md +0 -285
- package/work-orders/CHART-2.md +0 -222
- package/work-orders/CHART-3.md +0 -163
- package/work-orders/CHART-4.md +0 -203
- package/work-orders/CHART-5.md +0 -226
- package/work-orders/CHART-6.md +0 -428
- package/work-orders/CHART-7.md +0 -175
- package/work-orders/DX-1.md +0 -169
- package/work-orders/DX-2.md +0 -188
- package/work-orders/DX-3.md +0 -195
- package/work-orders/I18N-1.md +0 -254
- package/work-orders/I18N-3.md +0 -207
- package/work-orders/MSG-3.md +0 -375
- package/work-orders/MSG-3b.md +0 -1002
- package/work-orders/MSG-3c.md +0 -378
- package/work-orders/MSG-3d.md +0 -268
- package/work-orders/MSG-3e.md +0 -164
- package/work-orders/MSG-3f.md +0 -391
- package/work-orders/MSG-6e.md +0 -308
- package/work-orders/MSG-6f.md +0 -214
- package/work-orders/MSG-6g.md +0 -244
- package/work-orders/MSG-6h.md +0 -238
- package/work-orders/MSG-6i.md +0 -271
- package/work-orders/MSG-6j.md +0 -117
- package/work-orders/NOTIF-12.md +0 -214
- package/work-orders/NOTIF-13.md +0 -142
- package/work-orders/NOTIF-14.md +0 -151
- package/work-orders/PRIM-1.md +0 -177
- package/work-orders/SHELL-1.md +0 -255
- package/work-orders/SHELL-2.md +0 -197
- package/work-orders/SHELL-3.md +0 -359
- package/work-orders/SHELL-4.md +0 -351
- package/work-orders/SHELL-5.md +0 -345
- package/work-orders/SHELL-6.md +0 -210
- package/work-orders/THEME-1.md +0 -587
- package/work-orders/THEME-10.md +0 -303
- package/work-orders/THEME-11.md +0 -208
- package/work-orders/THEME-2.md +0 -339
- package/work-orders/THEME-3.md +0 -210
- package/work-orders/THEME-4.md +0 -271
- package/work-orders/THEME-5.md +0 -341
- package/work-orders/THEME-6.md +0 -247
- package/work-orders/THEME-7.md +0 -82
- package/work-orders/THEME-8.md +0 -211
- package/work-orders/THEME-9.md +0 -194
- package/work-orders/UCM-AUTH-10.md +0 -490
- package/work-orders/UCM-AUTH-11.md +0 -185
- package/work-orders/UCM-AUTH-12.md +0 -98
- package/work-orders/UCM-AUTH-13.md +0 -47
- package/work-orders/UCM-AUTH-9.md +0 -207
- package/work-orders/UCM-CHART-10.md +0 -150
- package/work-orders/UCM-CHART-11.md +0 -132
- package/work-orders/UCM-CHART-12.md +0 -348
- package/work-orders/UCM-CHART-13.md +0 -122
- package/work-orders/UCM-CHART-14.md +0 -198
- package/work-orders/UCM-CHART-15.md +0 -187
- package/work-orders/UCM-CHART-16.md +0 -169
- package/work-orders/UCM-CHART-17.md +0 -195
- package/work-orders/UCM-CHART-18.md +0 -200
- package/work-orders/UCM-CHART-8.md +0 -147
- package/work-orders/UCM-CHART-9.md +0 -265
- package/work-orders/UCM-CHAT-1.md +0 -190
- package/work-orders/UCM-CHAT-2.md +0 -75
- package/work-orders/UCM-CI-1.md +0 -65
- package/work-orders/UCM-DEP-1.md +0 -63
- package/work-orders/UCM-I18N-4.md +0 -226
- package/work-orders/UCM-I18N-5.md +0 -211
- package/work-orders/UCM-MSG-20.md +0 -192
- package/work-orders/UCM-PRIM-2.md +0 -114
- package/work-orders/UCM-SHELL-7.md +0 -134
- package/work-orders/UCM-SHELL-8.md +0 -125
- package/work-orders/UCM-TEST-1.md +0 -304
- package/work-orders/UCM-THEME-13.md +0 -69
- package/work-orders/UCM-THEME-14.md +0 -312
- package/work-orders/UCM-THEME-15.md +0 -356
- package/work-orders/UCM-THEME-16.md +0 -80
- package/work-orders/UCM-THEME-17.md +0 -111
- package/work-orders/UCM-THEME-18.md +0 -184
- package/work-orders/assets/AUTH-4-user-list-card.html +0 -407
- package/work-orders/assets/PRIM-1-dashboard-primitives.html +0 -624
- package/work-orders/assets/SHELL-2-account-navigation.html +0 -1159
- package/work-orders/assets/THEME-1-baseline-reference-sheet.html +0 -1352
- package/work-orders/assets/UCM-CHAT-1-ai-chat.html +0 -447
- package/work-orders/assets/UCM-THEME-13-dark-prototype.html +0 -390
- package/work-orders/assets/UCM-THEME-17-type-scale.html +0 -391
package/work-orders/AUTH-4.md
DELETED
|
@@ -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`.
|
package/work-orders/AUTH-5.md
DELETED
|
@@ -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.
|
package/work-orders/AUTH-7.md
DELETED
|
@@ -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).
|