chore: prepare for public release
- add repository/homepage/bugs metadata; target Directus ^11 - genericize internal deployment references - document install, compatibility, scheduling, security - stop tracking internal .opencode work artifacts
This commit is contained in:
parent
c8f8bbc5ac
commit
94f197bdec
10 changed files with 181 additions and 706 deletions
52
AGENTS.md
52
AGENTS.md
|
|
@ -5,11 +5,14 @@ Common confusion points for agents working here. Read before touching the warmer
|
|||
## What this is
|
||||
|
||||
A Directus **bundle** extension that pre-generates image transform ("preview") cache files so the
|
||||
admin UI never pays the first-request sharp cost. Target server: **Directus 11.17.4** on `land-nest`
|
||||
(self-hosted, PM2 cluster, `STORAGE_LOCAL_ROOT=./uploads`).
|
||||
admin UI never pays the first-request sharp cost.
|
||||
|
||||
Bundle entries: an api **hook** (`files.upload`), an api **endpoint** (`/image-previews/*`), and an
|
||||
app **module** (`image-previews` admin page: progress, disk usage, config).
|
||||
Bundle entries: an api **hook** (`files.upload`), an api **endpoint** (`/image-previews/*`), and an app
|
||||
**module** (`image-previews` admin page: progress, storage, config, diagnostics, API reference).
|
||||
|
||||
Tested against Directus **11.17.4** (self-hosted, PM2 cluster, local disk storage). The manifest targets
|
||||
`^11.0.0`; the extension uses non-public `@directus/api` internals at runtime, so re-verify on each
|
||||
Directus minor upgrade.
|
||||
|
||||
## Directus transform invariants (source-verified, tag v11.17.4) — DO NOT REGRESS
|
||||
|
||||
|
|
@ -71,7 +74,8 @@ const { stream } = await assets.getAsset(fileId, {
|
|||
```
|
||||
|
||||
`acceptFormat` reproduces what a browser's `Accept` header does → byte-identical cache filename with
|
||||
no HTTP/token. Warm **both** `avif` and `webp` for `format:'auto'` presets.
|
||||
no HTTP/token. Warm **both** `avif` and `webp` for `format:'auto'` presets. For fixed-format presets,
|
||||
omit `acceptFormat` and let the preset's own format drive.
|
||||
|
||||
HTTP-replay (`GET /assets/{id}?key=…`) is the documented **fallback** only (needs a token + rate-limit
|
||||
pacing).
|
||||
|
|
@ -91,39 +95,19 @@ pacing).
|
|||
silently killed the upload hook.
|
||||
- **Docker bind mounts**: never `rm -rf` the bind-mounted extension directory — it breaks the mount and
|
||||
Directus removes the extension without re-adding it. Sync contents in place; restart the dev container.
|
||||
- The dev stack (`dev/compose.dev.yml`) is the only place to test; never load this into prod while
|
||||
iterating (prod has `EXTENSIONS_AUTO_RELOAD=true`).
|
||||
|
||||
|
||||
## Server facts (land-nest)
|
||||
|
||||
- Directus image `directus/directus:11.17.4`; `PUBLIC_URL=https://data.landshaft.life`;
|
||||
`PM2_INSTANCES=8`; `STORAGE_LOCAL_ROOT=./uploads`; logs at `~/apps/directus/logs`.
|
||||
- `ASSETS_TRANSFORM_MAX_CONCURRENT=45` per worker → over it errors; catch per file/preset.
|
||||
- `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` default 6000 is a **pixel dimension** guard, not a file-size
|
||||
limit. The extension imposes no limit; raise the Directus env var to process larger images.
|
||||
- Local storage writes are **non-atomic** — warm only after an upload is committed.
|
||||
- `RATE_LIMITER_*` applies to HTTP only → irrelevant to in-process generation (this is why the admin
|
||||
knob is *concurrency*, not a rate limit).
|
||||
- Observed bottleneck (2026-10-23 log triage): `storage:local:responseTime 1206ms`,
|
||||
`pg:responseTime` 150–738ms; **no** 503s, **no** sharp errors. Pre-generation removes the
|
||||
cold-transform cost; uploads-volume I/O latency is a separate ops concern.
|
||||
|
||||
## Safety (do not crash prod)
|
||||
|
||||
- Every entrypoint body is wrapped so thrown errors are logged and swallowed — never propagate into
|
||||
Directus core. ALL behaviour is gated by `enabled` (default **false**): a loaded-but-disabled bundle
|
||||
does nothing.
|
||||
- Test only on the **staging** stack (`dev/compose.dev.yml`), never the prod instance.
|
||||
- Rollout = backup previous `dist/` → deploy → healthcheck → enable; rollback = restore `dist/` + disable.
|
||||
- Automation (autonomous loops) gets **staging only**: a scoped token limited to `/image-previews/*`
|
||||
(+ `directus_files` metadata read), never a prod admin token; never the prod Docker socket; restricted
|
||||
non-sudo SSH or opencode-on-host. Promotion to prod is a human action.
|
||||
- **Dimension vs file size**: `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` (default 6000) is a **pixel
|
||||
dimension** guard in Directus, not a file-size limit. The extension imposes no limit; raise the
|
||||
Directus env var to process larger images.
|
||||
- **Unsupported preset formats** (e.g. `bmp`) fail at generation; surface the error in `/ops` and the
|
||||
module's Recent operations.
|
||||
- The dev stack (`dev/compose.dev.yml`) is the only place to test; never load this into a production
|
||||
instance while iterating (production may have `EXTENSIONS_AUTO_RELOAD=true`).
|
||||
|
||||
## Conventions
|
||||
|
||||
- Build via `@directus/extensions-sdk` (`npm run build` / `dev` / `link`); bundle emits `dist/app.js` + `dist/api.js`.
|
||||
- Deploy with `npm run publish` (scp `dist` + `package.json` to land-nest extensions dir).
|
||||
- Deploy by copying `dist/` + `package.json` into the Directus extensions dir (see README); a staging
|
||||
helper lives in `dev/deploy-staging.sh`.
|
||||
- Tests: `node:test` via `tsx` (`npm test`). Typecheck: `npm run typecheck`.
|
||||
- Do not add comments unless asked. Follow the sibling extensions' style.
|
||||
- Never commit without explicit request.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue