@hahnpro/hpc-api 2026.7.1 → 2026.7.3

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/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # @hahnpro/hpc-api
2
2
 
3
+ # 2026.7.3
4
+
5
+ - Added partial-object validation support to the `isAsset`, `isContent`, `isEvent`, `isLogbookEntry`, and `isTask` type guards
6
+ - Expanded `isAsset` to validate populated asset types as well as all supported asset fields
7
+ - Added stricter enum, resource-reference, and attachment-handling validation to the content analysis, event, and user-message type guards
8
+ - Changed `Event.level (string)` to `EventLevel`
9
+ - Updated `Task.expiryDate` and its type guard to accept strings as well as `Date` values
10
+
11
+ # 2026.7.2
12
+
13
+ - Added dedicated logbook API service, logbook interfaces, and mock support
14
+ - Moved logbook entry types out of the task interface
15
+
3
16
  # 2026.7.1
17
+
4
18
  - Added ASSET_ATTACHMENT and CONTENT_ATTACHMENT as ObjectReferences
5
19
 
6
20
  # 2026.6.7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hahnpro/hpc-api",
3
- "version": "2026.7.1",
3
+ "version": "2026.7.3",
4
4
  "description": "Module for easy access to the HahnPRO Cloud API",
5
5
  "license": "MIT",
6
6
  "author": {
package/src/lib/api.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { QueueOptions } from './queue';
2
- import { AiService, AlertService, AssetService, AssetTypesService, ContentService, CrmService, DataspaceService, EndpointService, EventService, FlangeSkillControlService, FlowDeploymentService, FlowFunctionService, FlowModuleService, FlowService, HttpClientService, LabelService, NotificationRuleService, NotificationService, ObjectReferenceService, OrganizationsAdministrationService, OrganizationsResourcesService, OrganizationsService, ProxyService, SearchService, TaskService, TimeSeriesService, UserService, VaultService } from './services';
2
+ import { AiService, AlertService, AssetService, AssetTypesService, ContentService, CrmService, DataspaceService, EndpointService, EventService, FlangeSkillControlService, FlowDeploymentService, FlowFunctionService, FlowModuleService, FlowService, HttpClientService, LabelService, LogbookService, NotificationRuleService, NotificationService, ObjectReferenceService, OrganizationsAdministrationService, OrganizationsResourcesService, OrganizationsService, ProxyService, SearchService, TaskService, TimeSeriesService, UserService, VaultService } from './services';
3
3
  export declare class API {
4
4
  readonly httpClient?: HttpClientService;
5
5
  ai: AiService;
@@ -17,6 +17,7 @@ export declare class API {
17
17
  flowFunctions: FlowFunctionService;
18
18
  flowModules: FlowModuleService;
19
19
  labels: LabelService;
20
+ logbook: LogbookService;
20
21
  objectReferences: ObjectReferenceService;
21
22
  organizations: OrganizationsService;
22
23
  organizationsAdministration: OrganizationsAdministrationService;
package/src/lib/api.js CHANGED
@@ -49,6 +49,7 @@ class API {
49
49
  this.flowFunctions = new services_1.FlowFunctionService(this.httpClient);
50
50
  this.flowModules = new services_1.FlowModuleService(this.httpClient);
51
51
  this.labels = new services_1.LabelService(this.httpClient);
52
+ this.logbook = new services_1.LogbookService(this.httpClient);
52
53
  this.objectReferences = new services_1.ObjectReferenceService(this.httpClient);
53
54
  this.organizations = new services_1.OrganizationsService(this.httpClient);
54
55
  this.organizationsAdministration = new services_1.OrganizationsAdministrationService(this.httpClient);
@@ -8,7 +8,7 @@ export interface Event extends Resource {
8
8
  tsRef?: string;
9
9
  eventRef?: string;
10
10
  cause?: string;
11
- level: string;
11
+ level: EventLevel;
12
12
  group?: string;
13
13
  owner?: Owner;
14
14
  createdBy?: Author;
@@ -38,7 +38,9 @@ export type { SearchMatchReason, SearchMatchReasonContentPart, SearchOptions, Se
38
38
  export type { Secret } from './secret.interface';
39
39
  export type { ServerSentEvent } from './sse.interface';
40
40
  export type { Artifact, FileType, Storage, StorageProvider } from './storage.interface';
41
- export type { Assignee, LogbookEntry, LogbookEntryDto, Task } from './task.interface';
41
+ export { LogbookEntrySource } from './logbook.interface';
42
+ export type { LogbookEntry, LogbookEntryDto } from './logbook.interface';
43
+ export type { Assignee, Task } from './task.interface';
42
44
  export type { Retention, SearchTimeSeriesResult, SelectedField, TimeSeries, TimeSeriesBucket, TimeseriesChange, TimeSeriesCondition, TimeseriesSubject, TimeSeriesValue, TS_GROUPS, } from './timeseries.interface';
43
45
  export type { Translation, TranslationData } from './translation.interface';
44
46
  export type { Application, Consent, Permission, TableSetting, TableSettingProfile, UserSettings } from './user-settings.interface';
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NatsConsumers = exports.SubscriptionType = exports.LABEL_COLORS = exports.FlowDiagram = exports.Flow = exports.NATS_FLOW_TRIGGER_STATUSES = exports.FlowDeployment = exports.UNKOWN_STATES = exports.STOPPED_STATES = exports.RUNNING_STATES = exports.PROCESSING_STATES = exports.FlowDeploymentStatus = exports.ERROR_STATES = exports.TimeSlotStatus = exports.APPLICATION_AREA = exports.eventLevels = exports.EventLevelOverrideWrapper = exports.EventLevel = exports.NotificationEndpointType = exports.NotificationEndpointStatus = exports.NotificationEndpointSpamProtection = exports.DataspaceWorkflowType = exports.DataspaceAllowedResourceTypes = exports.instanceOfTimePeriod = exports.ReturnType = exports.IndexingStatus = exports.ContentAnalysisStatus = exports.BillingResourceType = exports.ChangeAction = exports.DEFAULT_THRESHOLD_CONDITION = exports.DEFAULT_RELATIVE_CONDITION = exports.DEFAULT_DEADMAN_CONDITION = exports.AlertType = exports.AlertStatus = exports.AlertLevel = exports.ToolType = exports.ToolName = exports.ToolMessageStatus = exports.Role = exports.ReturnToReferrerTool = exports.ReferenceType = exports.OneShotTaskId = exports.HandOffTool = exports.FinishReason = exports.ErrorMessageType = exports.AvailableLanguages = exports.AttachmentHandlingMode = exports.AssistantMessageStatus = exports.AiAssistantId = exports.AgentId = void 0;
4
- exports.WebSocketMessageType = exports.SecretType = exports.isUserMessage = exports.isTask = exports.isStorage = exports.isOwner = exports.isLogbookEntry = exports.isEvent = exports.isContentAnalysis = exports.isContent = exports.isAuthor = exports.isAssignee = exports.isAsset = exports.TranslationEditData = exports.RETENTION_VALUES = exports.TaskStatus = exports.Priority = exports.INACTIVE_TASK_STATUSES = exports.buildTaskStatusFilter = exports.AssigneeType = exports.ACTIVE_TASK_STATUSES = exports.ResourceType = exports.resourceApiPathToTypeMap = exports.ResourceApiPath = exports.PermissionType = exports.isPopulated = exports.EventType = exports.CommandType = exports.arePopulated = exports.ObjectReferenceType = exports.OwnerType = exports.OrganizationMembersInviteOrAdd = exports.NotificationRuleStatus = exports.NatsStreams = exports.natsHpcPrefix = exports.natsFlowsPrefix = void 0;
3
+ exports.SubscriptionType = exports.LABEL_COLORS = exports.FlowDiagram = exports.Flow = exports.NATS_FLOW_TRIGGER_STATUSES = exports.FlowDeployment = exports.UNKOWN_STATES = exports.STOPPED_STATES = exports.RUNNING_STATES = exports.PROCESSING_STATES = exports.FlowDeploymentStatus = exports.ERROR_STATES = exports.TimeSlotStatus = exports.APPLICATION_AREA = exports.eventLevels = exports.EventLevelOverrideWrapper = exports.EventLevel = exports.NotificationEndpointType = exports.NotificationEndpointStatus = exports.NotificationEndpointSpamProtection = exports.DataspaceWorkflowType = exports.DataspaceAllowedResourceTypes = exports.instanceOfTimePeriod = exports.ReturnType = exports.IndexingStatus = exports.ContentAnalysisStatus = exports.BillingResourceType = exports.ChangeAction = exports.DEFAULT_THRESHOLD_CONDITION = exports.DEFAULT_RELATIVE_CONDITION = exports.DEFAULT_DEADMAN_CONDITION = exports.AlertType = exports.AlertStatus = exports.AlertLevel = exports.ToolType = exports.ToolName = exports.ToolMessageStatus = exports.Role = exports.ReturnToReferrerTool = exports.ReferenceType = exports.OneShotTaskId = exports.HandOffTool = exports.FinishReason = exports.ErrorMessageType = exports.AvailableLanguages = exports.AttachmentHandlingMode = exports.AssistantMessageStatus = exports.AiAssistantId = exports.AgentId = exports.LogbookEntrySource = void 0;
4
+ exports.WebSocketMessageType = exports.SecretType = exports.isUserMessage = exports.isTask = exports.isStorage = exports.isOwner = exports.isLogbookEntry = exports.isEvent = exports.isContentAnalysis = exports.isContent = exports.isAuthor = exports.isAssignee = exports.isAsset = exports.TranslationEditData = exports.RETENTION_VALUES = exports.TaskStatus = exports.Priority = exports.INACTIVE_TASK_STATUSES = exports.buildTaskStatusFilter = exports.AssigneeType = exports.ACTIVE_TASK_STATUSES = exports.ResourceType = exports.resourceApiPathToTypeMap = exports.ResourceApiPath = exports.PermissionType = exports.isPopulated = exports.EventType = exports.CommandType = exports.arePopulated = exports.ObjectReferenceType = exports.OwnerType = exports.OrganizationMembersInviteOrAdd = exports.NotificationRuleStatus = exports.NatsStreams = exports.natsHpcPrefix = exports.natsFlowsPrefix = exports.NatsConsumers = void 0;
5
+ var logbook_interface_1 = require("./logbook.interface");
6
+ Object.defineProperty(exports, "LogbookEntrySource", { enumerable: true, get: function () { return logbook_interface_1.LogbookEntrySource; } });
5
7
  var ai_interface_1 = require("./ai.interface");
6
8
  Object.defineProperty(exports, "AgentId", { enumerable: true, get: function () { return ai_interface_1.AgentId; } });
7
9
  Object.defineProperty(exports, "AiAssistantId", { enumerable: true, get: function () { return ai_interface_1.AiAssistantId; } });
@@ -0,0 +1,32 @@
1
+ import type { Author } from './author.interface';
2
+ export declare enum LogbookEntrySource {
3
+ MANUAL = "manual",
4
+ AUTOMATIC = "automatic"
5
+ }
6
+ export interface LogbookEntry {
7
+ id: string;
8
+ taskId: string;
9
+ date: string;
10
+ duration: number;
11
+ materials?: {
12
+ name: string;
13
+ quantity: number;
14
+ }[];
15
+ comment?: string;
16
+ source: LogbookEntrySource;
17
+ createdBy?: Author;
18
+ createdAt?: string;
19
+ updatedAt?: string;
20
+ data?: Record<string, unknown>;
21
+ }
22
+ export interface LogbookEntryDto {
23
+ date?: string;
24
+ duration?: number;
25
+ materials?: {
26
+ name: string;
27
+ quantity: number;
28
+ }[];
29
+ comment?: string;
30
+ source?: LogbookEntrySource;
31
+ data?: Record<string, unknown>;
32
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogbookEntrySource = void 0;
4
+ var LogbookEntrySource;
5
+ (function (LogbookEntrySource) {
6
+ LogbookEntrySource["MANUAL"] = "manual";
7
+ LogbookEntrySource["AUTOMATIC"] = "automatic";
8
+ })(LogbookEntrySource || (exports.LogbookEntrySource = LogbookEntrySource = {}));
@@ -1,4 +1,4 @@
1
- import { Api, Author } from '.';
1
+ import { Api } from '.';
2
2
  export declare enum AssigneeType {
3
3
  USER = "user",
4
4
  ORG = "org"
@@ -38,7 +38,7 @@ export interface Task extends Api {
38
38
  eventRef$name?: string;
39
39
  gitHubNr?: number;
40
40
  schedule?: string;
41
- expiryDate?: Date;
41
+ expiryDate?: string | Date;
42
42
  parent?: string;
43
43
  parent$name?: string;
44
44
  subTasks?: string[];
@@ -49,32 +49,3 @@ export interface Task extends Api {
49
49
  statusHistoryLog?: TaskStatus[];
50
50
  logbookSchema?: string;
51
51
  }
52
- export interface LogbookEntry {
53
- id?: string;
54
- taskId: string;
55
- date: string;
56
- duration: number;
57
- materials?: {
58
- name: string;
59
- quantity: number;
60
- }[];
61
- comment?: string;
62
- source: 'manual' | 'voice' | 'automatic';
63
- createdBy?: Author;
64
- createdAt?: string;
65
- updatedAt?: string;
66
- data?: Record<string, unknown>;
67
- }
68
- export interface LogbookEntryDto {
69
- date: string;
70
- duration: number;
71
- materials: {
72
- name: string;
73
- quantity: number;
74
- }[];
75
- comment?: string;
76
- source?: 'manual' | 'voice' | 'automatic';
77
- taskId: string;
78
- createdBy?: Author;
79
- data?: Record<string, unknown>;
80
- }
@@ -1,19 +1,30 @@
1
1
  import { type UserMessage } from './ai.interface';
2
2
  import type { Asset } from './asset.interface';
3
3
  import type { Author } from './author.interface';
4
- import type { Content, ContentAnalysis } from './content.interface';
4
+ import { type Content, type ContentAnalysis } from './content.interface';
5
5
  import { type Event } from './event.interface';
6
+ import { type LogbookEntry } from './logbook.interface';
6
7
  import { type Owner } from './owner.interface';
7
8
  import type { Storage } from './storage.interface';
8
- import { type Assignee, type LogbookEntry, type Task } from './task.interface';
9
+ import { type Assignee, type Task } from './task.interface';
9
10
  export declare function isAuthor(value: unknown): value is Author;
10
11
  export declare function isOwner(value: unknown): value is Owner;
11
12
  export declare function isStorage(value: unknown): value is Storage;
12
13
  export declare function isContentAnalysis(value: unknown): value is ContentAnalysis;
13
- export declare function isAsset(value: unknown): value is Asset;
14
- export declare function isContent(value: unknown): value is Content;
15
- export declare function isEvent(value: unknown): value is Event;
14
+ export declare function isAsset(value: unknown, isPartial?: false): value is Asset;
15
+ export declare function isAsset(value: unknown, isPartial: true): value is Partial<Asset>;
16
+ export declare function isAsset(value: unknown, isPartial: boolean): value is Asset | Partial<Asset>;
17
+ export declare function isContent(value: unknown, isPartial?: false): value is Content;
18
+ export declare function isContent(value: unknown, isPartial: true): value is Partial<Content>;
19
+ export declare function isContent(value: unknown, isPartial: boolean): value is Content | Partial<Content>;
20
+ export declare function isEvent(value: unknown, isPartial?: false): value is Event;
21
+ export declare function isEvent(value: unknown, isPartial: true): value is Partial<Event>;
22
+ export declare function isEvent(value: unknown, isPartial: boolean): value is Event | Partial<Event>;
16
23
  export declare function isAssignee(value: unknown): value is Assignee;
17
- export declare function isLogbookEntry(value: unknown): value is LogbookEntry;
18
- export declare function isTask(value: unknown): value is Task;
24
+ export declare function isLogbookEntry(value: unknown, isPartial?: false): value is LogbookEntry;
25
+ export declare function isLogbookEntry(value: unknown, isPartial: true): value is Partial<LogbookEntry>;
26
+ export declare function isLogbookEntry(value: unknown, isPartial: boolean): value is LogbookEntry | Partial<LogbookEntry>;
27
+ export declare function isTask(value: unknown, isPartial?: false): value is Task;
28
+ export declare function isTask(value: unknown, isPartial: true): value is Partial<Task>;
29
+ export declare function isTask(value: unknown, isPartial: boolean): value is Task | Partial<Task>;
19
30
  export declare function isUserMessage(value: unknown): value is UserMessage;
@@ -12,8 +12,11 @@ exports.isLogbookEntry = isLogbookEntry;
12
12
  exports.isTask = isTask;
13
13
  exports.isUserMessage = isUserMessage;
14
14
  const ai_interface_1 = require("./ai.interface");
15
+ const content_interface_1 = require("./content.interface");
15
16
  const event_interface_1 = require("./event.interface");
17
+ const logbook_interface_1 = require("./logbook.interface");
16
18
  const owner_interface_1 = require("./owner.interface");
19
+ const resource_interface_1 = require("./resource.interface");
17
20
  const task_interface_1 = require("./task.interface");
18
21
  function isRecord(value) {
19
22
  return typeof value === 'object' && value !== null;
@@ -31,10 +34,14 @@ const isArrayOf = (value, predicate) => Array.isArray(value) && value.every(pred
31
34
  const isOptionalArrayOf = (value, predicate) => value === undefined || isArrayOf(value, predicate);
32
35
  const isStringArray = (value) => isArrayOf(value, isString);
33
36
  const isOptionalStringArray = (value) => isOptionalArrayOf(value, isString);
37
+ const isOptionalUnknownArray = (value) => value === undefined || Array.isArray(value);
38
+ const hasOwn = (value, property) => Object.prototype.hasOwnProperty.call(value, property);
34
39
  const isMessageAttachment = (value) => isRecord(value) && isOptionalString(value.id) && isString(value.filename) && isString(value.text);
40
+ const isResourceReference = (value) => isRecord(value) && isString(value.id) && isEnumValue(resource_interface_1.ResourceType, value.resourceType) && isOptionalBoolean(value.dependent);
35
41
  const isOneOf = (value, allowed) => allowed.includes(value);
36
42
  const isEnumValue = (target, value) => Object.values(target).includes(value);
37
43
  const hasPermissions = (value) => isStringArray(value.readPermissions) && isStringArray(value.readWritePermissions);
44
+ const hasOptionalPermissions = (value) => isOptionalStringArray(value.readPermissions) && isOptionalStringArray(value.readWritePermissions);
38
45
  const hasResourceMeta = (value, options) => {
39
46
  const { owner, author, date } = options;
40
47
  if (owner && value.owner !== undefined && !owner(value.owner)) {
@@ -88,61 +95,114 @@ function isContentAnalysis(value) {
88
95
  }
89
96
  return (isString(value.id) &&
90
97
  isString(value.contentId) &&
91
- isString(value.status) &&
98
+ isEnumValue(content_interface_1.ContentAnalysisStatus, value.status) &&
92
99
  isOptionalString(value.error) &&
93
100
  isOptionalString(value.text) &&
94
101
  isOptionalArrayOf(value.pages, (page) => isRecord(page) && isNumber(page.pageNumber) && isOptionalString(page.text)));
95
102
  }
96
- function isAsset(value) {
103
+ function isTemplate(value) {
104
+ return isRecord(value) && isString(value.id) && isString(value.name) && isRecord(value.template);
105
+ }
106
+ function isAssetType(value) {
97
107
  if (!isRecord(value)) {
98
108
  return false;
99
109
  }
100
- return (isString(value.id) &&
101
- isOptionalString(value.translationId) &&
110
+ const hasValidAllowedParents = value.allowedParents === undefined || isStringArray(value.allowedParents) || isArrayOf(value.allowedParents, isAssetType);
111
+ const hasValidSupertype = value.supertype === undefined || isString(value.supertype) || isAssetType(value.supertype);
112
+ const hasValidTabPermissions = value.tabPermissions === undefined || (isRecord(value.tabPermissions) && Object.values(value.tabPermissions).every(isStringArray));
113
+ const hasValidTemplates = value.templates === undefined || isStringArray(value.templates) || isArrayOf(value.templates, isTemplate);
114
+ return (isOptionalString(value.id) &&
102
115
  isString(value.name) &&
103
- isOptionalString(value.description) &&
116
+ isOptionalStringArray(value.tags) &&
117
+ isOptionalString(value.translationId) &&
118
+ hasValidAllowedParents &&
119
+ isOptionalString(value.allowedParent$name) &&
104
120
  hasPermissions(value) &&
105
- isString(value.type) &&
121
+ hasValidSupertype &&
122
+ isOptionalString(value.supertype$name) &&
123
+ hasOwn(value, 'typeSchema') &&
124
+ hasOwn(value, 'uiSchema') &&
125
+ isOptionalString(value.author) &&
126
+ isOptionalNumber(value.revision) &&
127
+ isOptionalBoolean(value.isSystemAssetType) &&
128
+ isOptionalString(value.startTab) &&
129
+ hasValidTabPermissions &&
130
+ isOptionalNumber(value.templateVersion) &&
131
+ hasValidTemplates &&
132
+ hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: isString }));
133
+ }
134
+ function isAsset(value, isPartial = false) {
135
+ if (!isRecord(value)) {
136
+ return false;
137
+ }
138
+ let requiredFieldsValid = false;
139
+ if (!isPartial) {
140
+ requiredFieldsValid =
141
+ isOptionalString(value.id) && isString(value.name) && hasPermissions(value) && (isString(value.type) || isAssetType(value.type));
142
+ }
143
+ else {
144
+ requiredFieldsValid =
145
+ isOptionalString(value.id) &&
146
+ isOptionalString(value.name) &&
147
+ hasOptionalPermissions(value) &&
148
+ isOptional(value.type, (type) => isString(type) || isAssetType(type));
149
+ }
150
+ return (requiredFieldsValid &&
151
+ isOptionalString(value.externalKey) &&
152
+ isOptionalString(value.translationId) &&
106
153
  isOptionalString(value.type$name) &&
107
154
  isOptionalStringArray(value.tags) &&
108
155
  isOptionalString(value.parent) &&
109
156
  isOptionalString(value.parent$name) &&
157
+ isOptionalStringArray(value.ancestors) &&
158
+ isOptionalUnknownArray(value.relations) &&
159
+ isOptionalString(value.image) &&
110
160
  isOptionalStringArray(value.attachments) &&
111
161
  isOptionalStringArray(value.notificationEndpoints) &&
112
162
  isOptionalStringArray(value.aliases) &&
113
- isOptional(value.data, isRecord) &&
114
- isOptional(value.timeseries, isRecord) &&
115
- isOptional(value.event, isRecord) &&
116
- hasResourceMeta(value, { owner: isOwner, author: isAuthor }));
163
+ isOptionalString(value.author) &&
164
+ isOptionalNumber(value.revision) &&
165
+ hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: isString }));
117
166
  }
118
- function isContent(value) {
167
+ function isContent(value, isPartial = false) {
119
168
  if (!isRecord(value)) {
120
169
  return false;
121
170
  }
122
171
  const hasValidAnalysis = value.analysis === undefined || isString(value.analysis) || isContentAnalysis(value.analysis);
123
- return (isOptionalString(value.id) &&
124
- isString(value.fileId) &&
125
- isString(value.filename) &&
172
+ let requiredFieldsValid = false;
173
+ if (!isPartial) {
174
+ requiredFieldsValid =
175
+ isString(value.fileId) && isString(value.filename) && isString(value.mimetype) && isNumber(value.size) && hasPermissions(value);
176
+ }
177
+ else {
178
+ requiredFieldsValid =
179
+ isOptionalString(value.fileId) &&
180
+ isOptionalString(value.filename) &&
181
+ isOptionalString(value.mimetype) &&
182
+ isOptionalNumber(value.size) &&
183
+ hasOptionalPermissions(value);
184
+ }
185
+ return (requiredFieldsValid &&
186
+ isOptionalString(value.id) &&
126
187
  isOptionalString(value.description) &&
127
- isString(value.mimetype) &&
128
- isNumber(value.size) &&
129
- hasPermissions(value) &&
130
188
  isOptionalStringArray(value.tags) &&
131
189
  isOptionalStringArray(value.assets) &&
132
190
  isOptionalArrayOf(value.files, isStorage) &&
133
- hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: isString }) &&
134
- hasValidAnalysis);
191
+ hasValidAnalysis &&
192
+ hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: isString }));
135
193
  }
136
- function isEvent(value) {
194
+ function isEvent(value, isPartial = false) {
137
195
  if (!isRecord(value)) {
138
196
  return false;
139
197
  }
140
- return (isOptionalString(value.id) &&
141
- isString(value.name) &&
198
+ const requiredFieldsValid = isPartial
199
+ ? isOptionalString(value.name) && hasOptionalPermissions(value) && isOptional(value.level, (level) => isEnumValue(event_interface_1.EventLevel, level))
200
+ : isString(value.name) && hasPermissions(value) && isEnumValue(event_interface_1.EventLevel, value.level);
201
+ return (requiredFieldsValid &&
202
+ isOptionalString(value.id) &&
142
203
  isOptionalString(value.description) &&
143
204
  isOptionalStringArray(value.tags) &&
144
- hasPermissions(value) &&
145
- isEnumValue(event_interface_1.EventLevel, value.level) &&
205
+ isOptionalArrayOf(value.refs, isResourceReference) &&
146
206
  isOptional(value.data, isRecord) &&
147
207
  isOptionalString(value.assetRef) &&
148
208
  isOptionalString(value.assetRef$name) &&
@@ -151,20 +211,27 @@ function isEvent(value) {
151
211
  isOptionalString(value.eventRef) &&
152
212
  isOptionalString(value.cause) &&
153
213
  isOptionalString(value.group) &&
154
- hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: isString }));
214
+ hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: (candidate) => isString(candidate) || isDate(candidate) }));
155
215
  }
156
216
  function isAssignee(value) {
157
217
  return isRecord(value) && isString(value.id) && isEnumValue(task_interface_1.AssigneeType, value.type);
158
218
  }
159
- function isLogbookEntry(value) {
219
+ function isLogbookEntry(value, isPartial = false) {
160
220
  if (!isRecord(value)) {
161
221
  return false;
162
222
  }
163
- return (isString(value.taskId) &&
164
- isString(value.date) &&
165
- isNumber(value.duration) &&
166
- isOneOf(value.source, ['manual', 'voice', 'automatic']) &&
167
- isOptionalString(value.id) &&
223
+ const requiredFieldsValid = isPartial
224
+ ? isOptionalString(value.taskId) &&
225
+ isOptionalString(value.date) &&
226
+ isOptionalNumber(value.duration) &&
227
+ isOptional(value.source, (source) => isEnumValue(logbook_interface_1.LogbookEntrySource, source)) &&
228
+ isOptionalString(value.id)
229
+ : isString(value.taskId) &&
230
+ isString(value.date) &&
231
+ isNumber(value.duration) &&
232
+ isEnumValue(logbook_interface_1.LogbookEntrySource, value.source) &&
233
+ isString(value.id);
234
+ return (requiredFieldsValid &&
168
235
  isOptionalString(value.comment) &&
169
236
  isOptionalString(value.createdAt) &&
170
237
  isOptionalString(value.updatedAt) &&
@@ -172,34 +239,37 @@ function isLogbookEntry(value) {
172
239
  isOptional(value.data, isRecord) &&
173
240
  isOptional(value.createdBy, isAuthor));
174
241
  }
175
- function isTask(value) {
242
+ function isTask(value, isPartial = false) {
176
243
  if (!isRecord(value)) {
177
244
  return false;
178
245
  }
179
246
  const hasValidStatusHistory = value.statusHistoryLog === undefined ||
180
247
  (Array.isArray(value.statusHistoryLog) && value.statusHistoryLog.every((status) => isEnumValue(task_interface_1.TaskStatus, status)));
181
- return (isOptionalString(value.id) &&
248
+ const requiredFieldsValid = isPartial
249
+ ? isOptionalString(value.name) &&
250
+ isOptional(value.priority, (priority) => isEnumValue(task_interface_1.Priority, priority)) &&
251
+ hasOptionalPermissions(value) &&
252
+ isOptionalArrayOf(value.assignedTo, isAssignee)
253
+ : isString(value.name) && isEnumValue(task_interface_1.Priority, value.priority) && hasPermissions(value) && isArrayOf(value.assignedTo, isAssignee);
254
+ return (requiredFieldsValid &&
255
+ isOptionalString(value.id) &&
182
256
  isOptionalDateOrString(value.createdAt) &&
183
257
  isOptionalDateOrString(value.updatedAt) &&
184
258
  isOptionalDateOrString(value.deletedAt) &&
185
259
  isOptionalNumber(value.revision) &&
186
260
  hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: (candidate) => isString(candidate) || candidate instanceof Date }) &&
187
- isString(value.name) &&
188
261
  isOptionalString(value.description) &&
189
- isEnumValue(task_interface_1.Priority, value.priority) &&
190
262
  isOptionalStringArray(value.tags) &&
191
- hasPermissions(value) &&
192
263
  isOptionalString(value.assetRef) &&
193
264
  isOptionalString(value.assetRef$name) &&
194
265
  isOptionalString(value.eventRef) &&
195
266
  isOptionalString(value.eventRef$name) &&
196
267
  isOptionalNumber(value.gitHubNr) &&
197
268
  isOptionalString(value.schedule) &&
198
- (value.expiryDate === undefined || value.expiryDate instanceof Date) &&
269
+ isOptionalDateOrString(value.expiryDate) &&
199
270
  isOptionalString(value.parent) &&
200
271
  isOptionalString(value.parent$name) &&
201
272
  isOptionalStringArray(value.subTasks) &&
202
- isArrayOf(value.assignedTo, isAssignee) &&
203
273
  isOptionalString(value.acceptedBy) &&
204
274
  (value.status === undefined || isEnumValue(task_interface_1.TaskStatus, value.status)) &&
205
275
  hasValidStatusHistory &&
@@ -219,5 +289,6 @@ function isUserMessage(value) {
219
289
  isOptionalString(value.content) &&
220
290
  isOptionalBoolean(value.hidden) &&
221
291
  isOptionalBoolean(value.useWebSearch) &&
292
+ isOptional(value.attachmentHandling, (mode) => isEnumValue(ai_interface_1.AttachmentHandlingMode, mode)) &&
222
293
  isOptionalArrayOf(value.attachments, isMessageAttachment));
223
294
  }
@@ -8,7 +8,6 @@ export interface UserSettings extends Api {
8
8
  creationWriteRoles?: Permission[];
9
9
  deletionRequested?: boolean;
10
10
  favoriteLabelsOrder?: Record<string, number>;
11
- language?: string;
12
11
  tableSettings?: TableSetting[];
13
12
  userId?: string;
14
13
  }
@@ -1,6 +1,6 @@
1
- import { AiMockService, AlertMockService, AssetMockService, AssetTypesMockService, ContentMockService, CrmMockService, DataspaceMockService, EndpointMockService, EventMockService, FlangeSkillControlMockService, FlowDeploymentMockService, FlowFunctionsMockService, FlowMockService, FlowModulesMockService, HttpClientMockService, LabelMockService, NotificationMockService, NotificationRulesMockService, ObjectReferenceMockService, OrganizationsAdministrationMockService, OrganizationsMockService, OrganizationsResourcesMockService, SearchMockService, TaskMockService, TimeseriesMockService, UserMockService, VaultMockService } from '.';
1
+ import { AiMockService, AlertMockService, AssetMockService, AssetTypesMockService, ContentMockService, CrmMockService, DataspaceMockService, EndpointMockService, EventMockService, FlangeSkillControlMockService, FlowDeploymentMockService, FlowFunctionsMockService, FlowMockService, FlowModulesMockService, HttpClientMockService, LabelMockService, LogbookMockService, NotificationMockService, NotificationRulesMockService, ObjectReferenceMockService, OrganizationsAdministrationMockService, OrganizationsMockService, OrganizationsResourcesMockService, SearchMockService, TaskMockService, TimeseriesMockService, UserMockService, VaultMockService } from '.';
2
2
  import { API } from '../api';
3
- import { Artifact, Asset, AssetRevision, AssetType, Content, Endpoint, Event, FlowDeployment, FlowDiagram, FlowDto, FlowFunctionDto, FlowFunctionRevision, FlowModule, FlowRevision, Label, Notification, ObjectReference, Organization, Secret, Task, TimeSeries, TimeSeriesValue, VaultSecret } from '../interfaces';
3
+ import { Artifact, Asset, AssetRevision, AssetType, Content, Endpoint, Event, FlowDeployment, FlowDiagram, FlowDto, FlowFunctionDto, FlowFunctionRevision, FlowModule, FlowRevision, Label, LogbookEntry, Notification, ObjectReference, Organization, Secret, Task, TimeSeries, TimeSeriesValue, VaultSecret } from '../interfaces';
4
4
  export interface MockAPIInitData {
5
5
  assets?: AssetInit[];
6
6
  assetRevisions?: AssetRevisionInit[];
@@ -19,6 +19,7 @@ export interface MockAPIInitData {
19
19
  modules?: FlowModuleInit[];
20
20
  diagrams?: FlowDiagramInit[];
21
21
  labels?: LabelInit[];
22
+ logbookEntries?: LogbookEntryInit[];
22
23
  vault?: VaultSecretInit[];
23
24
  notifications?: NotificationInit[];
24
25
  organizations?: OrganizationInit[];
@@ -42,6 +43,7 @@ export declare class MockAPI implements API {
42
43
  flowModules: FlowModulesMockService;
43
44
  httpClient: HttpClientMockService;
44
45
  labels: LabelMockService;
46
+ logbook: LogbookMockService;
45
47
  notifications: NotificationMockService;
46
48
  notificationRules: NotificationRulesMockService;
47
49
  organizations: OrganizationsMockService;
@@ -64,6 +66,7 @@ export type AtLeast<T, K extends keyof T> = Identity<Partial<T> & Pick<T, K>>;
64
66
  export type Replace<T, K extends keyof T, TReplace> = Identity<Pick<T, Exclude<keyof T, K>> & {
65
67
  [P in K]: TReplace;
66
68
  }>;
69
+ export type LogbookEntryInit = AtLeast<LogbookEntry, 'id' | 'taskId' | 'date' | 'duration' | 'source'>;
67
70
  export type AssetInit = Replace<AtLeast<Asset, 'id' | 'name' | 'type'>, 'type', AssetTypeInit | string>;
68
71
  export type AssetRevisionInit = Replace<AtLeast<AssetRevision, 'id' | 'name' | 'type' | 'originalId'>, 'type', AssetTypeInit | string>;
69
72
  export type AssetTypeInit = AtLeast<AssetType, 'id' | 'name'>;
@@ -6,7 +6,7 @@ const interfaces_1 = require("../interfaces");
6
6
  class MockAPI {
7
7
  constructor(initData) {
8
8
  this.proxy = null;
9
- const { assets = [], assetRevisions = [], contents = [], endpoints = [], secrets = [], timeSeries = [], tasks = [], events = [], users, flows = [], flowRevisions = [], deployments = [], functions = [], functionRevisions = [], modules = [], diagrams = [], labels = [], vault = [], notifications = [], organizations = [], objectReferences = [], resourceSetNames = [], } = initData;
9
+ const { assets = [], assetRevisions = [], contents = [], endpoints = [], secrets = [], timeSeries = [], tasks = [], events = [], users, flows = [], flowRevisions = [], deployments = [], functions = [], functionRevisions = [], modules = [], diagrams = [], labels = [], logbookEntries = [], vault = [], notifications = [], organizations = [], objectReferences = [], resourceSetNames = [], } = initData;
10
10
  // convert init data to normal data that the services usually use
11
11
  const assetTypes = assets
12
12
  .map((v) => v.type)
@@ -199,6 +199,7 @@ class MockAPI {
199
199
  this.flowModules = new _1.FlowModulesMockService(modules1);
200
200
  this.httpClient = new _1.HttpClientMockService();
201
201
  this.labels = new _1.LabelMockService(labels1);
202
+ this.logbook = new _1.LogbookMockService(logbookEntries);
202
203
  this.notificationRules = new _1.NotificationRulesMockService([]);
203
204
  this.notifications = new _1.NotificationMockService(notifications1);
204
205
  this.organizations = new _1.OrganizationsMockService(organizations1);
@@ -19,6 +19,7 @@ export { FlowModulesMockService } from './flow-modules.mock.service';
19
19
  export { FlowMockService } from './flow.mock.service';
20
20
  export { HttpClientMockService } from './http-client.mock.service';
21
21
  export { LabelMockService } from './label.mock.service';
22
+ export { LogbookMockService } from './logbook.mock.service';
22
23
  export { NotificationRulesMockService } from './notification-rules.mock.service';
23
24
  export { NotificationMockService } from './notification.mock.service';
24
25
  export { ObjectReferenceMockService } from './object-reference.mock.service';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VaultMockService = exports.UserMockService = exports.TimeseriesMockService = exports.TaskMockService = exports.ShareMockService = exports.SearchMockService = exports.OrganizationsMockService = exports.OrganizationsResourcesMockService = exports.OrganizationsAdministrationMockService = exports.ObjectReferenceMockService = exports.NotificationMockService = exports.NotificationRulesMockService = exports.LabelMockService = exports.HttpClientMockService = exports.FlowMockService = exports.FlowModulesMockService = exports.FlowFunctionsMockService = exports.FlowDeploymentMockService = exports.FlangeSkillControlMockService = exports.EventMockService = exports.EndpointMockService = exports.DataspaceMockService = exports.CrmMockService = exports.ContentMockService = exports.AssetTypesMockService = exports.AssetMockService = exports.AlertMockService = exports.AiMockService = exports.TrashMockService = exports.DataMockService = exports.APIBaseMock = exports.sortData = void 0;
3
+ exports.VaultMockService = exports.UserMockService = exports.TimeseriesMockService = exports.TaskMockService = exports.ShareMockService = exports.SearchMockService = exports.OrganizationsMockService = exports.OrganizationsResourcesMockService = exports.OrganizationsAdministrationMockService = exports.ObjectReferenceMockService = exports.NotificationMockService = exports.NotificationRulesMockService = exports.LogbookMockService = exports.LabelMockService = exports.HttpClientMockService = exports.FlowMockService = exports.FlowModulesMockService = exports.FlowFunctionsMockService = exports.FlowDeploymentMockService = exports.FlangeSkillControlMockService = exports.EventMockService = exports.EndpointMockService = exports.DataspaceMockService = exports.CrmMockService = exports.ContentMockService = exports.AssetTypesMockService = exports.AssetMockService = exports.AlertMockService = exports.AiMockService = exports.TrashMockService = exports.DataMockService = exports.APIBaseMock = exports.sortData = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  var utils_1 = require("./utils");
6
6
  Object.defineProperty(exports, "sortData", { enumerable: true, get: function () { return utils_1.sortData; } });
@@ -43,6 +43,8 @@ var http_client_mock_service_1 = require("./http-client.mock.service");
43
43
  Object.defineProperty(exports, "HttpClientMockService", { enumerable: true, get: function () { return http_client_mock_service_1.HttpClientMockService; } });
44
44
  var label_mock_service_1 = require("./label.mock.service");
45
45
  Object.defineProperty(exports, "LabelMockService", { enumerable: true, get: function () { return label_mock_service_1.LabelMockService; } });
46
+ var logbook_mock_service_1 = require("./logbook.mock.service");
47
+ Object.defineProperty(exports, "LogbookMockService", { enumerable: true, get: function () { return logbook_mock_service_1.LogbookMockService; } });
46
48
  var notification_rules_mock_service_1 = require("./notification-rules.mock.service");
47
49
  Object.defineProperty(exports, "NotificationRulesMockService", { enumerable: true, get: function () { return notification_rules_mock_service_1.NotificationRulesMockService; } });
48
50
  var notification_mock_service_1 = require("./notification.mock.service");
@@ -0,0 +1,18 @@
1
+ import { LogbookEntry, LogbookEntryDto, Paginated, TokenOption } from '../interfaces';
2
+ import { LogbookService } from '../services';
3
+ import { APIBaseMock } from './api-base.mock';
4
+ export declare class LogbookMockService extends APIBaseMock<LogbookEntry> implements LogbookService {
5
+ constructor(logbookEntries?: LogbookEntry[]);
6
+ getEntries(taskId: string, limit?: number, offset?: number, _options?: TokenOption): Promise<Paginated<LogbookEntry>>;
7
+ getEntriesByIds(ids: string[], _options?: TokenOption): Promise<LogbookEntry[]>;
8
+ addEntry(taskId: string, dto: LogbookEntryDto, _options?: TokenOption): Promise<LogbookEntry>;
9
+ updateEntry(taskId: string, entryId: string, dto: Partial<LogbookEntryDto>, _options?: TokenOption): Promise<LogbookEntry>;
10
+ deleteEntry(taskId: string, entryId: string, _options?: TokenOption): Promise<{
11
+ deleted: boolean;
12
+ }>;
13
+ getUserEntries(limit?: number, offset?: number, _options?: TokenOption, _filter?: string): Promise<Paginated<LogbookEntry>>;
14
+ getMemberEntries(memberId: string, limit?: number, _options?: TokenOption, _filter?: string): Promise<Paginated<LogbookEntry>>;
15
+ getEntriesByTaskIds(taskIds: string[], _startDate?: string, _endDate?: string, _options?: TokenOption): Promise<LogbookEntry[]>;
16
+ seed(entries: LogbookEntry[]): void;
17
+ clear(): void;
18
+ }
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogbookMockService = void 0;
4
+ const interfaces_1 = require("../interfaces");
5
+ const api_base_mock_1 = require("./api-base.mock");
6
+ class LogbookMockService extends api_base_mock_1.APIBaseMock {
7
+ constructor(logbookEntries = []) {
8
+ super(logbookEntries);
9
+ }
10
+ async getEntries(taskId, limit = 50, offset = 0, _options = {}) {
11
+ const taskEntries = this.data.filter((e) => e.taskId === taskId);
12
+ const docs = taskEntries.slice(offset, offset + limit);
13
+ return {
14
+ docs,
15
+ limit,
16
+ offset,
17
+ total: taskEntries.length,
18
+ page: Math.floor(offset / limit) + 1,
19
+ pages: Math.max(1, Math.ceil(taskEntries.length / limit)),
20
+ };
21
+ }
22
+ getEntriesByIds(ids, _options = {}) {
23
+ const entries = this.data.filter((e) => ids.includes(e.id));
24
+ return Promise.resolve(entries);
25
+ }
26
+ async addEntry(taskId, dto, _options = {}) {
27
+ const id = globalThis.crypto?.randomUUID?.() || Math.random().toString(36).slice(2);
28
+ const now = new Date().toISOString();
29
+ const entry = {
30
+ id,
31
+ taskId,
32
+ date: dto.date || now,
33
+ duration: dto.duration ?? 0,
34
+ materials: dto.materials || [],
35
+ comment: dto.comment || '',
36
+ source: dto.source || interfaces_1.LogbookEntrySource.MANUAL,
37
+ createdAt: now,
38
+ updatedAt: now,
39
+ createdBy: { id: 'mock-user', username: 'mock-user' },
40
+ };
41
+ this.data.push(entry);
42
+ return entry;
43
+ }
44
+ async updateEntry(taskId, entryId, dto, _options = {}) {
45
+ const idx = this.data.findIndex((e) => e.id === entryId && e.taskId === taskId);
46
+ if (idx === -1) {
47
+ throw new Error('Not found');
48
+ }
49
+ const updated = {
50
+ ...this.data[idx],
51
+ ...dto,
52
+ materials: dto.materials !== undefined ? dto.materials : this.data[idx].materials,
53
+ updatedAt: new Date().toISOString(),
54
+ };
55
+ this.data[idx] = updated;
56
+ return updated;
57
+ }
58
+ async deleteEntry(taskId, entryId, _options = {}) {
59
+ const before = this.data.length;
60
+ this.data = this.data.filter((e) => !(e.id === entryId && e.taskId === taskId));
61
+ return { deleted: this.data.length < before };
62
+ }
63
+ async getUserEntries(limit = 50, offset = 0, _options = {}, _filter) {
64
+ const userEntries = this.data.filter((e) => e.createdBy?.id === 'mock-user');
65
+ const docs = userEntries.slice(offset, offset + limit);
66
+ return {
67
+ docs,
68
+ limit,
69
+ offset,
70
+ total: userEntries.length,
71
+ page: Math.floor(offset / limit) + 1,
72
+ pages: Math.max(1, Math.ceil(userEntries.length / limit)),
73
+ };
74
+ }
75
+ async getMemberEntries(memberId, limit = 300, _options = {}, _filter) {
76
+ const memberEntries = this.data.filter((e) => e.createdBy?.id === memberId);
77
+ const docs = memberEntries.slice(0, limit);
78
+ return {
79
+ docs,
80
+ limit,
81
+ offset: 0,
82
+ total: memberEntries.length,
83
+ page: 1,
84
+ pages: Math.max(1, Math.ceil(memberEntries.length / limit)),
85
+ };
86
+ }
87
+ getEntriesByTaskIds(taskIds, _startDate, _endDate, _options = {}) {
88
+ return Promise.resolve(this.data.filter((e) => taskIds.includes(e.taskId)));
89
+ }
90
+ seed(entries) {
91
+ this.data = [...entries];
92
+ }
93
+ clear() {
94
+ this.data = [];
95
+ }
96
+ }
97
+ exports.LogbookMockService = LogbookMockService;
@@ -1,5 +1,5 @@
1
1
  import { APIBaseMock, DataMockService, TrashMockService } from '.';
2
- import { DeleteQuery, LogbookEntry, LogbookEntryDto, Paginated, RequestParameter, Task, TokenOption } from '../interfaces';
2
+ import { DeleteQuery, Paginated, RequestParameter, Task } from '../interfaces';
3
3
  import { TaskService } from '../services';
4
4
  import { ShareMockService } from './share.mock.service';
5
5
  interface BaseService extends DataMockService<Task>, ShareMockService<Task>, TrashMockService<Task> {
@@ -7,22 +7,11 @@ interface BaseService extends DataMockService<Task>, ShareMockService<Task>, Tra
7
7
  declare class BaseService extends APIBaseMock<Task> {
8
8
  }
9
9
  export declare class TaskMockService extends BaseService implements TaskService {
10
- private entries;
11
- constructor(tasks: Task[], logbookEntries?: LogbookEntry[]);
10
+ constructor(tasks: Task[]);
12
11
  createTaskAttachedToAsset(dto: any): Promise<Task>;
13
12
  deleteOne(taskId: string, deleteQuery?: DeleteQuery): Promise<Task>;
14
13
  getMany(params?: RequestParameter): Promise<Paginated<Task>>;
15
14
  findByName(name: string, options?: any): Promise<Paginated<Task>>;
16
15
  findByAsset(assetId: string, options?: any): Promise<Paginated<Task>>;
17
- getLogbookEntries(taskId: string, limit?: number, offset?: number, _options?: TokenOption): Promise<Paginated<LogbookEntry>>;
18
- getLogbookEntriesByIds(ids: string[], _options?: TokenOption): Promise<LogbookEntry[]>;
19
- addLogbookEntry(taskId: string, dto: LogbookEntryDto, _options?: TokenOption): Promise<LogbookEntry>;
20
- updateLogbookEntry(taskId: string, entryId: string, dto: Partial<LogbookEntryDto>, _options?: TokenOption): Promise<LogbookEntry>;
21
- deleteLogbookEntry(taskId: string, entryId: string, _options?: TokenOption): Promise<{
22
- deleted: boolean;
23
- }>;
24
- getUserLogbookEntries(limit?: number, offset?: number, _options?: TokenOption, userId?: string): Promise<Paginated<LogbookEntry>>;
25
- seed(entries: LogbookEntry[]): void;
26
- clear(): void;
27
16
  }
28
17
  export {};
@@ -12,10 +12,8 @@ BaseService = tslib_1.__decorate([
12
12
  ], BaseService);
13
13
  /* eslint-enable @typescript-eslint/no-unsafe-declaration-merging */
14
14
  class TaskMockService extends BaseService {
15
- constructor(tasks, logbookEntries = []) {
15
+ constructor(tasks) {
16
16
  super(tasks);
17
- this.entries = [];
18
- this.entries = [...logbookEntries];
19
17
  }
20
18
  async createTaskAttachedToAsset(dto) {
21
19
  this.data.push(dto);
@@ -54,78 +52,5 @@ class TaskMockService extends BaseService {
54
52
  };
55
53
  return Promise.resolve(result);
56
54
  }
57
- // override network methods to in‑memory versions
58
- async getLogbookEntries(taskId, limit = 50, offset = 0, _options = {}) {
59
- const taskEntries = this.entries.filter((e) => e.taskId === taskId);
60
- const docs = taskEntries.slice(offset, offset + limit);
61
- return {
62
- docs,
63
- limit,
64
- offset,
65
- total: taskEntries.length,
66
- page: Math.floor(offset / limit) + 1,
67
- pages: Math.max(1, Math.ceil(taskEntries.length / limit)),
68
- };
69
- }
70
- getLogbookEntriesByIds(ids, _options = {}) {
71
- const entries = this.entries.filter((e) => ids.includes(e.id));
72
- return Promise.resolve(entries);
73
- }
74
- async addLogbookEntry(taskId, dto, _options = {}) {
75
- const id = globalThis.crypto?.randomUUID?.() || Math.random().toString(36).slice(2);
76
- const now = new Date().toISOString();
77
- const entry = {
78
- id,
79
- taskId,
80
- date: dto.date || now,
81
- duration: dto.duration ?? 0,
82
- materials: dto.materials || [],
83
- comment: dto.comment || '',
84
- source: 'manual',
85
- createdAt: now,
86
- updatedAt: now,
87
- createdBy: dto.createdBy || { id: 'mock-user', username: 'mock-user' },
88
- };
89
- this.entries.push(entry);
90
- return entry;
91
- }
92
- async updateLogbookEntry(taskId, entryId, dto, _options = {}) {
93
- const idx = this.entries.findIndex((e) => e.id === entryId && e.taskId === taskId);
94
- if (idx === -1) {
95
- throw new Error('Not found');
96
- }
97
- const updated = {
98
- ...this.entries[idx],
99
- ...dto,
100
- materials: dto.materials !== undefined ? dto.materials : this.entries[idx].materials,
101
- updatedAt: new Date().toISOString(),
102
- };
103
- this.entries[idx] = updated;
104
- return updated;
105
- }
106
- async deleteLogbookEntry(taskId, entryId, _options = {}) {
107
- const before = this.entries.length;
108
- this.entries = this.entries.filter((e) => !(e.id === entryId && e.taskId === taskId));
109
- return { deleted: this.entries.length < before };
110
- }
111
- async getUserLogbookEntries(limit = 50, offset = 0, _options = {}, userId = 'mock-user') {
112
- const userEntries = this.entries.filter((e) => e.createdBy?.id === userId);
113
- const docs = userEntries.slice(offset, offset + limit);
114
- return {
115
- docs,
116
- limit,
117
- offset,
118
- total: userEntries.length,
119
- page: Math.floor(offset / limit) + 1,
120
- pages: Math.max(1, Math.ceil(userEntries.length / limit)),
121
- };
122
- }
123
- // test helpers
124
- seed(entries) {
125
- this.entries = [...entries];
126
- }
127
- clear() {
128
- this.entries = [];
129
- }
130
55
  }
131
56
  exports.TaskMockService = TaskMockService;
@@ -16,6 +16,7 @@ export { FlowModuleService } from './flow-module.service';
16
16
  export { FlowService } from './flow.service';
17
17
  export { HttpClientService } from './http-client.service';
18
18
  export { LabelService } from './label.service';
19
+ export { LogbookService } from './logbook.service';
19
20
  export { NotificationRuleService } from './notification-rule.service';
20
21
  export { NotificationService } from './notification.service';
21
22
  export { ObjectReferenceService } from './object-reference.service';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VaultService = exports.UserService = exports.TimeSeriesService = exports.TaskService = exports.ShareService = exports.SearchService = exports.ProxyService = exports.OrganizationsService = exports.OrganizationsResourcesService = exports.OrganizationsAdministrationService = exports.ObjectReferenceService = exports.NotificationService = exports.NotificationRuleService = exports.LabelService = exports.HttpClientService = exports.FlowService = exports.FlowModuleService = exports.FlowFunctionService = exports.FlowDeploymentService = exports.FlangeSkillControlService = exports.EventService = exports.EndpointService = exports.DataspaceService = exports.CrmService = exports.ContentService = exports.AssetTypesService = exports.AssetService = exports.AlertService = exports.AiService = exports.TrashService = exports.DataService = void 0;
3
+ exports.VaultService = exports.UserService = exports.TimeSeriesService = exports.TaskService = exports.ShareService = exports.SearchService = exports.ProxyService = exports.OrganizationsService = exports.OrganizationsResourcesService = exports.OrganizationsAdministrationService = exports.ObjectReferenceService = exports.NotificationService = exports.NotificationRuleService = exports.LogbookService = exports.LabelService = exports.HttpClientService = exports.FlowService = exports.FlowModuleService = exports.FlowFunctionService = exports.FlowDeploymentService = exports.FlangeSkillControlService = exports.EventService = exports.EndpointService = exports.DataspaceService = exports.CrmService = exports.ContentService = exports.AssetTypesService = exports.AssetService = exports.AlertService = exports.AiService = exports.TrashService = exports.DataService = void 0;
4
4
  var data_service_1 = require("./data.service");
5
5
  Object.defineProperty(exports, "DataService", { enumerable: true, get: function () { return data_service_1.DataService; } });
6
6
  var trash_service_1 = require("./trash.service");
@@ -37,6 +37,8 @@ var http_client_service_1 = require("./http-client.service");
37
37
  Object.defineProperty(exports, "HttpClientService", { enumerable: true, get: function () { return http_client_service_1.HttpClientService; } });
38
38
  var label_service_1 = require("./label.service");
39
39
  Object.defineProperty(exports, "LabelService", { enumerable: true, get: function () { return label_service_1.LabelService; } });
40
+ var logbook_service_1 = require("./logbook.service");
41
+ Object.defineProperty(exports, "LogbookService", { enumerable: true, get: function () { return logbook_service_1.LogbookService; } });
40
42
  var notification_rule_service_1 = require("./notification-rule.service");
41
43
  Object.defineProperty(exports, "NotificationRuleService", { enumerable: true, get: function () { return notification_rule_service_1.NotificationRuleService; } });
42
44
  var notification_service_1 = require("./notification.service");
@@ -0,0 +1,16 @@
1
+ import { APIBase } from '../api-base';
2
+ import { LogbookEntry, LogbookEntryDto, Paginated, TokenOption } from '../interfaces';
3
+ import { HttpClientService } from './http-client.service';
4
+ export declare class LogbookService extends APIBase {
5
+ constructor(httpClient: HttpClientService);
6
+ getEntries(taskId: string, limit?: number, offset?: number, options?: TokenOption): Promise<Paginated<LogbookEntry>>;
7
+ getEntriesByIds(ids: string[], options?: TokenOption): Promise<LogbookEntry[]>;
8
+ addEntry(taskId: string, entry: LogbookEntryDto, options?: TokenOption): Promise<LogbookEntry>;
9
+ updateEntry(taskId: string, entryId: string, entry: Partial<LogbookEntryDto>, options?: TokenOption): Promise<LogbookEntry>;
10
+ deleteEntry(taskId: string, entryId: string, options?: TokenOption): Promise<{
11
+ deleted: boolean;
12
+ }>;
13
+ getUserEntries(limit?: number, offset?: number, options?: TokenOption, filter?: string): Promise<Paginated<LogbookEntry>>;
14
+ getMemberEntries(memberId: string, limit?: number, options?: TokenOption, filter?: string): Promise<Paginated<LogbookEntry>>;
15
+ getEntriesByTaskIds(taskIds: string[], startDate?: string, endDate?: string, options?: TokenOption): Promise<LogbookEntry[]>;
16
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogbookService = void 0;
4
+ const api_base_1 = require("../api-base");
5
+ class LogbookService extends api_base_1.APIBase {
6
+ constructor(httpClient) {
7
+ super(httpClient, '/tasks/logbook');
8
+ }
9
+ getEntries(taskId, limit = 50, offset = 0, options = {}) {
10
+ return this.httpClient.get(this.basePath, {
11
+ ...options,
12
+ params: { taskId, limit: String(limit), offset: String(offset) },
13
+ });
14
+ }
15
+ getEntriesByIds(ids, options = {}) {
16
+ return this.httpClient.get(`${this.basePath}/by-ids`, {
17
+ ...options,
18
+ params: {
19
+ ids: ids.join(','),
20
+ },
21
+ });
22
+ }
23
+ addEntry(taskId, entry, options = {}) {
24
+ return this.httpClient.post(this.basePath, entry, {
25
+ ...options,
26
+ params: { taskId },
27
+ });
28
+ }
29
+ updateEntry(taskId, entryId, entry, options = {}) {
30
+ return this.httpClient.patch(`${this.basePath}/${entryId}`, entry, {
31
+ ...options,
32
+ params: { taskId },
33
+ });
34
+ }
35
+ deleteEntry(taskId, entryId, options = {}) {
36
+ return this.httpClient.delete(`${this.basePath}/${entryId}`, {
37
+ ...options,
38
+ params: { taskId },
39
+ });
40
+ }
41
+ getUserEntries(limit = 50, offset = 0, options = {}, filter) {
42
+ return this.httpClient.get(`${this.basePath}/mine`, {
43
+ ...options,
44
+ params: { limit: String(limit), offset: String(offset), ...(filter ? { filter } : {}) },
45
+ });
46
+ }
47
+ getMemberEntries(memberId, limit = 300, options = {}, filter) {
48
+ return this.httpClient.get(`${this.basePath}/member`, {
49
+ ...options,
50
+ params: { memberId, limit: String(limit), ...(filter ? { filter } : {}) },
51
+ });
52
+ }
53
+ getEntriesByTaskIds(taskIds, startDate, endDate, options = {}) {
54
+ return this.httpClient.get(`${this.basePath}/by-tasks`, {
55
+ ...options,
56
+ params: {
57
+ taskIds: taskIds.join(','),
58
+ ...(startDate ? { startDate } : {}),
59
+ ...(endDate ? { endDate } : {}),
60
+ },
61
+ });
62
+ }
63
+ }
64
+ exports.LogbookService = LogbookService;
@@ -1,6 +1,6 @@
1
1
  import { DataService, HttpClientService, TrashService } from '.';
2
2
  import { APIBase } from '../api-base';
3
- import { LogbookEntry, LogbookEntryDto, Paginated, Task, TokenOption } from '../interfaces';
3
+ import { Paginated, Task, TokenOption } from '../interfaces';
4
4
  import { ShareService } from './share.service';
5
5
  interface BaseService extends DataService<Task>, ShareService, TrashService<Task> {
6
6
  }
@@ -11,13 +11,5 @@ export declare class TaskService extends BaseService {
11
11
  createTaskAttachedToAsset(dto: any, options?: TokenOption): Promise<Task>;
12
12
  findByName(name: string, options?: TokenOption): Promise<Paginated<Task>>;
13
13
  findByAsset(assetId: string, options?: TokenOption): Promise<Paginated<Task>>;
14
- getLogbookEntries(taskId: string, limit?: number, offset?: number, options?: TokenOption): Promise<Paginated<LogbookEntry>>;
15
- getLogbookEntriesByIds(ids: string[], options?: TokenOption): Promise<LogbookEntry[]>;
16
- addLogbookEntry(taskId: string, entry: LogbookEntryDto, options?: TokenOption): Promise<LogbookEntry>;
17
- updateLogbookEntry(taskId: string, entryId: string, entry: Partial<LogbookEntryDto>, options?: TokenOption): Promise<LogbookEntry>;
18
- deleteLogbookEntry(taskId: string, entryId: string, options?: TokenOption): Promise<{
19
- deleted: boolean;
20
- }>;
21
- getUserLogbookEntries(limit?: number, offset?: number, options?: TokenOption): Promise<Paginated<LogbookEntry>>;
22
14
  }
23
15
  export {};
@@ -26,34 +26,5 @@ class TaskService extends BaseService {
26
26
  findByAsset(assetId, options = {}) {
27
27
  return this.httpClient.get(`${this.basePath}`, { ...options, params: { filter: `assetRef==${assetId}` } });
28
28
  }
29
- getLogbookEntries(taskId, limit = 50, offset = 0, options = {}) {
30
- return this.httpClient.get(`${this.basePath}/${taskId}/logbook`, {
31
- ...options,
32
- params: { limit: String(limit), offset: String(offset) },
33
- });
34
- }
35
- getLogbookEntriesByIds(ids, options = {}) {
36
- return this.httpClient.get(`${this.basePath}/logbook`, {
37
- ...options,
38
- params: {
39
- ids: ids.join(','),
40
- },
41
- });
42
- }
43
- addLogbookEntry(taskId, entry, options = {}) {
44
- return this.httpClient.post(`${this.basePath}/${taskId}/logbook`, entry, options);
45
- }
46
- updateLogbookEntry(taskId, entryId, entry, options = {}) {
47
- return this.httpClient.patch(`${this.basePath}/${taskId}/logbook/${entryId}`, entry, options);
48
- }
49
- deleteLogbookEntry(taskId, entryId, options = {}) {
50
- return this.httpClient.delete(`${this.basePath}/${taskId}/logbook/${entryId}`, options);
51
- }
52
- getUserLogbookEntries(limit = 50, offset = 0, options = {}) {
53
- return this.httpClient.get(`${this.basePath}/logbook/mine`, {
54
- ...options,
55
- params: { limit: String(limit), offset: String(offset) },
56
- });
57
- }
58
29
  }
59
30
  exports.TaskService = TaskService;