@astram/guide 0.2.5 → 0.2.7
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/CAPABILITIES.md +71 -1
- package/package.json +1 -1
package/CAPABILITIES.md
CHANGED
|
@@ -313,16 +313,86 @@ upload(@Req() req: Record<string, unknown>) {
|
|
|
313
313
|
the upload check.
|
|
314
314
|
- **Lint wall** — the scaffold bans `multer`, `@aws-sdk/*`, `minio`, `fs` / `node:fs` (and
|
|
315
315
|
`/promises`) in `src/features/**`: use `FileIntake` and `FilesService`, never the bucket.
|
|
316
|
-
-
|
|
316
|
+
- Roles that upload need `stored_file:create` (FilesService creates the record as the caller), but app code must create `stored_file` rows only through `FilesService.store()` — never `records.create('stored_file', …)` / `createMany`, which would let a caller set its own `storageKey` (downloads still refuse a key outside the caller's tenant, KI #137).
|
|
317
317
|
- Not provided: malware scanning, per-tenant encryption of file bytes (SSE-S3 only), streaming
|
|
318
318
|
downloads, dedup (each upload is its own record; `sha256` is returned so you can detect repeats).
|
|
319
319
|
|
|
320
|
+
## Database names and several environments on one server (`SHIELD_DB_NAMESPACE`, ADR-0037)
|
|
321
|
+
- The framework uses four databases, `<ns>_app`, `<ns>_identity`, `<ns>_authz` and `<ns>_audit`,
|
|
322
|
+
with its own accounts (`<ns>_core`, `<ns>_migrate`, `<ns>_audit_ops`, …). If you leave
|
|
323
|
+
`SHIELD_DB_NAMESPACE` unset, `<ns>` is `shield` (`shield_app`, …), which is unchanged from
|
|
324
|
+
earlier releases.
|
|
325
|
+
- **To run dev and beta on one MariaDB server**, give each environment its own namespace. It must
|
|
326
|
+
be lowercase letters and digits only (`beta`, `staging2`; no `_`). Then:
|
|
327
|
+
1. Provision it with the framework's `db-provision --namespace beta` (from the astram-framework
|
|
328
|
+
repo, runbook §6). Use distinct passwords per namespace.
|
|
329
|
+
2. Set `SHIELD_DB_NAMESPACE=beta` for both the server and `npm run migration:run`. The same
|
|
330
|
+
value must reach both.
|
|
331
|
+
3. Run migrations (the ledger is `beta_app.schema_migrations`), then start the server.
|
|
332
|
+
- Defaults follow the namespace: `APP_DB_USER` ⇒ `<ns>_core`, `APP_DB_NAME` ⇒ `<ns>_identity`,
|
|
333
|
+
`DDL_DB_USER` ⇒ `<ns>_migrate`. Explicit values win.
|
|
334
|
+
- **Rules your app must follow:**
|
|
335
|
+
- `APP_DB_NAME` must be one of the four framework databases, even with the namespace unset.
|
|
336
|
+
Any other value refuses to boot.
|
|
337
|
+
- An invalid namespace refuses to boot and to migrate.
|
|
338
|
+
- Use a separate Redis (instance or DB index) per environment: Redis keys are not namespaced.
|
|
339
|
+
- Your own object types keep a literal `schema` or none. Do not hard-code `shield_*` names in
|
|
340
|
+
app SQL or migrations: read them from the injected `FRAMEWORK_SCHEMAS` (`@astram/guard`).
|
|
341
|
+
- **Boot check:** outside development/test (an unset `NODE_ENV` counts as production), the server
|
|
342
|
+
refuses to start when framework migrations are missing from the ledger, no ledger is found, or
|
|
343
|
+
the ledger is unreachable. Run `migration:run` before starting. With the namespace unset, the
|
|
344
|
+
server looks for the ledger in `DDL_DB_NAME`, its own `APP_DB_NAME`, then `shield_app`, so
|
|
345
|
+
`migration:run` with the server's `.env` is found. If your migrate job uses a different
|
|
346
|
+
`APP_DB_NAME`, set the same `DDL_DB_NAME` for migrate and the server.
|
|
347
|
+
- The `<ns>_backup` and `<ns>_monitor` accounts keep server-wide grants and can see every
|
|
348
|
+
namespace on the server.
|
|
349
|
+
- One database per account (some managed hosts): see the single-database layout below.
|
|
350
|
+
|
|
351
|
+
## Single-database layout (`SHIELD_DB_LAYOUT=single`, ADR-0041, opt-in, reduced isolation)
|
|
352
|
+
- For hosts that give one database per account. The four-database layout stays the default.
|
|
353
|
+
- **Set:** `SHIELD_DB_LAYOUT=single`, `SHIELD_DB_NAME=<db>` (`^[a-z0-9_]{1,64}$`),
|
|
354
|
+
`SHIELD_DB_LAYOUT_ACK_REDUCED_ISOLATION=1` (exactly `1`, every environment, production
|
|
355
|
+
included), `APP_DB_USER`. Leave `SHIELD_DB_NAMESPACE` unset; `APP_DB_NAME`/`DDL_DB_NAME` unset
|
|
356
|
+
or `<db>`. Same values for the server and `npm run migration:run`. Anything else refuses to boot
|
|
357
|
+
and to migrate.
|
|
358
|
+
- **Set `POOL_MAX_ENGINE`** (e.g. 10). Unset, the engine pool uses `APP_DB_MAX_CONNECTIONS`, and
|
|
359
|
+
the single-layout budget `workers × (POOL_MAX_CORE + POOL_MAX_ENGINE + APP_AUTHZ_POOL_MAX) +
|
|
360
|
+
headroom` fails boot. `APP_DB_MAX_USER_CONNECTIONS` (the account's cap, if the host sets one) is
|
|
361
|
+
checked too.
|
|
362
|
+
- All framework tables keep their names in `<db>`; your tables live there too. **Reserved
|
|
363
|
+
table names:** your object types and migrations must not use a framework table name (`companies`,
|
|
364
|
+
`users`, `roles`, `departments`, `branches`, `company_membership`, `membership_posting`,
|
|
365
|
+
`company_departments`, `company_branches`, `service_account`, `shared_resource`, `stored_file`,
|
|
366
|
+
`identity_credential`, `session`, `refresh_token`, `mfa_device`, `password_reset_token`,
|
|
367
|
+
`mfa_recovery_code`, `email_change_token`, `permission`, `role_permission`,
|
|
368
|
+
`authz_permission_version`, `access_bundle`, `access_bundle_permission`,
|
|
369
|
+
`record_permission_rule`, `record_share`, `scope_closure`, `service_account_key`,
|
|
370
|
+
`cross_tenant_grant`, `audit_log`, the ledger `schema_migrations`) or `prune_audit`. In single
|
|
371
|
+
mode a clash refuses to boot (object type) or to migrate (`CREATE TABLE` in your migrations);
|
|
372
|
+
in the four layout it only warns, so you see it early. The migration check reads whole files,
|
|
373
|
+
`down()` included: an app whose migrations ever created or renamed onto a reserved name cannot
|
|
374
|
+
migrate in single mode.
|
|
375
|
+
- **One account** (`DDL_DB_*` unset ⇒ `APP_DB_*`): migrations and the server share the account
|
|
376
|
+
(`ALL PRIVILEGES ON <db>.*`). You lose append-only audit (#6), no runtime DDL and schema
|
|
377
|
+
separation (#11), the DB-enforced retention floor, and the separate DDL account; `audit:prune`
|
|
378
|
+
refuses to run. Boot logs this list every time (the privilege probe runs with
|
|
379
|
+
`ShieldModule.forRoot({ auth: true })`).
|
|
380
|
+
- **Two accounts** (if the host allows a second user): the framework repo's
|
|
381
|
+
`db-provision --layout single` keeps `audit_log` append-only and the runtime free of DDL, and
|
|
382
|
+
installs `prune_audit`; re-run it after a migration adds a table. Schema separation is still lost.
|
|
383
|
+
- Choose the layout at install: switching an existing install is not supported. MariaDB only.
|
|
384
|
+
|
|
320
385
|
## Migrations (`@astram/migrate`)
|
|
321
386
|
- `migrate` / `migrate:revert` / `migrate:status` with the deploy-time DDL account (`DDL_DB_*`);
|
|
322
387
|
the running app never holds DDL. Framework migrations merge with yours (`APP_MIGRATION_DIR`).
|
|
323
388
|
- Numeric ordering, duplicate-id detection, a database lock so concurrent deploys never apply a
|
|
324
389
|
migration twice (`APP_MIGRATION_LOCK_TIMEOUT`, default 120 s), and drift detection (a changed
|
|
325
390
|
applied file is reported; `--strict` fails on it). Never edit a migration that already ran.
|
|
391
|
+
- Upgrade `@astram/migrate` together with `@astram/guard` and `@astram/identity`. The framework
|
|
392
|
+
migrations read the database names from the migrate context (`ctx.schemas`). An older migrate
|
|
393
|
+
works only while `SHIELD_DB_NAMESPACE` is unset, and stops with "upgrade @astram/migrate"
|
|
394
|
+
otherwise. On upgrade, `migrate:status --strict` reports the framework's rewritten migrations as
|
|
395
|
+
SUPERSEDED, not drift, and `migrate` updates their ledger rows without re-running them.
|
|
326
396
|
|
|
327
397
|
## Frontend (`@astram/frontend-core`, `@astram/sdk`, scaffolded `frontend/`)
|
|
328
398
|
- `@astram/frontend-core`: auth, account, identity, audit, record-policy, share, cross-tenant and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astram/guide",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Astram framework — the AI/dev GUIDE layer (ADR-0025). Ships the framework's hard rules + capabilities manifest as installed, upgrade-refreshed docs. A consumer app's CLAUDE.md references FRAMEWORK_RULES.md from this package; `npm update` replaces it wholesale so new rules arrive cleanly, while the app's own .astram/guide/ layer is never touched. This is the framework-owned FLOOR: an app rule may tighten it, never weaken it.",
|
|
6
6
|
"type": "commonjs",
|