harper-kb 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +288 -0
- package/config.yaml +13 -0
- package/dist/core/embeddings.d.ts +31 -0
- package/dist/core/embeddings.d.ts.map +1 -0
- package/dist/core/embeddings.js +199 -0
- package/dist/core/embeddings.js.map +1 -0
- package/dist/core/entries.d.ts +101 -0
- package/dist/core/entries.d.ts.map +1 -0
- package/dist/core/entries.js +304 -0
- package/dist/core/entries.js.map +1 -0
- package/dist/core/history.d.ts +31 -0
- package/dist/core/history.d.ts.map +1 -0
- package/dist/core/history.js +119 -0
- package/dist/core/history.js.map +1 -0
- package/dist/core/knowledge-base.d.ts +49 -0
- package/dist/core/knowledge-base.d.ts.map +1 -0
- package/dist/core/knowledge-base.js +117 -0
- package/dist/core/knowledge-base.js.map +1 -0
- package/dist/core/search.d.ts +34 -0
- package/dist/core/search.d.ts.map +1 -0
- package/dist/core/search.js +327 -0
- package/dist/core/search.js.map +1 -0
- package/dist/core/tags.d.ts +39 -0
- package/dist/core/tags.d.ts.map +1 -0
- package/dist/core/tags.js +97 -0
- package/dist/core/tags.js.map +1 -0
- package/dist/core/triage.d.ts +61 -0
- package/dist/core/triage.d.ts.map +1 -0
- package/dist/core/triage.js +136 -0
- package/dist/core/triage.js.map +1 -0
- package/dist/core/webhook-endpoints.d.ts +46 -0
- package/dist/core/webhook-endpoints.d.ts.map +1 -0
- package/dist/core/webhook-endpoints.js +85 -0
- package/dist/core/webhook-endpoints.js.map +1 -0
- package/dist/hooks.d.ts +67 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +53 -0
- package/dist/hooks.js.map +1 -0
- package/dist/http-utils.d.ts +38 -0
- package/dist/http-utils.d.ts.map +1 -0
- package/dist/http-utils.js +133 -0
- package/dist/http-utils.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/protocol.d.ts +25 -0
- package/dist/mcp/protocol.d.ts.map +1 -0
- package/dist/mcp/protocol.js +105 -0
- package/dist/mcp/protocol.js.map +1 -0
- package/dist/mcp/server.d.ts +28 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +144 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +26 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +706 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/oauth/authorize.d.ts +28 -0
- package/dist/oauth/authorize.d.ts.map +1 -0
- package/dist/oauth/authorize.js +421 -0
- package/dist/oauth/authorize.js.map +1 -0
- package/dist/oauth/init.d.ts +18 -0
- package/dist/oauth/init.d.ts.map +1 -0
- package/dist/oauth/init.js +30 -0
- package/dist/oauth/init.js.map +1 -0
- package/dist/oauth/keys.d.ts +34 -0
- package/dist/oauth/keys.d.ts.map +1 -0
- package/dist/oauth/keys.js +101 -0
- package/dist/oauth/keys.js.map +1 -0
- package/dist/oauth/metadata.d.ts +23 -0
- package/dist/oauth/metadata.d.ts.map +1 -0
- package/dist/oauth/metadata.js +57 -0
- package/dist/oauth/metadata.js.map +1 -0
- package/dist/oauth/middleware.d.ts +23 -0
- package/dist/oauth/middleware.d.ts.map +1 -0
- package/dist/oauth/middleware.js +65 -0
- package/dist/oauth/middleware.js.map +1 -0
- package/dist/oauth/register.d.ts +15 -0
- package/dist/oauth/register.d.ts.map +1 -0
- package/dist/oauth/register.js +78 -0
- package/dist/oauth/register.js.map +1 -0
- package/dist/oauth/token.d.ts +16 -0
- package/dist/oauth/token.d.ts.map +1 -0
- package/dist/oauth/token.js +184 -0
- package/dist/oauth/token.js.map +1 -0
- package/dist/oauth/validate.d.ts +40 -0
- package/dist/oauth/validate.d.ts.map +1 -0
- package/dist/oauth/validate.js +61 -0
- package/dist/oauth/validate.js.map +1 -0
- package/dist/resources/HistoryResource.d.ts +41 -0
- package/dist/resources/HistoryResource.d.ts.map +1 -0
- package/dist/resources/HistoryResource.js +61 -0
- package/dist/resources/HistoryResource.js.map +1 -0
- package/dist/resources/KnowledgeBaseResource.d.ts +60 -0
- package/dist/resources/KnowledgeBaseResource.d.ts.map +1 -0
- package/dist/resources/KnowledgeBaseResource.js +118 -0
- package/dist/resources/KnowledgeBaseResource.js.map +1 -0
- package/dist/resources/KnowledgeEntryResource.d.ts +61 -0
- package/dist/resources/KnowledgeEntryResource.d.ts.map +1 -0
- package/dist/resources/KnowledgeEntryResource.js +191 -0
- package/dist/resources/KnowledgeEntryResource.js.map +1 -0
- package/dist/resources/MeResource.d.ts +31 -0
- package/dist/resources/MeResource.d.ts.map +1 -0
- package/dist/resources/MeResource.js +40 -0
- package/dist/resources/MeResource.js.map +1 -0
- package/dist/resources/QueryLogResource.d.ts +22 -0
- package/dist/resources/QueryLogResource.d.ts.map +1 -0
- package/dist/resources/QueryLogResource.js +66 -0
- package/dist/resources/QueryLogResource.js.map +1 -0
- package/dist/resources/ServiceKeyResource.d.ts +52 -0
- package/dist/resources/ServiceKeyResource.d.ts.map +1 -0
- package/dist/resources/ServiceKeyResource.js +151 -0
- package/dist/resources/ServiceKeyResource.js.map +1 -0
- package/dist/resources/TagResource.d.ts +27 -0
- package/dist/resources/TagResource.d.ts.map +1 -0
- package/dist/resources/TagResource.js +41 -0
- package/dist/resources/TagResource.js.map +1 -0
- package/dist/resources/TriageResource.d.ts +53 -0
- package/dist/resources/TriageResource.d.ts.map +1 -0
- package/dist/resources/TriageResource.js +120 -0
- package/dist/resources/TriageResource.js.map +1 -0
- package/dist/resources/WebhookEndpointResource.d.ts +63 -0
- package/dist/resources/WebhookEndpointResource.d.ts.map +1 -0
- package/dist/resources/WebhookEndpointResource.js +115 -0
- package/dist/resources/WebhookEndpointResource.js.map +1 -0
- package/dist/types.d.ts +378 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/webhooks/github.d.ts +25 -0
- package/dist/webhooks/github.d.ts.map +1 -0
- package/dist/webhooks/github.js +165 -0
- package/dist/webhooks/github.js.map +1 -0
- package/dist/webhooks/middleware.d.ts +19 -0
- package/dist/webhooks/middleware.d.ts.map +1 -0
- package/dist/webhooks/middleware.js +144 -0
- package/dist/webhooks/middleware.js.map +1 -0
- package/dist/webhooks/types.d.ts +18 -0
- package/dist/webhooks/types.d.ts.map +1 -0
- package/dist/webhooks/types.js +5 -0
- package/dist/webhooks/types.js.map +1 -0
- package/package.json +69 -0
- package/schema/knowledge.graphql +136 -0
- package/schema/oauth.graphql +45 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Webhook Handler
|
|
3
|
+
*
|
|
4
|
+
* Validates GitHub webhook signatures (HMAC-SHA256) and parses payloads
|
|
5
|
+
* for issues, issue comments, discussions, and discussion comments.
|
|
6
|
+
*/
|
|
7
|
+
import type { WebhookResult } from './types.ts';
|
|
8
|
+
/**
|
|
9
|
+
* Validate a GitHub webhook signature using HMAC-SHA256.
|
|
10
|
+
*
|
|
11
|
+
* @param rawBody - The raw request body string
|
|
12
|
+
* @param signature - The X-Hub-Signature-256 header value
|
|
13
|
+
* @param secret - The configured webhook secret
|
|
14
|
+
* @returns true if the signature is valid
|
|
15
|
+
*/
|
|
16
|
+
export declare function validateSignature(rawBody: string, signature: string, secret: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Parse a GitHub webhook payload and extract a triage-ready result.
|
|
19
|
+
*
|
|
20
|
+
* @param event - The X-GitHub-Event header value
|
|
21
|
+
* @param payload - The parsed JSON payload
|
|
22
|
+
* @returns A WebhookResult for triage, or null if the event should be ignored
|
|
23
|
+
*/
|
|
24
|
+
export declare function parsePayload(event: string, payload: Record<string, any>): WebhookResult | null;
|
|
25
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/webhooks/github.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKhD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAQ7F;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,aAAa,GAAG,IAAI,CAa9F"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Webhook Handler
|
|
3
|
+
*
|
|
4
|
+
* Validates GitHub webhook signatures (HMAC-SHA256) and parses payloads
|
|
5
|
+
* for issues, issue comments, discussions, and discussion comments.
|
|
6
|
+
*/
|
|
7
|
+
import crypto from 'node:crypto';
|
|
8
|
+
/** Maximum body length included in the summary */
|
|
9
|
+
const MAX_BODY_LENGTH = 500;
|
|
10
|
+
/**
|
|
11
|
+
* Validate a GitHub webhook signature using HMAC-SHA256.
|
|
12
|
+
*
|
|
13
|
+
* @param rawBody - The raw request body string
|
|
14
|
+
* @param signature - The X-Hub-Signature-256 header value
|
|
15
|
+
* @param secret - The configured webhook secret
|
|
16
|
+
* @returns true if the signature is valid
|
|
17
|
+
*/
|
|
18
|
+
export function validateSignature(rawBody, signature, secret) {
|
|
19
|
+
if (!signature || !secret)
|
|
20
|
+
return false;
|
|
21
|
+
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
|
|
22
|
+
// Constant-time comparison to prevent timing attacks
|
|
23
|
+
if (expected.length !== signature.length)
|
|
24
|
+
return false;
|
|
25
|
+
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse a GitHub webhook payload and extract a triage-ready result.
|
|
29
|
+
*
|
|
30
|
+
* @param event - The X-GitHub-Event header value
|
|
31
|
+
* @param payload - The parsed JSON payload
|
|
32
|
+
* @returns A WebhookResult for triage, or null if the event should be ignored
|
|
33
|
+
*/
|
|
34
|
+
export function parsePayload(event, payload) {
|
|
35
|
+
switch (event) {
|
|
36
|
+
case 'issues':
|
|
37
|
+
return parseIssueEvent(payload);
|
|
38
|
+
case 'issue_comment':
|
|
39
|
+
return parseIssueCommentEvent(payload);
|
|
40
|
+
case 'discussion':
|
|
41
|
+
return parseDiscussionEvent(payload);
|
|
42
|
+
case 'discussion_comment':
|
|
43
|
+
return parseDiscussionCommentEvent(payload);
|
|
44
|
+
default:
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function parseIssueEvent(payload) {
|
|
49
|
+
const action = payload.action;
|
|
50
|
+
const issue = payload.issue;
|
|
51
|
+
const repo = payload.repository?.full_name;
|
|
52
|
+
if (!issue || !repo)
|
|
53
|
+
return null;
|
|
54
|
+
// Only handle opened, closed, reopened
|
|
55
|
+
const directActions = ['opened', 'closed', 'reopened'];
|
|
56
|
+
if (directActions.includes(action)) {
|
|
57
|
+
return {
|
|
58
|
+
source: 'github-webhook',
|
|
59
|
+
sourceId: `github:issues:${action}:${repo}#${issue.number}`,
|
|
60
|
+
summary: formatIssueSummary(repo, issue, action),
|
|
61
|
+
rawPayload: payload,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Handle labeled — only if the label is "kb-candidate"
|
|
65
|
+
if (action === 'labeled') {
|
|
66
|
+
const label = payload.label;
|
|
67
|
+
if (label?.name === 'kb-candidate') {
|
|
68
|
+
return {
|
|
69
|
+
source: 'github-webhook',
|
|
70
|
+
sourceId: `github:issues:labeled:${repo}#${issue.number}`,
|
|
71
|
+
summary: formatIssueSummary(repo, issue, 'labeled'),
|
|
72
|
+
rawPayload: payload,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
function parseIssueCommentEvent(payload) {
|
|
80
|
+
const action = payload.action;
|
|
81
|
+
if (action !== 'created')
|
|
82
|
+
return null;
|
|
83
|
+
const comment = payload.comment;
|
|
84
|
+
const issue = payload.issue;
|
|
85
|
+
const repo = payload.repository?.full_name;
|
|
86
|
+
if (!comment || !issue || !repo)
|
|
87
|
+
return null;
|
|
88
|
+
const body = truncate(comment.body || '');
|
|
89
|
+
const summary = [
|
|
90
|
+
`[GitHub Comment] ${repo}#${issue.number}: "${issue.title}" (comment by ${comment.user?.login || 'unknown'})`,
|
|
91
|
+
'---',
|
|
92
|
+
body,
|
|
93
|
+
].join('\n');
|
|
94
|
+
return {
|
|
95
|
+
source: 'github-webhook',
|
|
96
|
+
sourceId: `github:issue_comment:${comment.id}`,
|
|
97
|
+
summary,
|
|
98
|
+
rawPayload: payload,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function parseDiscussionEvent(payload) {
|
|
102
|
+
const action = payload.action;
|
|
103
|
+
if (action !== 'created' && action !== 'answered')
|
|
104
|
+
return null;
|
|
105
|
+
const discussion = payload.discussion;
|
|
106
|
+
const repo = payload.repository?.full_name;
|
|
107
|
+
if (!discussion || !repo)
|
|
108
|
+
return null;
|
|
109
|
+
const body = truncate(discussion.body || '');
|
|
110
|
+
const category = discussion.category?.name;
|
|
111
|
+
const summary = [
|
|
112
|
+
`[GitHub Discussion] ${repo}#${discussion.number}: "${discussion.title}" (${action} by ${discussion.user?.login || 'unknown'})`,
|
|
113
|
+
category ? `Category: ${category}` : '',
|
|
114
|
+
'---',
|
|
115
|
+
body,
|
|
116
|
+
]
|
|
117
|
+
.filter(Boolean)
|
|
118
|
+
.join('\n');
|
|
119
|
+
return {
|
|
120
|
+
source: 'github-webhook',
|
|
121
|
+
sourceId: `github:discussion:${action}:${repo}#${discussion.number}`,
|
|
122
|
+
summary,
|
|
123
|
+
rawPayload: payload,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function parseDiscussionCommentEvent(payload) {
|
|
127
|
+
const action = payload.action;
|
|
128
|
+
if (action !== 'created')
|
|
129
|
+
return null;
|
|
130
|
+
const comment = payload.comment;
|
|
131
|
+
const discussion = payload.discussion;
|
|
132
|
+
const repo = payload.repository?.full_name;
|
|
133
|
+
if (!comment || !discussion || !repo)
|
|
134
|
+
return null;
|
|
135
|
+
const body = truncate(comment.body || '');
|
|
136
|
+
const summary = [
|
|
137
|
+
`[GitHub Discussion Comment] ${repo}#${discussion.number}: "${discussion.title}" (comment by ${comment.user?.login || 'unknown'})`,
|
|
138
|
+
'---',
|
|
139
|
+
body,
|
|
140
|
+
].join('\n');
|
|
141
|
+
return {
|
|
142
|
+
source: 'github-webhook',
|
|
143
|
+
sourceId: `github:discussion_comment:${comment.id}`,
|
|
144
|
+
summary,
|
|
145
|
+
rawPayload: payload,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function formatIssueSummary(repo, issue, action) {
|
|
149
|
+
const labels = (issue.labels || []).map((l) => l.name).join(', ');
|
|
150
|
+
const body = truncate(issue.body || '');
|
|
151
|
+
const parts = [
|
|
152
|
+
`[GitHub Issue] ${repo}#${issue.number}: "${issue.title}" (${action} by ${issue.user?.login || 'unknown'})`,
|
|
153
|
+
];
|
|
154
|
+
if (labels)
|
|
155
|
+
parts.push(`Labels: ${labels}`);
|
|
156
|
+
parts.push('---');
|
|
157
|
+
parts.push(body);
|
|
158
|
+
return parts.join('\n');
|
|
159
|
+
}
|
|
160
|
+
function truncate(text) {
|
|
161
|
+
if (text.length <= MAX_BODY_LENGTH)
|
|
162
|
+
return text;
|
|
163
|
+
return text.slice(0, MAX_BODY_LENGTH) + '...';
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/webhooks/github.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,kDAAkD;AAClD,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,SAAiB,EAAE,MAAc;IACnF,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAExC,MAAM,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAE/F,qDAAqD;IACrD,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACvD,OAAO,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,OAA4B;IACvE,QAAQ,KAAK,EAAE,CAAC;QACf,KAAK,QAAQ;YACZ,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;QACjC,KAAK,eAAe;YACnB,OAAO,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACxC,KAAK,YAAY;YAChB,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACtC,KAAK,oBAAoB;YACxB,OAAO,2BAA2B,CAAC,OAAO,CAAC,CAAC;QAC7C;YACC,OAAO,IAAI,CAAC;IACd,CAAC;AACF,CAAC;AAED,SAAS,eAAe,CAAC,OAA4B;IACpD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC;IAE3C,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEjC,uCAAuC;IACvC,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACvD,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO;YACN,MAAM,EAAE,gBAAgB;YACxB,QAAQ,EAAE,iBAAiB,MAAM,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE;YAC3D,OAAO,EAAE,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC;YAChD,UAAU,EAAE,OAAO;SACnB,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,IAAI,KAAK,EAAE,IAAI,KAAK,cAAc,EAAE,CAAC;YACpC,OAAO;gBACN,MAAM,EAAE,gBAAgB;gBACxB,QAAQ,EAAE,yBAAyB,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE;gBACzD,OAAO,EAAE,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC;gBACnD,UAAU,EAAE,OAAO;aACnB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,sBAAsB,CAAC,OAA4B;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEtC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAChC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC;IAE3C,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAE7C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG;QACf,oBAAoB,IAAI,IAAI,KAAK,CAAC,MAAM,MAAM,KAAK,CAAC,KAAK,iBAAiB,OAAO,CAAC,IAAI,EAAE,KAAK,IAAI,SAAS,GAAG;QAC7G,KAAK;QACL,IAAI;KACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO;QACN,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,wBAAwB,OAAO,CAAC,EAAE,EAAE;QAC9C,OAAO;QACP,UAAU,EAAE,OAAO;KACnB,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,OAA4B;IACzD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAE/D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC;IAE3C,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEtC,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC;IAC3C,MAAM,OAAO,GAAG;QACf,uBAAuB,IAAI,IAAI,UAAU,CAAC,MAAM,MAAM,UAAU,CAAC,KAAK,MAAM,MAAM,OAAO,UAAU,CAAC,IAAI,EAAE,KAAK,IAAI,SAAS,GAAG;QAC/H,QAAQ,CAAC,CAAC,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;QACvC,KAAK;QACL,IAAI;KACJ;SACC,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO;QACN,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,qBAAqB,MAAM,IAAI,IAAI,IAAI,UAAU,CAAC,MAAM,EAAE;QACpE,OAAO;QACP,UAAU,EAAE,OAAO;KACnB,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B,CAAC,OAA4B;IAChE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEtC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAChC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC;IAE3C,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAElD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG;QACf,+BAA+B,IAAI,IAAI,UAAU,CAAC,MAAM,MAAM,UAAU,CAAC,KAAK,iBAAiB,OAAO,CAAC,IAAI,EAAE,KAAK,IAAI,SAAS,GAAG;QAClI,KAAK;QACL,IAAI;KACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO;QACN,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,6BAA6B,OAAO,CAAC,EAAE,EAAE;QACnD,OAAO;QACP,UAAU,EAAE,OAAO;KACnB,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY,EAAE,KAA0B,EAAE,MAAc;IACnF,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAsB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvF,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAExC,MAAM,KAAK,GAAG;QACb,kBAAkB,IAAI,IAAI,KAAK,CAAC,MAAM,MAAM,KAAK,CAAC,KAAK,MAAM,MAAM,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,SAAS,GAAG;KAC3G,CAAC;IACF,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC7B,IAAI,IAAI,CAAC,MAAM,IAAI,eAAe;QAAE,OAAO,IAAI,CAAC;IAChD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Middleware
|
|
3
|
+
*
|
|
4
|
+
* HTTP middleware for Harper's scope.server.http() that routes
|
|
5
|
+
* /webhooks/<kbId>/<provider>/<secret> requests to the appropriate
|
|
6
|
+
* webhook handler after validating the per-KB secret.
|
|
7
|
+
*/
|
|
8
|
+
import type { Scope, HarperRequest } from '../types.ts';
|
|
9
|
+
/**
|
|
10
|
+
* Create a webhook middleware function for Harper's scope.server.http().
|
|
11
|
+
*
|
|
12
|
+
* URL format: /webhooks/<kbId>/<provider>/<secret>
|
|
13
|
+
*
|
|
14
|
+
* The secret is validated against the WebhookEndpoint table for the
|
|
15
|
+
* given KB and provider. The same secret is used to verify the GitHub
|
|
16
|
+
* HMAC payload signature.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createWebhookMiddleware(scope: Scope): (request: HarperRequest, next: (req: HarperRequest) => Promise<unknown>) => Promise<unknown>;
|
|
19
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/webhooks/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAcxD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACtC,KAAK,EAAE,KAAK,GACV,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAyC9F"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Middleware
|
|
3
|
+
*
|
|
4
|
+
* HTTP middleware for Harper's scope.server.http() that routes
|
|
5
|
+
* /webhooks/<kbId>/<provider>/<secret> requests to the appropriate
|
|
6
|
+
* webhook handler after validating the per-KB secret.
|
|
7
|
+
*/
|
|
8
|
+
import { readBody } from "../http-utils.js";
|
|
9
|
+
import { submitTriage, findBySourceId } from "../core/triage.js";
|
|
10
|
+
import { validateWebhookSecret } from "../core/webhook-endpoints.js";
|
|
11
|
+
import { validateSignature as validateGitHubSignature, parsePayload as parseGitHubPayload } from "./github.js";
|
|
12
|
+
/**
|
|
13
|
+
* Check if a delivery ID has already been processed, using a TTL table
|
|
14
|
+
* so dedup is consistent across all workers.
|
|
15
|
+
*/
|
|
16
|
+
async function isDuplicateDelivery(deliveryId, kbId, provider) {
|
|
17
|
+
const existing = await databases.kb.WebhookDelivery.get(deliveryId);
|
|
18
|
+
if (existing)
|
|
19
|
+
return true;
|
|
20
|
+
await databases.kb.WebhookDelivery.put({ id: deliveryId, kbId, provider });
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a webhook middleware function for Harper's scope.server.http().
|
|
25
|
+
*
|
|
26
|
+
* URL format: /webhooks/<kbId>/<provider>/<secret>
|
|
27
|
+
*
|
|
28
|
+
* The secret is validated against the WebhookEndpoint table for the
|
|
29
|
+
* given KB and provider. The same secret is used to verify the GitHub
|
|
30
|
+
* HMAC payload signature.
|
|
31
|
+
*/
|
|
32
|
+
export function createWebhookMiddleware(scope) {
|
|
33
|
+
const scopeLogger = scope.logger;
|
|
34
|
+
return async (request, next) => {
|
|
35
|
+
const pathname = request.pathname || '';
|
|
36
|
+
// Only handle /webhooks/* routes
|
|
37
|
+
if (!pathname.startsWith('/webhooks/')) {
|
|
38
|
+
return next(request);
|
|
39
|
+
}
|
|
40
|
+
// Only accept POST
|
|
41
|
+
if (request.method !== 'POST') {
|
|
42
|
+
return jsonResponse(405, { error: 'Method not allowed' });
|
|
43
|
+
}
|
|
44
|
+
// Extract kbId, provider, and secret from path:
|
|
45
|
+
// /webhooks/<kbId>/<provider>/<secret>
|
|
46
|
+
const parts = pathname.replace(/^\/webhooks\//, '').split('/');
|
|
47
|
+
if (parts.length < 3 || !parts[0] || !parts[1] || !parts[2]) {
|
|
48
|
+
return jsonResponse(400, {
|
|
49
|
+
error: 'Invalid webhook path. Use /webhooks/<kbId>/<provider>/<secret>',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
const kbId = parts[0];
|
|
53
|
+
const provider = parts[1];
|
|
54
|
+
const secret = parts[2];
|
|
55
|
+
// Validate the secret against the WebhookEndpoint table
|
|
56
|
+
const endpoint = await validateWebhookSecret(secret, kbId, provider);
|
|
57
|
+
if (!endpoint) {
|
|
58
|
+
return jsonResponse(404, { error: 'Unknown webhook endpoint' });
|
|
59
|
+
}
|
|
60
|
+
// Route to the appropriate handler
|
|
61
|
+
if (provider === 'github') {
|
|
62
|
+
return handleGitHub(request, secret, kbId, scopeLogger);
|
|
63
|
+
}
|
|
64
|
+
return jsonResponse(404, { error: 'Unknown webhook provider' });
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async function handleGitHub(request, secret, kbId, scopeLogger) {
|
|
68
|
+
// Read raw body
|
|
69
|
+
const rawBody = await readBody(request);
|
|
70
|
+
// Validate HMAC signature using the secret from the URL
|
|
71
|
+
const signature = getHeader(request, 'x-hub-signature-256');
|
|
72
|
+
if (!validateGitHubSignature(rawBody, signature, secret)) {
|
|
73
|
+
return jsonResponse(401, { error: 'Invalid signature' });
|
|
74
|
+
}
|
|
75
|
+
// Replay protection — reject duplicate delivery IDs
|
|
76
|
+
const deliveryId = getHeader(request, 'x-github-delivery');
|
|
77
|
+
if (deliveryId && (await isDuplicateDelivery(deliveryId, kbId, 'github'))) {
|
|
78
|
+
return jsonResponse(200, { status: 'duplicate', deliveryId });
|
|
79
|
+
}
|
|
80
|
+
// Parse payload
|
|
81
|
+
let payload;
|
|
82
|
+
try {
|
|
83
|
+
payload = JSON.parse(rawBody);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return jsonResponse(400, { error: 'Invalid JSON' });
|
|
87
|
+
}
|
|
88
|
+
const event = getHeader(request, 'x-github-event');
|
|
89
|
+
const result = parseGitHubPayload(event, payload);
|
|
90
|
+
if (!result) {
|
|
91
|
+
// Event type we don't handle — acknowledge without creating triage item
|
|
92
|
+
return jsonResponse(200, { status: 'ignored' });
|
|
93
|
+
}
|
|
94
|
+
return submitResult(kbId, result, scopeLogger);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Submit a webhook result to the triage queue, checking for duplicates first.
|
|
98
|
+
*/
|
|
99
|
+
async function submitResult(kbId, result, scopeLogger) {
|
|
100
|
+
// Idempotency check
|
|
101
|
+
const existing = await findBySourceId(kbId, result.sourceId);
|
|
102
|
+
if (existing) {
|
|
103
|
+
return jsonResponse(200, { status: 'duplicate', triageId: existing.id });
|
|
104
|
+
}
|
|
105
|
+
const item = await submitTriage(kbId, result.source, result.summary, result.rawPayload, result.sourceId);
|
|
106
|
+
scopeLogger?.info?.(`Webhook triage item created: ${item.id} (${result.source})`);
|
|
107
|
+
return jsonResponse(200, { status: 'accepted', triageId: item.id });
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get a header value from Harper's request, case-insensitive.
|
|
111
|
+
*/
|
|
112
|
+
function getHeader(request, name) {
|
|
113
|
+
const headers = request.headers;
|
|
114
|
+
if (!headers)
|
|
115
|
+
return '';
|
|
116
|
+
// Try direct access (case-sensitive)
|
|
117
|
+
const direct = headers[name] ?? headers[name.toLowerCase()];
|
|
118
|
+
if (direct !== undefined) {
|
|
119
|
+
return Array.isArray(direct) ? direct[0] : String(direct);
|
|
120
|
+
}
|
|
121
|
+
// Try .get() method (Harper's Headers class)
|
|
122
|
+
if (typeof headers.get === 'function') {
|
|
123
|
+
const val = headers.get(name);
|
|
124
|
+
if (val !== undefined && val !== null)
|
|
125
|
+
return String(val);
|
|
126
|
+
}
|
|
127
|
+
// Fallback: iterate to find case-insensitive match
|
|
128
|
+
const lowerName = name.toLowerCase();
|
|
129
|
+
if (typeof headers === 'object') {
|
|
130
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
131
|
+
if (key.toLowerCase() === lowerName && value !== undefined) {
|
|
132
|
+
return Array.isArray(value) ? value[0] : String(value);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return '';
|
|
137
|
+
}
|
|
138
|
+
function jsonResponse(status, body) {
|
|
139
|
+
return new Response(JSON.stringify(body), {
|
|
140
|
+
status,
|
|
141
|
+
headers: { 'Content-Type': 'application/json' },
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/webhooks/middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for webhook handlers.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Result from parsing a webhook payload.
|
|
6
|
+
* Returned by webhook handlers for the middleware to submit to triage.
|
|
7
|
+
*/
|
|
8
|
+
export interface WebhookResult {
|
|
9
|
+
/** Source identifier (e.g., "github-webhook") */
|
|
10
|
+
source: string;
|
|
11
|
+
/** Deduplication key for idempotency */
|
|
12
|
+
sourceId: string;
|
|
13
|
+
/** Human-readable summary for triage review */
|
|
14
|
+
summary: string;
|
|
15
|
+
/** Original raw payload */
|
|
16
|
+
rawPayload: unknown;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/webhooks/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,UAAU,EAAE,OAAO,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/webhooks/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "harper-kb",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Knowledge base plugin for Harper with MCP server integration",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./config": "./config.yaml"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"dev": "tsc --watch",
|
|
18
|
+
"test": "npm run build && node --test \"test/**/*.test.js\"",
|
|
19
|
+
"test:watch": "npm run build && node --test --watch \"test/**/*.test.js\"",
|
|
20
|
+
"test:coverage": "npm run build && node --enable-source-maps --test --experimental-test-coverage --test-coverage-exclude='test/**' --test-coverage-exclude='**/harperdb/**' \"test/**/*.test.js\"",
|
|
21
|
+
"lint": "oxlint --deny-warnings .",
|
|
22
|
+
"lint:fix": "oxlint --deny-warnings --fix .",
|
|
23
|
+
"format": "prettier --write .",
|
|
24
|
+
"format:check": "prettier --check .",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"harper",
|
|
29
|
+
"harperdb",
|
|
30
|
+
"plugin",
|
|
31
|
+
"knowledge-base",
|
|
32
|
+
"mcp",
|
|
33
|
+
"ai",
|
|
34
|
+
"embeddings",
|
|
35
|
+
"vector-search"
|
|
36
|
+
],
|
|
37
|
+
"author": "Nathan Heskew <nathan@heskew.dev> (https://heskew.dev)",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/heskew/harper-kb"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"jose": "^6.1.3"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@harperdb/code-guidelines": "^0.0.6",
|
|
48
|
+
"@types/node": "^22.0.0",
|
|
49
|
+
"oxlint": "^1.31.0",
|
|
50
|
+
"prettier": "^3.7.0",
|
|
51
|
+
"typescript": "^5.7.0"
|
|
52
|
+
},
|
|
53
|
+
"optionalDependencies": {
|
|
54
|
+
"harper-fabric-embeddings": "^0.1.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"harperdb": ">=4.7.0"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=22"
|
|
61
|
+
},
|
|
62
|
+
"files": [
|
|
63
|
+
"dist",
|
|
64
|
+
"schema",
|
|
65
|
+
"config.yaml",
|
|
66
|
+
"README.md",
|
|
67
|
+
"LICENSE"
|
|
68
|
+
]
|
|
69
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
## Knowledge Base Plugin Schema
|
|
2
|
+
## Defines all tables for the knowledge base in the "kb" database
|
|
3
|
+
|
|
4
|
+
## Knowledge base registry — one record per tenant
|
|
5
|
+
type KnowledgeBase @table(database: "kb") @export {
|
|
6
|
+
id: ID @primaryKey
|
|
7
|
+
name: String
|
|
8
|
+
description: String
|
|
9
|
+
settings: Any
|
|
10
|
+
createdBy: String
|
|
11
|
+
createdAt: Date @createdTime
|
|
12
|
+
updatedAt: Date @updatedTime
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
## Core knowledge entries with vector embeddings for semantic search
|
|
16
|
+
type KnowledgeEntry @table(database: "kb") @export {
|
|
17
|
+
id: ID @primaryKey
|
|
18
|
+
kbId: ID @indexed
|
|
19
|
+
kb: KnowledgeBase @relationship(from: "kbId")
|
|
20
|
+
title: String @indexed
|
|
21
|
+
content: String
|
|
22
|
+
tags: [String]
|
|
23
|
+
appliesTo: Any
|
|
24
|
+
source: String
|
|
25
|
+
sourceUrl: String
|
|
26
|
+
references: Any
|
|
27
|
+
confidence: String @indexed
|
|
28
|
+
addedBy: String
|
|
29
|
+
reviewedBy: String
|
|
30
|
+
embedding: [Float] @indexed(type: "HNSW", distance: "cosine")
|
|
31
|
+
supersedesId: ID
|
|
32
|
+
supersedes: KnowledgeEntry @relationship(from: "supersedesId")
|
|
33
|
+
supersededById: ID
|
|
34
|
+
supersededBy: KnowledgeEntry @relationship(from: "supersededById")
|
|
35
|
+
siblingIds: [ID]
|
|
36
|
+
siblings: [KnowledgeEntry] @relationship(from: "siblingIds")
|
|
37
|
+
relatedIds: [ID]
|
|
38
|
+
relatedEntries: [KnowledgeEntry] @relationship(from: "relatedIds")
|
|
39
|
+
metadata: Any
|
|
40
|
+
deprecated: Boolean @indexed
|
|
41
|
+
createdAt: Date @createdTime
|
|
42
|
+
updatedAt: Date @updatedTime
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
## Webhook intake queue for new knowledge submissions
|
|
46
|
+
## 7-day TTL (604800 seconds)
|
|
47
|
+
type TriageItem @table(database: "kb", expiration: 604800) {
|
|
48
|
+
id: ID @primaryKey
|
|
49
|
+
kbId: ID @indexed
|
|
50
|
+
kb: KnowledgeBase @relationship(from: "kbId")
|
|
51
|
+
source: String @indexed
|
|
52
|
+
sourceId: String @indexed
|
|
53
|
+
rawPayload: Any
|
|
54
|
+
summary: String
|
|
55
|
+
status: String @indexed
|
|
56
|
+
matchedEntryId: ID
|
|
57
|
+
matchedEntry: KnowledgeEntry @relationship(from: "matchedEntryId")
|
|
58
|
+
draftEntryId: ID
|
|
59
|
+
draftEntry: KnowledgeEntry @relationship(from: "draftEntryId")
|
|
60
|
+
action: String
|
|
61
|
+
processedBy: String
|
|
62
|
+
createdAt: Date @createdTime
|
|
63
|
+
processedAt: Date
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
## Tag registry with descriptions and usage counts
|
|
67
|
+
type KnowledgeTag @table(database: "kb") {
|
|
68
|
+
id: ID @primaryKey
|
|
69
|
+
kbId: ID @indexed
|
|
70
|
+
kb: KnowledgeBase @relationship(from: "kbId")
|
|
71
|
+
description: String
|
|
72
|
+
entryCount: Int
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
## Search query analytics log
|
|
76
|
+
## 30-day TTL (2592000 seconds)
|
|
77
|
+
type QueryLog @table(database: "kb", expiration: 2592000) {
|
|
78
|
+
id: ID @primaryKey
|
|
79
|
+
kbId: ID @indexed
|
|
80
|
+
kb: KnowledgeBase @relationship(from: "kbId")
|
|
81
|
+
query: String
|
|
82
|
+
context: Any
|
|
83
|
+
source: String
|
|
84
|
+
resultCount: Int
|
|
85
|
+
topResultId: ID
|
|
86
|
+
topResult: KnowledgeEntry @relationship(from: "topResultId")
|
|
87
|
+
createdAt: Date @createdTime
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
## API keys for webhooks and service accounts
|
|
91
|
+
type ServiceKey @table(database: "kb") {
|
|
92
|
+
id: ID @primaryKey
|
|
93
|
+
kbId: ID @indexed
|
|
94
|
+
kb: KnowledgeBase @relationship(from: "kbId")
|
|
95
|
+
name: String
|
|
96
|
+
keyHash: String
|
|
97
|
+
role: String
|
|
98
|
+
permissions: Any
|
|
99
|
+
createdBy: String
|
|
100
|
+
createdAt: Date @createdTime
|
|
101
|
+
lastUsedAt: Date
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
## Webhook delivery dedup — id is the delivery ID from the provider
|
|
105
|
+
## 1-hour TTL (3600 seconds) — enough to catch replays, auto-cleans
|
|
106
|
+
type WebhookDelivery @table(database: "kb", expiration: 3600) {
|
|
107
|
+
id: ID @primaryKey
|
|
108
|
+
kbId: String
|
|
109
|
+
provider: String
|
|
110
|
+
createdAt: Date @createdTime
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
## Webhook endpoint secrets — one per KB+provider, id = SHA-256(secret)
|
|
114
|
+
type WebhookEndpoint @table(database: "kb") @export {
|
|
115
|
+
id: ID @primaryKey
|
|
116
|
+
kbId: ID @indexed
|
|
117
|
+
kb: KnowledgeBase @relationship(from: "kbId")
|
|
118
|
+
provider: String
|
|
119
|
+
label: String
|
|
120
|
+
createdBy: String
|
|
121
|
+
createdAt: Date @createdTime
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
## Edit history for knowledge entries — append-only audit log
|
|
125
|
+
type KnowledgeEntryEdit @table(database: "kb") {
|
|
126
|
+
id: ID @primaryKey
|
|
127
|
+
kbId: ID @indexed
|
|
128
|
+
kb: KnowledgeBase @relationship(from: "kbId")
|
|
129
|
+
entryId: ID @indexed
|
|
130
|
+
entry: KnowledgeEntry @relationship(from: "entryId")
|
|
131
|
+
editedBy: String @indexed
|
|
132
|
+
editSummary: String
|
|
133
|
+
previousSnapshot: Any
|
|
134
|
+
changedFields: [String]
|
|
135
|
+
createdAt: Date @createdTime
|
|
136
|
+
}
|