feat(build): make summer new apps admin-ready
- NewOptions.AdminSecret: summer new writes SUMMER_ADMIN__JWT__SECRET to .env (still 0600), generated from 32 crypto/rand bytes when empty and validated as at least 32 .env-safe characters - .env.example gets an empty SUMMER_ADMIN__JWT__SECRET= placeholder with a comment; the secret never reaches the printed next steps - The next steps and the generated CLAUDE.md explain the admin at /backend: make:admin-controller, build, migrate and summer admin:create --email you@example.com --superuser - Goldens use a fixed, non-secret admin secret fixture - Scaffolding, installation and users-and-permissions docs updated
This commit is contained in:
@@ -23,6 +23,8 @@ summer migrate # run plugin migrations
|
||||
summer serve # start the HTTP server
|
||||
summer make:plugin golem15.<name> # scaffold a plugin module under plugins/<name>
|
||||
summer plugin:add plugins/<name> # register it in summer.yaml, go.mod and go.work
|
||||
summer make:admin-controller golem15.<plugin> <Name> # scaffold an admin controller with its YAML
|
||||
summer admin:create --email you@example.com --superuser # create a backend administrator (password prompted)
|
||||
```
|
||||
|
||||
## Layout
|
||||
@@ -30,13 +32,23 @@ summer plugin:add plugins/<name> # register it in summer.yaml, go.mod and go.w
|
||||
- `summer.yaml`: the application manifest (module path, binary name, ordered plugin list).
|
||||
- `plugins/`: local plugin modules.
|
||||
- `config/`: YAML configuration (`app.yaml`, `database.yaml`, `http.yaml`, `storage.yaml`). Any key can be overridden with a `SUMMER_` environment variable, a double underscore separating path segments (`SUMMER_DATABASE__DSN` sets `database.dsn`).
|
||||
- `.env`: local secrets (database DSN, application key). Never commit it; `.gitignore` excludes it. `.env.example` lists the variables.
|
||||
- `.env`: local secrets (database DSN, application key, admin token secret). Never commit it; `.gitignore` excludes it. `.env.example` lists the variables.
|
||||
- `compose.yaml`: the local PostgreSQL 16.
|
||||
- `main.go`, `plugins.gen.go`: generated by `summer build` from `summer.yaml`. Do not edit them by hand; they are committed.
|
||||
- `go.work`: the workspace that joins the application and its plugin modules.
|
||||
|
||||
Plugins are Go modules compiled into the binary at build time; there is no runtime plugin loading. Add a plugin with `summer make:plugin` and `summer plugin:add`, then run `summer build`.
|
||||
|
||||
## Admin
|
||||
|
||||
The backend admin (the admin SPA and its JSON API) lives under `/backend`, at `http://127.0.0.1:8080/backend` with the default `summer serve` address. It is mounted only when a plugin registers an admin controller; until then `summer serve` prints `admin: off`. To add it:
|
||||
|
||||
1. `summer make:admin-controller golem15.<plugin> <Name>` scaffolds the controller and its YAML. The generated controller requires the permission `golem15.<plugin>.access_<name>` (`<name>` is the controller name in snake case): declare it in the plugin's `Permissions()` (`pact.HasPermissions`) or the admin refuses to start. Its `NewRecord` returns `nil` until you return the plugin's model.
|
||||
2. `summer build`, then `summer migrate`.
|
||||
3. `summer admin:create --email you@example.com --superuser` creates the first administrator; the password is prompted.
|
||||
|
||||
`.env` already holds `SUMMER_ADMIN__JWT__SECRET`, which signs admin tokens.
|
||||
|
||||
## Naming convention
|
||||
|
||||
- `sm-<name>-app`: an application, like this repository.
|
||||
|
||||
@@ -8,3 +8,10 @@ Next steps, inside sm-demo-app:
|
||||
|
||||
The app has no plugins yet. Add one with summer make:plugin golem15.<name>
|
||||
and summer plugin:add plugins/<name>, then run summer build again.
|
||||
|
||||
Admin, at http://127.0.0.1:8080/backend once a plugin registers an admin
|
||||
controller (.env already holds SUMMER_ADMIN__JWT__SECRET):
|
||||
summer make:admin-controller golem15.<plugin> <Name>
|
||||
summer build
|
||||
summer migrate
|
||||
summer admin:create --email you@example.com --superuser
|
||||
|
||||
14
internal/build/testdata/new/CLAUDE.md.golden
vendored
14
internal/build/testdata/new/CLAUDE.md.golden
vendored
@@ -23,6 +23,8 @@ summer migrate # run plugin migrations
|
||||
summer serve # start the HTTP server
|
||||
summer make:plugin golem15.<name> # scaffold a plugin module under plugins/<name>
|
||||
summer plugin:add plugins/<name> # register it in summer.yaml, go.mod and go.work
|
||||
summer make:admin-controller golem15.<plugin> <Name> # scaffold an admin controller with its YAML
|
||||
summer admin:create --email you@example.com --superuser # create a backend administrator (password prompted)
|
||||
```
|
||||
|
||||
## Layout
|
||||
@@ -30,13 +32,23 @@ summer plugin:add plugins/<name> # register it in summer.yaml, go.mod and go.w
|
||||
- `summer.yaml`: the application manifest (module path, binary name, ordered plugin list).
|
||||
- `plugins/`: local plugin modules. `plugins/demo` is the starter plugin `golem15.demo`; its `routes.go` answers `GET /` with JSON.
|
||||
- `config/`: YAML configuration (`app.yaml`, `database.yaml`, `http.yaml`, `storage.yaml`). Any key can be overridden with a `SUMMER_` environment variable, a double underscore separating path segments (`SUMMER_DATABASE__DSN` sets `database.dsn`).
|
||||
- `.env`: local secrets (database DSN, application key). Never commit it; `.gitignore` excludes it. `.env.example` lists the variables.
|
||||
- `.env`: local secrets (database DSN, application key, admin token secret). Never commit it; `.gitignore` excludes it. `.env.example` lists the variables.
|
||||
- `compose.yaml`: the local PostgreSQL 16.
|
||||
- `main.go`, `plugins.gen.go`: generated by `summer build` from `summer.yaml`. Do not edit them by hand; they are committed.
|
||||
- `go.work`: the workspace that joins the application and its plugin modules.
|
||||
|
||||
Plugins are Go modules compiled into the binary at build time; there is no runtime plugin loading. Add a plugin with `summer make:plugin` and `summer plugin:add`, then run `summer build`.
|
||||
|
||||
## Admin
|
||||
|
||||
The backend admin (the admin SPA and its JSON API) lives under `/backend`, at `http://127.0.0.1:8080/backend` with the default `summer serve` address. It is mounted only when a plugin registers an admin controller; until then `summer serve` prints `admin: off`. To add it:
|
||||
|
||||
1. `summer make:admin-controller golem15.<plugin> <Name>` scaffolds the controller and its YAML. The generated controller requires the permission `golem15.<plugin>.access_<name>` (`<name>` is the controller name in snake case): declare it in the plugin's `Permissions()` (`pact.HasPermissions`) or the admin refuses to start. Its `NewRecord` returns `nil` until you return the plugin's model.
|
||||
2. `summer build`, then `summer migrate`.
|
||||
3. `summer admin:create --email you@example.com --superuser` creates the first administrator; the password is prompted.
|
||||
|
||||
`.env` already holds `SUMMER_ADMIN__JWT__SECRET`, which signs admin tokens.
|
||||
|
||||
## Naming convention
|
||||
|
||||
- `sm-<name>-app`: an application, like this repository.
|
||||
|
||||
@@ -4,6 +4,10 @@ SUMMER_DATABASE__DSN=postgres://summer:summer@127.0.0.1:54320/demo?sslmode=disab
|
||||
# A 32-byte base64 application key. Generate one with ./bin/demo key:generate
|
||||
# and paste only the key, without the leading check mark.
|
||||
SUMMER_APP__KEY=
|
||||
# Signs backend admin tokens; the admin refuses to start without it once a
|
||||
# plugin registers an admin controller. summer new wrote a random value to .env;
|
||||
# any long random string works, for example one from ./bin/demo key:generate.
|
||||
SUMMER_ADMIN__JWT__SECRET=
|
||||
# Uploads bucket; config/storage.yaml already sets this default.
|
||||
# SUMMER_STORAGE__UPLOADS__BUCKET_URL=file://./storage/app/uploads
|
||||
# Configuration environment; selects the config overlay (default production).
|
||||
|
||||
7
internal/build/testdata/new/dot-env.golden
vendored
7
internal/build/testdata/new/dot-env.golden
vendored
@@ -1,5 +1,6 @@
|
||||
# Local secrets for this application: the database DSN and the application
|
||||
# key. .gitignore excludes this file; never commit it. Real environment
|
||||
# variables override the values here.
|
||||
# Local secrets for this application: the database DSN, the application key
|
||||
# and the admin token secret. .gitignore excludes this file; never commit it.
|
||||
# Real environment variables override the values here.
|
||||
SUMMER_DATABASE__DSN=postgres://summer:summer@127.0.0.1:54320/demo?sslmode=disable
|
||||
SUMMER_APP__KEY=AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=
|
||||
SUMMER_ADMIN__JWT__SECRET=ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8=
|
||||
|
||||
@@ -8,3 +8,10 @@ Next steps, inside sm-demo-app:
|
||||
|
||||
Then, from another terminal:
|
||||
curl http://127.0.0.1:8080/
|
||||
|
||||
Admin, at http://127.0.0.1:8080/backend once a plugin registers an admin
|
||||
controller (.env already holds SUMMER_ADMIN__JWT__SECRET):
|
||||
summer make:admin-controller golem15.<plugin> <Name>
|
||||
summer build
|
||||
summer migrate
|
||||
summer admin:create --email you@example.com --superuser
|
||||
|
||||
Reference in New Issue
Block a user