@adminiumjs/meta 0.2.2 → 0.2.4
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/dist/ids.d.ts +2 -0
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +7 -0
- package/dist/ids.js.map +1 -1
- package/dist/migrations/0015_connection_tenant_config.d.ts +42 -0
- package/dist/migrations/0015_connection_tenant_config.d.ts.map +1 -0
- package/dist/migrations/0015_connection_tenant_config.js +53 -0
- package/dist/migrations/0015_connection_tenant_config.js.map +1 -0
- package/dist/migrations/0016_audit_entity.d.ts +33 -0
- package/dist/migrations/0016_audit_entity.d.ts.map +1 -0
- package/dist/migrations/0016_audit_entity.js +137 -0
- package/dist/migrations/0016_audit_entity.js.map +1 -0
- package/dist/migrations/0017_surface_binding.d.ts +23 -0
- package/dist/migrations/0017_surface_binding.d.ts.map +1 -0
- package/dist/migrations/0017_surface_binding.js +37 -0
- package/dist/migrations/0017_surface_binding.js.map +1 -0
- package/dist/migrations/0018_connection_timezone_source.d.ts +44 -0
- package/dist/migrations/0018_connection_timezone_source.d.ts.map +1 -0
- package/dist/migrations/0018_connection_timezone_source.js +51 -0
- package/dist/migrations/0018_connection_timezone_source.js.map +1 -0
- package/dist/migrations/0019_connection_disabled.d.ts +38 -0
- package/dist/migrations/0019_connection_disabled.d.ts.map +1 -0
- package/dist/migrations/0019_connection_disabled.js +43 -0
- package/dist/migrations/0019_connection_disabled.js.map +1 -0
- package/dist/migrations/0020_manifests_add_on.d.ts +71 -0
- package/dist/migrations/0020_manifests_add_on.d.ts.map +1 -0
- package/dist/migrations/0020_manifests_add_on.js +111 -0
- package/dist/migrations/0020_manifests_add_on.js.map +1 -0
- package/dist/migrations/0021_add_on_credentials.d.ts +50 -0
- package/dist/migrations/0021_add_on_credentials.d.ts.map +1 -0
- package/dist/migrations/0021_add_on_credentials.js +80 -0
- package/dist/migrations/0021_add_on_credentials.js.map +1 -0
- package/dist/migrations/0022_studio_namespace.d.ts +44 -0
- package/dist/migrations/0022_studio_namespace.d.ts.map +1 -0
- package/dist/migrations/0022_studio_namespace.js +113 -0
- package/dist/migrations/0022_studio_namespace.js.map +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +16 -0
- package/dist/migrations/index.js.map +1 -1
- package/dist/repos/audit.d.ts.map +1 -1
- package/dist/repos/audit.js +8 -2
- package/dist/repos/audit.js.map +1 -1
- package/dist/repos/connections.d.ts +62 -0
- package/dist/repos/connections.d.ts.map +1 -1
- package/dist/repos/connections.js +104 -0
- package/dist/repos/connections.js.map +1 -1
- package/dist/repos/index.d.ts +1 -0
- package/dist/repos/index.d.ts.map +1 -1
- package/dist/repos/index.js +1 -0
- package/dist/repos/index.js.map +1 -1
- package/dist/repos/manifests.d.ts +139 -0
- package/dist/repos/manifests.d.ts.map +1 -0
- package/dist/repos/manifests.js +279 -0
- package/dist/repos/manifests.js.map +1 -0
- package/dist/repos/pages.d.ts +7 -0
- package/dist/repos/pages.d.ts.map +1 -1
- package/dist/repos/pages.js +39 -8
- package/dist/repos/pages.js.map +1 -1
- package/dist/repos/public-api.d.ts +24 -0
- package/dist/repos/public-api.d.ts.map +1 -1
- package/dist/repos/public-api.js +50 -0
- package/dist/repos/public-api.js.map +1 -1
- package/dist/schema/json-payloads.d.ts +27 -2
- package/dist/schema/json-payloads.d.ts.map +1 -1
- package/dist/schema/json-payloads.js +41 -2
- package/dist/schema/json-payloads.js.map +1 -1
- package/dist/schema/settings-registry.d.ts +26 -0
- package/dist/schema/settings-registry.d.ts.map +1 -1
- package/dist/schema/settings-registry.js +130 -0
- package/dist/schema/settings-registry.js.map +1 -1
- package/dist/schema/tables.d.ts +89 -1
- package/dist/schema/tables.d.ts.map +1 -1
- package/dist/schema/tables.js +2 -0
- package/dist/schema/tables.js.map +1 -1
- package/package.json +1 -1
package/dist/ids.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ export declare const ID_PREFIXES: {
|
|
|
44
44
|
readonly whd: "adminium_webhook_deliveries";
|
|
45
45
|
readonly flag: "adminium_feature_flags";
|
|
46
46
|
readonly mft: "adminium_manifests";
|
|
47
|
+
readonly mat: "adminium_manifest_attachments";
|
|
48
|
+
readonly aoc: "adminium_add_on_credentials";
|
|
47
49
|
readonly loc: "adminium_locales";
|
|
48
50
|
readonly trn: "adminium_translations";
|
|
49
51
|
readonly pbk: "adminium_public_keys";
|
package/dist/ids.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;GAWG;AAQH,QAAA,MAAM,QAAQ,QAAsB,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;GAWG;AAQH,QAAA,MAAM,QAAQ,QAAsB,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Cd,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,WAAW,CAAC;AAOhD,sEAAsE;AACtE,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC,qBAAa,cAAe,SAAQ,KAAK;IAC9B,IAAI,SAAoB;CAClC;AAiDD;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAc9C;AAED,MAAM,WAAW,QAAQ;IACvB,qCAAqC;IACrC,MAAM,EAAE,QAAQ,CAAC;IACjB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,8FAA8F;AAC9F,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,CAY5C;AAED,uFAAuF;AACvF,wBAAgB,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,CAQ5D;AAED,yDAAyD;AACzD,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,2CAA2C;AAC3C,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAED,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,CAAC"}
|
package/dist/ids.js
CHANGED
|
@@ -50,6 +50,13 @@ export const ID_PREFIXES = {
|
|
|
50
50
|
whd: 'adminium_webhook_deliveries',
|
|
51
51
|
flag: 'adminium_feature_flags',
|
|
52
52
|
mft: 'adminium_manifests',
|
|
53
|
+
// 26-add-on-runtime.md §4. `mat` and `aoc` are separate spaces rather than
|
|
54
|
+
// reusing `mft`: an attachment and a credential are addressable rows with
|
|
55
|
+
// their own lifetimes (an attachment is disabled per host, a credential is
|
|
56
|
+
// deleted on disconnect while the manifest stays), and sharing an id space
|
|
57
|
+
// with the manifest they hang off would make a stray id look valid.
|
|
58
|
+
mat: 'adminium_manifest_attachments',
|
|
59
|
+
aoc: 'adminium_add_on_credentials',
|
|
53
60
|
loc: 'adminium_locales',
|
|
54
61
|
trn: 'adminium_translations',
|
|
55
62
|
// 28-public-surface.md §3.3 — the public surface. `pbk` is deliberately not
|
package/dist/ids.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 0015 — `adminium_connections.timezone` / `.currency` (28-T34, D20).
|
|
3
|
+
*
|
|
4
|
+
* ─── Why these are connection columns and not a settings table ──────────────
|
|
5
|
+
*
|
|
6
|
+
* D20 ruled O7 as a hybrid: Adminium owns only what it needs to serve correct
|
|
7
|
+
* data, and it placed `timezone` on the SCOPE document — explicitly rejecting a
|
|
8
|
+
* global `adminium_settings` key, because that is "wrong the moment an instance
|
|
9
|
+
* holds two connections for businesses in different zones".
|
|
10
|
+
*
|
|
11
|
+
* That argument is right, and it points one level further than the ruling took
|
|
12
|
+
* it. The thing a zone belongs to is the BUSINESS, and the business is the
|
|
13
|
+
* database — the connection. A scope is a view onto a connection, and an
|
|
14
|
+
* instance can hold several scopes over one connection; putting the zone on the
|
|
15
|
+
* scope means the same business can be described by two scopes that disagree
|
|
16
|
+
* about what time it is there, with nothing to reconcile them.
|
|
17
|
+
*
|
|
18
|
+
* ─── What forced it ────────────────────────────────────────────────────────
|
|
19
|
+
*
|
|
20
|
+
* A surface hosted BY Adminium reads through the operator's session. It has no
|
|
21
|
+
* publishable key and therefore NO SCOPE, so under the old placement there was
|
|
22
|
+
* nowhere for it to read a zone from at all — the app took it as a build
|
|
23
|
+
* argument, which makes a property of the business a property of the artifact.
|
|
24
|
+
* Hosted mode postdates D20; this is the consequence, not a reversal.
|
|
25
|
+
*
|
|
26
|
+
* ─── What does not change ──────────────────────────────────────────────────
|
|
27
|
+
*
|
|
28
|
+
* `scope.timezone` stays, as an OVERRIDE. It becomes optional and inherits from
|
|
29
|
+
* the connection when omitted, and `compileScope` still refuses a scope that
|
|
30
|
+
* ends up with no valid IANA zone from either source — so D20's boot-fatal
|
|
31
|
+
* guarantee survives intact and every scope already stored keeps working
|
|
32
|
+
* unchanged.
|
|
33
|
+
*
|
|
34
|
+
* Both columns are nullable with no default. There is no defensible default for
|
|
35
|
+
* a timezone: a wrong zone is worse than a missing one, because it looks like
|
|
36
|
+
* data. `null` means "not configured", and the refusal happens where the value
|
|
37
|
+
* is needed rather than being papered over here.
|
|
38
|
+
*/
|
|
39
|
+
import type { Kysely } from 'kysely';
|
|
40
|
+
import type { ColumnHelpers } from '../columns.js';
|
|
41
|
+
export declare function up(db: Kysely<unknown>, c: ColumnHelpers): Promise<void>;
|
|
42
|
+
//# sourceMappingURL=0015_connection_tenant_config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0015_connection_tenant_config.d.ts","sourceRoot":"","sources":["../../src/migrations/0015_connection_tenant_config.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAY7E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
/**
|
|
3
|
+
* Wave 0015 — `adminium_connections.timezone` / `.currency` (28-T34, D20).
|
|
4
|
+
*
|
|
5
|
+
* ─── Why these are connection columns and not a settings table ──────────────
|
|
6
|
+
*
|
|
7
|
+
* D20 ruled O7 as a hybrid: Adminium owns only what it needs to serve correct
|
|
8
|
+
* data, and it placed `timezone` on the SCOPE document — explicitly rejecting a
|
|
9
|
+
* global `adminium_settings` key, because that is "wrong the moment an instance
|
|
10
|
+
* holds two connections for businesses in different zones".
|
|
11
|
+
*
|
|
12
|
+
* That argument is right, and it points one level further than the ruling took
|
|
13
|
+
* it. The thing a zone belongs to is the BUSINESS, and the business is the
|
|
14
|
+
* database — the connection. A scope is a view onto a connection, and an
|
|
15
|
+
* instance can hold several scopes over one connection; putting the zone on the
|
|
16
|
+
* scope means the same business can be described by two scopes that disagree
|
|
17
|
+
* about what time it is there, with nothing to reconcile them.
|
|
18
|
+
*
|
|
19
|
+
* ─── What forced it ────────────────────────────────────────────────────────
|
|
20
|
+
*
|
|
21
|
+
* A surface hosted BY Adminium reads through the operator's session. It has no
|
|
22
|
+
* publishable key and therefore NO SCOPE, so under the old placement there was
|
|
23
|
+
* nowhere for it to read a zone from at all — the app took it as a build
|
|
24
|
+
* argument, which makes a property of the business a property of the artifact.
|
|
25
|
+
* Hosted mode postdates D20; this is the consequence, not a reversal.
|
|
26
|
+
*
|
|
27
|
+
* ─── What does not change ──────────────────────────────────────────────────
|
|
28
|
+
*
|
|
29
|
+
* `scope.timezone` stays, as an OVERRIDE. It becomes optional and inherits from
|
|
30
|
+
* the connection when omitted, and `compileScope` still refuses a scope that
|
|
31
|
+
* ends up with no valid IANA zone from either source — so D20's boot-fatal
|
|
32
|
+
* guarantee survives intact and every scope already stored keeps working
|
|
33
|
+
* unchanged.
|
|
34
|
+
*
|
|
35
|
+
* Both columns are nullable with no default. There is no defensible default for
|
|
36
|
+
* a timezone: a wrong zone is worse than a missing one, because it looks like
|
|
37
|
+
* data. `null` means "not configured", and the refusal happens where the value
|
|
38
|
+
* is needed rather than being papered over here.
|
|
39
|
+
*/
|
|
40
|
+
import { metaTable } from '../prefix.js';
|
|
41
|
+
export async function up(db, c) {
|
|
42
|
+
await db.schema
|
|
43
|
+
.alterTable(metaTable('connections'))
|
|
44
|
+
// IANA zone, e.g. `Europe/Lisbon`. 64 matches the scope schema's own cap.
|
|
45
|
+
.addColumn('timezone', c.str(64))
|
|
46
|
+
.execute();
|
|
47
|
+
await db.schema
|
|
48
|
+
.alterTable(metaTable('connections'))
|
|
49
|
+
// ISO-4217, three letters. Null when this business's data carries no money.
|
|
50
|
+
.addColumn('currency', c.str(3))
|
|
51
|
+
.execute();
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=0015_connection_tenant_config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0015_connection_tenant_config.js","sourceRoot":"","sources":["../../src/migrations/0015_connection_tenant_config.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAKH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,EAAmB,EAAE,CAAgB;IAC5D,MAAM,EAAE,CAAC,MAAM;SACZ,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACrC,0EAA0E;SACzE,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SAChC,OAAO,EAAE,CAAC;IAEb,MAAM,EAAE,CAAC,MAAM;SACZ,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACrC,4EAA4E;SAC3E,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAC/B,OAAO,EAAE,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 0016 — per-record audit lookup (30-record-pages.md WS-A).
|
|
3
|
+
*
|
|
4
|
+
* The record page's Activity tab needs "every audit entry for THIS record".
|
|
5
|
+
* The entry's `entity` column stores a RecordRef, but as packed JSON text —
|
|
6
|
+
* filtering on it means either a per-dialect JSON-extract expression (three
|
|
7
|
+
* syntaxes, none of them indexable without generated columns) or a full scan
|
|
8
|
+
* of the `data` category. Both are the amplification anti-pattern D6 exists
|
|
9
|
+
* to rule out, so the ref's two lookup facts are denormalized into real,
|
|
10
|
+
* indexed columns instead:
|
|
11
|
+
*
|
|
12
|
+
* entity_table the ref's qualified table ("public.invoices")
|
|
13
|
+
* entity_id the canonical record-id string — `pkLabel` form: a single
|
|
14
|
+
* PK stringified, a composite PK as the JSON value tuple —
|
|
15
|
+
* the same string the record route and `rowIdOf` use. See
|
|
16
|
+
* `keysOf` for why a BACKFILLED composite reads the ref's
|
|
17
|
+
* `label` rather than re-deriving from `pk`.
|
|
18
|
+
*
|
|
19
|
+
* Both are clamped by `auditEntityKeyPart` (write AND query side, so a
|
|
20
|
+
* truncated key still matches itself), written by `auditRepo.append` from
|
|
21
|
+
* this wave on, and BACKFILLED here from the stored refs so pre-existing
|
|
22
|
+
* activity shows up on day one. The backfill parses each ref in JS — the
|
|
23
|
+
* only portable JSON reader across the three dialects — in id-keyset batches;
|
|
24
|
+
* audit volume is retention-bounded (§8 `audit-log` policy), so this is a
|
|
25
|
+
* one-time bounded cost.
|
|
26
|
+
*
|
|
27
|
+
* Bulk writes (`record.bulk-*`) carry no per-row entity and stay out of the
|
|
28
|
+
* feed by design (30 D6) — their rows simply keep NULL keys.
|
|
29
|
+
*/
|
|
30
|
+
import type { Kysely } from 'kysely';
|
|
31
|
+
import type { ColumnHelpers } from '../columns.js';
|
|
32
|
+
export declare function up(db: Kysely<unknown>, c: ColumnHelpers): Promise<void>;
|
|
33
|
+
//# sourceMappingURL=0016_audit_entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0016_audit_entity.d.ts","sourceRoot":"","sources":["../../src/migrations/0016_audit_entity.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAuEnD,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA8C7E"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
/**
|
|
3
|
+
* Wave 0016 — per-record audit lookup (30-record-pages.md WS-A).
|
|
4
|
+
*
|
|
5
|
+
* The record page's Activity tab needs "every audit entry for THIS record".
|
|
6
|
+
* The entry's `entity` column stores a RecordRef, but as packed JSON text —
|
|
7
|
+
* filtering on it means either a per-dialect JSON-extract expression (three
|
|
8
|
+
* syntaxes, none of them indexable without generated columns) or a full scan
|
|
9
|
+
* of the `data` category. Both are the amplification anti-pattern D6 exists
|
|
10
|
+
* to rule out, so the ref's two lookup facts are denormalized into real,
|
|
11
|
+
* indexed columns instead:
|
|
12
|
+
*
|
|
13
|
+
* entity_table the ref's qualified table ("public.invoices")
|
|
14
|
+
* entity_id the canonical record-id string — `pkLabel` form: a single
|
|
15
|
+
* PK stringified, a composite PK as the JSON value tuple —
|
|
16
|
+
* the same string the record route and `rowIdOf` use. See
|
|
17
|
+
* `keysOf` for why a BACKFILLED composite reads the ref's
|
|
18
|
+
* `label` rather than re-deriving from `pk`.
|
|
19
|
+
*
|
|
20
|
+
* Both are clamped by `auditEntityKeyPart` (write AND query side, so a
|
|
21
|
+
* truncated key still matches itself), written by `auditRepo.append` from
|
|
22
|
+
* this wave on, and BACKFILLED here from the stored refs so pre-existing
|
|
23
|
+
* activity shows up on day one. The backfill parses each ref in JS — the
|
|
24
|
+
* only portable JSON reader across the three dialects — in id-keyset batches;
|
|
25
|
+
* audit volume is retention-bounded (§8 `audit-log` policy), so this is a
|
|
26
|
+
* one-time bounded cost.
|
|
27
|
+
*
|
|
28
|
+
* Bulk writes (`record.bulk-*`) carry no per-row entity and stay out of the
|
|
29
|
+
* feed by design (30 D6) — their rows simply keep NULL keys.
|
|
30
|
+
*/
|
|
31
|
+
import { metaTable } from '../prefix.js';
|
|
32
|
+
import { AUDIT_ENTITY_KEY_MAX, auditEntityKeyOf, auditEntityKeyPart, recordRefSchema, } from '../schema/json-payloads.js';
|
|
33
|
+
const BACKFILL_BATCH = 500;
|
|
34
|
+
/**
|
|
35
|
+
* A STORED ref has lost the one thing `auditEntityKeyOf` reads for a composite
|
|
36
|
+
* key: the order of `pk`.
|
|
37
|
+
*
|
|
38
|
+
* `entity` is `jsonb` on postgres and `json` on mysql, and both normalise
|
|
39
|
+
* object keys on the way in — jsonb by key length then bytes, mysql likewise.
|
|
40
|
+
* So `{invoice_id, line}` comes back as `{line, invoice_id}` and
|
|
41
|
+
* `Object.values()` yields the tuple backwards, producing an id that matches no
|
|
42
|
+
* record. Only sqlite, which stores the column as text, keeps the written
|
|
43
|
+
* order, which is why deriving from `pk` passed there and failed on the other
|
|
44
|
+
* two. There is no recovering the order from the stored value: jsonb and mysql
|
|
45
|
+
* json are parsed forms, so even casting back to text returns the normalised
|
|
46
|
+
* key order rather than the original.
|
|
47
|
+
*
|
|
48
|
+
* A single-column key has no order to lose, so it still derives from `pk`.
|
|
49
|
+
*
|
|
50
|
+
* A composite one falls back to the ref's `label`, which the only writer of a
|
|
51
|
+
* record ref (`routes/data`) sets to `pkLabel(table, pk)` — the same tuple, in
|
|
52
|
+
* the table's primary-key order, as a plain string no store reorders. `label`
|
|
53
|
+
* is display text by contract and NOT guaranteed to be that tuple, so it is
|
|
54
|
+
* used only when it still parses as a JSON array of the right arity; anything
|
|
55
|
+
* else leaves the row NULL. A legacy row that opts out of the feed is the
|
|
56
|
+
* documented outcome for a ref this reader cannot trust — a confidently wrong
|
|
57
|
+
* key that silently attaches one record's history to another is not.
|
|
58
|
+
*/
|
|
59
|
+
function keysOf(entity) {
|
|
60
|
+
// Postgres `jsonb` columns come back as objects; sqlite/mysql as text.
|
|
61
|
+
let candidate = entity;
|
|
62
|
+
if (typeof entity === 'string') {
|
|
63
|
+
try {
|
|
64
|
+
candidate = JSON.parse(entity);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const parsed = recordRefSchema.safeParse(candidate);
|
|
71
|
+
if (!parsed.success)
|
|
72
|
+
return null;
|
|
73
|
+
const ref = parsed.data;
|
|
74
|
+
const arity = Object.keys(ref.pk).length;
|
|
75
|
+
if (arity <= 1)
|
|
76
|
+
return auditEntityKeyOf(ref);
|
|
77
|
+
let tuple;
|
|
78
|
+
try {
|
|
79
|
+
tuple = JSON.parse(ref.label);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
if (!Array.isArray(tuple) || tuple.length !== arity)
|
|
85
|
+
return null;
|
|
86
|
+
return { entityTable: auditEntityKeyPart(ref.table), entityId: auditEntityKeyPart(ref.label) };
|
|
87
|
+
}
|
|
88
|
+
export async function up(db, c) {
|
|
89
|
+
await db.schema
|
|
90
|
+
.alterTable(metaTable('audit_log'))
|
|
91
|
+
.addColumn('entity_table', c.str(AUDIT_ENTITY_KEY_MAX))
|
|
92
|
+
.execute();
|
|
93
|
+
await db.schema
|
|
94
|
+
.alterTable(metaTable('audit_log'))
|
|
95
|
+
.addColumn('entity_id', c.str(AUDIT_ENTITY_KEY_MAX))
|
|
96
|
+
.execute();
|
|
97
|
+
// (entity_table, entity_id, created_at): the feed's exact access path —
|
|
98
|
+
// equality on both keys, ordered by recency. 2×200×4 utf8mb4 bytes + the
|
|
99
|
+
// timestamp stays under MySQL's 3072-byte InnoDB index cap.
|
|
100
|
+
await db.schema
|
|
101
|
+
.createIndex('idx_adminium_audit_log_entity_created')
|
|
102
|
+
.on(metaTable('audit_log'))
|
|
103
|
+
.columns(['entity_table', 'entity_id', 'created_at'])
|
|
104
|
+
.execute();
|
|
105
|
+
// Backfill: id-keyset batches over rows that carry a ref. Unparseable JSON
|
|
106
|
+
// stays NULL — a row this reader cannot interpret must not fail the wave.
|
|
107
|
+
const backfill = db;
|
|
108
|
+
const audit = metaTable('audit_log');
|
|
109
|
+
let after = '';
|
|
110
|
+
for (;;) {
|
|
111
|
+
const rows = await backfill
|
|
112
|
+
.selectFrom(audit)
|
|
113
|
+
.select(['id', 'entity'])
|
|
114
|
+
.where('entity', 'is not', null)
|
|
115
|
+
.where('id', '>', after)
|
|
116
|
+
.orderBy('id', 'asc')
|
|
117
|
+
.limit(BACKFILL_BATCH)
|
|
118
|
+
.execute();
|
|
119
|
+
if (rows.length === 0)
|
|
120
|
+
break;
|
|
121
|
+
for (const row of rows) {
|
|
122
|
+
const keys = keysOf(row.entity);
|
|
123
|
+
if (keys === null)
|
|
124
|
+
continue;
|
|
125
|
+
await backfill
|
|
126
|
+
.updateTable(audit)
|
|
127
|
+
.set({ entityTable: keys.entityTable, entityId: keys.entityId })
|
|
128
|
+
.where('id', '=', row.id)
|
|
129
|
+
.execute();
|
|
130
|
+
}
|
|
131
|
+
const last = rows[rows.length - 1];
|
|
132
|
+
if (last === undefined || rows.length < BACKFILL_BATCH)
|
|
133
|
+
break;
|
|
134
|
+
after = last.id;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=0016_audit_entity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0016_audit_entity.js","sourceRoot":"","sources":["../../src/migrations/0016_audit_entity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 0017 — key ↔ app-surface binding (29-app-surfaces.md D10, 29-T15).
|
|
3
|
+
*
|
|
4
|
+
* A hosted CUSTOMER surface is configured at serve time, not bake time: the
|
|
5
|
+
* surfaces plugin answers `GET /apps/<key>/customer/surface-config.json` with
|
|
6
|
+
* the newest live publishable key bound to that app, so rotating a key is
|
|
7
|
+
* Studio + reload rather than a rebuild. "Bound to that app" needs a COLUMN —
|
|
8
|
+
* before this wave, "minted per side per app" was a naming convention on
|
|
9
|
+
* `adminium_public_keys.name`, which nothing could query.
|
|
10
|
+
*
|
|
11
|
+
* `app_key` is the manifest key of the owning app (`clients`, `clinic`, …),
|
|
12
|
+
* nullable because binding is optional: a key minted for a standalone build
|
|
13
|
+
* or a third-party integration belongs to no hosted surface and stays NULL.
|
|
14
|
+
*
|
|
15
|
+
* Planned as `0016_surface_binding` (29 D10); renumbered to 0017 because
|
|
16
|
+
* plan 30's `0016_audit_entity` shipped first and the list is append-only.
|
|
17
|
+
*/
|
|
18
|
+
import type { Kysely } from 'kysely';
|
|
19
|
+
import type { ColumnHelpers } from '../columns.js';
|
|
20
|
+
/** Matches the discovery layout: a surface directory name, e.g. `clients`. */
|
|
21
|
+
export declare const PUBLIC_KEY_APP_KEY_MAX = 64;
|
|
22
|
+
export declare function up(db: Kysely<unknown>, c: ColumnHelpers): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=0017_surface_binding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0017_surface_binding.d.ts","sourceRoot":"","sources":["../../src/migrations/0017_surface_binding.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAc7E"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
/**
|
|
3
|
+
* Wave 0017 — key ↔ app-surface binding (29-app-surfaces.md D10, 29-T15).
|
|
4
|
+
*
|
|
5
|
+
* A hosted CUSTOMER surface is configured at serve time, not bake time: the
|
|
6
|
+
* surfaces plugin answers `GET /apps/<key>/customer/surface-config.json` with
|
|
7
|
+
* the newest live publishable key bound to that app, so rotating a key is
|
|
8
|
+
* Studio + reload rather than a rebuild. "Bound to that app" needs a COLUMN —
|
|
9
|
+
* before this wave, "minted per side per app" was a naming convention on
|
|
10
|
+
* `adminium_public_keys.name`, which nothing could query.
|
|
11
|
+
*
|
|
12
|
+
* `app_key` is the manifest key of the owning app (`clients`, `clinic`, …),
|
|
13
|
+
* nullable because binding is optional: a key minted for a standalone build
|
|
14
|
+
* or a third-party integration belongs to no hosted surface and stays NULL.
|
|
15
|
+
*
|
|
16
|
+
* Planned as `0016_surface_binding` (29 D10); renumbered to 0017 because
|
|
17
|
+
* plan 30's `0016_audit_entity` shipped first and the list is append-only.
|
|
18
|
+
*/
|
|
19
|
+
import { metaTable } from '../prefix.js';
|
|
20
|
+
/** Matches the discovery layout: a surface directory name, e.g. `clients`. */
|
|
21
|
+
export const PUBLIC_KEY_APP_KEY_MAX = 64;
|
|
22
|
+
export async function up(db, c) {
|
|
23
|
+
await db.schema
|
|
24
|
+
.alterTable(metaTable('public_keys'))
|
|
25
|
+
.addColumn('app_key', c.str(PUBLIC_KEY_APP_KEY_MAX))
|
|
26
|
+
.execute();
|
|
27
|
+
// (app_key, side): the config route's exact lookup — every live key for one
|
|
28
|
+
// app's side, newest picked in the query. The table is operator-scale (tens
|
|
29
|
+
// of rows), but the read is on an anonymous, unauthenticated path, so it
|
|
30
|
+
// should not scan by policy rather than by size.
|
|
31
|
+
await db.schema
|
|
32
|
+
.createIndex('ix_adminium_public_keys_app')
|
|
33
|
+
.on(metaTable('public_keys'))
|
|
34
|
+
.columns(['app_key', 'side'])
|
|
35
|
+
.execute();
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=0017_surface_binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0017_surface_binding.js","sourceRoot":"","sources":["../../src/migrations/0017_surface_binding.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,EAAmB,EAAE,CAAgB;IAC5D,MAAM,EAAE,CAAC,MAAM;SACZ,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;SACpC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;SACnD,OAAO,EAAE,CAAC;IACb,4EAA4E;IAC5E,4EAA4E;IAC5E,yEAAyE;IACzE,iDAAiD;IACjD,MAAM,EAAE,CAAC,MAAM;SACZ,WAAW,CAAC,6BAA6B,CAAC;SAC1C,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;SAC5B,OAAO,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;SAC5B,OAAO,EAAE,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 0018 — `adminium_connections.timezoneSource`: WHO chose the zone.
|
|
3
|
+
*
|
|
4
|
+
* ─── What changed under 0015 ───────────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* 0015 added `timezone` and argued for no default at all: "a wrong zone is
|
|
7
|
+
* worse than a missing one, because it looks like data". `connectionsRepo`
|
|
8
|
+
* later seeded new rows from the SERVER's zone anyway, and for a good reason —
|
|
9
|
+
* a null zone made a hosted app surface refuse to render, so the cost of the
|
|
10
|
+
* missing value landed as total unavailability rather than an hour's drift.
|
|
11
|
+
*
|
|
12
|
+
* Both positions are right about their own failure, and the column below is
|
|
13
|
+
* what lets them both hold. A seeded zone keeps surfaces rendering; recording
|
|
14
|
+
* that it was seeded keeps it from passing as a decision nobody made.
|
|
15
|
+
*
|
|
16
|
+
* ─── Why provenance and not a different default ────────────────────────────
|
|
17
|
+
*
|
|
18
|
+
* Without this column a stored zone is two very different facts wearing one
|
|
19
|
+
* value: something an operator chose for the business, or something the server
|
|
20
|
+
* guessed from the clock of whatever machine it happens to run on (a developer
|
|
21
|
+
* laptop, a container defaulting to UTC, a VM in the wrong region). Studio
|
|
22
|
+
* renders them identically, so the guess reads as a decision — reproducing in
|
|
23
|
+
* the UI precisely the failure 0015 refused in the data.
|
|
24
|
+
*
|
|
25
|
+
* ─── Values, and why NULL is not backfilled ────────────────────────────────
|
|
26
|
+
*
|
|
27
|
+
* 'operator' a human set this — the wizard, Studio, or `PATCH /connections`
|
|
28
|
+
* 'host' `connectionsRepo.create` derived it from the server's own zone
|
|
29
|
+
* NULL unknown, or no zone to attribute
|
|
30
|
+
*
|
|
31
|
+
* Rows predating this column are left NULL rather than guessed at, and NULL
|
|
32
|
+
* must render as no claim at all. The asymmetry is deliberate: under-claiming
|
|
33
|
+
* costs an operator a badge they did not need, while over-claiming tells
|
|
34
|
+
* someone their correct, deliberately chosen zone is a guess — which is how a
|
|
35
|
+
* badge earns the right to be ignored.
|
|
36
|
+
*
|
|
37
|
+
* A zone that is itself NULL carries a NULL source: there is no choice to
|
|
38
|
+
* attribute, and "the operator chose nothing" is a state `timezone` already
|
|
39
|
+
* records on its own.
|
|
40
|
+
*/
|
|
41
|
+
import type { Kysely } from 'kysely';
|
|
42
|
+
import type { ColumnHelpers } from '../columns.js';
|
|
43
|
+
export declare function up(db: Kysely<unknown>, c: ColumnHelpers): Promise<void>;
|
|
44
|
+
//# sourceMappingURL=0018_connection_timezone_source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0018_connection_timezone_source.d.ts","sourceRoot":"","sources":["../../src/migrations/0018_connection_timezone_source.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAO7E"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
/**
|
|
3
|
+
* Wave 0018 — `adminium_connections.timezoneSource`: WHO chose the zone.
|
|
4
|
+
*
|
|
5
|
+
* ─── What changed under 0015 ───────────────────────────────────────────────
|
|
6
|
+
*
|
|
7
|
+
* 0015 added `timezone` and argued for no default at all: "a wrong zone is
|
|
8
|
+
* worse than a missing one, because it looks like data". `connectionsRepo`
|
|
9
|
+
* later seeded new rows from the SERVER's zone anyway, and for a good reason —
|
|
10
|
+
* a null zone made a hosted app surface refuse to render, so the cost of the
|
|
11
|
+
* missing value landed as total unavailability rather than an hour's drift.
|
|
12
|
+
*
|
|
13
|
+
* Both positions are right about their own failure, and the column below is
|
|
14
|
+
* what lets them both hold. A seeded zone keeps surfaces rendering; recording
|
|
15
|
+
* that it was seeded keeps it from passing as a decision nobody made.
|
|
16
|
+
*
|
|
17
|
+
* ─── Why provenance and not a different default ────────────────────────────
|
|
18
|
+
*
|
|
19
|
+
* Without this column a stored zone is two very different facts wearing one
|
|
20
|
+
* value: something an operator chose for the business, or something the server
|
|
21
|
+
* guessed from the clock of whatever machine it happens to run on (a developer
|
|
22
|
+
* laptop, a container defaulting to UTC, a VM in the wrong region). Studio
|
|
23
|
+
* renders them identically, so the guess reads as a decision — reproducing in
|
|
24
|
+
* the UI precisely the failure 0015 refused in the data.
|
|
25
|
+
*
|
|
26
|
+
* ─── Values, and why NULL is not backfilled ────────────────────────────────
|
|
27
|
+
*
|
|
28
|
+
* 'operator' a human set this — the wizard, Studio, or `PATCH /connections`
|
|
29
|
+
* 'host' `connectionsRepo.create` derived it from the server's own zone
|
|
30
|
+
* NULL unknown, or no zone to attribute
|
|
31
|
+
*
|
|
32
|
+
* Rows predating this column are left NULL rather than guessed at, and NULL
|
|
33
|
+
* must render as no claim at all. The asymmetry is deliberate: under-claiming
|
|
34
|
+
* costs an operator a badge they did not need, while over-claiming tells
|
|
35
|
+
* someone their correct, deliberately chosen zone is a guess — which is how a
|
|
36
|
+
* badge earns the right to be ignored.
|
|
37
|
+
*
|
|
38
|
+
* A zone that is itself NULL carries a NULL source: there is no choice to
|
|
39
|
+
* attribute, and "the operator chose nothing" is a state `timezone` already
|
|
40
|
+
* records on its own.
|
|
41
|
+
*/
|
|
42
|
+
import { metaTable } from '../prefix.js';
|
|
43
|
+
export async function up(db, c) {
|
|
44
|
+
await db.schema
|
|
45
|
+
.alterTable(metaTable('connections'))
|
|
46
|
+
// 'operator' is the longest value at 8; 16 leaves room for a third source
|
|
47
|
+
// (an inherited or probed zone) without a second ALTER.
|
|
48
|
+
.addColumn('timezone_source', c.str(16))
|
|
49
|
+
.execute();
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=0018_connection_timezone_source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0018_connection_timezone_source.js","sourceRoot":"","sources":["../../src/migrations/0018_connection_timezone_source.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAKH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,EAAmB,EAAE,CAAgB;IAC5D,MAAM,EAAE,CAAC,MAAM;SACZ,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACrC,0EAA0E;QAC1E,wDAAwD;SACvD,SAAS,CAAC,iBAAiB,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SACvC,OAAO,EAAE,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 0019 — `adminium_connections.disabled_at`: the operator PAUSED this
|
|
3
|
+
* source, and when.
|
|
4
|
+
*
|
|
5
|
+
* ─── Why not a `status` value ──────────────────────────────────────────────
|
|
6
|
+
*
|
|
7
|
+
* `status` is a HEALTH reading — `connected` / `error` / `unconfigured` — and
|
|
8
|
+
* every writer of it is a probe (`recordTestResult`, the create path). Folding
|
|
9
|
+
* a pause into that enum would mean the next successful test silently unpaused
|
|
10
|
+
* the connection, because a probe's whole job is to overwrite `status` with
|
|
11
|
+
* what it just observed. It would also destroy the reading underneath: an
|
|
12
|
+
* operator who pauses a source that is currently failing, fixes the database,
|
|
13
|
+
* and resumes has no way back to `error` because nothing recorded it.
|
|
14
|
+
*
|
|
15
|
+
* Health is observed; a pause is INTENDED. Two facts, two columns, and the
|
|
16
|
+
* card can say "paused, and it was failing when you paused it".
|
|
17
|
+
*
|
|
18
|
+
* ─── Why a timestamp and not a boolean ─────────────────────────────────────
|
|
19
|
+
*
|
|
20
|
+
* A pause is meant to be temporary, so "how long has this been off?" is the
|
|
21
|
+
* question that follows it — a source paused an hour ago during a migration
|
|
22
|
+
* and one paused five weeks ago and forgotten are the same boolean and very
|
|
23
|
+
* different situations. NULL means enabled; anything else is the epoch-ms
|
|
24
|
+
* instant it was paused (07-meta-store.md §2.1: never a native datetime).
|
|
25
|
+
*
|
|
26
|
+
* WHO paused it is not stored here. The audit log already records the actor
|
|
27
|
+
* for `connection.disable` / `connection.enable` alongside every other
|
|
28
|
+
* connection action, and a second, unjoined copy on the row would be one more
|
|
29
|
+
* thing that can disagree with it.
|
|
30
|
+
*
|
|
31
|
+
* ─── Backfill ──────────────────────────────────────────────────────────────
|
|
32
|
+
*
|
|
33
|
+
* None. Every pre-0019 row was serving, which is exactly what NULL means.
|
|
34
|
+
*/
|
|
35
|
+
import type { Kysely } from 'kysely';
|
|
36
|
+
import type { ColumnHelpers } from '../columns.js';
|
|
37
|
+
export declare function up(db: Kysely<unknown>, c: ColumnHelpers): Promise<void>;
|
|
38
|
+
//# sourceMappingURL=0019_connection_disabled.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0019_connection_disabled.d.ts","sourceRoot":"","sources":["../../src/migrations/0019_connection_disabled.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7E"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
/**
|
|
3
|
+
* Wave 0019 — `adminium_connections.disabled_at`: the operator PAUSED this
|
|
4
|
+
* source, and when.
|
|
5
|
+
*
|
|
6
|
+
* ─── Why not a `status` value ──────────────────────────────────────────────
|
|
7
|
+
*
|
|
8
|
+
* `status` is a HEALTH reading — `connected` / `error` / `unconfigured` — and
|
|
9
|
+
* every writer of it is a probe (`recordTestResult`, the create path). Folding
|
|
10
|
+
* a pause into that enum would mean the next successful test silently unpaused
|
|
11
|
+
* the connection, because a probe's whole job is to overwrite `status` with
|
|
12
|
+
* what it just observed. It would also destroy the reading underneath: an
|
|
13
|
+
* operator who pauses a source that is currently failing, fixes the database,
|
|
14
|
+
* and resumes has no way back to `error` because nothing recorded it.
|
|
15
|
+
*
|
|
16
|
+
* Health is observed; a pause is INTENDED. Two facts, two columns, and the
|
|
17
|
+
* card can say "paused, and it was failing when you paused it".
|
|
18
|
+
*
|
|
19
|
+
* ─── Why a timestamp and not a boolean ─────────────────────────────────────
|
|
20
|
+
*
|
|
21
|
+
* A pause is meant to be temporary, so "how long has this been off?" is the
|
|
22
|
+
* question that follows it — a source paused an hour ago during a migration
|
|
23
|
+
* and one paused five weeks ago and forgotten are the same boolean and very
|
|
24
|
+
* different situations. NULL means enabled; anything else is the epoch-ms
|
|
25
|
+
* instant it was paused (07-meta-store.md §2.1: never a native datetime).
|
|
26
|
+
*
|
|
27
|
+
* WHO paused it is not stored here. The audit log already records the actor
|
|
28
|
+
* for `connection.disable` / `connection.enable` alongside every other
|
|
29
|
+
* connection action, and a second, unjoined copy on the row would be one more
|
|
30
|
+
* thing that can disagree with it.
|
|
31
|
+
*
|
|
32
|
+
* ─── Backfill ──────────────────────────────────────────────────────────────
|
|
33
|
+
*
|
|
34
|
+
* None. Every pre-0019 row was serving, which is exactly what NULL means.
|
|
35
|
+
*/
|
|
36
|
+
import { metaTable } from '../prefix.js';
|
|
37
|
+
export async function up(db, c) {
|
|
38
|
+
await db.schema
|
|
39
|
+
.alterTable(metaTable('connections'))
|
|
40
|
+
.addColumn('disabled_at', c.ts)
|
|
41
|
+
.execute();
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=0019_connection_disabled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0019_connection_disabled.js","sourceRoot":"","sources":["../../src/migrations/0019_connection_disabled.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAKH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,EAAmB,EAAE,CAAgB;IAC5D,MAAM,EAAE,CAAC,MAAM;SACZ,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;SACpC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC;SAC9B,OAAO,EAAE,CAAC;AACf,CAAC"}
|