@cat-factory/node-server 0.6.0 → 0.7.2
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 -21
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -2
- package/dist/config.js.map +1 -1
- package/dist/container.d.ts +10 -1
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +133 -26
- package/dist/container.js.map +1 -1
- package/dist/db/schema.d.ts +362 -18
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +55 -14
- package/dist/db/schema.js.map +1 -1
- package/dist/execution/config.d.ts +0 -2
- package/dist/execution/config.d.ts.map +1 -1
- package/dist/execution/config.js +1 -2
- package/dist/execution/config.js.map +1 -1
- package/dist/execution/pgBossRunner.d.ts +0 -11
- package/dist/execution/pgBossRunner.d.ts.map +1 -1
- package/dist/execution/pgBossRunner.js +5 -45
- package/dist/execution/pgBossRunner.js.map +1 -1
- package/dist/notifications.d.ts +11 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.js +32 -0
- package/dist/notifications.js.map +1 -0
- package/dist/repositories/drizzle.d.ts +35 -13
- package/dist/repositories/drizzle.d.ts.map +1 -1
- package/dist/repositories/drizzle.js +177 -46
- package/dist/repositories/drizzle.js.map +1 -1
- package/dist/repositories/notifications.d.ts.map +1 -1
- package/dist/repositories/notifications.js +3 -0
- package/dist/repositories/notifications.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +8 -5
- package/dist/server.js.map +1 -1
- package/drizzle/20260624145108_volatile_the_renegades/migration.sql +4 -0
- package/drizzle/20260624145108_volatile_the_renegades/snapshot.json +9178 -0
- package/package.json +19 -14
- package/dist/tasks/JiraProvider.d.ts +0 -27
- package/dist/tasks/JiraProvider.d.ts.map +0 -1
- package/dist/tasks/JiraProvider.js +0 -79
- package/dist/tasks/JiraProvider.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LLM_WARNING_FINISH_REASONS } from '@cat-factory/kernel';
|
|
2
2
|
import { blockInsertValues, blockPatchToColumns, rowToBlock, rowToExecution, executionToDetail, rowToPipeline, rowToWorkspace, } from '@cat-factory/server';
|
|
3
3
|
import { and, desc, eq, gte, inArray, isNull, lt, or, sql } from 'drizzle-orm';
|
|
4
|
-
import { accountInvitations, accounts, agentRuns, blocks, consensusSessions, emailConnections, llmCallMetrics, memberships, mergeThresholdPresets,
|
|
4
|
+
import { accountInvitations, accounts, agentRuns, blocks, consensusSessions, datadogConnections, emailConnections, llmCallMetrics, memberships, mergeThresholdPresets, releaseHealthConfigs, pipelineScheduleRuns, pipelineSchedules, pipelines, requirementReviews, clarityReviews, services, tokenUsage, trackerSettings, userIdentities, users, workspaceFragmentDefaults, workspaceModelDefaults, workspaceServices, workspaceSettings, workspaces, } from '../db/schema.js';
|
|
5
5
|
// Drizzle/Postgres implementations of the core kernel repository ports. The
|
|
6
6
|
// row<->domain mapping is the SAME shared mapping the Cloudflare D1 repos use
|
|
7
7
|
// (@cat-factory/server), so behaviour matches across stores; this layer only owns
|
|
@@ -181,6 +181,9 @@ class DrizzlePipelineRepository {
|
|
|
181
181
|
thresholds: pipeline.thresholds ? JSON.stringify(pipeline.thresholds) : null,
|
|
182
182
|
enabled: pipeline.enabled ? JSON.stringify(pipeline.enabled) : null,
|
|
183
183
|
consensus: pipeline.consensus ? JSON.stringify(pipeline.consensus) : null,
|
|
184
|
+
gating: pipeline.gating ? JSON.stringify(pipeline.gating) : null,
|
|
185
|
+
labels: pipeline.labels ? JSON.stringify(pipeline.labels) : null,
|
|
186
|
+
archived: pipeline.archived ? 1 : null,
|
|
184
187
|
builtin: pipeline.builtin ? 1 : null,
|
|
185
188
|
});
|
|
186
189
|
}
|
|
@@ -196,6 +199,9 @@ class DrizzlePipelineRepository {
|
|
|
196
199
|
thresholds: pipeline.thresholds ? JSON.stringify(pipeline.thresholds) : null,
|
|
197
200
|
enabled: pipeline.enabled ? JSON.stringify(pipeline.enabled) : null,
|
|
198
201
|
consensus: pipeline.consensus ? JSON.stringify(pipeline.consensus) : null,
|
|
202
|
+
gating: pipeline.gating ? JSON.stringify(pipeline.gating) : null,
|
|
203
|
+
labels: pipeline.labels ? JSON.stringify(pipeline.labels) : null,
|
|
204
|
+
archived: pipeline.archived ? 1 : null,
|
|
199
205
|
})
|
|
200
206
|
.where(and(eq(pipelines.workspace_id, workspaceId), eq(pipelines.id, pipeline.id)));
|
|
201
207
|
}
|
|
@@ -1148,6 +1154,8 @@ class DrizzleTrackerSettingsRepository {
|
|
|
1148
1154
|
return {
|
|
1149
1155
|
tracker: row.tracker ?? null,
|
|
1150
1156
|
jiraProjectKey: row.jira_project_key,
|
|
1157
|
+
writebackCommentOnPrOpen: row.writeback_comment_on_pr_open === 1,
|
|
1158
|
+
writebackResolveOnMerge: row.writeback_resolve_on_merge === 1,
|
|
1151
1159
|
updatedAt: row.updated_at,
|
|
1152
1160
|
};
|
|
1153
1161
|
}
|
|
@@ -1158,6 +1166,8 @@ class DrizzleTrackerSettingsRepository {
|
|
|
1158
1166
|
workspace_id: workspaceId,
|
|
1159
1167
|
tracker: settings.tracker,
|
|
1160
1168
|
jira_project_key: settings.jiraProjectKey,
|
|
1169
|
+
writeback_comment_on_pr_open: settings.writebackCommentOnPrOpen ? 1 : 0,
|
|
1170
|
+
writeback_resolve_on_merge: settings.writebackResolveOnMerge ? 1 : 0,
|
|
1161
1171
|
updated_at: settings.updatedAt,
|
|
1162
1172
|
})
|
|
1163
1173
|
.onConflictDoUpdate({
|
|
@@ -1165,6 +1175,8 @@ class DrizzleTrackerSettingsRepository {
|
|
|
1165
1175
|
set: {
|
|
1166
1176
|
tracker: settings.tracker,
|
|
1167
1177
|
jira_project_key: settings.jiraProjectKey,
|
|
1178
|
+
writeback_comment_on_pr_open: settings.writebackCommentOnPrOpen ? 1 : 0,
|
|
1179
|
+
writeback_resolve_on_merge: settings.writebackResolveOnMerge ? 1 : 0,
|
|
1168
1180
|
updated_at: settings.updatedAt,
|
|
1169
1181
|
},
|
|
1170
1182
|
});
|
|
@@ -1674,6 +1686,8 @@ function rowToMergePreset(row) {
|
|
|
1674
1686
|
ciMaxAttempts: row.ci_max_attempts,
|
|
1675
1687
|
maxRequirementIterations: row.max_requirement_iterations,
|
|
1676
1688
|
maxRequirementConcernAllowed: row.max_requirement_concern_allowed,
|
|
1689
|
+
releaseWatchWindowMinutes: row.release_watch_window_minutes,
|
|
1690
|
+
releaseMaxAttempts: row.release_max_attempts,
|
|
1677
1691
|
isDefault: row.is_default === 1,
|
|
1678
1692
|
createdAt: row.created_at,
|
|
1679
1693
|
};
|
|
@@ -1727,6 +1741,8 @@ export class DrizzleMergePresetRepository {
|
|
|
1727
1741
|
ci_max_attempts: preset.ciMaxAttempts,
|
|
1728
1742
|
max_requirement_iterations: preset.maxRequirementIterations,
|
|
1729
1743
|
max_requirement_concern_allowed: preset.maxRequirementConcernAllowed,
|
|
1744
|
+
release_watch_window_minutes: preset.releaseWatchWindowMinutes,
|
|
1745
|
+
release_max_attempts: preset.releaseMaxAttempts,
|
|
1730
1746
|
is_default: preset.isDefault ? 1 : 0,
|
|
1731
1747
|
created_at: preset.createdAt,
|
|
1732
1748
|
};
|
|
@@ -1753,6 +1769,8 @@ export class DrizzleMergePresetRepository {
|
|
|
1753
1769
|
ci_max_attempts: values.ci_max_attempts,
|
|
1754
1770
|
max_requirement_iterations: values.max_requirement_iterations,
|
|
1755
1771
|
max_requirement_concern_allowed: values.max_requirement_concern_allowed,
|
|
1772
|
+
release_watch_window_minutes: values.release_watch_window_minutes,
|
|
1773
|
+
release_max_attempts: values.release_max_attempts,
|
|
1756
1774
|
is_default: values.is_default,
|
|
1757
1775
|
},
|
|
1758
1776
|
});
|
|
@@ -1764,81 +1782,192 @@ export class DrizzleMergePresetRepository {
|
|
|
1764
1782
|
.where(and(eq(mergeThresholdPresets.workspace_id, workspaceId), eq(mergeThresholdPresets.id, id), eq(mergeThresholdPresets.is_default, 0)));
|
|
1765
1783
|
}
|
|
1766
1784
|
}
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
}
|
|
1785
|
+
/**
|
|
1786
|
+
* Per-workspace runtime settings over Postgres (the Drizzle mirror of the Worker's
|
|
1787
|
+
* `D1WorkspaceSettingsRepository`, migration 0004). One row per workspace; the service
|
|
1788
|
+
* lazily seeds the default, so an absent row reads as null. Per-type task limits are a
|
|
1789
|
+
* JSON column.
|
|
1790
|
+
*/
|
|
1791
|
+
export class DrizzleWorkspaceSettingsRepository {
|
|
1792
|
+
db;
|
|
1793
|
+
constructor(db) {
|
|
1794
|
+
this.db = db;
|
|
1795
|
+
}
|
|
1796
|
+
async get(workspaceId) {
|
|
1797
|
+
const rows = await this.db
|
|
1798
|
+
.select()
|
|
1799
|
+
.from(workspaceSettings)
|
|
1800
|
+
.where(eq(workspaceSettings.workspace_id, workspaceId))
|
|
1801
|
+
.limit(1);
|
|
1802
|
+
const row = rows[0];
|
|
1803
|
+
if (!row)
|
|
1804
|
+
return null;
|
|
1805
|
+
let perType = null;
|
|
1806
|
+
if (row.task_limit_per_type) {
|
|
1807
|
+
try {
|
|
1808
|
+
perType = JSON.parse(row.task_limit_per_type);
|
|
1809
|
+
}
|
|
1810
|
+
catch {
|
|
1811
|
+
perType = null;
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
return {
|
|
1815
|
+
waitingEscalationMinutes: row.waiting_escalation_minutes,
|
|
1816
|
+
taskLimitMode: row.task_limit_mode,
|
|
1817
|
+
taskLimitShared: row.task_limit_shared,
|
|
1818
|
+
taskLimitPerType: perType,
|
|
1819
|
+
};
|
|
1820
|
+
}
|
|
1821
|
+
async upsert(workspaceId, settings) {
|
|
1822
|
+
const values = {
|
|
1823
|
+
workspace_id: workspaceId,
|
|
1824
|
+
waiting_escalation_minutes: settings.waitingEscalationMinutes,
|
|
1825
|
+
task_limit_mode: settings.taskLimitMode,
|
|
1826
|
+
task_limit_shared: settings.taskLimitShared,
|
|
1827
|
+
task_limit_per_type: settings.taskLimitPerType
|
|
1828
|
+
? JSON.stringify(settings.taskLimitPerType)
|
|
1829
|
+
: null,
|
|
1830
|
+
};
|
|
1831
|
+
await this.db
|
|
1832
|
+
.insert(workspaceSettings)
|
|
1833
|
+
.values(values)
|
|
1834
|
+
.onConflictDoUpdate({
|
|
1835
|
+
target: [workspaceSettings.workspace_id],
|
|
1836
|
+
set: {
|
|
1837
|
+
waiting_escalation_minutes: values.waiting_escalation_minutes,
|
|
1838
|
+
task_limit_mode: values.task_limit_mode,
|
|
1839
|
+
task_limit_shared: values.task_limit_shared,
|
|
1840
|
+
task_limit_per_type: values.task_limit_per_type,
|
|
1841
|
+
},
|
|
1842
|
+
});
|
|
1843
|
+
}
|
|
1778
1844
|
}
|
|
1779
1845
|
/**
|
|
1780
|
-
*
|
|
1781
|
-
* `
|
|
1782
|
-
*
|
|
1783
|
-
* `(workspace_id, repo_owner, repo_name)` index, so the row is always the single
|
|
1784
|
-
* current decomposition. The service → modules tree is persisted whole as JSON.
|
|
1846
|
+
* A workspace's Datadog connection over Postgres (the Drizzle mirror of the Worker's
|
|
1847
|
+
* `D1DatadogConnectionRepository`, migration 0003). One row per workspace; the keys are
|
|
1848
|
+
* stored as sealed envelopes (encrypted by the caller).
|
|
1785
1849
|
*/
|
|
1786
|
-
export class
|
|
1850
|
+
export class DrizzleDatadogConnectionRepository {
|
|
1787
1851
|
db;
|
|
1788
1852
|
constructor(db) {
|
|
1789
1853
|
this.db = db;
|
|
1790
1854
|
}
|
|
1855
|
+
async get(workspaceId) {
|
|
1856
|
+
const rows = await this.db
|
|
1857
|
+
.select()
|
|
1858
|
+
.from(datadogConnections)
|
|
1859
|
+
.where(eq(datadogConnections.workspace_id, workspaceId))
|
|
1860
|
+
.limit(1);
|
|
1861
|
+
const row = rows[0];
|
|
1862
|
+
if (!row)
|
|
1863
|
+
return null;
|
|
1864
|
+
return {
|
|
1865
|
+
workspaceId: row.workspace_id,
|
|
1866
|
+
site: row.site,
|
|
1867
|
+
apiKey: row.api_key,
|
|
1868
|
+
appKey: row.app_key,
|
|
1869
|
+
createdAt: row.created_at,
|
|
1870
|
+
updatedAt: row.updated_at,
|
|
1871
|
+
};
|
|
1872
|
+
}
|
|
1791
1873
|
async upsert(record) {
|
|
1792
1874
|
const values = {
|
|
1793
|
-
id: record.id,
|
|
1794
1875
|
workspace_id: record.workspaceId,
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
service_json: JSON.stringify(record.service),
|
|
1876
|
+
site: record.site,
|
|
1877
|
+
api_key: record.apiKey,
|
|
1878
|
+
app_key: record.appKey,
|
|
1799
1879
|
created_at: record.createdAt,
|
|
1800
1880
|
updated_at: record.updatedAt,
|
|
1801
1881
|
};
|
|
1802
1882
|
await this.db
|
|
1803
|
-
.insert(
|
|
1883
|
+
.insert(datadogConnections)
|
|
1804
1884
|
.values(values)
|
|
1805
1885
|
.onConflictDoUpdate({
|
|
1806
|
-
target:
|
|
1886
|
+
target: datadogConnections.workspace_id,
|
|
1807
1887
|
set: {
|
|
1808
|
-
|
|
1809
|
-
|
|
1888
|
+
site: values.site,
|
|
1889
|
+
api_key: values.api_key,
|
|
1890
|
+
app_key: values.app_key,
|
|
1810
1891
|
updated_at: values.updated_at,
|
|
1811
1892
|
},
|
|
1812
1893
|
});
|
|
1813
1894
|
}
|
|
1814
|
-
async
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1895
|
+
async delete(workspaceId) {
|
|
1896
|
+
await this.db.delete(datadogConnections).where(eq(datadogConnections.workspace_id, workspaceId));
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
function parseReleaseIds(json) {
|
|
1900
|
+
try {
|
|
1901
|
+
const parsed = JSON.parse(json);
|
|
1902
|
+
return Array.isArray(parsed) ? parsed.map((x) => String(x)) : [];
|
|
1903
|
+
}
|
|
1904
|
+
catch {
|
|
1905
|
+
return [];
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
function rowToReleaseHealthConfig(row) {
|
|
1909
|
+
return {
|
|
1910
|
+
workspaceId: row.workspace_id,
|
|
1911
|
+
blockId: row.block_id,
|
|
1912
|
+
monitorIds: parseReleaseIds(row.monitor_ids),
|
|
1913
|
+
sloIds: parseReleaseIds(row.slo_ids),
|
|
1914
|
+
envTag: row.env_tag,
|
|
1915
|
+
createdAt: row.created_at,
|
|
1916
|
+
updatedAt: row.updated_at,
|
|
1917
|
+
};
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* Per-block monitor/SLO mapping for the post-release-health gate over Postgres (the
|
|
1921
|
+
* Drizzle mirror of the Worker's `D1ReleaseHealthConfigRepository`, migration 0003).
|
|
1922
|
+
*/
|
|
1923
|
+
export class DrizzleReleaseHealthConfigRepository {
|
|
1924
|
+
db;
|
|
1925
|
+
constructor(db) {
|
|
1926
|
+
this.db = db;
|
|
1821
1927
|
}
|
|
1822
|
-
async
|
|
1928
|
+
async getByBlock(workspaceId, blockId) {
|
|
1823
1929
|
const rows = await this.db
|
|
1824
1930
|
.select()
|
|
1825
|
-
.from(
|
|
1826
|
-
.where(and(eq(
|
|
1931
|
+
.from(releaseHealthConfigs)
|
|
1932
|
+
.where(and(eq(releaseHealthConfigs.workspace_id, workspaceId), eq(releaseHealthConfigs.block_id, blockId)))
|
|
1827
1933
|
.limit(1);
|
|
1828
|
-
return rows[0] ?
|
|
1934
|
+
return rows[0] ? rowToReleaseHealthConfig(rows[0]) : null;
|
|
1829
1935
|
}
|
|
1830
1936
|
async listByWorkspace(workspaceId) {
|
|
1831
1937
|
const rows = await this.db
|
|
1832
1938
|
.select()
|
|
1833
|
-
.from(
|
|
1834
|
-
.where(eq(
|
|
1835
|
-
.orderBy(
|
|
1836
|
-
return rows.map(
|
|
1939
|
+
.from(releaseHealthConfigs)
|
|
1940
|
+
.where(eq(releaseHealthConfigs.workspace_id, workspaceId))
|
|
1941
|
+
.orderBy(releaseHealthConfigs.block_id);
|
|
1942
|
+
return rows.map(rowToReleaseHealthConfig);
|
|
1837
1943
|
}
|
|
1838
|
-
async
|
|
1944
|
+
async upsert(record) {
|
|
1945
|
+
const values = {
|
|
1946
|
+
workspace_id: record.workspaceId,
|
|
1947
|
+
block_id: record.blockId,
|
|
1948
|
+
monitor_ids: JSON.stringify(record.monitorIds),
|
|
1949
|
+
slo_ids: JSON.stringify(record.sloIds),
|
|
1950
|
+
env_tag: record.envTag,
|
|
1951
|
+
created_at: record.createdAt,
|
|
1952
|
+
updated_at: record.updatedAt,
|
|
1953
|
+
};
|
|
1954
|
+
await this.db
|
|
1955
|
+
.insert(releaseHealthConfigs)
|
|
1956
|
+
.values(values)
|
|
1957
|
+
.onConflictDoUpdate({
|
|
1958
|
+
target: [releaseHealthConfigs.workspace_id, releaseHealthConfigs.block_id],
|
|
1959
|
+
set: {
|
|
1960
|
+
monitor_ids: values.monitor_ids,
|
|
1961
|
+
slo_ids: values.slo_ids,
|
|
1962
|
+
env_tag: values.env_tag,
|
|
1963
|
+
updated_at: values.updated_at,
|
|
1964
|
+
},
|
|
1965
|
+
});
|
|
1966
|
+
}
|
|
1967
|
+
async delete(workspaceId, blockId) {
|
|
1839
1968
|
await this.db
|
|
1840
|
-
.delete(
|
|
1841
|
-
.where(and(eq(
|
|
1969
|
+
.delete(releaseHealthConfigs)
|
|
1970
|
+
.where(and(eq(releaseHealthConfigs.workspace_id, workspaceId), eq(releaseHealthConfigs.block_id, blockId)));
|
|
1842
1971
|
}
|
|
1843
1972
|
}
|
|
1844
1973
|
/** Build the Drizzle/Postgres-backed core repositories. */
|
|
@@ -1866,7 +1995,9 @@ export function createDrizzleRepositories(db, clock) {
|
|
|
1866
1995
|
consensusSessionRepository: new DrizzleConsensusSessionRepository(db),
|
|
1867
1996
|
clarityReviewRepository: new DrizzleClarityReviewRepository(db),
|
|
1868
1997
|
mergePresetRepository: new DrizzleMergePresetRepository(db),
|
|
1869
|
-
|
|
1998
|
+
workspaceSettingsRepository: new DrizzleWorkspaceSettingsRepository(db),
|
|
1999
|
+
datadogConnectionRepository: new DrizzleDatadogConnectionRepository(db),
|
|
2000
|
+
releaseHealthConfigRepository: new DrizzleReleaseHealthConfigRepository(db),
|
|
1870
2001
|
};
|
|
1871
2002
|
}
|
|
1872
2003
|
//# sourceMappingURL=drizzle.js.map
|