@nocobase/app-plugin-office-flows-example 0.0.0-stage → 0.1.0-beta.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 (189) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +55 -2
  3. package/dist/client/components/flow-ui.d.ts +111 -0
  4. package/dist/client/components/flow-ui.d.ts.map +1 -0
  5. package/dist/client/components/flow-ui.js +175 -0
  6. package/dist/client/components/flow-ui.js.map +1 -0
  7. package/dist/client/components/page-container.d.ts +4 -0
  8. package/dist/client/components/page-container.d.ts.map +1 -0
  9. package/dist/client/components/page-container.js +6 -0
  10. package/dist/client/components/page-container.js.map +1 -0
  11. package/dist/client/components/page-header.d.ts +8 -0
  12. package/dist/client/components/page-header.d.ts.map +1 -0
  13. package/dist/client/components/page-header.js +5 -0
  14. package/dist/client/components/page-header.js.map +1 -0
  15. package/dist/client/components/ui/badge.d.ts +7 -0
  16. package/dist/client/components/ui/badge.d.ts.map +1 -0
  17. package/dist/client/components/ui/badge.js +19 -0
  18. package/dist/client/components/ui/badge.js.map +1 -0
  19. package/dist/client/components/ui/button.d.ts +8 -0
  20. package/dist/client/components/ui/button.d.ts.map +1 -0
  21. package/dist/client/components/ui/button.js +25 -0
  22. package/dist/client/components/ui/button.js.map +1 -0
  23. package/dist/client/components/ui/card.d.ts +11 -0
  24. package/dist/client/components/ui/card.d.ts.map +1 -0
  25. package/dist/client/components/ui/card.js +19 -0
  26. package/dist/client/components/ui/card.js.map +1 -0
  27. package/dist/client/components/ui/input.d.ts +4 -0
  28. package/dist/client/components/ui/input.d.ts.map +1 -0
  29. package/dist/client/components/ui/input.js +8 -0
  30. package/dist/client/components/ui/input.js.map +1 -0
  31. package/dist/client/components/ui/select.d.ts +16 -0
  32. package/dist/client/components/ui/select.d.ts.map +1 -0
  33. package/dist/client/components/ui/select.js +36 -0
  34. package/dist/client/components/ui/select.js.map +1 -0
  35. package/dist/client/index.d.ts +2 -0
  36. package/dist/client/index.d.ts.map +1 -0
  37. package/dist/client/index.js +4 -0
  38. package/dist/client/index.js.map +1 -0
  39. package/dist/client/lib/api.d.ts +93 -0
  40. package/dist/client/lib/api.d.ts.map +1 -0
  41. package/dist/client/lib/api.js +67 -0
  42. package/dist/client/lib/api.js.map +1 -0
  43. package/dist/client/lib/format.d.ts +4 -0
  44. package/dist/client/lib/format.d.ts.map +1 -0
  45. package/dist/client/lib/format.js +8 -0
  46. package/dist/client/lib/format.js.map +1 -0
  47. package/dist/client/lib/labels.d.ts +5 -0
  48. package/dist/client/lib/labels.d.ts.map +1 -0
  49. package/dist/client/lib/labels.js +38 -0
  50. package/dist/client/lib/labels.js.map +1 -0
  51. package/dist/client/lib/use-loader.d.ts +10 -0
  52. package/dist/client/lib/use-loader.d.ts.map +1 -0
  53. package/dist/client/lib/use-loader.js +43 -0
  54. package/dist/client/lib/use-loader.js.map +1 -0
  55. package/dist/client/lib/utils.d.ts +2 -0
  56. package/dist/client/lib/utils.d.ts.map +1 -0
  57. package/dist/client/lib/utils.js +2 -0
  58. package/dist/client/lib/utils.js.map +1 -0
  59. package/dist/client/locales/en-US.d.ts +99 -0
  60. package/dist/client/locales/en-US.d.ts.map +1 -0
  61. package/dist/client/locales/en-US.js +92 -0
  62. package/dist/client/locales/en-US.js.map +1 -0
  63. package/dist/client/locales/index.d.ts +4 -0
  64. package/dist/client/locales/index.d.ts.map +1 -0
  65. package/dist/client/locales/index.js +7 -0
  66. package/dist/client/locales/index.js.map +1 -0
  67. package/dist/client/locales/zh-CN.d.ts +4 -0
  68. package/dist/client/locales/zh-CN.d.ts.map +1 -0
  69. package/dist/client/locales/zh-CN.js +92 -0
  70. package/dist/client/locales/zh-CN.js.map +1 -0
  71. package/dist/client/pages/configuration.d.ts +4 -0
  72. package/dist/client/pages/configuration.d.ts.map +1 -0
  73. package/dist/client/pages/configuration.js +34 -0
  74. package/dist/client/pages/configuration.js.map +1 -0
  75. package/dist/client/pages/data-requests.d.ts +3 -0
  76. package/dist/client/pages/data-requests.d.ts.map +1 -0
  77. package/dist/client/pages/data-requests.js +216 -0
  78. package/dist/client/pages/data-requests.js.map +1 -0
  79. package/dist/client/pages/incoming.d.ts +3 -0
  80. package/dist/client/pages/incoming.d.ts.map +1 -0
  81. package/dist/client/pages/incoming.js +128 -0
  82. package/dist/client/pages/incoming.js.map +1 -0
  83. package/dist/client/pages/tasks.d.ts +3 -0
  84. package/dist/client/pages/tasks.d.ts.map +1 -0
  85. package/dist/client/pages/tasks.js +116 -0
  86. package/dist/client/pages/tasks.js.map +1 -0
  87. package/dist/client/plugin.d.ts +4 -0
  88. package/dist/client/plugin.d.ts.map +1 -0
  89. package/dist/client/plugin.js +10 -0
  90. package/dist/client/plugin.js.map +1 -0
  91. package/dist/client/routes.d.ts +4 -0
  92. package/dist/client/routes.d.ts.map +1 -0
  93. package/dist/client/routes.js +51 -0
  94. package/dist/client/routes.js.map +1 -0
  95. package/dist/database/migrations/.manifest.json +9 -0
  96. package/dist/database/migrations/202610010001_office_flows_example_create_collections.d.ts +4 -0
  97. package/dist/database/migrations/202610010001_office_flows_example_create_collections.d.ts.map +1 -0
  98. package/dist/database/migrations/202610010001_office_flows_example_create_collections.js +280 -0
  99. package/dist/database/migrations/202610010001_office_flows_example_create_collections.js.map +1 -0
  100. package/dist/database/seeds/.manifest.json +9 -0
  101. package/dist/database/seeds/202610010002_office_flows_example_seed_configuration.d.ts +10 -0
  102. package/dist/database/seeds/202610010002_office_flows_example_seed_configuration.d.ts.map +1 -0
  103. package/dist/database/seeds/202610010002_office_flows_example_seed_configuration.js +104 -0
  104. package/dist/database/seeds/202610010002_office_flows_example_seed_configuration.js.map +1 -0
  105. package/dist/server/calendar.d.ts +35 -0
  106. package/dist/server/calendar.d.ts.map +1 -0
  107. package/dist/server/calendar.js +103 -0
  108. package/dist/server/calendar.js.map +1 -0
  109. package/dist/server/index.d.ts +2 -0
  110. package/dist/server/index.d.ts.map +1 -0
  111. package/dist/server/index.js +2 -0
  112. package/dist/server/index.js.map +1 -0
  113. package/dist/server/lifecycles/data-request.d.ts +36 -0
  114. package/dist/server/lifecycles/data-request.d.ts.map +1 -0
  115. package/dist/server/lifecycles/data-request.js +182 -0
  116. package/dist/server/lifecycles/data-request.js.map +1 -0
  117. package/dist/server/lifecycles/extraction.d.ts +21 -0
  118. package/dist/server/lifecycles/extraction.d.ts.map +1 -0
  119. package/dist/server/lifecycles/extraction.js +60 -0
  120. package/dist/server/lifecycles/extraction.js.map +1 -0
  121. package/dist/server/lifecycles/incoming.d.ts +27 -0
  122. package/dist/server/lifecycles/incoming.d.ts.map +1 -0
  123. package/dist/server/lifecycles/incoming.js +177 -0
  124. package/dist/server/lifecycles/incoming.js.map +1 -0
  125. package/dist/server/lifecycles/index.d.ts +8 -0
  126. package/dist/server/lifecycles/index.d.ts.map +1 -0
  127. package/dist/server/lifecycles/index.js +20 -0
  128. package/dist/server/lifecycles/index.js.map +1 -0
  129. package/dist/server/lifecycles/tasks.d.ts +63 -0
  130. package/dist/server/lifecycles/tasks.d.ts.map +1 -0
  131. package/dist/server/lifecycles/tasks.js +259 -0
  132. package/dist/server/lifecycles/tasks.js.map +1 -0
  133. package/dist/server/plugin.d.ts +4 -0
  134. package/dist/server/plugin.d.ts.map +1 -0
  135. package/dist/server/plugin.js +16 -0
  136. package/dist/server/plugin.js.map +1 -0
  137. package/dist/server/providers/index.d.ts +4 -0
  138. package/dist/server/providers/index.d.ts.map +1 -0
  139. package/dist/server/providers/index.js +6 -0
  140. package/dist/server/providers/index.js.map +1 -0
  141. package/dist/server/providers/office-flows.d.ts +23 -0
  142. package/dist/server/providers/office-flows.d.ts.map +1 -0
  143. package/dist/server/providers/office-flows.js +90 -0
  144. package/dist/server/providers/office-flows.js.map +1 -0
  145. package/dist/server/routes/index.d.ts +8 -0
  146. package/dist/server/routes/index.d.ts.map +1 -0
  147. package/dist/server/routes/index.js +553 -0
  148. package/dist/server/routes/index.js.map +1 -0
  149. package/dist/server/routes/schemas.d.ts +157 -0
  150. package/dist/server/routes/schemas.d.ts.map +1 -0
  151. package/dist/server/routes/schemas.js +188 -0
  152. package/dist/server/routes/schemas.js.map +1 -0
  153. package/dist/server/scope.d.ts +23 -0
  154. package/dist/server/scope.d.ts.map +1 -0
  155. package/dist/server/scope.js +23 -0
  156. package/dist/server/scope.js.map +1 -0
  157. package/dist/server/services/office-flows.d.ts +151 -0
  158. package/dist/server/services/office-flows.d.ts.map +1 -0
  159. package/dist/server/services/office-flows.js +603 -0
  160. package/dist/server/services/office-flows.js.map +1 -0
  161. package/dist/server/services/store.d.ts +119 -0
  162. package/dist/server/services/store.d.ts.map +1 -0
  163. package/dist/server/services/store.js +389 -0
  164. package/dist/server/services/store.js.map +1 -0
  165. package/dist/server/tokens.d.ts +4 -0
  166. package/dist/server/tokens.d.ts.map +1 -0
  167. package/dist/server/tokens.js +3 -0
  168. package/dist/server/tokens.js.map +1 -0
  169. package/dist/shared/data-request.d.ts +73 -0
  170. package/dist/shared/data-request.d.ts.map +1 -0
  171. package/dist/shared/data-request.js +182 -0
  172. package/dist/shared/data-request.js.map +1 -0
  173. package/dist/shared/fields.d.ts +12 -0
  174. package/dist/shared/fields.d.ts.map +1 -0
  175. package/dist/shared/fields.js +48 -0
  176. package/dist/shared/fields.js.map +1 -0
  177. package/dist/shared/people.d.ts +29 -0
  178. package/dist/shared/people.d.ts.map +1 -0
  179. package/dist/shared/people.js +54 -0
  180. package/dist/shared/people.js.map +1 -0
  181. package/dist/shared/routes.d.ts +7 -0
  182. package/dist/shared/routes.d.ts.map +1 -0
  183. package/dist/shared/routes.js +7 -0
  184. package/dist/shared/routes.js.map +1 -0
  185. package/dist/shared/text.d.ts +3 -0
  186. package/dist/shared/text.d.ts.map +1 -0
  187. package/dist/shared/text.js +9 -0
  188. package/dist/shared/text.js.map +1 -0
  189. package/package.json +72 -3
@@ -0,0 +1,119 @@
1
+ import type { DatabaseConnection, DatabaseManager, Repository, Row } from '@nocobase/db';
2
+ import { type WorkCalendar } from '../calendar.js';
3
+ export type TaskKind = 'clerk' | 'team' | 'executor';
4
+ /** The level a distribution row sends to, and what it creates there. */
5
+ export declare const LEVELS: Readonly<Record<1 | 2 | 3, {
6
+ readonly kind: TaskKind;
7
+ readonly collection: string;
8
+ readonly prefix: string;
9
+ readonly initial: string;
10
+ }>>;
11
+ export declare const TASK_COLLECTIONS: Readonly<Record<TaskKind, string>>;
12
+ export type Plain = Record<string, unknown>;
13
+ /** A bigInt filter takes a number; ids travel as strings. */
14
+ export declare function idOf(value: unknown): number;
15
+ export declare function plain(row: Row | undefined): Plain | undefined;
16
+ export declare function people(value: unknown): string[];
17
+ export interface NoticeInput {
18
+ readonly rootKind: 'incoming' | 'dataRequest';
19
+ readonly rootId: number;
20
+ /** Each recipient is reminded once per root and level. */
21
+ readonly level: string;
22
+ readonly recipients: readonly string[];
23
+ readonly message: string;
24
+ readonly sourceKind: string;
25
+ readonly sourceId: number;
26
+ }
27
+ export interface DispatchResult {
28
+ readonly created: readonly {
29
+ readonly kind: TaskKind;
30
+ readonly id: number;
31
+ readonly number: string;
32
+ readonly departmentName: string;
33
+ }[];
34
+ readonly notified: readonly string[];
35
+ readonly skipped: readonly string[];
36
+ }
37
+ /**
38
+ * Database operations the lifecycles' guards and effects share. Each one is
39
+ * safe to repeat: an effect may run more than once, so creating a task
40
+ * claims its distribution row first and reminders go through a ledger with
41
+ * a unique key.
42
+ */
43
+ export declare class OfficeStore {
44
+ private readonly database;
45
+ private readonly clock;
46
+ private readonly connection;
47
+ constructor(database: DatabaseManager, clock?: () => Date, connection?: DatabaseConnection | undefined);
48
+ /**
49
+ * The same operations on one transaction's connection. Guards run inside
50
+ * the transition's transaction and must read through it: SQLite has one
51
+ * connection, and a read elsewhere would wait for it.
52
+ */
53
+ bound(handle: unknown): OfficeStore;
54
+ repository(collection: string): Repository;
55
+ private transaction;
56
+ now(): string;
57
+ find(collection: string, id: unknown): Promise<Plain | undefined>;
58
+ list(collection: string, filter: Record<string, string | number | boolean | null>): Promise<Plain[]>;
59
+ /** `PREFIX-YYYYMM-0001`, numbered per prefix and month. */
60
+ nextNumber(prefix: string): Promise<string>;
61
+ calendar(): Promise<WorkCalendar>;
62
+ /** Extraction tasks of a request, by status. Voided tasks never count. */
63
+ countExtractions(requestId: unknown, statuses: readonly string[]): Promise<number>;
64
+ /**
65
+ * Creates an extraction task for a request in acceptance, unless the
66
+ * period already has one: the (request, period) key is unique, so a
67
+ * repeated sweep or a retried effect creates nothing twice. A manual task
68
+ * has no period and takes its number as its key. Returns nothing when the
69
+ * task exists or the request has left acceptance.
70
+ *
71
+ * The insert and the request's acceptance are decided together: the task's
72
+ * transaction first bumps the request's `lifecycleVersion` while it is
73
+ * still `accepting`, which locks the row against a `complete` deciding at
74
+ * the same time and makes the one that commits second meet a conflict.
75
+ * The version belongs to the lifecycle, and this is why it is touched from
76
+ * outside it: a transition that counted the request's tasks must not
77
+ * commit over a task it did not see.
78
+ */
79
+ createExtraction(values: {
80
+ readonly requestId: number;
81
+ readonly periodKey?: string;
82
+ readonly origin: 'scheduled' | 'once' | 'manual';
83
+ readonly scheduledDate: string;
84
+ readonly topic: string;
85
+ readonly requirement: string;
86
+ readonly executorIds: readonly string[];
87
+ }): Promise<Plain | undefined>;
88
+ /**
89
+ * Reminds each recipient once per root document and level; returns who
90
+ * was reminded now. Someone already reminded at this level is skipped,
91
+ * however many rows or rounds name them again.
92
+ */
93
+ notify(input: NoticeInput): Promise<string[]>;
94
+ /**
95
+ * Adds a line to a document's distribution record. An effect passes its
96
+ * run's idempotency key, so a retry after a partial attempt writes the
97
+ * line once; without a key every call writes one.
98
+ */
99
+ trace(values: {
100
+ readonly docKind: string;
101
+ readonly docId: number;
102
+ readonly actorId: string;
103
+ readonly action: string;
104
+ readonly detail: Plain;
105
+ readonly key?: string;
106
+ }): Promise<void>;
107
+ /**
108
+ * Sends distribution rows down one level: each row not yet dispatched
109
+ * becomes a task for its department, and everyone the row names is
110
+ * reminded. Claiming the row and creating its task are one transaction.
111
+ * A row an earlier attempt already dispatched is reported again rather
112
+ * than skipped, so a retry after the reminders failed still sends them;
113
+ * the reminders themselves go out once per person and level.
114
+ */
115
+ dispatch(level: 1 | 2 | 3, rowIds: readonly number[]): Promise<DispatchResult>;
116
+ /** Readable names, for messages and traces. */
117
+ names(ids: readonly string[]): string;
118
+ }
119
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../server/services/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,389 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { setTimeout as delay } from 'node:timers/promises';
3
+ import { personName } from '../../shared/people.js';
4
+ import { createWorkCalendar, } from '../calendar.js';
5
+ import { COLLECTIONS } from '../scope.js';
6
+ import { text } from '../../shared/text.js';
7
+ /** The level a distribution row sends to, and what it creates there. */
8
+ export const LEVELS = {
9
+ 1: {
10
+ kind: 'clerk',
11
+ collection: COLLECTIONS.clerkTasks,
12
+ prefix: 'SWSQ_BSRY',
13
+ initial: 'signing',
14
+ },
15
+ 2: {
16
+ kind: 'team',
17
+ collection: COLLECTIONS.teamTasks,
18
+ prefix: 'SWSQ_ZXTDCL',
19
+ initial: 'processing',
20
+ },
21
+ 3: {
22
+ kind: 'executor',
23
+ collection: COLLECTIONS.executorTasks,
24
+ prefix: 'SWSQ_BSRY_ZB',
25
+ initial: 'processing',
26
+ },
27
+ };
28
+ export const TASK_COLLECTIONS = {
29
+ clerk: COLLECTIONS.clerkTasks,
30
+ team: COLLECTIONS.teamTasks,
31
+ executor: COLLECTIONS.executorTasks,
32
+ };
33
+ /** A bigInt filter takes a number; ids travel as strings. */
34
+ export function idOf(value) {
35
+ const id = Number(value);
36
+ if (!Number.isSafeInteger(id))
37
+ throw new Error(`"${text(value)}" is not an id.`);
38
+ return id;
39
+ }
40
+ export function plain(row) {
41
+ if (!row)
42
+ return undefined;
43
+ const values = {};
44
+ for (const [field, value] of Object.entries(row))
45
+ values[field] = value instanceof Date ? value.toISOString() : value;
46
+ return values;
47
+ }
48
+ export function people(value) {
49
+ if (Array.isArray(value))
50
+ return value.map(String);
51
+ if (typeof value === 'string' && value.startsWith('['))
52
+ return JSON.parse(value).map(String);
53
+ return [];
54
+ }
55
+ /** These errors confirm a deadlock victim's transaction was aborted. */
56
+ function isDeadlock(error) {
57
+ const visited = new Set();
58
+ let current = error;
59
+ while (current && typeof current === 'object' && !visited.has(current)) {
60
+ visited.add(current);
61
+ const record = current;
62
+ if (record.code === 'ER_LOCK_DEADLOCK' ||
63
+ record.code === '40P01' ||
64
+ record.number === 1205)
65
+ return true;
66
+ current = record.cause ?? record.originalError;
67
+ }
68
+ return false;
69
+ }
70
+ function unique(values) {
71
+ return [...new Set(values)];
72
+ }
73
+ /**
74
+ * Database operations the lifecycles' guards and effects share. Each one is
75
+ * safe to repeat: an effect may run more than once, so creating a task
76
+ * claims its distribution row first and reminders go through a ledger with
77
+ * a unique key.
78
+ */
79
+ export class OfficeStore {
80
+ database;
81
+ clock;
82
+ connection;
83
+ constructor(database, clock = () => new Date(), connection = undefined) {
84
+ this.database = database;
85
+ this.clock = clock;
86
+ this.connection = connection;
87
+ }
88
+ /**
89
+ * The same operations on one transaction's connection. Guards run inside
90
+ * the transition's transaction and must read through it: SQLite has one
91
+ * connection, and a read elsewhere would wait for it.
92
+ */
93
+ bound(handle) {
94
+ return handle === undefined
95
+ ? this
96
+ : new OfficeStore(this.database, this.clock, handle);
97
+ }
98
+ repository(collection) {
99
+ return this.connection
100
+ ? this.connection.repository(collection)
101
+ : this.database.repository(collection);
102
+ }
103
+ transaction(work) {
104
+ return this.connection
105
+ ? work(this.connection)
106
+ : this.database.transaction(work);
107
+ }
108
+ now() {
109
+ return this.clock().toISOString();
110
+ }
111
+ async find(collection, id) {
112
+ return plain(await this.repository(collection).findOne({ filter: { id: idOf(id) } }));
113
+ }
114
+ async list(collection, filter) {
115
+ const rows = await this.repository(collection).findMany({
116
+ filter,
117
+ sort: (sort) => sort.field('id').asc(),
118
+ });
119
+ return rows.map((row) => plain(row));
120
+ }
121
+ /** `PREFIX-YYYYMM-0001`, numbered per prefix and month. */
122
+ async nextNumber(prefix) {
123
+ const period = this.now().slice(0, 7).replace('-', '');
124
+ const key = `${prefix}-${period}`;
125
+ // The value the upsert itself wrote: a separate read could see another
126
+ // caller's increment and hand out the same number twice.
127
+ for (let attempt = 0;; attempt++) {
128
+ try {
129
+ const { record } = await this.repository(COLLECTIONS.serials).upsertOne({
130
+ filter: { key },
131
+ create: { key, value: 1 },
132
+ update: { value: (value) => value.increment(1) },
133
+ });
134
+ return `${key}-${text(Number(record.value)).padStart(4, '0')}`;
135
+ }
136
+ catch (error) {
137
+ // A new counter can deadlock with another insert. Retry only the
138
+ // implicit transaction we own, never part of a caller's aborted
139
+ // transaction or an error with an unknown commit outcome.
140
+ if (this.connection || attempt >= 5 || !isDeadlock(error))
141
+ throw error;
142
+ await delay(5 * 2 ** attempt + Math.floor(Math.random() * 5));
143
+ }
144
+ }
145
+ }
146
+ async calendar() {
147
+ const rows = await this.repository(COLLECTIONS.holidays).findMany({});
148
+ return createWorkCalendar(rows.map((row) => ({
149
+ date: text(row.date),
150
+ kind: row.kind === 'workday' ? 'workday' : 'holiday',
151
+ })));
152
+ }
153
+ /** Extraction tasks of a request, by status. Voided tasks never count. */
154
+ async countExtractions(requestId, statuses) {
155
+ return this.repository(COLLECTIONS.extractions).count({
156
+ filter: (filter) => filter.and([
157
+ filter.number('requestId').eq(idOf(requestId)),
158
+ filter.or(statuses.map((status) => filter.string('status').eq(status))),
159
+ ]),
160
+ });
161
+ }
162
+ /**
163
+ * Creates an extraction task for a request in acceptance, unless the
164
+ * period already has one: the (request, period) key is unique, so a
165
+ * repeated sweep or a retried effect creates nothing twice. A manual task
166
+ * has no period and takes its number as its key. Returns nothing when the
167
+ * task exists or the request has left acceptance.
168
+ *
169
+ * The insert and the request's acceptance are decided together: the task's
170
+ * transaction first bumps the request's `lifecycleVersion` while it is
171
+ * still `accepting`, which locks the row against a `complete` deciding at
172
+ * the same time and makes the one that commits second meet a conflict.
173
+ * The version belongs to the lifecycle, and this is why it is touched from
174
+ * outside it: a transition that counted the request's tasks must not
175
+ * commit over a task it did not see.
176
+ */
177
+ async createExtraction(values) {
178
+ const { periodKey } = values;
179
+ const existing = async (repository) => periodKey === undefined
180
+ ? undefined
181
+ : repository.findOne({
182
+ filter: { requestId: values.requestId, periodKey },
183
+ });
184
+ if (await existing(this.repository(COLLECTIONS.extractions)))
185
+ return undefined;
186
+ // Numbered before the transaction: SQLite has one connection, and a
187
+ // read outside the transaction would wait for it.
188
+ const number = await this.nextNumber('SJSY_CS');
189
+ const now = this.now();
190
+ return this.transaction(async (connection) => {
191
+ const accepting = await connection
192
+ .repository(COLLECTIONS.dataRequests)
193
+ .updateMany({
194
+ filter: { id: values.requestId, status: 'accepting' },
195
+ values: { lifecycleVersion: { increment: 1 } },
196
+ });
197
+ if (accepting.updatedCount === 0)
198
+ return undefined;
199
+ const extractions = connection.repository(COLLECTIONS.extractions);
200
+ if (await existing(extractions))
201
+ return undefined;
202
+ try {
203
+ const created = await extractions.createOne({
204
+ values: {
205
+ ...values,
206
+ periodKey: periodKey ?? `manual:${number}`,
207
+ executorIds: [...values.executorIds],
208
+ feedbackFiles: [],
209
+ number,
210
+ status: 'pending',
211
+ statusChangedAt: now,
212
+ lifecycleVersion: 0,
213
+ createdAt: now,
214
+ },
215
+ });
216
+ return plain(created.record);
217
+ }
218
+ catch (error) {
219
+ // Another sweep created it between the read and the insert.
220
+ if (await existing(extractions))
221
+ return undefined;
222
+ throw error;
223
+ }
224
+ });
225
+ }
226
+ /**
227
+ * Reminds each recipient once per root document and level; returns who
228
+ * was reminded now. Someone already reminded at this level is skipped,
229
+ * however many rows or rounds name them again.
230
+ */
231
+ async notify(input) {
232
+ const reached = [];
233
+ for (const recipient of unique(input.recipients)) {
234
+ const key = {
235
+ rootKind: input.rootKind,
236
+ rootId: input.rootId,
237
+ level: input.level,
238
+ recipient,
239
+ };
240
+ if (await this.repository(COLLECTIONS.notices).exists({ filter: key }))
241
+ continue;
242
+ try {
243
+ await this.repository(COLLECTIONS.notices).createOne({
244
+ values: {
245
+ ...key,
246
+ message: input.message,
247
+ sourceKind: input.sourceKind,
248
+ sourceId: input.sourceId,
249
+ createdAt: this.now(),
250
+ },
251
+ });
252
+ reached.push(recipient);
253
+ }
254
+ catch (error) {
255
+ // The unique key: a concurrent dispatch reminded them first.
256
+ if (!(await this.repository(COLLECTIONS.notices).exists({ filter: key })))
257
+ throw error;
258
+ }
259
+ }
260
+ return reached;
261
+ }
262
+ /**
263
+ * Adds a line to a document's distribution record. An effect passes its
264
+ * run's idempotency key, so a retry after a partial attempt writes the
265
+ * line once; without a key every call writes one.
266
+ */
267
+ async trace(values) {
268
+ const key = values.key ?? `trace:${randomUUID()}`;
269
+ const traces = this.repository(COLLECTIONS.traces);
270
+ if (values.key && (await traces.exists({ filter: { key } })))
271
+ return;
272
+ try {
273
+ await traces.createOne({
274
+ values: { ...values, key, at: this.now() },
275
+ });
276
+ }
277
+ catch (error) {
278
+ // The unique key: a concurrent attempt wrote it first.
279
+ if (!(await traces.exists({ filter: { key } })))
280
+ throw error;
281
+ }
282
+ }
283
+ /**
284
+ * Sends distribution rows down one level: each row not yet dispatched
285
+ * becomes a task for its department, and everyone the row names is
286
+ * reminded. Claiming the row and creating its task are one transaction.
287
+ * A row an earlier attempt already dispatched is reported again rather
288
+ * than skipped, so a retry after the reminders failed still sends them;
289
+ * the reminders themselves go out once per person and level.
290
+ */
291
+ async dispatch(level, rowIds) {
292
+ const target = LEVELS[level];
293
+ const created = [];
294
+ const recipients = [];
295
+ let rootId = 0;
296
+ for (const rowId of rowIds) {
297
+ // Numbered before the transaction: SQLite has one connection, and a
298
+ // read outside the transaction would wait for it. A claim that loses
299
+ // leaves a gap in the sequence, nothing worse.
300
+ const number = await this.nextNumber(target.prefix);
301
+ const task = await this.transaction(async (connection) => {
302
+ const rows = connection.repository(COLLECTIONS.assignments);
303
+ const claimed = await rows.updateMany({
304
+ filter: { id: rowId, dispatched: false, level },
305
+ values: { dispatched: true },
306
+ });
307
+ if (claimed.updatedCount === 0) {
308
+ const done = plain(await rows.findOne({ filter: { id: rowId } }));
309
+ if (!done || done.level !== level || done.childId == null)
310
+ return undefined;
311
+ const child = plain(await connection
312
+ .repository(target.collection)
313
+ .findOne({ filter: { id: idOf(done.childId) } }));
314
+ return child
315
+ ? { row: done, id: idOf(done.childId), number: text(child.number) }
316
+ : undefined;
317
+ }
318
+ const row = plain(await rows.findOne({ filter: { id: rowId } }));
319
+ const now = this.now();
320
+ const record = await connection
321
+ .repository(target.collection)
322
+ .createOne({
323
+ values: {
324
+ number,
325
+ rootId: idOf(row.rootId),
326
+ parentId: idOf(row.parentId),
327
+ assignmentId: rowId,
328
+ departmentName: text(row.departmentName),
329
+ assignees: people(row.assignees),
330
+ ccHeads: people(row.ccHeads),
331
+ ccLeaders: people(row.ccLeaders),
332
+ signedBy: [],
333
+ attachments: [],
334
+ status: target.initial,
335
+ statusChangedAt: now,
336
+ lifecycleVersion: 0,
337
+ createdAt: now,
338
+ },
339
+ });
340
+ const id = idOf(record.record.id);
341
+ // Publish ownership with the task and the dispatch claim. A retry
342
+ // reuses the existing task, so it cannot duplicate these memberships.
343
+ for (const personId of unique(people(row.assignees))) {
344
+ await connection.repository(COLLECTIONS.taskAssignees).createOne({
345
+ values: { kind: target.kind, taskId: id, personId },
346
+ });
347
+ }
348
+ await rows.updateMany({
349
+ filter: { id: rowId },
350
+ values: { childId: id },
351
+ });
352
+ return { row, id, number };
353
+ });
354
+ if (!task)
355
+ continue;
356
+ rootId = idOf(task.row.rootId);
357
+ recipients.push(...people(task.row.assignees), ...people(task.row.ccHeads), ...people(task.row.ccLeaders));
358
+ created.push({
359
+ kind: target.kind,
360
+ id: task.id,
361
+ number: task.number,
362
+ departmentName: text(task.row.departmentName),
363
+ });
364
+ }
365
+ if (!created.length)
366
+ return { created, notified: [], skipped: [] };
367
+ const root = await this.find(COLLECTIONS.incoming, rootId);
368
+ const title = text(root?.title);
369
+ const notified = await this.notify({
370
+ rootKind: 'incoming',
371
+ rootId,
372
+ level: text(level),
373
+ recipients,
374
+ message: `收文《${title}》已派发至${created.map((item) => item.departmentName).join('、')}`,
375
+ sourceKind: target.kind,
376
+ sourceId: created[0].id,
377
+ });
378
+ return {
379
+ created,
380
+ notified,
381
+ skipped: unique(recipients).filter((person) => !notified.includes(person)),
382
+ };
383
+ }
384
+ /** Readable names, for messages and traces. */
385
+ names(ids) {
386
+ return ids.map(personName).join('、');
387
+ }
388
+ }
389
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../server/services/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type ServiceToken } from '@nocobase/service-provider';
2
+ import type { OfficeFlowsService } from './services/office-flows.js';
3
+ export declare const officeFlowsServiceToken: ServiceToken<OfficeFlowsService>;
4
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../server/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,eAAO,MAAM,uBAAuB,EAAE,YAAY,CAAC,kBAAkB,CAGlE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { createServiceToken, } from '@nocobase/service-provider';
2
+ export const officeFlowsServiceToken = createServiceToken('@nocobase/app-plugin-office-flows-example/service');
3
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../server/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAEnB,MAAM,4BAA4B,CAAC;AAIpC,MAAM,CAAC,MAAM,uBAAuB,GAClC,kBAAkB,CAChB,mDAAmD,CACpD,CAAC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The data usage request form: which fields exist, which options they offer
3
+ * and when they appear. The page renders from these rules and the server
4
+ * validates with them, so the two cannot drift apart.
5
+ */
6
+ export declare const VOLUMES: readonly string[];
7
+ export type Frequency = 'once' | 'quarterly' | 'monthly' | 'weekly' | 'daily' | 'other';
8
+ export declare const FREQUENCIES: readonly {
9
+ value: Frequency;
10
+ label: string;
11
+ }[];
12
+ export type UsageScope = 'external' | 'internal';
13
+ export declare const SCOPES: readonly {
14
+ value: UsageScope;
15
+ label: string;
16
+ }[];
17
+ export declare const CONSUMERS: Readonly<Record<UsageScope, readonly string[]>>;
18
+ export declare const WEEKDAYS: readonly string[];
19
+ export declare const INTERNAL_ANALYSIS = "\u5185\u90E8\u7BA1\u7406\u53CA\u5206\u6790";
20
+ export declare const THIRD_PARTY = "\u7B2C\u4E09\u65B9\u5408\u4F5C";
21
+ /** The fields an applicant fills in, as the server stores them. */
22
+ export interface DataRequestForm {
23
+ subject: string;
24
+ reason: string;
25
+ volume: string;
26
+ frequency: Frequency | '';
27
+ deliveryDate: string;
28
+ firstUseDate: string;
29
+ lastDeliveryDate: string;
30
+ /** 1–92: the day of the quarter, counted from its first day. */
31
+ quarterDay: number | null;
32
+ /** 1–31; a shorter month uses its last day. */
33
+ monthDay: number | null;
34
+ /** 1 (Monday) – 7 (Sunday). */
35
+ weekDay: number | null;
36
+ frequencyNote: string;
37
+ scope: UsageScope | '';
38
+ consumers: string[];
39
+ fileShieldAccepted: boolean | null;
40
+ fileShieldScope: string;
41
+ fileShieldCopy: boolean | null;
42
+ fileShieldValidUntil: string;
43
+ ndaFiles: string[];
44
+ securityFiles: string[];
45
+ }
46
+ export declare function emptyDataRequest(): DataRequestForm;
47
+ /** Which conditional parts of the form are showing for these values. */
48
+ export interface DataRequestVisibility {
49
+ readonly deliveryDate: boolean;
50
+ readonly periodDates: boolean;
51
+ readonly quarterDay: boolean;
52
+ readonly monthDay: boolean;
53
+ readonly weekDay: boolean;
54
+ readonly frequencyNote: boolean;
55
+ readonly fileShield: boolean;
56
+ readonly thirdParty: boolean;
57
+ }
58
+ export declare function visibility(form: DataRequestForm): DataRequestVisibility;
59
+ /** The consumer types the chosen scope offers. */
60
+ export declare function consumerOptions(scope: UsageScope | ''): readonly string[];
61
+ /** A `YYYY-MM-DD` that names a real day: `2026-02-31` is refused, not moved to March. */
62
+ export declare function isDate(value: string): boolean;
63
+ /**
64
+ * Field → message for every problem; empty when the form may be submitted.
65
+ * Fields that are hidden for these values are neither required nor checked.
66
+ */
67
+ export declare function validateDataRequest(form: DataRequestForm): Record<string, string>;
68
+ /**
69
+ * Drops the values of fields the choices hide, so a stored request never
70
+ * carries an answer to a question it did not ask.
71
+ */
72
+ export declare function normalizeDataRequest(form: DataRequestForm): DataRequestForm;
73
+ //# sourceMappingURL=data-request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-request.d.ts","sourceRoot":"","sources":["../../shared/data-request.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,OAAO,EAAE,SAAS,MAAM,EAKpC,CAAC;AAEF,MAAM,MAAM,SAAS,GACnB,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAElE,eAAO,MAAM,WAAW,EAAE,SAAS;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAOrE,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;AAEjD,eAAO,MAAM,MAAM,EAAE,SAAS;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAGjE,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC,CAUrE,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,SAAS,MAAM,EAQrC,CAAC;AAEF,eAAO,MAAM,iBAAiB,+CAAY,CAAC;AAC3C,eAAO,MAAM,WAAW,mCAAU,CAAC;AAEnC,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,GAAG,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,UAAU,GAAG,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kBAAkB,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,gBAAgB,IAAI,eAAe,CAsBlD;AAED,wEAAwE;AACxE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,qBAAqB,CAYvE;AAED,kDAAkD;AAClD,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,EAAE,GAAG,SAAS,MAAM,EAAE,CAEzE;AAID,yFAAyF;AACzF,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAM7C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,eAAe,GACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAoExB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe,CAqB3E"}