Repository navigation
Commit 3cdcf7f
authored
refactor(users): split into admin/auth_local/oauth feature folders (#153)
* refactor(users): split into admin/auth_local/oauth feature folders
Reorganize the users module intra-package from a type-folder layout
(endpoints/, service.py, oauth.py at top level) to a feature-folder
layout where each sub-feature owns its routes, service, views, and
components.
modules/users/users/
admin/ # service, REST API, Inertia views, React components
auth_local/ # login/register/reset/verify/profile + accept-invite
oauth/ # provider builders + per-provider routes (__init__.py
# re-exports the prior `users.oauth.{X}` surface)
Shared infrastructure stays at top level (deps, manager, backend, models,
contracts, mailer, middleware, bootstrap, pages, locales).
UsersModule.register_routes is now the single point of cross-feature
wiring; no feature imports from a sibling feature in either the API or
views layer. The login page's OAuth-provider list is cached once at boot
on app.state.users.oauth_providers so auth_local/views.py doesn't reach
into the oauth feature.
Framework filesystem conventions are preserved unchanged: pages/ stays
a single tree at the package root (required by
simple_module_hosting.manifest.compute_module_pages) and locales/ stays
in place.
Scope: the users module only. The scaffold templates, framework-conventions
docs, and other modules are deliberately not touched — this is a POC to
validate the layout before propagating it.
Verified locally: make lint, make doctor, full pytest (1010 passed), JS
tests (8 passed), and a live uvicorn+Vite run exercising the refactored
auth_local/api login wrapper, auth_local/views login page, admin/api
list, admin/views Inertia index, and the moved admin/components/*.tsx
imports.
* fix(users): read login_redirect_url lazily on OAuth callback
Address two issues raised in PR review:
1. `oauth/api.py` captured `settings.login_redirect_url` as a string at
route-registration time, then closed over it. `UsersModule.on_startup`
mutates `app.state.users.settings.login_redirect_url` (dashboard
fallback), and admins can change it at runtime via the settings UI,
so OAuth callbacks could redirect to a stale URL. Now the callback
reads it from `request.app.state.users.settings` at request time.
`_build_provider_router` no longer takes a `login_redirect_url`
parameter.
2. The `register_routes` comment claimed constructing `UsersSettings()`
"re-reads env_str-bound fields like OAuth client ids/secrets" — this
is wrong: `env_str()` is evaluated when `UsersSettings` is defined
(class-attribute defaults), so re-instantiating doesn't re-read env.
Updated to accurately describe why a fresh instance is acceptable
here (only `build_clients` reads it, and only static fields) and to
point readers at `app.state.users.settings` for mutable fields.
Both issues were pre-existing latent behaviour surfaced by the review
of this PR. Tests still pass (1010); doctor clean.1 parent 52f47a0 commit 3cdcf7f
26 files changed
Lines changed: 319 additions & 320 deletions
File tree
- docs/testing
- modules/users
- tests
- users
- admin
- components
- auth_local
- endpoints
- oauth
- pages/Users
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
108 | | - | |
| 108 | + | |
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
198 | 198 | | |
199 | 199 | | |
200 | 200 | | |
201 | | - | |
| 201 | + | |
202 | 202 | | |
203 | 203 | | |
204 | 204 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
16 | | - | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
15 | | - | |
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| 80 | + | |
80 | 81 | | |
81 | 82 | | |
82 | 83 | | |
83 | | - | |
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
187 | 187 | | |
188 | 188 | | |
189 | 189 | | |
190 | | - | |
| 190 | + | |
191 | 191 | | |
192 | 192 | | |
193 | 193 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
2 | | - | |
3 | | - | |
4 | | - | |
5 | | - | |
| 1 | + | |
6 | 2 | | |
7 | 3 | | |
8 | 4 | | |
| |||
13 | 9 | | |
14 | 10 | | |
15 | 11 | | |
| 12 | + | |
16 | 13 | | |
17 | 14 | | |
18 | 15 | | |
| |||
23 | 20 | | |
24 | 21 | | |
25 | 22 | | |
26 | | - | |
27 | 23 | | |
28 | 24 | | |
29 | 25 | | |
| |||
File renamed without changes.
File renamed without changes.
0 commit comments