create-ampless 0.2.0-alpha.9 → 1.0.0-alpha.101
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/README.ja.md +77 -0
- package/README.md +6 -3
- package/dist/index.js +743 -84
- package/dist/templates/_shared/AGENTS.ja.md +94 -0
- package/dist/templates/_shared/AGENTS.md +94 -0
- package/dist/templates/_shared/README.ja.md +239 -0
- package/dist/templates/_shared/README.md +239 -0
- package/dist/templates/_shared/RUNBOOK.ja.md +120 -0
- package/dist/templates/_shared/RUNBOOK.md +32 -58
- package/dist/templates/_shared/THEMES.ja.md +495 -0
- package/dist/templates/_shared/THEMES.md +523 -0
- package/dist/templates/_shared/amplify/auth/post-confirmation/resource.ts +7 -0
- package/dist/templates/_shared/amplify/backend.ts +10 -0
- package/dist/templates/_shared/amplify/data/get-media-by-src.js +45 -0
- package/dist/templates/_shared/amplify/data/get-published-post.js +9 -12
- package/dist/templates/_shared/amplify/data/list-posts-by-tag.js +6 -9
- package/dist/templates/_shared/amplify/data/list-published-posts.js +10 -11
- package/dist/templates/_shared/amplify/data/resource.custom.ts +1 -2
- package/dist/templates/_shared/amplify/data/resource.ts +28 -7
- package/dist/templates/_shared/amplify/events/dispatcher/resource.ts +1 -0
- package/dist/templates/_shared/amplify/events/processor-trusted/resource.ts +1 -0
- package/dist/templates/_shared/amplify/events/processor-untrusted/resource.ts +5 -0
- package/dist/templates/_shared/amplify/functions/api-key-renewer/resource.ts +1 -0
- package/dist/templates/_shared/amplify/functions/mcp-handler/handler.ts +1 -0
- package/dist/templates/_shared/amplify/functions/mcp-handler/resource.ts +12 -0
- package/dist/templates/_shared/amplify/functions/plugin-secret-handler/handler.ts +11 -0
- package/dist/templates/_shared/amplify/functions/plugin-secret-handler/resource.ts +12 -0
- package/dist/templates/_shared/amplify/functions/user-admin/resource.ts +7 -0
- package/dist/templates/_shared/amplify/secrets/.gitkeep +0 -0
- package/dist/templates/_shared/amplify/secrets/encryption-key.ts +9 -0
- package/dist/templates/_shared/app/(admin)/admin/mcp-tokens/page.tsx +5 -0
- package/dist/templates/_shared/app/(admin)/admin/plugins/page.tsx +5 -0
- package/dist/templates/_shared/app/globals.css +55 -39
- package/dist/templates/_shared/app/layout.tsx +51 -16
- package/dist/templates/_shared/app/providers.tsx +0 -2
- package/dist/templates/_shared/app/raw/[slug]/route.ts +10 -0
- package/dist/templates/_shared/app/static/[slug]/[[...path]]/route.ts +14 -0
- package/dist/templates/_shared/cms.config.ts +64 -23
- package/dist/templates/_shared/components/site-chrome/site-sidebar.tsx +3 -4
- package/dist/templates/_shared/components/tag-list.tsx +9 -2
- package/dist/templates/_shared/components.json +1 -1
- package/dist/templates/_shared/docs/plugin-author-guide.ja.md +934 -0
- package/dist/templates/_shared/docs/plugin-author-guide.md +1336 -0
- package/dist/templates/_shared/lib/admin.ts +12 -12
- package/dist/templates/_shared/lib/ampless.ts +2 -8
- package/dist/templates/_shared/lib/amplify.ts +0 -5
- package/dist/templates/_shared/package.json +51 -43
- package/dist/templates/_shared/plugins/README.ja.md +139 -0
- package/dist/templates/_shared/plugins/README.md +143 -0
- package/dist/templates/_shared/proxy.ts +23 -8
- package/dist/templates/blog/README.ja.md +22 -0
- package/dist/templates/blog/README.md +17 -47
- package/dist/templates/blog/manifest.ts +1 -1
- package/dist/templates/blog/pages/feed.ts +4 -5
- package/dist/templates/blog/pages/home.tsx +10 -15
- package/dist/templates/blog/pages/post.tsx +42 -14
- package/dist/templates/blog/pages/sitemap.ts +4 -5
- package/dist/templates/blog/pages/tag.tsx +8 -10
- package/dist/templates/blog/tokens.css +26 -40
- package/dist/templates/corporate/README.ja.md +18 -0
- package/dist/templates/corporate/README.md +12 -14
- package/dist/templates/corporate/pages/feed.ts +3 -4
- package/dist/templates/corporate/pages/home.tsx +7 -12
- package/dist/templates/corporate/pages/post.tsx +20 -14
- package/dist/templates/corporate/pages/sitemap.ts +3 -4
- package/dist/templates/corporate/pages/tag.tsx +8 -10
- package/dist/templates/corporate/tokens.css +17 -39
- package/dist/templates/dads/README.ja.md +31 -0
- package/dist/templates/dads/README.md +13 -17
- package/dist/templates/dads/pages/feed.ts +3 -4
- package/dist/templates/dads/pages/home.tsx +7 -12
- package/dist/templates/dads/pages/post.tsx +20 -14
- package/dist/templates/dads/pages/sitemap.ts +3 -4
- package/dist/templates/dads/pages/tag.tsx +8 -10
- package/dist/templates/dads/tokens.css +22 -42
- package/dist/templates/docs/README.ja.md +24 -0
- package/dist/templates/docs/README.md +10 -13
- package/dist/templates/docs/pages/feed.ts +3 -4
- package/dist/templates/docs/pages/home.tsx +6 -9
- package/dist/templates/docs/pages/post.tsx +19 -13
- package/dist/templates/docs/pages/sitemap.ts +3 -4
- package/dist/templates/docs/pages/tag.tsx +8 -10
- package/dist/templates/docs/tokens.css +17 -39
- package/dist/templates/landing/README.ja.md +20 -0
- package/dist/templates/landing/README.md +14 -19
- package/dist/templates/landing/pages/feed.ts +4 -5
- package/dist/templates/landing/pages/home.tsx +7 -12
- package/dist/templates/landing/pages/post.tsx +20 -14
- package/dist/templates/landing/pages/sitemap.ts +3 -4
- package/dist/templates/landing/pages/tag.tsx +8 -10
- package/dist/templates/landing/tokens.css +17 -39
- package/dist/templates/minimal/README.ja.md +14 -0
- package/dist/templates/minimal/README.md +9 -47
- package/dist/templates/minimal/pages/feed.ts +4 -5
- package/dist/templates/minimal/pages/home.tsx +6 -8
- package/dist/templates/minimal/pages/post.tsx +19 -12
- package/dist/templates/minimal/pages/sitemap.ts +4 -5
- package/dist/templates/minimal/pages/tag.tsx +7 -8
- package/dist/templates/minimal/tokens.css +17 -39
- package/dist/templates/plugin-local/README.md +34 -0
- package/dist/templates/plugin-local/index.ts +39 -0
- package/dist/templates/plugin-standalone/CHANGELOG.md +1 -0
- package/dist/templates/plugin-standalone/README.ja.md +43 -0
- package/dist/templates/plugin-standalone/README.md +43 -0
- package/dist/templates/plugin-standalone/package.json +47 -0
- package/dist/templates/plugin-standalone/src/index.test.ts +16 -0
- package/dist/templates/plugin-standalone/src/index.ts +29 -0
- package/dist/templates/plugin-standalone/tsconfig.json +16 -0
- package/dist/templates/plugin-standalone/tsup.config.ts +8 -0
- package/package.json +1 -1
- package/dist/templates/_shared/app/(admin)/admin/sites/page.tsx +0 -5
- package/dist/templates/_shared/app/site/[siteId]/raw/[slug]/route.ts +0 -5
- package/dist/templates/_shared/components/i18n-provider.tsx +0 -15
- package/dist/templates/_shared/lib/admin-site-client.ts +0 -10
- package/dist/templates/_shared/lib/admin-site.ts +0 -12
- package/dist/templates/_shared/lib/amplify-server.ts +0 -7
- package/dist/templates/_shared/lib/auth-server.ts +0 -15
- package/dist/templates/_shared/lib/cn.ts +0 -5
- package/dist/templates/_shared/lib/i18n.ts +0 -35
- package/dist/templates/_shared/lib/kv-provider.ts +0 -7
- package/dist/templates/_shared/lib/media.ts +0 -6
- package/dist/templates/_shared/lib/posts-provider.ts +0 -7
- package/dist/templates/_shared/lib/posts-public.ts +0 -27
- package/dist/templates/_shared/lib/posts.ts +0 -12
- package/dist/templates/_shared/lib/seo.ts +0 -11
- package/dist/templates/_shared/lib/site-settings.ts +0 -11
- package/dist/templates/_shared/lib/storage.ts +0 -10
- package/dist/templates/_shared/lib/theme-actions.ts +0 -5
- package/dist/templates/_shared/lib/theme-active.ts +0 -10
- package/dist/templates/_shared/lib/theme-config.ts +0 -12
- package/dist/templates/_shared/lib/upload.ts +0 -6
- /package/dist/templates/_shared/app/{site/[siteId]/[slug] → [slug]}/page.tsx +0 -0
- /package/dist/templates/_shared/app/{site/[siteId]/feed.xml → feed.xml}/route.ts +0 -0
- /package/dist/templates/_shared/app/{site/[siteId]/og → og}/[slug]/route.ts +0 -0
- /package/dist/templates/_shared/app/{site/[siteId]/page.tsx → page.tsx} +0 -0
- /package/dist/templates/_shared/app/{site/[siteId]/sitemap.xml → sitemap.xml}/route.ts +0 -0
- /package/dist/templates/_shared/app/{site/[siteId]/tag → tag}/[tag]/page.tsx +0 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
> 日本語版: [README.ja.md](./README.ja.md)
|
|
2
|
+
>
|
|
3
|
+
# {{siteName}}
|
|
4
|
+
|
|
5
|
+
Your site is built with [ampless](https://github.com/heavymoons/ampless) — a serverless CMS that runs on AWS Amplify Gen 2 (Cognito + DynamoDB + S3 + AppSync + Lambda) with a Next.js 16 frontend.
|
|
6
|
+
|
|
7
|
+
This README covers what you, the site owner, need to know day-to-day. Operational recipes (rotating keys, restoring backups, etc.) live in [RUNBOOK.md](./RUNBOOK.md). Per-theme customization details live in `themes/<name>/README.md`.
|
|
8
|
+
|
|
9
|
+
If you use an AI coding agent (Claude Code, Cursor, Codex, etc.) on this project, point it at [AGENTS.md](./AGENTS.md) — that file tells the agent what it can and can't touch.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- **Node.js 22+** and **npm**.
|
|
14
|
+
- **AWS account.** Install the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html), then `aws configure` to set credentials + default region. The sandbox + production both deploy real AWS resources.
|
|
15
|
+
- **GitHub account** for production hosting via AWS Amplify Hosting. The CLI deploy flow ([below](#option-1-cli-one-shot-recommended)) also needs the [`gh` CLI](https://cli.github.com/) authenticated via `gh auth login` (or a `GITHUB_TOKEN` env var with `repo` scope). The manual console flow doesn't need `gh`.
|
|
16
|
+
|
|
17
|
+
## Commands
|
|
18
|
+
|
|
19
|
+
| Command | What it does |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `npm install` | Install dependencies |
|
|
22
|
+
| `npm run sandbox` | Provision a personal AWS sandbox (Cognito / DynamoDB / S3 / etc.), regenerate `amplify_outputs.json`, then start `next dev` on `http://localhost:3000` |
|
|
23
|
+
| `npm run dev` | Start Next.js only (skip sandbox provisioning — use after `sandbox` has already run once) |
|
|
24
|
+
| `npm run build` | Production build of the Next.js app (also runs as part of Amplify Hosting deploy) |
|
|
25
|
+
| `npm run start` | Serve the production build locally |
|
|
26
|
+
| `npm run lint` | Lint with `next lint` |
|
|
27
|
+
| `npm run update-ampless` | Pull the latest ampless template files into this project, preserving your config and themes (see "Updating ampless" below) |
|
|
28
|
+
| `npm run copy-theme` | Add another official theme to this project after-the-fact |
|
|
29
|
+
|
|
30
|
+
## First time setup
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install
|
|
34
|
+
npm run sandbox
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
First sandbox run takes 5–10 minutes (AWS resource provisioning). `amplify_outputs.json` is regenerated each time before `next dev` starts.
|
|
38
|
+
|
|
39
|
+
Open [http://localhost:3000/login](http://localhost:3000/login) and click **Create admin account**. The first registered user is automatically added to the `ampless-admin` Cognito group.
|
|
40
|
+
|
|
41
|
+
## Admin UI
|
|
42
|
+
|
|
43
|
+
After signing in, the admin lives at `/admin`:
|
|
44
|
+
|
|
45
|
+
| Path | Purpose |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| `/admin` | Dashboard |
|
|
48
|
+
| `/admin/posts` | List / create / edit posts (Tiptap editor, Markdown, raw HTML, or zip-uploaded static bundles) |
|
|
49
|
+
| `/admin/media` | Upload images / videos / files to S3 |
|
|
50
|
+
| `/admin/sites/<siteId>` | Site-level settings (name, URL) |
|
|
51
|
+
| `/admin/sites/<siteId>/theme` | Activate a theme + customize its fields (colors, fonts, nav, logo, etc.) |
|
|
52
|
+
| `/admin/users` | View users + Cognito group memberships |
|
|
53
|
+
| `/admin/mcp-tokens` | Issue Bearer tokens for the HTTP MCP endpoint |
|
|
54
|
+
|
|
55
|
+
User roles (Cognito groups):
|
|
56
|
+
|
|
57
|
+
- `ampless-admin` — full access (content + ops + destructive)
|
|
58
|
+
- `ampless-editor` — content CRUD (no destructive ops)
|
|
59
|
+
- `ampless-reader` — reserved for future REST/MCP API consumers
|
|
60
|
+
|
|
61
|
+
Promotion/demotion is done in the AWS Cognito console — see [RUNBOOK.md → Promote / demote a user](./RUNBOOK.md#promote--demote-a-user).
|
|
62
|
+
|
|
63
|
+
## Authoring content
|
|
64
|
+
|
|
65
|
+
Posts are the single content type. Each post has:
|
|
66
|
+
|
|
67
|
+
- **Format** — `tiptap` (rich text) / `markdown` / `html` (raw, no sanitization) / `static` (zip-upload of HTML/CSS/JS)
|
|
68
|
+
- **No layout** flag (`format: 'html'` only) — render the body verbatim with no Next.js layout and no theme chrome. URL stays `/<slug>`; middleware rewrites the request to the internal bare-HTML handler.
|
|
69
|
+
- **Cache strategy** (`metadata.cache`) — override the per-post Cache-Control: `'auto'` (default; cooldown by edit time), `'deep'` (always long-cache), or `'hot'` (always no-store). See `docs/CONTENT.md` for details.
|
|
70
|
+
- **Slug** — the public URL
|
|
71
|
+
- **Status** — `draft` (admin only) or `published`
|
|
72
|
+
|
|
73
|
+
Full reference: [docs/CONTENT.md on GitHub](https://github.com/heavymoons/ampless/blob/main/docs/CONTENT.md) ([日本語](https://github.com/heavymoons/ampless/blob/main/docs/CONTENT.ja.md)).
|
|
74
|
+
|
|
75
|
+
## Themes
|
|
76
|
+
|
|
77
|
+
Every installed theme is bundled in this project under `themes/<name>/`. The **active** theme per site is a runtime setting — switching themes does **not** require a redeploy.
|
|
78
|
+
|
|
79
|
+
To switch the active theme: `/admin/sites/<siteId>/theme` → pick from the installed list → save.
|
|
80
|
+
|
|
81
|
+
To customize the active theme (colors, fonts, header / footer nav, etc.): same page — each theme exposes its own customization fields. See `themes/<name>/README.md` for what's customizable per theme.
|
|
82
|
+
|
|
83
|
+
To install another official theme into this project:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npm run copy-theme
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
To customize an installed theme without losing the customization on `npm run update-ampless`, copy it under the `my-` prefix:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npm run copy-theme blog my-blog
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The full working guide for theme customization — base-theme selection, the standard copy / edit / activate flow, Claude Design handoff, AI-assisted implementation, responsive QA, Markdown styling, and the common pitfalls — lives in [THEMES.md](./THEMES.md) (and [THEMES.ja.md](./THEMES.ja.md)) right in this project.
|
|
96
|
+
|
|
97
|
+
## Plugins
|
|
98
|
+
|
|
99
|
+
Plugins extend the CMS with event-driven side effects (SEO metadata, RSS feed, webhooks to external URLs, OG image generation, etc.). They're declared in [`cms.config.ts`](./cms.config.ts) and run on Lambda when posts are published / updated / deleted.
|
|
100
|
+
|
|
101
|
+
Bundled and ready to enable in `cms.config.ts`:
|
|
102
|
+
|
|
103
|
+
| Package | Purpose |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `@ampless/plugin-seo` | Per-post OGP / Twitter / canonical metadata + `sitemap.xml` |
|
|
106
|
+
| `@ampless/plugin-rss` | RSS 2.0 feed at `/feed.xml` |
|
|
107
|
+
| `@ampless/plugin-webhook` | POST events to external URLs (HMAC-signed) |
|
|
108
|
+
| `@ampless/plugin-og-image` | Dynamic Open Graph image generation at `/og/<slug>` |
|
|
109
|
+
|
|
110
|
+
To add a plugin: install (`npm i @ampless/plugin-...`), import in `cms.config.ts`, and add to the `plugins` array:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import seoPlugin from '@ampless/plugin-seo'
|
|
114
|
+
import rssPlugin from '@ampless/plugin-rss'
|
|
115
|
+
|
|
116
|
+
export default defineConfig({
|
|
117
|
+
// ...
|
|
118
|
+
plugins: [
|
|
119
|
+
seoPlugin({ twitterSite: '@example' }),
|
|
120
|
+
rssPlugin({ language: 'en', limit: 20 }),
|
|
121
|
+
],
|
|
122
|
+
})
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
A redeploy is required for plugin changes (the plugin code ships in the Lambda bundle).
|
|
126
|
+
|
|
127
|
+
## Deploying to production
|
|
128
|
+
|
|
129
|
+
The shipped [`amplify.yml`](./amplify.yml) runs `npx ampx pipeline-deploy` (Amplify backend) + `npm run build` (Next.js) on every push to the branch you connect.
|
|
130
|
+
|
|
131
|
+
### Option 1: CLI one-shot (recommended)
|
|
132
|
+
|
|
133
|
+
From inside this project directory:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npx create-ampless@latest --mount \
|
|
137
|
+
--github-owner <your-user-or-org> \
|
|
138
|
+
--aws-region <region> \
|
|
139
|
+
--create-iam-role # first time only; reuse `--iam-service-role <arn>` on later mounts
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The CLI:
|
|
143
|
+
|
|
144
|
+
1. Creates a GitHub repo (uses your authenticated `gh` CLI, the `GITHUB_TOKEN` env var, or the `--github-token` flag).
|
|
145
|
+
2. Pushes this project to that repo.
|
|
146
|
+
3. Provisions an Amplify Hosting app + branch, registers the GitHub connection, writes the `amplify.yml` build spec.
|
|
147
|
+
4. Kicks off the first deploy.
|
|
148
|
+
|
|
149
|
+
Useful extra flags:
|
|
150
|
+
|
|
151
|
+
- `--github-private` — private repo (default: public)
|
|
152
|
+
- `--domain <name>` `--subdomain <prefix>` — bind a custom domain in the same pass
|
|
153
|
+
- `--skip-confirm` — non-interactive (good for CI / re-runs)
|
|
154
|
+
- `--aws-profile <name>` — explicit AWS profile when you have multiple
|
|
155
|
+
|
|
156
|
+
See `npx create-ampless@latest --help` for the full list.
|
|
157
|
+
|
|
158
|
+
**Prerequisites for this flow (in addition to the [top-level Requirements](#requirements)):**
|
|
159
|
+
|
|
160
|
+
| | Why | How |
|
|
161
|
+
|---|---|---|
|
|
162
|
+
| `aws` CLI authenticated | Provisions the Amplify Hosting app + service role | [Install](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and run `aws configure` (or `aws sso login`). Verify with `aws sts get-caller-identity`. |
|
|
163
|
+
| `gh` CLI authenticated **or** `GITHUB_TOKEN` env | Creates the GitHub repo and pushes the initial commit | [Install `gh`](https://cli.github.com/) and `gh auth login`, **or** export a [personal access token](https://github.com/settings/tokens) with `repo` scope as `GITHUB_TOKEN`. Skip if you pass `--github-token <token>` directly. |
|
|
164
|
+
| IAM service role for Amplify Hosting | Lets Amplify deploy backend resources on your behalf | Either pass `--create-iam-role` to have the CLI provision one named `AmplifyDeployBackend` (idempotent), or pass `--iam-service-role <arn>` to reuse an existing role. The role must trust `amplify.amazonaws.com` and have `AdministratorAccess-Amplify` attached. |
|
|
165
|
+
|
|
166
|
+
### Option 2: Console (manual)
|
|
167
|
+
|
|
168
|
+
1. **Push this project to GitHub** (or another git host Amplify Hosting supports):
|
|
169
|
+
```bash
|
|
170
|
+
git init && git add . && git commit -m "init"
|
|
171
|
+
git remote add origin <your-repo>
|
|
172
|
+
git push -u origin main
|
|
173
|
+
```
|
|
174
|
+
2. **AWS Amplify Hosting console** → **Create new app** → **Host web app** → connect the repo → pick the branch → review the auto-detected build settings (they should match `amplify.yml`) → deploy.
|
|
175
|
+
3. First deploy takes 10–20 minutes. Subsequent pushes to the connected branch redeploy automatically.
|
|
176
|
+
|
|
177
|
+
### Environment variables
|
|
178
|
+
|
|
179
|
+
Set per-environment values in **Amplify Hosting console → Hosting → Environment variables**. Common ones:
|
|
180
|
+
|
|
181
|
+
| Variable | Used by |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| `WEBHOOK_SECRET` | `@ampless/plugin-webhook` HMAC signing |
|
|
184
|
+
|
|
185
|
+
Trigger a redeploy after adding/changing env vars.
|
|
186
|
+
|
|
187
|
+
### Custom domains
|
|
188
|
+
|
|
189
|
+
Bind a domain to your Amplify Hosting app in **Domain management** — Amplify provisions an ACM certificate and DNS records automatically. Full step-by-step: [RUNBOOK.md → Adding a custom domain](./RUNBOOK.md#adding-a-custom-domain-to-amplify-hosting).
|
|
190
|
+
|
|
191
|
+
## AI integration (MCP)
|
|
192
|
+
|
|
193
|
+
ampless ships an MCP (Model Context Protocol) server so Claude Desktop / Cursor / Claude Code / anything that speaks MCP can read and write your posts via HTTP transport with Bearer token authentication.
|
|
194
|
+
|
|
195
|
+
**Setup:**
|
|
196
|
+
|
|
197
|
+
1. Go to `/admin/mcp-tokens` in your admin UI and issue a Bearer token (`amk_...`).
|
|
198
|
+
2. Find the `mcp-handler` Lambda Function URL in your Amplify console or `amplify_outputs.json`.
|
|
199
|
+
3. Add an entry to your MCP client's config (`.mcp.json` at the project root, `claude_desktop_config.json`, etc.):
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
{
|
|
203
|
+
"mcpServers": {
|
|
204
|
+
"ampless": {
|
|
205
|
+
"url": "https://<function-url-id>.lambda-url.<region>.on.aws/",
|
|
206
|
+
"transport": "http",
|
|
207
|
+
"headers": {
|
|
208
|
+
"Authorization": "Bearer amk_..."
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
See [docs/architecture/04-access-layer-mcp.md](./docs/architecture/04-access-layer-mcp.md) for the full MCP setup and token management guide.
|
|
216
|
+
|
|
217
|
+
## Updating ampless
|
|
218
|
+
|
|
219
|
+
ampless releases on the `alpha` dist-tag. To pick up new features:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npm run update-ampless
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
This runs `npx create-ampless@latest upgrade`, which:
|
|
226
|
+
|
|
227
|
+
- Bumps the `@ampless/*` and `ampless` dependencies in `package.json`
|
|
228
|
+
- Re-syncs the shared template files (admin app shell, amplify backend, lib/, middleware, themes) — your customizations to `cms.config.ts`, `theme.*` admin settings, posts, and theme manifest values are preserved.
|
|
229
|
+
- Updates `update-ampless` and `copy-theme` script entries if their commands change
|
|
230
|
+
|
|
231
|
+
You can review the diff before committing.
|
|
232
|
+
|
|
233
|
+
## Operations
|
|
234
|
+
|
|
235
|
+
Day-to-day operational recipes — user promotion, password reset, backup restore, custom domain wiring, AppSync API key rotation — live in [RUNBOOK.md](./RUNBOOK.md).
|
|
236
|
+
|
|
237
|
+
## License
|
|
238
|
+
|
|
239
|
+
This project's own code is yours. ampless itself is MIT-licensed; see the [ampless repository](https://github.com/heavymoons/ampless) for details.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
> English: [RUNBOOK.md](./RUNBOOK.md)
|
|
2
|
+
>
|
|
3
|
+
|
|
4
|
+
# ランブック
|
|
5
|
+
|
|
6
|
+
ampless で構築したサイトで、ときどき必要になる運用作業の手順集です。毎日やるわけではないけれど、いざ必要になったときに迷わずに進めるためのものです。
|
|
7
|
+
|
|
8
|
+
日常的な使い方(コマンド、管理画面、テーマ、プラグイン、デプロイなど)は [README.ja.md](./README.ja.md) を参照してください。
|
|
9
|
+
|
|
10
|
+
## 目次
|
|
11
|
+
|
|
12
|
+
- [AppSync API キー(自動更新)](#appsync-api-キー自動更新)
|
|
13
|
+
- [よくある運用](#よくある運用)
|
|
14
|
+
- [ユーザーの昇格 / 降格](#promote--demote-a-user)
|
|
15
|
+
- [パスワードリセット(管理者上書き)](#reset-a-users-password-admin-override)
|
|
16
|
+
- [Post テーブルのバックアップから復元](#restore-from-a-post-table-backup)
|
|
17
|
+
- [失敗したプラグインイベントを確認する](#inspect-failed-plugin-events)
|
|
18
|
+
- [カスタムドメイン](#custom-domains)
|
|
19
|
+
- [カスタムドメインを Amplify Hosting に追加する](#adding-a-custom-domain-to-amplify-hosting)
|
|
20
|
+
|
|
21
|
+
## AppSync API キー(自動更新)
|
|
22
|
+
|
|
23
|
+
パブリックブログの読み取り(`listPublishedPosts`、`getPublishedPost`、`listPostsByTag`)は AppSync API キーで保護されています。このキーは `amplify_outputs.json` に含まれているため、**公開サイトを訪問した誰もが確認できる**状態にあります。低信頼度のクレデンシャルとして扱ってください。このキーが持つ権限は上記 3 つのカスタムクエリを呼び出すことのみであり、それらのクエリは `status === 'published'` の行しか返しません。
|
|
24
|
+
|
|
25
|
+
### なぜ API キーなのか(Identity Pool ゲストロールではなく)?
|
|
26
|
+
|
|
27
|
+
Amplify Gen 2 の `a.handler.custom` リゾルバーは `allow.guest()` や `allow.authenticated('identityPool')` をサポートしておらず、apiKey / userPool / lambda / group / owner のみが使用可能です。ampless では簡潔さを優先して API キーを選択しています。パブリック読み取りを Lambda 関数データソース(`a.handler.function`)に移行することは将来の選択肢です。
|
|
28
|
+
|
|
29
|
+
### 自動更新 — ローテーション手順は不要
|
|
30
|
+
|
|
31
|
+
`api-key-renewer` Lambda(`amplify/functions/api-key-renewer/` を参照)は、毎月 1 日の UTC 03:00 に EventBridge スケジュールで起動します。`AppSync.UpdateApiKey` を呼び出して既存キーの `expires` を「現時点 + 364 日」に延長するため、以下が保証されます:
|
|
32
|
+
|
|
33
|
+
- キー ID は変化しない
|
|
34
|
+
- `amplify_outputs.json` は引き続き有効
|
|
35
|
+
- Next.js アプリの再ビルドは不要
|
|
36
|
+
- 常に約 334 日以上の残有効期限が維持される
|
|
37
|
+
|
|
38
|
+
手動で確認または実行したい場合:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# 現在の有効期限を確認
|
|
42
|
+
aws appsync list-api-keys \
|
|
43
|
+
--region <amplify_outputs.json の data.aws_region> \
|
|
44
|
+
--api-id <amplify_outputs.json の data.url から導出した api-id>
|
|
45
|
+
|
|
46
|
+
# 手動実行(サンドボックスを長期間停止した後など)
|
|
47
|
+
aws lambda invoke \
|
|
48
|
+
--function-name $(aws lambda list-functions \
|
|
49
|
+
--query "Functions[?contains(FunctionName,'api-key-renewer')].FunctionName | [0]" \
|
|
50
|
+
--output text) \
|
|
51
|
+
/tmp/out.json && cat /tmp/out.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### キーの漏洩が疑われる場合
|
|
55
|
+
|
|
56
|
+
有効期限の延長ではなく、キーの値そのものをローテーションする即時対応を行います:
|
|
57
|
+
|
|
58
|
+
1. `amplify/data/resource.ts` のコメントを編集して CFN 更新を強制する
|
|
59
|
+
2. `npx ampx sandbox`(サンドボックス)または `npx ampx pipeline-deploy ...`(本番)を実行 — Amplify がキーの値を再生成する
|
|
60
|
+
3. Next.js アプリを再デプロイして SSR が新しい `data.api_key` を参照するようにする
|
|
61
|
+
|
|
62
|
+
## 一般的な操作
|
|
63
|
+
|
|
64
|
+
### ユーザーのグループ昇格 / 降格
|
|
65
|
+
|
|
66
|
+
AWS Cognito コンソールから操作します:
|
|
67
|
+
|
|
68
|
+
1. User Pool → Users → 対象ユーザーを選択
|
|
69
|
+
2. Group memberships → グループに追加 / グループから削除
|
|
70
|
+
3. ユーザーに一度サインアウトしてサインインし直してもらい、新しいクレームを適用させる
|
|
71
|
+
|
|
72
|
+
グループの種類: `ampless-admin`(フル CRUD + 運用操作)、`ampless-editor`(コンテンツ CRUD)、`ampless-reader`(将来の REST/MCP API 利用者向けに予約済み)。
|
|
73
|
+
|
|
74
|
+
### ユーザーパスワードのリセット(管理者による上書き)
|
|
75
|
+
|
|
76
|
+
ロックアウトされており、メールによる復旧が利用できない場合:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
aws cognito-idp admin-set-user-password \
|
|
80
|
+
--user-pool-id <amplify_outputs.json の auth.user_pool_id> \
|
|
81
|
+
--region <リージョン> \
|
|
82
|
+
--username <メールアドレス> \
|
|
83
|
+
--password '<新しいパスワード>' --permanent
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`/login` ページにはセルフサービスの「パスワードを忘れた場合」フローもあります。
|
|
87
|
+
|
|
88
|
+
### Post テーブルのバックアップからの復元
|
|
89
|
+
|
|
90
|
+
DynamoDB のポイントインタイムリカバリ(PITR)は `defineData` では有効になっていません。AWS コンソール → DynamoDB → Tables → `<投稿テーブル名>` → Backups → Edit PITR から手動で有効化してください。有効化後は `aws dynamodb restore-table-to-point-in-time` で新しいテーブルに復元し、その後アイテムをライブテーブルに移行する作業が必要です。
|
|
91
|
+
|
|
92
|
+
### 失敗したプラグインイベントの確認
|
|
93
|
+
|
|
94
|
+
処理に失敗したプロセッサー呼び出しは、`amplify/backend.ts` で作成された共有イベント DLQ(`EventsDlq`)に送られます。SQS コンソールまたは `aws sqs receive-message --queue-url <dlq-url> --max-number-of-messages 10` でメッセージを確認してください。ampless にはデフォルトの自動アラームがないため、定期的な手動確認を推奨します。あるいは `ApproximateNumberOfMessagesVisible` に CloudWatch アラームを設定してください。
|
|
95
|
+
|
|
96
|
+
## カスタムドメイン
|
|
97
|
+
|
|
98
|
+
ampless は 1 Amplify デプロイ = 1 サイト。複数サイトを別ドメインで配信したい場合は、サイトごとに Amplify 環境を分けてデプロイしてください。
|
|
99
|
+
|
|
100
|
+
### Amplify Hosting へのカスタムドメイン追加
|
|
101
|
+
|
|
102
|
+
バインドしたいドメインごとに以下を実施します:
|
|
103
|
+
|
|
104
|
+
1. **Amplify Hosting コンソール** → アプリ → **Domain management** → **Add domain** を選択。
|
|
105
|
+
2. 頂点ドメイン(`example.com`)と接続したいサブドメインを入力します。Amplify が ACM 証明書と CloudFront SAN エントリを自動でプロビジョニングします。
|
|
106
|
+
3. DNS を更新:
|
|
107
|
+
- **Route 53 / Amplify 管理の DNS プロバイダー**:Amplify が CNAME を作成してくれるので、確認するだけです。
|
|
108
|
+
- **外部 DNS**(Cloudflare、Squarespace など):Amplify が表示する CNAME / DNS 検証レコードをコピーします。ACM のメール検証もフォールバックとして使用できます。
|
|
109
|
+
4. **Domain activation** が完了するまで待ちます(通常 15〜60 分。証明書の検証が最も時間がかかります)。
|
|
110
|
+
5. `cms.config.ts` の `site.url` を新しい canonical URL に更新し、commit して push します:
|
|
111
|
+
```bash
|
|
112
|
+
git add cms.config.ts && git commit -m "feat: bind docs.example.com"
|
|
113
|
+
git push # Amplify Hosting が自動検出します
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
エンドツーエンドで確認:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
curl -I https://docs.example.com/ # 200 とサイトの HTML
|
|
120
|
+
```
|
|
@@ -1,6 +1,22 @@
|
|
|
1
|
+
> 日本語版: [RUNBOOK.ja.md](./RUNBOOK.ja.md)
|
|
2
|
+
>
|
|
3
|
+
|
|
1
4
|
# Runbook
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
Step-by-step recipes for occasional operations on an ampless-powered site — the things you don't do every day but want a reliable procedure for when you do.
|
|
7
|
+
|
|
8
|
+
For day-to-day usage (commands, admin UI tour, themes, plugins, deploying), start with [README.md](./README.md).
|
|
9
|
+
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- [AppSync API key (auto-renewed)](#appsync-api-key-auto-renewed)
|
|
13
|
+
- [Common operations](#common-operations)
|
|
14
|
+
- [Promote / demote a user](#promote--demote-a-user)
|
|
15
|
+
- [Reset a user's password (admin override)](#reset-a-users-password-admin-override)
|
|
16
|
+
- [Restore from a Post-table backup](#restore-from-a-post-table-backup)
|
|
17
|
+
- [Inspect failed plugin events](#inspect-failed-plugin-events)
|
|
18
|
+
- [Custom domains](#custom-domains)
|
|
19
|
+
- [Adding a custom domain to Amplify Hosting](#adding-a-custom-domain-to-amplify-hosting)
|
|
4
20
|
|
|
5
21
|
## AppSync API key (auto-renewed)
|
|
6
22
|
|
|
@@ -15,9 +31,9 @@ return rows where `status === 'published'`.
|
|
|
15
31
|
|
|
16
32
|
Amplify Gen 2 `a.handler.custom` resolvers don't support `allow.guest()`
|
|
17
33
|
or `allow.authenticated('identityPool')` — only apiKey / userPool /
|
|
18
|
-
lambda / group / owner.
|
|
19
|
-
the public reads to a Lambda function data source
|
|
20
|
-
is a
|
|
34
|
+
lambda / group / owner. ampless uses the API key for simplicity;
|
|
35
|
+
moving the public reads to a Lambda function data source
|
|
36
|
+
(`a.handler.function`) is a future option.
|
|
21
37
|
|
|
22
38
|
### Auto-renewal — no rotation runbook required
|
|
23
39
|
|
|
@@ -85,8 +101,8 @@ The `/login` page also has a self-service "Forgot password?" flow.
|
|
|
85
101
|
|
|
86
102
|
### Restore from a Post-table backup
|
|
87
103
|
|
|
88
|
-
DynamoDB Point-in-Time Recovery is **not** enabled by `defineData
|
|
89
|
-
|
|
104
|
+
DynamoDB Point-in-Time Recovery is **not** enabled by `defineData`;
|
|
105
|
+
turn it on manually via AWS Console → DynamoDB → Tables →
|
|
90
106
|
`<your post table>` → Backups → Edit PITR. Once enabled, restoration
|
|
91
107
|
takes the form `aws dynamodb restore-table-to-point-in-time` to a new
|
|
92
108
|
table; you'll need to migrate items back to the live table afterwards.
|
|
@@ -96,52 +112,14 @@ table; you'll need to migrate items back to the live table afterwards.
|
|
|
96
112
|
Failed processor invocations land in the shared events DLQ created in
|
|
97
113
|
`amplify/backend.ts` (`EventsDlq`). View messages via the SQS console
|
|
98
114
|
or `aws sqs receive-message --queue-url <dlq-url> --max-number-of-messages 10`.
|
|
99
|
-
|
|
100
|
-
or wire up a CloudWatch alarm on
|
|
101
|
-
|
|
102
|
-
## Multi-site / custom domains
|
|
103
|
-
|
|
104
|
-
ampless can serve multiple sites from one Amplify Hosting deployment.
|
|
105
|
-
Each site is identified by a `siteId` and bound to one or more
|
|
106
|
-
hostnames via `cms.config.ts`:
|
|
107
|
-
|
|
108
|
-
```ts
|
|
109
|
-
sites: {
|
|
110
|
-
blog: {
|
|
111
|
-
domains: ['blog.example.com', 'www.example.com'],
|
|
112
|
-
name: 'My Blog',
|
|
113
|
-
url: 'https://blog.example.com',
|
|
114
|
-
},
|
|
115
|
-
docs: {
|
|
116
|
-
domains: ['docs.example.com'],
|
|
117
|
-
name: 'Docs',
|
|
118
|
-
url: 'https://docs.example.com',
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
```
|
|
115
|
+
ampless doesn't ship an automated alarm out of the box — periodic
|
|
116
|
+
manual checks are recommended, or wire up a CloudWatch alarm on
|
|
117
|
+
`ApproximateNumberOfMessagesVisible`.
|
|
122
118
|
|
|
123
|
-
|
|
124
|
-
internally rewrites the path to `/_sites/{siteId}/...`. Subdomains and
|
|
125
|
-
fully separate domains are equivalent at the application layer — only
|
|
126
|
-
the AWS-side wiring differs.
|
|
119
|
+
## Custom domains
|
|
127
120
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
If `sites` is undefined or has only one entry, ampless runs in
|
|
131
|
-
single-site mode (`siteId='default'`). SSR responses follow each page's
|
|
132
|
-
own caching directives (so you can opt into CloudFront caching with
|
|
133
|
-
`Cache-Control: public, s-maxage=...` per route).
|
|
134
|
-
|
|
135
|
-
### Multi-site mode caveat: SSR caching is force-disabled
|
|
136
|
-
|
|
137
|
-
When two or more sites are declared, the middleware adds
|
|
138
|
-
`Cache-Control: private, no-store` to every public response. This is
|
|
139
|
-
because Amplify Hosting's CloudFront does not include `Host` in its
|
|
140
|
-
cache key — leaving caching on would let `https://site1/foo` and
|
|
141
|
-
`https://site2/foo` cross-contaminate at the edge. The trade-off is
|
|
142
|
-
that every public read hits Lambda. Lifting it requires moving off
|
|
143
|
-
Amplify Hosting onto a self-managed CloudFront + Open Next stack
|
|
144
|
-
(roadmap: post-v1.0).
|
|
121
|
+
ampless runs one site per Amplify deployment. To serve multiple sites
|
|
122
|
+
on different domains, deploy a separate Amplify environment per site.
|
|
145
123
|
|
|
146
124
|
### Adding a custom domain to Amplify Hosting
|
|
147
125
|
|
|
@@ -160,19 +138,15 @@ For each domain you want to bind:
|
|
|
160
138
|
also works as a fallback.
|
|
161
139
|
4. Wait for the **Domain activation** to finish (typically 15–60
|
|
162
140
|
minutes; certificate validation is the slow step).
|
|
163
|
-
5.
|
|
164
|
-
|
|
141
|
+
5. Update `cms.config.ts` so `site.url` reflects the new canonical URL,
|
|
142
|
+
commit, and push to redeploy:
|
|
165
143
|
```bash
|
|
166
|
-
git add cms.config.ts && git commit -m "feat:
|
|
144
|
+
git add cms.config.ts && git commit -m "feat: bind docs.example.com"
|
|
167
145
|
git push # Amplify Hosting picks it up
|
|
168
146
|
```
|
|
169
147
|
|
|
170
148
|
Verify end-to-end:
|
|
171
149
|
|
|
172
150
|
```bash
|
|
173
|
-
curl -I https://docs.example.com/
|
|
174
|
-
curl -sI https://docs.example.com/ | grep -i cache # Cache-Control: private, no-store
|
|
151
|
+
curl -I https://docs.example.com/ # 200 with your site's HTML
|
|
175
152
|
```
|
|
176
|
-
|
|
177
|
-
If the request returns `404 Site not found` instead, the host is not
|
|
178
|
-
listed in any `sites.*.domains[]` — fix the config and redeploy.
|