UNPKG

@swoft/gtd-domain

Version:

Getting Things Done (GTD) productivity system - consolidated domain implementation

262 lines (260 loc) 8.57 kB
import { ApiValidationError, BackendApiError, BackendInboxListResponseSchema, classifyError, defaultErrorLogger, isBackendSuccessResponse, withRetry } from "./chunk-GQ5XH56W.mjs"; import { __name } from "./chunk-PAWJFY3S.mjs"; // src/client/gtd-client.ts var GTDClient = class { static { __name(this, "GTDClient"); } http; basePath; config; constructor(http, basePath = "/api/productivity/gtd", config = {}) { this.http = http; this.basePath = basePath; this.config = { enableValidation: true, enableRetry: true, errorLogger: defaultErrorLogger, ...config }; } async executeRequest(operation) { try { if (this.config.enableRetry) { return await withRetry(operation); } return await operation(); } catch (error) { const standardError = classifyError(error); this.config.errorLogger?.logError(standardError); throw standardError; } } validateResponse(data, schema, operationName) { if (!this.config.enableValidation) { return data; } const result = schema.safeParse(data); if (!result.success) { throw new ApiValidationError(`Invalid response format for ${operationName}`, result.error.issues); } return result.data; } // Inbox Operations async getInboxItems(filters) { return this.executeRequest(async () => { const queryParams = filters ? new URLSearchParams(Object.entries(filters).filter(([_, value]) => value !== void 0).reduce((acc, [key, value]) => ({ ...acc, [key]: String(value) }), {})).toString() : ""; const url = queryParams ? `${this.basePath}/inbox?${queryParams}` : `${this.basePath}/inbox`; const rawResponse = await this.http.get(url, { headers: { "Content-Type": "application/json" } }); const validatedResponse = this.validateResponse(rawResponse, BackendInboxListResponseSchema, "getInboxItems"); if (!isBackendSuccessResponse(validatedResponse)) { throw BackendApiError.fromBackendError(validatedResponse); } const { data } = validatedResponse; return { items: data.items.map((item) => ({ id: item.id, originalContent: item.content || item.text || item.title || "", capturedAt: item.capturedAt, capturedByPersonId: item.capturedBy || "unknown", processingStatus: item.status === "processed" ? "processed" : "unprocessed", clarification: item.clarification || void 0, isActionable: item.isActionable || void 0, // These fields are not available in backend response yet - use undefined for now lastRefinedAt: void 0, refinedByPersonId: void 0 })), pagination: { totalCount: data.total }, totalCount: data.total }; }); } async getInboxItem(id) { const response = await this.http.get(`${this.basePath}/inbox/${id}`); return response.item || null; } async captureInboxItem(request) { const response = await this.http.post(`${this.basePath}/inbox`, request); return response.item || response; } async refineInboxItem(id, request) { const response = await this.http.post(`${this.basePath}/inbox/${id}/refine`, request); return response.item || response; } async clarifyInboxItem(id, request) { const response = await this.http.post(`${this.basePath}/inbox/${id}/clarify`, request); return response.item || response; } async processInboxItem(id, request) { return this.http.post(`${this.basePath}/inbox/${id}/process`, request); } async deleteInboxItem(id) { await this.http.delete(`${this.basePath}/inbox/${id}`); } // Project Operations async getProjects(filters) { const queryParams = filters ? new URLSearchParams(Object.entries(filters).filter(([_, value]) => value !== void 0).reduce((acc, [key, value]) => ({ ...acc, [key]: String(value) }), {})).toString() : ""; const url = queryParams ? `${this.basePath}/projects?${queryParams}` : `${this.basePath}/projects`; const response = await this.http.get(url); if (response.items && response.total !== void 0) { return { items: response.items, pagination: { totalCount: response.total, page: response.meta?.page, pageSize: response.meta?.limit }, totalCount: response.total }; } const items = Array.isArray(response) ? response : []; return { items, pagination: { totalCount: items.length }, totalCount: items.length }; } async getProject(id) { const response = await this.http.get(`${this.basePath}/projects/${id}`); return response.item || null; } async createProject(request) { const response = await this.http.post(`${this.basePath}/projects`, request); return response.item || response; } async completeProject(id, completedBy, completionNotes) { const response = await this.http.post(`${this.basePath}/projects/${id}/complete`, { completedBy, completionNotes }); return response.item || response; } async deferProject(id) { const response = await this.http.post(`${this.basePath}/projects/${id}/defer`); return response.item || response; } async activateProject(id) { const response = await this.http.post(`${this.basePath}/projects/${id}/activate`); return response.item || response; } async cancelProject(id) { const response = await this.http.post(`${this.basePath}/projects/${id}/cancel`); return response.item || response; } async deleteProject(id) { await this.http.delete(`${this.basePath}/projects/${id}`); } // Next Action Operations async getNextActions(filters) { const queryParams = filters ? new URLSearchParams(Object.entries(filters).filter(([_, value]) => value !== void 0).reduce((acc, [key, value]) => ({ ...acc, [key]: String(value) }), {})).toString() : ""; const url = queryParams ? `${this.basePath}/actions?${queryParams}` : `${this.basePath}/actions`; const response = await this.http.get(url); if (response.items && response.total !== void 0) { return { items: response.items, pagination: { totalCount: response.total, page: response.meta?.page, pageSize: response.meta?.limit }, totalCount: response.total }; } const items = Array.isArray(response) ? response : []; return { items, pagination: { totalCount: items.length }, totalCount: items.length }; } async getNextAction(id) { const response = await this.http.get(`${this.basePath}/actions/${id}`); return response.item || null; } async createNextAction(request) { const response = await this.http.post(`${this.basePath}/actions`, request); return response.item || response; } async assignNextAction(id, request) { const response = await this.http.post(`${this.basePath}/actions/${id}/assign`, request); return response.item || response; } async unassignNextAction(id) { const response = await this.http.post(`${this.basePath}/actions/${id}/unassign`); return response.item || response; } async completeNextAction(id) { const response = await this.http.post(`${this.basePath}/actions/${id}/complete`); return response.item || response; } async deleteNextAction(id) { await this.http.delete(`${this.basePath}/actions/${id}`); } // Convenience methods that match the existing frontend API async getActionsByProject(projectId) { return this.getNextActions({ projectId }); } async getActionsByContext(context) { return this.getNextActions({ context }); } async getContexts() { const response = await this.http.get(`${this.basePath}/contexts`); const contexts = Array.isArray(response) ? response : []; return { items: contexts, pagination: { totalCount: contexts.length }, totalCount: contexts.length }; } // Weekly Review async getWeeklyReview(reviewedBy) { const queryParams = new URLSearchParams({ reviewedBy }).toString(); const response = await this.http.get(`${this.basePath}/weekly-review?${queryParams}`, { headers: { "Content-Type": "application/json" } }); return response.review || response; } }; export { GTDClient }; //# sourceMappingURL=chunk-KWIF3JSN.mjs.map