@astram/identity 0.19.0 → 0.20.0

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.
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Framework identity migration — the per-user notification store (G-027 step 2, NAES G-034 R5;
3
+ * spec `docs/features/notification-store/SPEC.md` §4A).
4
+ *
5
+ * `<identity>.user_notification` — one row per notice to one user in one company. Written and read
6
+ * only by guard (`MariaDbNotificationStore`, through `NotificationService.post` and the
7
+ * `/account/notifications` routes); identity owns the DDL only, like `email_change_token`.
8
+ * - un_tenant_id: the company the notice belongs to, stamped server-side; a user reads only the
9
+ * notices of the session's active company. A deleted company takes its notices with it.
10
+ * - un_user_uuid: the recipient; a deleted user takes their notices with it.
11
+ * - un_category: 'announcement' | 'personal' (from the kind's registration, never the caller).
12
+ * - un_title / un_body / un_link: plain text; the link is an app-relative path.
13
+ * - un_dedupe_key: the poster's optional idempotency key; unique per user and company (NULL keys
14
+ * never collide), so a retried post inserts nothing. Binary collation: keys compare exactly
15
+ * (`A1` and `a1` are different keys).
16
+ * - un_created_at_ms / un_read_at_ms: epoch milliseconds (BIGINT, no driver time-zone shift);
17
+ * NULL read time = unread.
18
+ * Indexes serve the inbox list and counts, the dedupe key, the retention purge and the tenant FK.
19
+ *
20
+ * Idempotent (CREATE TABLE IF NOT EXISTS); `down` drops the table with IF EXISTS. No rows are
21
+ * written, no ids are hard-coded. Database names come from `ctx.schemas` (namespace or single
22
+ * layout, ADR-0037/ADR-0041); the table is listed in core `FRAMEWORK_TABLES`.
23
+ */
24
+
25
+ const { frameworkSchemasForMigration } = require('@astram/core');
26
+
27
+ async function up(ctx) {
28
+ const { query } = ctx;
29
+ const { app: APP, identity: IDENTITY } = frameworkSchemasForMigration(ctx, process.env);
30
+
31
+ await query(
32
+ `CREATE TABLE IF NOT EXISTS \`${IDENTITY}\`.\`user_notification\` (
33
+ un_uuid VARCHAR(36) NOT NULL,
34
+ un_tenant_id VARCHAR(36) NOT NULL,
35
+ un_user_uuid VARCHAR(36) NOT NULL,
36
+ un_category VARCHAR(16) NOT NULL,
37
+ un_kind VARCHAR(64) NOT NULL,
38
+ un_title VARCHAR(160) NOT NULL,
39
+ un_body VARCHAR(1000) NULL,
40
+ un_link VARCHAR(512) NULL,
41
+ un_dedupe_key VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL,
42
+ un_created_at_ms BIGINT NOT NULL,
43
+ un_read_at_ms BIGINT NULL,
44
+ PRIMARY KEY (un_uuid),
45
+ INDEX idx_un_inbox (un_user_uuid, un_tenant_id, un_category, un_read_at_ms, un_created_at_ms),
46
+ UNIQUE KEY uq_un_dedupe (un_user_uuid, un_tenant_id, un_dedupe_key),
47
+ INDEX idx_un_created (un_created_at_ms),
48
+ INDEX idx_un_tenant (un_tenant_id),
49
+ CONSTRAINT ck_un_category CHECK (un_category IN ('announcement', 'personal')),
50
+ CONSTRAINT FK_user_notification_tenant
51
+ FOREIGN KEY (un_tenant_id) REFERENCES \`${APP}\`.\`companies\` (c_uuid)
52
+ ON DELETE CASCADE,
53
+ CONSTRAINT FK_user_notification_user
54
+ FOREIGN KEY (un_user_uuid) REFERENCES \`${APP}\`.\`users\` (u_uuid)
55
+ ON DELETE CASCADE
56
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`,
57
+ );
58
+ }
59
+
60
+ async function down(ctx) {
61
+ const { query } = ctx;
62
+ const { identity: IDENTITY } = frameworkSchemasForMigration(ctx, process.env);
63
+ await query(`DROP TABLE IF EXISTS \`${IDENTITY}\`.\`user_notification\``);
64
+ }
65
+
66
+ module.exports = { up, down };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astram/identity",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "license": "MIT",
5
5
  "description": "Astram framework — the framework-owned identity + tenancy model. Hosts the identity @ObjectType classes (user, company, membership, posting), framework-authored identity migrations, and the identity resolver. Top of the dependency graph: depends on @astram/engine (for @ObjectType/@Field decorators) + @astram/guard / @astram/core (for the auth ports).",
6
6
  "type": "commonjs",
@@ -36,9 +36,9 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "mariadb": "^3.5.4",
39
- "@astram/core": "1.12.0",
40
- "@astram/guard": "0.23.0",
41
- "@astram/engine": "0.16.0"
39
+ "@astram/core": "1.13.0",
40
+ "@astram/guard": "0.24.0",
41
+ "@astram/engine": "0.16.1"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "@nestjs/common": "^11",