@astram/guide 0.2.20 → 0.2.22

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.
Files changed (2) hide show
  1. package/CAPABILITIES.md +24 -6
  2. package/package.json +1 -1
package/CAPABILITIES.md CHANGED
@@ -169,7 +169,10 @@ imports: [
169
169
  `GET /identity/auth-facts` feeds the frontend's permission-gated navigation.
170
170
  - **Scoped-hierarchy tenancy** (ADR-0027): a tenant is a company node; an admin's authority covers
171
171
  its subtree. Reads, updates, deletes AND creates of subtree-scoped types are walled in the query
172
- (ADR-0030, ADR-0034). Non-root admins cannot create top-level tenants.
172
+ (ADR-0030, ADR-0034). Non-root admins cannot create top-level tenants. With
173
+ `IdentityFeatureModule` wired, a session's subtree (its company and every company below) is
174
+ resolved at sign-in automatically (identity 0.24); pass `ShieldModule.forRoot({ scopeSubtreeResolver })`
175
+ only to replace identity's resolver. Without identity, reach is the active company only.
173
176
  - **No escalation**: you can grant, revoke or assign (via postings) only roles and keys you hold
174
177
  (ADR-0029); a role used outside your subtree is root-only; changing another user's email or
175
178
  status needs dominance over that user. Grant changes are audited in the same transaction.
@@ -471,10 +474,25 @@ imports: [
471
474
  (`{ announcement, personal, total }`), `POST /account/notifications/:uuid/read` (204),
472
475
  `POST /account/notifications/read-all?category=` (`{ updated }`). Another user's or company's
473
476
  notice is a 404, like a missing one. Restricted sessions (re-enrolment, mandatory 2FA) get 403.
477
+ - **Notification center (G-035):** the list also takes `kind`, `status=unread|read|archived`
478
+ (absent ⇒ not archived), `from` / `to` (UTC days `YYYY-MM-DD`, inclusive) and `search` (title or
479
+ body, case- and accent-insensitive, ≤ 100 characters; blank ⇒ no search); rows carry
480
+ `kindLabel`, `severity` and `archivedAt`. `GET /account/notifications/kinds` (`{ kinds: [{ kind,
481
+ label, category }] }`), `POST /account/notifications/:uuid/{unread,archive,unarchive}` (204;
482
+ archive also marks read, archived notices are never counted as unread) and `POST
483
+ /account/notifications/bulk` `{ action: read|unread|archive|unarchive, uuids (1–100) }` ⇒
484
+ `{ updated }` (only the caller's own notices in the active company change). Archive never
485
+ keeps a notice past retention. The scaffold's dropdowns show unread notices only and link to
486
+ the `/notifications` page; `server/src/notifications/app-notifications.service.ts` is an example
487
+ for posting your own.
474
488
  - **Register your kinds** once: `ShieldModule.forRoot({ notificationKinds: [{ kind:
475
- 'naes.import_review', category: 'personal' }] })`. A kind is dotted lower-case
476
- (`^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$`, ≤ 64); `shield.` is reserved. A bad or duplicate entry
477
- fails boot. `category` is `announcement` (release news, notices to many) or `personal`.
489
+ 'naes.import_review', category: 'personal', label: 'Import review', severity: 'warning' }] })`.
490
+ A kind is dotted lower-case (`^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$`, ≤ 64); `shield.` is
491
+ reserved. A bad or duplicate entry fails boot. `category` is `announcement` (release news,
492
+ notices to many) or `personal`. `label` (optional, 1–40 characters, plain text, shown to every
493
+ company: no company or person names) is the type users see; unset ⇒ made from the kind's last
494
+ segment (`Import review`), cut to 40 with "…", and boot logs one warning listing such kinds.
495
+ `severity` is `info` (default), `success` or `warning`; a bad label or severity fails boot.
478
496
  - **Post** with `NotificationService` (inject `SHIELD_NOTIFICATIONS` from `@astram/guard`):
479
497
  `post({ tenantId, recipients, kind, title, body?, link?, dedupeKey? }, { query? })` ⇒
480
498
  `{ created, skipped }`. `post` trusts its caller: take `tenantId` (and the recipients) from the
@@ -506,8 +524,8 @@ imports: [
506
524
  (directly or through `identity:<type>:*` / `identity:*`). `GET /identity/permission-announcements
507
525
  ?status=open|dismissed&page=&limit=&companyUuid=` lists the tasks the caller can act on: holders
508
526
  of `identity:role:update` whose grant ceiling covers the key, for the companies below them (their
509
- own company already holds what they can grant; this needs `scopeSubtreeResolver` wired in
510
- `ShieldModule.forRoot`, which the scaffold does not do yet); root sees every company. On a fresh
527
+ own company already holds what they can grant; the subtree comes with `IdentityFeatureModule`,
528
+ identity 0.24); root sees every company. On a fresh
511
529
  install the keys from the very first catalogue pass raise no task (identity 0.23). Granting the key to any of the company's roles closes the
512
530
  task on the next read; `POST /identity/permission-announcements/:companyUuid/:key/dismiss`
513
531
  ("Reviewed, not needed", audited) closes it on purpose and `…/reopen` undoes that. A key removed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astram/guide",
3
- "version": "0.2.20",
3
+ "version": "0.2.22",
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",