Split internal/web into subpackages before domain-admin growth.
test / test (push) Has been cancelled
test / test (push) Has been cancelled
Lay out view, auth, validate, and handlers under internal/web while keeping the cmd/panel API unchanged; update roadmap and changelog for web-split closure. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+11
-3
@@ -188,10 +188,10 @@ holds the cookie works after process restart, redeploy, or full backup restore.
|
||||
- **Idle timeout** — sliding window, `PANEL_SESSION_IDLE_DAYS` (default 7); no
|
||||
absolute cap (regular use keeps the session alive indefinitely).
|
||||
- **Renewal** — DB `last_seen` and cookie `Max-Age` update at most once per hour
|
||||
(`renewThreshold` in [internal/web/session.go](../internal/web/session.go)).
|
||||
(`renewThreshold` in [internal/web/auth/session.go](../internal/web/auth/session.go)).
|
||||
- **Password change** — all other sessions are deleted; the current session stays
|
||||
active ([internal/store/sessions.go](../internal/store/sessions.go),
|
||||
[handlers_account.go](../internal/web/handlers_account.go)).
|
||||
[handlers_account.go](../internal/web/handlers/handlers_account.go)).
|
||||
|
||||
Restoring an **older** backup also restores session rows: a session invalidated
|
||||
after that backup was taken can become valid again if the browser still has the
|
||||
@@ -218,7 +218,15 @@ flowchart TB
|
||||
backupcli["selfpost-backup CLI"]
|
||||
end
|
||||
subgraph web ["internal/web — HTTP surface"]
|
||||
handlers["handlers_*.go, templates, session/security"]
|
||||
webRoot["web.go — router, security"]
|
||||
viewPkg["web/view — templates, static"]
|
||||
authPkg["web/auth — session, login, setup"]
|
||||
handlersPkg["web/handlers — authenticated pages"]
|
||||
webRoot --> viewPkg
|
||||
webRoot --> authPkg
|
||||
webRoot --> handlersPkg
|
||||
handlersPkg --> authPkg
|
||||
handlersPkg --> viewPkg
|
||||
end
|
||||
subgraph services ["Services — multi-store operations + rollback"]
|
||||
domainSvc["internal/domain"]
|
||||
|
||||
+2
-2
@@ -112,7 +112,7 @@ the tree are AGPL-3.0-compatible.
|
||||
|
||||
| Asset | Version | Repository | License |
|
||||
|---|---|---|---|
|
||||
| `internal/web/static/htmx.min.js` | 2.0.4 | <https://github.com/bigskysoftware/htmx> | 0BSD |
|
||||
| `internal/web/view/static/htmx.min.js` | 2.0.4 | <https://github.com/bigskysoftware/htmx> | 0BSD |
|
||||
|
||||
### E2e module (`test/e2e/go.mod`)
|
||||
|
||||
@@ -354,7 +354,7 @@ to prose.
|
||||
| Mail path | [build/postfix-config.sh](../build/postfix-config.sh) |
|
||||
| Panel routes | [internal/web/web.go](../internal/web/web.go) |
|
||||
| Backup / restore, domain export | [internal/backup/](../internal/backup/), [cmd/selfpost-backup/](../cmd/selfpost-backup/) |
|
||||
| Sessions | [internal/store/sessions.go](../internal/store/sessions.go), [internal/web/session.go](../internal/web/session.go) |
|
||||
| Sessions | [internal/store/sessions.go](../internal/store/sessions.go), [internal/web/auth/session.go](../internal/web/auth/session.go) |
|
||||
| Log rotation, reload | [build/logrotate-mail.conf](../build/logrotate-mail.conf), [build/logrotate-loop.sh](../build/logrotate-loop.sh), [build/postfix-cert-reload.sh](../build/postfix-cert-reload.sh) |
|
||||
| Deploy | [deploy/docker-compose.yml](../deploy/docker-compose.yml), [build/Dockerfile](../build/Dockerfile) |
|
||||
| Operator checklist | [§ User-facing deliverables](#user-facing-deliverables); detail — [guide.md](guide.md) |
|
||||
|
||||
@@ -23,7 +23,7 @@ list:
|
||||
deletion, its own L2 limit);
|
||||
- the domain's DKIM/DNS status;
|
||||
- the send log filtered to the domain — the filter already exists in the log
|
||||
([sendLogData](../../internal/web/handlers_monitor.go)).
|
||||
([sendLogData](../../internal/web/handlers/handlers_monitor.go)).
|
||||
|
||||
What stays outside the role is what is global by nature:
|
||||
|
||||
|
||||
+18
-4
@@ -1,6 +1,6 @@
|
||||
# Plan: web-split (splitting `internal/web`)
|
||||
|
||||
**Status:** agreed
|
||||
**Status:** done (see [CHANGELOG](../CHANGELOG.md) `[Unreleased]`)
|
||||
**Version:** `1.x`; an internal refactor, it does not force a break on its own.
|
||||
|
||||
---
|
||||
@@ -42,11 +42,25 @@ domains. The refactor is cheaper before that growth than after it.
|
||||
|
||||
The order is a recommendation, not a blocker.
|
||||
|
||||
## Chosen scheme
|
||||
|
||||
**Horizontal split into four packages** (decided at implementation):
|
||||
|
||||
```
|
||||
internal/web/ # Config, Server, New, Handler — composition root; security.go
|
||||
internal/web/view/ # embed templates/static, render/renderFragment, staticHandler
|
||||
internal/web/auth/ # session, login/logout/setup, requireAuth, currentUser
|
||||
internal/web/validate/ # shared form validation (avoids auth ↔ handlers import cycle)
|
||||
internal/web/handlers/ # all authenticated page handlers (handlers_*.go)
|
||||
```
|
||||
|
||||
`cmd/panel` keeps importing only `internal/web`. Subpackages are not exported
|
||||
beyond what the composition root needs.
|
||||
|
||||
## Done when
|
||||
|
||||
The decision is made deliberately when the work starts — either the package is
|
||||
split along the chosen scheme, or it is settled that it stays flat. After a
|
||||
split: `build`/`vet`/`test` green, the panel's behaviour unchanged.
|
||||
The package is split along the scheme above. After the split: `build`/`vet`/`test`
|
||||
green, the panel's behaviour unchanged.
|
||||
|
||||
## Risks
|
||||
|
||||
|
||||
+5
-27
@@ -26,17 +26,15 @@ in `git log` and [CHANGELOG.md](../CHANGELOG.md).
|
||||
|
||||
| ID | Topic | Status | Plan |
|
||||
|---|---|---|---|
|
||||
| web-split | Splitting `internal/web` | **agreed** | [plans/web-split.md](plans/web-split.md) |
|
||||
| domain-admin | Domain administrator role | **agreed** | [plans/domain-admin.md](plans/domain-admin.md) |
|
||||
| inbound-relay | Inbound relay (backup-MX / forwarding) | **agreed** | [plans/inbound-relay.md](plans/inbound-relay.md) |
|
||||
| contributing | `CONTRIBUTING.md` | candidate | — |
|
||||
| visual-style | Обновление визуального стиля | candidate | — |
|
||||
| dmarc-reports | DMARC aggregate report ingestion and panel UI | candidate | [plans/dmarc-reports.md](plans/dmarc-reports.md) |
|
||||
|
||||
**Recommended order** (not binding): **web-split → domain-admin →
|
||||
inbound-relay** — first the package split, then role-wide authorisation, then
|
||||
the new vertical slice of the inbound relay. Deviating is allowed; there are no
|
||||
hard phases here.
|
||||
**Recommended order** (not binding): **domain-admin →
|
||||
inbound-relay** — role-wide authorisation first, then the inbound relay vertical
|
||||
slice. Deviating is allowed; there are no hard phases here.
|
||||
|
||||
After a context reset, pick an item marked `agreed` or `in progress`, then work
|
||||
the checklist in its linked plan.
|
||||
@@ -59,8 +57,7 @@ engine stays outside the image, only the attachment point is provided.
|
||||
|
||||
**Dependencies / risks:** a finished outbound path; open relay and backscatter;
|
||||
a wider attack surface (port 25 accepting mail).
|
||||
**Order:** recommended after [web-split](plans/web-split.md) and
|
||||
[domain-admin](plans/domain-admin.md).
|
||||
**Order:** recommended after [domain-admin](plans/domain-admin.md).
|
||||
**Version:** target bump `1.x`; `2.x` possible — to be settled once the
|
||||
implementation lands.
|
||||
|
||||
@@ -80,32 +77,13 @@ assigned domains (one or several).
|
||||
**Done when:** see [plans/domain-admin.md](plans/domain-admin.md).
|
||||
|
||||
**Dependencies / risks:** a users table, the role in the session, authorisation
|
||||
in every handler, setup and backup. **Order:** recommended after
|
||||
[web-split](plans/web-split.md), before
|
||||
in every handler, setup and backup. **Order:** recommended **before**
|
||||
[inbound-relay](plans/inbound-relay.md).
|
||||
**Version:** `1.x` MINOR, given a compatible migration of the current
|
||||
administrator into a global one.
|
||||
|
||||
---
|
||||
|
||||
## web-split
|
||||
|
||||
**Goal:** deliberately split `internal/web` (or settle on keeping the package
|
||||
flat) before it grows under inbound-relay and domain-admin.
|
||||
|
||||
**Boundary:** an internal refactor; the panel's behaviour for the operator does
|
||||
not change.
|
||||
|
||||
**Done when:** the package is split along the chosen scheme, or it is settled
|
||||
that it stays flat — see [plans/web-split.md](plans/web-split.md).
|
||||
|
||||
**Dependencies / risks:** exporting a package-private API. **Order:**
|
||||
recommended **first** among the agreed features (before domain-admin and
|
||||
inbound-relay).
|
||||
**Version:** `1.x`; on its own it does not force a break.
|
||||
|
||||
---
|
||||
|
||||
## contributing
|
||||
|
||||
**Goal:** `CONTRIBUTING.md` in the root — the dev loop, the checks to run
|
||||
|
||||
Reference in New Issue
Block a user