@openbrf/plugin-sdk 1.0.0 → 1.2.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.
Files changed (100) hide show
  1. package/README.md +95 -0
  2. package/dist/abort-signal.d.ts +23 -0
  3. package/dist/abort-signal.d.ts.map +1 -0
  4. package/dist/abort-signal.js +2 -0
  5. package/dist/abort-signal.js.map +1 -0
  6. package/dist/action-refusal.d.ts +101 -0
  7. package/dist/action-refusal.d.ts.map +1 -0
  8. package/dist/action-refusal.js +96 -0
  9. package/dist/action-refusal.js.map +1 -0
  10. package/dist/action-schema.d.ts.map +1 -1
  11. package/dist/action-schema.js +4 -1
  12. package/dist/action-schema.js.map +1 -1
  13. package/dist/actions.d.ts +94 -6
  14. package/dist/actions.d.ts.map +1 -1
  15. package/dist/actions.js.map +1 -1
  16. package/dist/blocks.d.ts +310 -0
  17. package/dist/blocks.d.ts.map +1 -0
  18. package/dist/blocks.js +185 -0
  19. package/dist/blocks.js.map +1 -0
  20. package/dist/catalog.d.ts +399 -7
  21. package/dist/catalog.d.ts.map +1 -1
  22. package/dist/catalog.js +373 -9
  23. package/dist/catalog.js.map +1 -1
  24. package/dist/entitlements.d.ts +117 -0
  25. package/dist/entitlements.d.ts.map +1 -0
  26. package/dist/entitlements.js +62 -0
  27. package/dist/entitlements.js.map +1 -0
  28. package/dist/extensions.d.ts +183 -0
  29. package/dist/extensions.d.ts.map +1 -0
  30. package/dist/extensions.js +67 -0
  31. package/dist/extensions.js.map +1 -0
  32. package/dist/finances.d.ts +294 -0
  33. package/dist/finances.d.ts.map +1 -0
  34. package/dist/finances.js +56 -0
  35. package/dist/finances.js.map +1 -0
  36. package/dist/findings.d.ts +90 -1
  37. package/dist/findings.d.ts.map +1 -1
  38. package/dist/findings.js +89 -0
  39. package/dist/findings.js.map +1 -1
  40. package/dist/host.d.ts +621 -2
  41. package/dist/host.d.ts.map +1 -1
  42. package/dist/host.js +39 -0
  43. package/dist/host.js.map +1 -1
  44. package/dist/imports.d.ts +104 -0
  45. package/dist/imports.d.ts.map +1 -0
  46. package/dist/imports.js +70 -0
  47. package/dist/imports.js.map +1 -0
  48. package/dist/index.d.ts +17 -7
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +15 -6
  51. package/dist/index.js.map +1 -1
  52. package/dist/localized-text.d.ts +18 -0
  53. package/dist/localized-text.d.ts.map +1 -0
  54. package/dist/localized-text.js +17 -0
  55. package/dist/localized-text.js.map +1 -0
  56. package/dist/manifest.d.ts +730 -0
  57. package/dist/manifest.d.ts.map +1 -1
  58. package/dist/manifest.js +805 -11
  59. package/dist/manifest.js.map +1 -1
  60. package/dist/permissions.d.ts +170 -11
  61. package/dist/permissions.d.ts.map +1 -1
  62. package/dist/permissions.js +210 -2
  63. package/dist/permissions.js.map +1 -1
  64. package/dist/recipients.d.ts +139 -0
  65. package/dist/recipients.d.ts.map +1 -0
  66. package/dist/recipients.js +223 -0
  67. package/dist/recipients.js.map +1 -0
  68. package/dist/records.d.ts +130 -0
  69. package/dist/records.d.ts.map +1 -0
  70. package/dist/records.js +85 -0
  71. package/dist/records.js.map +1 -0
  72. package/dist/require-capability.d.ts +37 -0
  73. package/dist/require-capability.d.ts.map +1 -0
  74. package/dist/require-capability.js +88 -0
  75. package/dist/require-capability.js.map +1 -0
  76. package/dist/settings-schema.d.ts +35 -0
  77. package/dist/settings-schema.d.ts.map +1 -1
  78. package/dist/settings-schema.js +55 -2
  79. package/dist/settings-schema.js.map +1 -1
  80. package/package.json +4 -4
  81. package/src/abort-signal.ts +22 -0
  82. package/src/action-refusal.ts +178 -0
  83. package/src/action-schema.ts +4 -1
  84. package/src/actions.ts +103 -6
  85. package/src/blocks.ts +289 -0
  86. package/src/catalog.ts +500 -57
  87. package/src/entitlements.ts +150 -0
  88. package/src/extensions.ts +212 -0
  89. package/src/finances.ts +317 -0
  90. package/src/findings.ts +92 -0
  91. package/src/host.ts +656 -2
  92. package/src/imports.ts +135 -0
  93. package/src/index.ts +193 -0
  94. package/src/localized-text.ts +19 -0
  95. package/src/manifest.ts +1039 -12
  96. package/src/permissions.ts +223 -3
  97. package/src/recipients.ts +294 -0
  98. package/src/records.ts +172 -0
  99. package/src/require-capability.ts +106 -0
  100. package/src/settings-schema.ts +64 -2
@@ -0,0 +1,183 @@
1
+ import type { PluginAbortSignal } from "./abort-signal.ts";
2
+ import type { StandardSchemaV1 } from "./standard-schema.ts";
3
+ /**
4
+ * Plugins that extend plugins (ADR 0030).
5
+ *
6
+ * An extension point (utökningspunkt) is a named slot a plugin declares in its
7
+ * manifest and offers to other plugins; that plugin is the point's host plugin.
8
+ * An addon (utökning) is a plugin that extends another at one of its points,
9
+ * and what it registers there is a contribution (bidrag): a title and a
10
+ * handler. Each is a plugin in every other respect, installed, consented to and
11
+ * switched on by itself, and neither receives the other's permissions.
12
+ *
13
+ * The host carries every call between them. It validates the input against the
14
+ * host plugin's schema before the call and the output after it, copies both as
15
+ * JSON values so that nothing but data crosses, and answers for what the addon
16
+ * did in the result rather than by throwing: a screen that loses one source
17
+ * should go on with the others.
18
+ *
19
+ * Swedish domain terms follow GLOSSARY.md.
20
+ */
21
+ /**
22
+ * What an extension point id may look like, in the manifest and at the host.
23
+ *
24
+ * Lowercase letters, digits and single hyphens, two to thirty-two characters:
25
+ * the shape a plugin id has, shorter, because it is shown beside one.
26
+ */
27
+ export declare const EXTENSION_POINT_ID_PATTERN: RegExp;
28
+ /** How many points a plugin may declare, and how many an addon may extend. */
29
+ export declare const MAX_EXTENSION_POINTS = 8;
30
+ /** How long a contribution may take when its point names no time of its own. */
31
+ export declare const EXTENSION_TIMEOUT_MS = 5000;
32
+ /** The longest a point may give a contribution. */
33
+ export declare const EXTENSION_MAX_TIMEOUT_MS = 15000;
34
+ /**
35
+ * The longest answer a contribution may give, in characters of its JSON text.
36
+ * A longer one is `output-invalid`, refused before it is parsed or validated.
37
+ */
38
+ export declare const EXTENSION_MAX_OUTPUT_LENGTH = 1048576;
39
+ /**
40
+ * Why `invoke` answered without a value.
41
+ *
42
+ * Everything an addon can do wrong, and the one state the host plugin cannot
43
+ * see from its own side, so a host plugin can tell a broken addon from one that
44
+ * is switched off without either being thrown at it.
45
+ */
46
+ export declare const EXTENSION_RESULT_REASONS: readonly [
47
+ /**
48
+ * The addon is not installed, not loaded, switched off, or has registered no
49
+ * contribution at this point.
50
+ */
51
+ "not-serving",
52
+ /**
53
+ * The handler did not answer in time. Its signal was aborted.
54
+ *
55
+ * The time bounds only how long the host waits for the handler's promise.
56
+ * Work the handler does synchronously, and a `toJSON` or getter in its
57
+ * answer, runs on the host's one thread with no limit, as any plugin code
58
+ * does: a handler that loops stalls the instance.
59
+ */
60
+ "timed-out",
61
+ /** The handler threw. What it threw is in the server log, never here. */
62
+ "failed",
63
+ /**
64
+ * The answer does not meet the point's output schema, has no JSON form, or
65
+ * is longer than EXTENSION_MAX_OUTPUT_LENGTH as JSON.
66
+ */
67
+ "output-invalid"];
68
+ export type ExtensionResultReason = (typeof EXTENSION_RESULT_REASONS)[number];
69
+ /** What the host plugin hands `define` for one point its manifest declares. */
70
+ export interface ExtensionPointDefinition<Input = unknown, Output = unknown> {
71
+ /**
72
+ * What the host plugin sends a contribution. A strict object at every depth,
73
+ * built with the host's zod, with no record, catchall, `unknown` or `any`
74
+ * anywhere inside it.
75
+ */
76
+ readonly input: StandardSchemaV1<unknown, Input>;
77
+ /**
78
+ * What a contribution must answer. A strict object at every depth, built with
79
+ * the host's zod, with no record, catchall, `unknown` or `any` anywhere inside
80
+ * it: a key the schema does not name is a key an addon could hand over
81
+ * something nobody consented to in.
82
+ */
83
+ readonly output: StandardSchemaV1<unknown, Output>;
84
+ /**
85
+ * How long a contribution may take, in milliseconds.
86
+ * EXTENSION_TIMEOUT_MS by default, at most EXTENSION_MAX_TIMEOUT_MS.
87
+ */
88
+ readonly timeoutMs?: number;
89
+ }
90
+ /** What the host tells a contribution about the call it is answering. */
91
+ export interface ExtensionContext {
92
+ /** The plugin whose point is being answered. */
93
+ readonly hostPlugin: string;
94
+ readonly point: string;
95
+ /** The point's major version, which is the one the addon named. */
96
+ readonly version: number;
97
+ /** For the logs, so a call can be followed from one plugin to the other. */
98
+ readonly requestId: string;
99
+ readonly now: Date;
100
+ /** Aborted when the call times out or the host plugin gives up on it. */
101
+ readonly signal: PluginAbortSignal;
102
+ }
103
+ /** What an addon hands `contribute` for one point its manifest extends. */
104
+ export interface ExtensionContributionDefinition<Input = unknown, Output = unknown> {
105
+ /**
106
+ * A bare key in the addon's own namespace, as an action's is. The host
107
+ * qualifies it as `plugin-<addon>:<key>`.
108
+ */
109
+ readonly titleKey: string;
110
+ readonly descriptionKey?: string;
111
+ /**
112
+ * Answers one call.
113
+ *
114
+ * Runs with the addon's own host object, under the permissions the board
115
+ * consented to for the addon, and with no person behind it: an extension
116
+ * point is a call from one plugin to another, not somebody's request. It
117
+ * must accept input fields it does not know, because a host plugin may add
118
+ * an optional field to a point without raising its version.
119
+ */
120
+ readonly handler: (input: Input, context: ExtensionContext) => Promise<Output>;
121
+ }
122
+ /** One contribution that is serving at a point, as its host plugin sees it. */
123
+ export interface ExtensionContributionSummary {
124
+ /** The addon's plugin id, which `invoke` takes. */
125
+ readonly addon: string;
126
+ /** Qualified into the addon's namespace, `plugin-<addon>:<key>`. */
127
+ readonly titleKey: string;
128
+ readonly descriptionKey: string | null;
129
+ }
130
+ /** What `invoke` answers: a value, or why there is none. */
131
+ export type ExtensionResult<Output> = {
132
+ readonly ok: true;
133
+ readonly value: Output;
134
+ } | {
135
+ readonly ok: false;
136
+ readonly reason: ExtensionResultReason;
137
+ };
138
+ /** The plugin and the point an addon contributes to. */
139
+ export interface ExtensionTarget {
140
+ readonly plugin: string;
141
+ readonly point: string;
142
+ }
143
+ /**
144
+ * Extension points, as a plugin sees them.
145
+ *
146
+ * A host plugin uses `define`, `list` and `invoke`; an addon uses
147
+ * `contribute`. `define` and `contribute` are declarations, callable from the
148
+ * module factory onwards and buffered until the application exists, as
149
+ * `host.actions.register` is. A definition or contribution the host cannot
150
+ * accept - a point or target the manifest does not declare, a schema that is
151
+ * not a strict object built with the host's zod, a second one for the same
152
+ * point - is found when the buffer is flushed and stops the plugin with
153
+ * `extension-refused`, rather than throwing here.
154
+ *
155
+ * `list` and `invoke` keep the ordinary gate and work from `onModuleInit`
156
+ * onwards.
157
+ */
158
+ export interface PluginExtensions {
159
+ /** Host plugin: the schemas of a point its manifest declares. */
160
+ define<Input, Output>(point: string, definition: ExtensionPointDefinition<Input, Output>): void;
161
+ /**
162
+ * Host plugin: the contributions to one of its points that are serving now,
163
+ * in addon id order.
164
+ *
165
+ * Throws for a point the manifest does not declare or the plugin has not
166
+ * defined.
167
+ */
168
+ list(point: string): Promise<readonly ExtensionContributionSummary[]>;
169
+ /**
170
+ * Host plugin: calls one addon's contribution.
171
+ *
172
+ * Throws for a mistake of the host plugin's own: a point its manifest does
173
+ * not declare or it has not defined, or an input its own schema refuses. An
174
+ * aborted `signal` rejects with the signal's reason. Everything the addon
175
+ * does is answered in the result.
176
+ */
177
+ invoke<Output>(point: string, addon: string, input: unknown, options?: {
178
+ signal?: PluginAbortSignal;
179
+ }): Promise<ExtensionResult<Output>>;
180
+ /** Addon: the handler for a point its manifest extends. Once per point. */
181
+ contribute<Input, Output>(target: ExtensionTarget, contribution: ExtensionContributionDefinition<Input, Output>): void;
182
+ }
183
+ //# sourceMappingURL=extensions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Plugins that extend plugins (ADR 0030).
3
+ *
4
+ * An extension point (utökningspunkt) is a named slot a plugin declares in its
5
+ * manifest and offers to other plugins; that plugin is the point's host plugin.
6
+ * An addon (utökning) is a plugin that extends another at one of its points,
7
+ * and what it registers there is a contribution (bidrag): a title and a
8
+ * handler. Each is a plugin in every other respect, installed, consented to and
9
+ * switched on by itself, and neither receives the other's permissions.
10
+ *
11
+ * The host carries every call between them. It validates the input against the
12
+ * host plugin's schema before the call and the output after it, copies both as
13
+ * JSON values so that nothing but data crosses, and answers for what the addon
14
+ * did in the result rather than by throwing: a screen that loses one source
15
+ * should go on with the others.
16
+ *
17
+ * Swedish domain terms follow GLOSSARY.md.
18
+ */
19
+ /**
20
+ * What an extension point id may look like, in the manifest and at the host.
21
+ *
22
+ * Lowercase letters, digits and single hyphens, two to thirty-two characters:
23
+ * the shape a plugin id has, shorter, because it is shown beside one.
24
+ */
25
+ export const EXTENSION_POINT_ID_PATTERN = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
26
+ /** How many points a plugin may declare, and how many an addon may extend. */
27
+ export const MAX_EXTENSION_POINTS = 8;
28
+ /** How long a contribution may take when its point names no time of its own. */
29
+ export const EXTENSION_TIMEOUT_MS = 5_000;
30
+ /** The longest a point may give a contribution. */
31
+ export const EXTENSION_MAX_TIMEOUT_MS = 15_000;
32
+ /**
33
+ * The longest answer a contribution may give, in characters of its JSON text.
34
+ * A longer one is `output-invalid`, refused before it is parsed or validated.
35
+ */
36
+ export const EXTENSION_MAX_OUTPUT_LENGTH = 1_048_576;
37
+ /**
38
+ * Why `invoke` answered without a value.
39
+ *
40
+ * Everything an addon can do wrong, and the one state the host plugin cannot
41
+ * see from its own side, so a host plugin can tell a broken addon from one that
42
+ * is switched off without either being thrown at it.
43
+ */
44
+ export const EXTENSION_RESULT_REASONS = [
45
+ /**
46
+ * The addon is not installed, not loaded, switched off, or has registered no
47
+ * contribution at this point.
48
+ */
49
+ "not-serving",
50
+ /**
51
+ * The handler did not answer in time. Its signal was aborted.
52
+ *
53
+ * The time bounds only how long the host waits for the handler's promise.
54
+ * Work the handler does synchronously, and a `toJSON` or getter in its
55
+ * answer, runs on the host's one thread with no limit, as any plugin code
56
+ * does: a handler that loops stalls the instance.
57
+ */
58
+ "timed-out",
59
+ /** The handler threw. What it threw is in the server log, never here. */
60
+ "failed",
61
+ /**
62
+ * The answer does not meet the point's output schema, has no JSON form, or
63
+ * is longer than EXTENSION_MAX_OUTPUT_LENGTH as JSON.
64
+ */
65
+ "output-invalid",
66
+ ];
67
+ //# sourceMappingURL=extensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,+BAA+B,CAAC;AAE1E,8EAA8E;AAC9E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAEtC,gFAAgF;AAChF,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAE1C,mDAAmD;AACnD,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,SAAS,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC;;;OAGG;IACH,aAAa;IACb;;;;;;;OAOG;IACH,WAAW;IACX,yEAAyE;IACzE,QAAQ;IACR;;;OAGG;IACH,gBAAgB;CACR,CAAC"}
@@ -0,0 +1,294 @@
1
+ /**
2
+ * The association's finances, as a plugin may read them, record a delivery
3
+ * against them and hear about them.
4
+ *
5
+ * What is here is the free half of the boundary ROADMAP.md publishes: the
6
+ * notices and charges core already records, read on the same masking rules as
7
+ * the files the board hands over, a receipt that says one of them was
8
+ * delivered, and an event that says one was issued. What carries them out of
9
+ * Open BRF - an accounting system, a bankgiro file, a reminder - is the
10
+ * plugin's own work.
11
+ *
12
+ * Three rules hold on every member here regardless of permission, and they are
13
+ * the address book's (`PluginAddressBook`) read for money:
14
+ *
15
+ * A person with protected personal data is never named. A notice for their
16
+ * household carries its apartment and its amount and withholds every name;
17
+ * a charge on them carries its date and its amount and withholds who, where
18
+ * and why. The row says so with a `withheld` branch rather than an empty
19
+ * string, so a reader cannot take a withheld value for an absent one.
20
+ *
21
+ * A personal identity number is never returned. No row carries one.
22
+ *
23
+ * There is no payment state, because core records none. Nothing here says
24
+ * whether a notice was paid, what is outstanding or what a balance is, and a
25
+ * delivery receipt is not that either: the accounting system settles the
26
+ * debt, and a second answer to whether something was paid is worse than none.
27
+ */
28
+ /**
29
+ * One delivery of a notice or a charge, as the plugin that made it recorded it.
30
+ *
31
+ * A receipt says that something left the association by a route, at a time,
32
+ * under a reference the receiving system knows it by. It never says that the
33
+ * money arrived, and it is not a status: a notice may carry several receipts,
34
+ * from several plugins, and none of them changes the notice.
35
+ */
36
+ export interface PluginDeliveryReceipt {
37
+ id: string;
38
+ /** The plugin that recorded it. */
39
+ pluginId: string;
40
+ /**
41
+ * The route, in the recording plugin's own word for it: `fortnox`,
42
+ * `autogiro`, `email`. Lowercase letters, digits and hyphens, at most 32.
43
+ */
44
+ channel: string;
45
+ /**
46
+ * What the receiving system calls it, or the statement that it is withheld.
47
+ *
48
+ * Withheld on every receipt another plugin recorded: a plugin reads its own
49
+ * references only. And withheld with the row it is on: on a notice whose
50
+ * holders are withheld and a charge whose party or reason is, by the
51
+ * register as it stands at the read rather than when the receipt was
52
+ * recorded. A reference is the recording plugin's free text, and one written
53
+ * while a household could be named can name it as well as the names can.
54
+ * The receipt itself stays, so a plugin can still tell that the row was
55
+ * delivered.
56
+ */
57
+ reference: PluginDeliveryReference;
58
+ /** When it was delivered, as the plugin stated it. An ISO 8601 instant. */
59
+ deliveredAt: string;
60
+ /** When the receipt was recorded. An ISO 8601 instant. */
61
+ recordedAt: string;
62
+ }
63
+ /**
64
+ * What the receiving system calls a delivery - a voucher number, a file name, a
65
+ * message id, at most 128 characters - or the statement that it is withheld.
66
+ */
67
+ export type PluginDeliveryReference = {
68
+ state: "visible";
69
+ text: string;
70
+ } | {
71
+ state: "withheld";
72
+ };
73
+ /** What a plugin states when it records a delivery. */
74
+ export interface PluginDeliveryReceiptInput {
75
+ target: {
76
+ kind: "feeNotice";
77
+ id: string;
78
+ } | {
79
+ kind: "memberCharge";
80
+ id: string;
81
+ };
82
+ channel: string;
83
+ reference: string;
84
+ /** When it was delivered. Now, when left out; never a time still to come. */
85
+ deliveredAt?: Date;
86
+ }
87
+ /** Who a notice names, or the statement that the names are withheld. */
88
+ export type PluginFeeNoticeHolders = {
89
+ state: "visible";
90
+ /** The tenant-owners' names, in the register's own order. */
91
+ names: string[];
92
+ } | {
93
+ state: "withheld";
94
+ };
95
+ /** One apartment's notice in one run (avi). */
96
+ export interface PluginFeeNotice {
97
+ id: string;
98
+ apartment: {
99
+ id: string;
100
+ /** "<street> <number> <apartment number>". Never withheld. */
101
+ label: string;
102
+ number: string;
103
+ };
104
+ /**
105
+ * The tenant-owners holding the apartment when the period closed. Withheld
106
+ * where anybody in the household carries protected personal data or has had
107
+ * processing restricted (GDPR art. 18).
108
+ */
109
+ holders: PluginFeeNoticeHolders;
110
+ /** Kronor with two decimals: "3450.50". What was billed, never a balance. */
111
+ amount: string;
112
+ paymentReference: string;
113
+ deliveries: PluginDeliveryReceipt[];
114
+ }
115
+ /** A fee notification run (avisering) without its notices. */
116
+ export interface PluginFeeNotificationSummary {
117
+ id: string;
118
+ /** The period billed, inclusive at both ends. "YYYY-MM-DD". */
119
+ from: string;
120
+ to: string;
121
+ /** The due date the board stated. Nothing in core computes from it. */
122
+ dueOn: string;
123
+ /** When the run was issued. An ISO 8601 instant. */
124
+ issuedAt: string;
125
+ /** How many notices the run carries. */
126
+ notices: number;
127
+ /** The sum of what was billed, as kronor with two decimals. */
128
+ total: string;
129
+ }
130
+ /** A fee notification run with its notices. */
131
+ export interface PluginFeeNotification extends Omit<PluginFeeNotificationSummary, "notices"> {
132
+ notices: PluginFeeNotice[];
133
+ }
134
+ /** Who a charge is on, or the statement that it is withheld. */
135
+ export type PluginMemberChargeParty = {
136
+ kind: "person";
137
+ state: "visible";
138
+ personId: string;
139
+ name: string;
140
+ /**
141
+ * Where they held a residency on the day of the charge, as the debiting
142
+ * list prints it, or null where they held none.
143
+ */
144
+ apartment: string | null;
145
+ } | {
146
+ /**
147
+ * A person the plugin is not told about: one carrying protected personal
148
+ * data, one whose processing is restricted (GDPR art. 18), or one the
149
+ * register no longer holds.
150
+ */
151
+ kind: "person";
152
+ state: "withheld";
153
+ } | {
154
+ kind: "apartment";
155
+ /** Null once the apartment has been corrected out of the register. */
156
+ apartmentId: string | null;
157
+ apartment: string | null;
158
+ };
159
+ /** The board's own words for a charge, or the statement they are withheld. */
160
+ export type PluginMemberChargeReason = {
161
+ state: "visible";
162
+ text: string;
163
+ } | {
164
+ state: "withheld";
165
+ };
166
+ /** One charge to a member or an apartment (debitering). */
167
+ export interface PluginMemberCharge {
168
+ id: string;
169
+ /** "YYYY-MM-DD" on the association's own calendar. */
170
+ chargedOn: string;
171
+ chargedTo: PluginMemberChargeParty;
172
+ /** Kronor with two decimals. What was charged, never a balance. */
173
+ amount: string;
174
+ vatTreatment: "EXEMPT" | "RATE";
175
+ /** Whole percent, and null exactly when the treatment is EXEMPT. */
176
+ vatRatePercent: number | null;
177
+ /**
178
+ * Withheld with the party, and on a charge to a household where somebody
179
+ * protected or restricted lived on the day of the charge: what the board
180
+ * wrote about a household can say who lives in it as well as a name can.
181
+ */
182
+ reason: PluginMemberChargeReason;
183
+ /** "YYYY-MM-DD" the basis went to the economic manager, or null. */
184
+ handedToManagerOn: string | null;
185
+ deliveries: PluginDeliveryReceipt[];
186
+ }
187
+ /**
188
+ * The events the host delivers, by type, with the version it delivers.
189
+ *
190
+ * A version moves when a field is removed or changes meaning; a field added
191
+ * keeps it. The host lists what it delivers in
192
+ * `host.finances.events.supported`, so a plugin built against a newer SDK can
193
+ * tell an event this instance will never send from one that has not happened.
194
+ */
195
+ export declare const PLUGIN_FINANCE_EVENTS: {
196
+ readonly "feeNotification.issued": 1;
197
+ readonly "memberCharge.recorded": 1;
198
+ readonly "memberCharge.corrected": 1;
199
+ readonly "memberCharge.removed": 1;
200
+ };
201
+ export type PluginFinanceEventType = keyof typeof PLUGIN_FINANCE_EVENTS;
202
+ interface PluginFinanceEventBase {
203
+ /** Unique per event, and the same on every redelivery of it. */
204
+ eventId: string;
205
+ /** When the act was committed. An ISO 8601 instant. */
206
+ occurredAt: string;
207
+ }
208
+ /**
209
+ * Something happened to the association's finances.
210
+ *
211
+ * Identifiers only. An event carries nothing that names a person or states a
212
+ * figure, so it needs no masking of its own: the plugin reads the row through
213
+ * `host.finances`, on the same rules as every other read.
214
+ */
215
+ export type PluginFinanceEvent = (PluginFinanceEventBase & {
216
+ type: "feeNotification.issued";
217
+ version: 1;
218
+ notificationId: string;
219
+ }) | (PluginFinanceEventBase & {
220
+ type: "memberCharge.recorded" | "memberCharge.corrected";
221
+ version: 1;
222
+ chargeId: string;
223
+ }) | (PluginFinanceEventBase & {
224
+ type: "memberCharge.removed";
225
+ version: 1;
226
+ /** The charge is gone; only its id is left to say which one it was. */
227
+ chargeId: string;
228
+ });
229
+ export interface PluginFinanceEvents {
230
+ /** What this host delivers, by type and version. */
231
+ readonly supported: Readonly<Record<string, number>>;
232
+ /**
233
+ * Receives every finance event from now on.
234
+ *
235
+ * Call it once, from `onModuleInit`. Delivery is at least once, from a queue
236
+ * the host keeps for this plugin, and the event is enqueued in the same
237
+ * transaction as the act it reports - so an act that rolled back never
238
+ * produces one and one that committed always does. A handler that throws is
239
+ * retried; one that keeps throwing has the event dropped once the retries
240
+ * are spent. Order is not guaranteed. Ignore a `type` you do not know.
241
+ *
242
+ * Events reach a plugin that is serving and subscribed when the act
243
+ * commits. A plugin switched off, or not yet subscribed, misses them, and
244
+ * reads what it missed with `notifications()` and `charges()` when it starts.
245
+ */
246
+ subscribe(handler: (event: PluginFinanceEvent) => Promise<void> | void): Promise<void>;
247
+ }
248
+ /**
249
+ * The association's finances, scoped to what the plugin declared.
250
+ *
251
+ * The reads and the events require finances:read; recording a delivery
252
+ * requires finances:recordDelivery.
253
+ */
254
+ export interface PluginFinances {
255
+ /** The fee notification runs, newest period first. */
256
+ notifications(): Promise<PluginFeeNotificationSummary[]>;
257
+ /** One run with its notices, or null where there is no such run. */
258
+ notification(id: string): Promise<PluginFeeNotification | null>;
259
+ /**
260
+ * The charges dated within a period, both ends inclusive, as "YYYY-MM-DD".
261
+ * In date order, and in the order they were entered within a day.
262
+ */
263
+ charges(period: {
264
+ from: string;
265
+ to: string;
266
+ }): Promise<PluginMemberCharge[]>;
267
+ /** One charge, or null where there is no such charge. */
268
+ charge(id: string): Promise<PluginMemberCharge | null>;
269
+ /**
270
+ * Records that a notice or a charge was delivered, and returns the receipt.
271
+ *
272
+ * Idempotent: the same target, channel and reference from the same plugin
273
+ * returns the receipt already recorded rather than a second one, so a job
274
+ * retried after a crash cannot record one delivery twice. A reference that
275
+ * holds a Swedish personal identity number is refused.
276
+ *
277
+ * The receipt returned carries the reference visible: it is what the plugin
278
+ * has just stated. A later read withholds it with the row it is on.
279
+ */
280
+ recordDelivery(input: PluginDeliveryReceiptInput): Promise<PluginDeliveryReceipt>;
281
+ events: PluginFinanceEvents;
282
+ }
283
+ /**
284
+ * A delivery the host would not record, and why.
285
+ *
286
+ * `reason` is stable and meant for the plugin's own code; the message is
287
+ * English for the server log.
288
+ */
289
+ export declare class PluginDeliveryRefusedError extends Error {
290
+ readonly reason: "target-not-found" | "channel-invalid" | "reference-invalid" | "reference-holds-personal-identity-number" | "delivered-at-invalid" | "delivered-in-the-future";
291
+ constructor(reason: "target-not-found" | "channel-invalid" | "reference-invalid" | "reference-holds-personal-identity-number" | "delivered-at-invalid" | "delivered-in-the-future", message: string);
292
+ }
293
+ export {};
294
+ //# sourceMappingURL=finances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finances.d.ts","sourceRoot":"","sources":["../src/finances.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The association's finances, as a plugin may read them, record a delivery
3
+ * against them and hear about them.
4
+ *
5
+ * What is here is the free half of the boundary ROADMAP.md publishes: the
6
+ * notices and charges core already records, read on the same masking rules as
7
+ * the files the board hands over, a receipt that says one of them was
8
+ * delivered, and an event that says one was issued. What carries them out of
9
+ * Open BRF - an accounting system, a bankgiro file, a reminder - is the
10
+ * plugin's own work.
11
+ *
12
+ * Three rules hold on every member here regardless of permission, and they are
13
+ * the address book's (`PluginAddressBook`) read for money:
14
+ *
15
+ * A person with protected personal data is never named. A notice for their
16
+ * household carries its apartment and its amount and withholds every name;
17
+ * a charge on them carries its date and its amount and withholds who, where
18
+ * and why. The row says so with a `withheld` branch rather than an empty
19
+ * string, so a reader cannot take a withheld value for an absent one.
20
+ *
21
+ * A personal identity number is never returned. No row carries one.
22
+ *
23
+ * There is no payment state, because core records none. Nothing here says
24
+ * whether a notice was paid, what is outstanding or what a balance is, and a
25
+ * delivery receipt is not that either: the accounting system settles the
26
+ * debt, and a second answer to whether something was paid is worse than none.
27
+ */
28
+ /**
29
+ * The events the host delivers, by type, with the version it delivers.
30
+ *
31
+ * A version moves when a field is removed or changes meaning; a field added
32
+ * keeps it. The host lists what it delivers in
33
+ * `host.finances.events.supported`, so a plugin built against a newer SDK can
34
+ * tell an event this instance will never send from one that has not happened.
35
+ */
36
+ export const PLUGIN_FINANCE_EVENTS = {
37
+ "feeNotification.issued": 1,
38
+ "memberCharge.recorded": 1,
39
+ "memberCharge.corrected": 1,
40
+ "memberCharge.removed": 1,
41
+ };
42
+ /**
43
+ * A delivery the host would not record, and why.
44
+ *
45
+ * `reason` is stable and meant for the plugin's own code; the message is
46
+ * English for the server log.
47
+ */
48
+ export class PluginDeliveryRefusedError extends Error {
49
+ reason;
50
+ constructor(reason, message) {
51
+ super(message);
52
+ this.reason = reason;
53
+ this.name = "PluginDeliveryRefusedError";
54
+ }
55
+ }
56
+ //# sourceMappingURL=finances.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finances.js","sourceRoot":"","sources":["../src/finances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAoKH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,wBAAwB,EAAE,CAAC;IAC3B,uBAAuB,EAAE,CAAC;IAC1B,wBAAwB,EAAE,CAAC;IAC3B,sBAAsB,EAAE,CAAC;CACjB,CAAC;AA6FX;;;;;GAKG;AACH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAExC,MAAM;IADjB,YACW,MAMoB,EAC7B,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;sBATN,MAAM;QAUf,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF"}