postgresai 0.16.0-rc.4 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +154 -0
  2. package/dist/bin/postgres-ai.js +2911 -255
  3. package/package.json +12 -3
  4. package/schemas/A002.schema.json +63 -0
  5. package/schemas/A003.schema.json +73 -0
  6. package/schemas/A004.schema.json +81 -0
  7. package/schemas/A007.schema.json +71 -0
  8. package/schemas/A013.schema.json +61 -0
  9. package/schemas/D001.schema.json +71 -0
  10. package/schemas/D004.schema.json +136 -0
  11. package/schemas/F001.schema.json +73 -0
  12. package/schemas/F002.schema.json +108 -0
  13. package/schemas/F003.schema.json +138 -0
  14. package/schemas/F004.schema.json +125 -0
  15. package/schemas/F005.schema.json +131 -0
  16. package/schemas/F009.schema.json +155 -0
  17. package/schemas/G001.schema.json +135 -0
  18. package/schemas/G003.schema.json +90 -0
  19. package/schemas/H001.schema.json +141 -0
  20. package/schemas/H002.schema.json +129 -0
  21. package/schemas/H004.schema.json +128 -0
  22. package/schemas/I001.schema.json +149 -0
  23. package/schemas/K001.schema.json +161 -0
  24. package/schemas/K003.schema.json +163 -0
  25. package/schemas/K004.schema.json +110 -0
  26. package/schemas/K005.schema.json +110 -0
  27. package/schemas/K006.schema.json +110 -0
  28. package/schemas/K007.schema.json +110 -0
  29. package/schemas/K008.schema.json +110 -0
  30. package/schemas/M001.schema.json +119 -0
  31. package/schemas/M002.schema.json +110 -0
  32. package/schemas/M003.schema.json +128 -0
  33. package/schemas/N001.schema.json +161 -0
  34. package/schemas/query.schema.json +62 -0
  35. package/CHANGELOG.md +0 -11
  36. package/bin/postgres-ai.ts +0 -5578
  37. package/bun.lock +0 -258
  38. package/bunfig.toml +0 -20
  39. package/lib/aas-onboard.ts +0 -251
  40. package/lib/auth-server.ts +0 -285
  41. package/lib/checkup-api.ts +0 -526
  42. package/lib/checkup-dictionary.ts +0 -103
  43. package/lib/checkup-summary.ts +0 -338
  44. package/lib/checkup.ts +0 -2261
  45. package/lib/config.ts +0 -171
  46. package/lib/init.ts +0 -1152
  47. package/lib/instances.ts +0 -245
  48. package/lib/issues.ts +0 -1060
  49. package/lib/mcp-server.ts +0 -667
  50. package/lib/metrics-loader.ts +0 -134
  51. package/lib/pkce.ts +0 -79
  52. package/lib/reports.ts +0 -373
  53. package/lib/storage.ts +0 -367
  54. package/lib/supabase.ts +0 -826
  55. package/lib/util.ts +0 -134
  56. package/packages/postgres-ai/README.md +0 -26
  57. package/packages/postgres-ai/bin/postgres-ai.js +0 -27
  58. package/packages/postgres-ai/package.json +0 -27
  59. package/scripts/embed-checkup-dictionary.ts +0 -115
  60. package/scripts/embed-metrics.ts +0 -160
  61. package/scripts/generate-release-notes.ts +0 -668
  62. package/test/PERMISSION_CHECK_TEST_SUMMARY.md +0 -139
  63. package/test/aas-onboard.test.ts +0 -301
  64. package/test/auth.test.ts +0 -287
  65. package/test/checkup.integration.test.ts +0 -413
  66. package/test/checkup.test.ts +0 -3626
  67. package/test/compose-cmd.test.ts +0 -120
  68. package/test/config-consistency.test.ts +0 -352
  69. package/test/init.integration.test.ts +0 -438
  70. package/test/init.test.ts +0 -1816
  71. package/test/issues.cli.test.ts +0 -1162
  72. package/test/issues.test.ts +0 -456
  73. package/test/mcp-server.test.ts +0 -2530
  74. package/test/monitoring.test.ts +0 -746
  75. package/test/permission-check-sql.test.ts +0 -116
  76. package/test/reports.cli.test.ts +0 -793
  77. package/test/reports.test.ts +0 -977
  78. package/test/schema-validation.test.ts +0 -231
  79. package/test/storage.test.ts +0 -935
  80. package/test/supabase.test.ts +0 -709
  81. package/test/targets-add-config.test.ts +0 -28
  82. package/test/test-utils.ts +0 -190
  83. package/test/upgrade.test.ts +0 -1056
  84. package/test/util.test.ts +0 -44
  85. package/tsconfig.json +0 -20
@@ -1,231 +0,0 @@
1
- /**
2
- * JSON Schema validation tests for express checkup reports.
3
- * Validates that generated reports match schemas in reporter/schemas/.
4
- */
5
- import { describe, test, expect } from "bun:test";
6
- import { resolve } from "path";
7
- import { readFileSync } from "fs";
8
- import Ajv2020 from "ajv/dist/2020";
9
-
10
- import * as checkup from "../lib/checkup";
11
- import { createMockClient } from "./test-utils";
12
-
13
- const ajv = new Ajv2020({ allErrors: true, strict: false });
14
- const schemasDir = resolve(import.meta.dir, "../../reporter/schemas");
15
-
16
- function validateAgainstSchema(report: any, checkId: string): void {
17
- const schemaPath = resolve(schemasDir, `${checkId}.schema.json`);
18
- const schema = JSON.parse(readFileSync(schemaPath, "utf8"));
19
- const validate = ajv.compile(schema);
20
- const valid = validate(report);
21
- if (!valid) {
22
- const errors = validate.errors?.map(e => `${e.instancePath}: ${e.message}`).join(", ");
23
- throw new Error(`${checkId} schema validation failed: ${errors}`);
24
- }
25
- }
26
-
27
- // Test data for index reports
28
- const indexTestData = {
29
- H001: {
30
- emptyRows: { invalidIndexesRows: [] },
31
- dataRows: {
32
- invalidIndexesRows: [
33
- { schema_name: "public", table_name: "users", index_name: "users_email_idx", relation_name: "users", index_size_bytes: "1048576", index_definition: "CREATE INDEX users_email_idx ON public.users USING btree (email)", supports_fk: false },
34
- ],
35
- },
36
- },
37
- H002: {
38
- emptyRows: { unusedIndexesRows: [] },
39
- dataRows: {
40
- unusedIndexesRows: [
41
- { schema_name: "public", table_name: "logs", index_name: "logs_created_idx", index_definition: "CREATE INDEX logs_created_idx ON public.logs USING btree (created_at)", reason: "Never Used Indexes", idx_scan: "0", index_size_bytes: "8388608", idx_is_btree: true, supports_fk: false },
42
- ],
43
- },
44
- },
45
- H004: {
46
- emptyRows: { redundantIndexesRows: [] },
47
- dataRows: {
48
- redundantIndexesRows: [
49
- { schema_name: "public", table_name: "orders", index_name: "orders_user_id_idx", relation_name: "orders", access_method: "btree", reason: "public.orders_user_id_created_idx", index_size_bytes: "2097152", table_size_bytes: "16777216", index_usage: "0", supports_fk: false, index_definition: "CREATE INDEX orders_user_id_idx ON public.orders USING btree (user_id)", redundant_to_json: JSON.stringify([{ index_name: "public.orders_user_id_created_idx", index_definition: "CREATE INDEX ...", index_size_bytes: 1048576 }]) },
50
- ],
51
- },
52
- },
53
- };
54
-
55
- describe("Schema validation", () => {
56
- // Index health checks (H001, H002, H004) - test empty and with data
57
- for (const [checkId, testData] of Object.entries(indexTestData)) {
58
- const generator = checkup.REPORT_GENERATORS[checkId];
59
-
60
- test(`${checkId} validates with empty data`, async () => {
61
- const mockClient = createMockClient(testData.emptyRows);
62
- const report = await generator(mockClient as any, "node-01");
63
- validateAgainstSchema(report, checkId);
64
- });
65
-
66
- test(`${checkId} validates with sample data`, async () => {
67
- const mockClient = createMockClient(testData.dataRows);
68
- const report = await generator(mockClient as any, "node-01");
69
- validateAgainstSchema(report, checkId);
70
- });
71
- }
72
-
73
- // F003 (Autovacuum: dead tuples) - test empty and with data
74
- test("F003 validates with empty data", async () => {
75
- const mockClient = createMockClient({ deadTuplesRows: [] });
76
- const report = await checkup.REPORT_GENERATORS.F003(mockClient as any, "node-01");
77
- validateAgainstSchema(report, "F003");
78
- });
79
-
80
- test("F003 validates with sample data", async () => {
81
- const mockClient = createMockClient({
82
- deadTuplesRows: [
83
- {
84
- tag_schemaname: "public",
85
- tag_relname: "events",
86
- n_live_tup: "6361538",
87
- n_dead_tup: "8270000",
88
- dead_pct: 56.52,
89
- last_autovacuum: "0",
90
- last_vacuum: "1704067200",
91
- autovacuum_count: "0",
92
- vacuum_count: "1",
93
- autovacuum_disabled: 1,
94
- table_size_b: "2147483648",
95
- },
96
- ],
97
- });
98
- const report = await checkup.REPORT_GENERATORS.F003(mockClient as any, "node-01");
99
- validateAgainstSchema(report, "F003");
100
- });
101
-
102
- for (const checkId of ["F004", "F005"]) {
103
- test(`${checkId} distinguishes a healthy empty result from missing schema`, async () => {
104
- const healthyClient = createMockClient();
105
- const healthy = await checkup.REPORT_GENERATORS[checkId](healthyClient as any, "node-01");
106
- const healthyDb = healthy.results["node-01"].data.testdb;
107
- expect(healthyDb.status).toEqual({ ok: true, reason: null, error: null });
108
- validateAgainstSchema(healthy, checkId);
109
-
110
- const missingSchemaClient = createMockClient({
111
- bloatCapabilityRows: [
112
- { schema_exists: false, schema_usage: false, view_exists: false, view_select: false },
113
- ],
114
- });
115
- const degraded = await checkup.REPORT_GENERATORS[checkId](missingSchemaClient as any, "node-01");
116
- const degradedDb = degraded.results["node-01"].data.testdb;
117
- expect(degradedDb.status).toEqual({
118
- ok: false,
119
- reason: "missing_schema",
120
- error: 'schema "postgres_ai" does not exist',
121
- });
122
- validateAgainstSchema(degraded, checkId);
123
- });
124
-
125
- test(`${checkId} exposes missing-grant degradation`, async () => {
126
- const client = createMockClient({
127
- bloatCapabilityRows: [
128
- { schema_exists: true, schema_usage: true, view_exists: true, view_select: false },
129
- ],
130
- });
131
- const report = await checkup.REPORT_GENERATORS[checkId](client as any, "node-01");
132
- const dbEntry = report.results["node-01"].data.testdb;
133
- expect(dbEntry.status).toEqual({
134
- ok: false,
135
- reason: "missing_grant",
136
- error: "permission denied for relation postgres_ai.pg_statistic",
137
- });
138
- validateAgainstSchema(report, checkId);
139
- });
140
- }
141
-
142
- // Settings reports (D004, F001, G001) - single test each
143
- for (const checkId of ["D004", "F001", "G001"]) {
144
- test(`${checkId} validates against schema`, async () => {
145
- const mockClient = createMockClient();
146
- const report = await checkup.REPORT_GENERATORS[checkId](mockClient as any, "node-01");
147
- validateAgainstSchema(report, checkId);
148
- });
149
- }
150
-
151
- test("I001 validates with available pg_stat_io data", () => {
152
- const report = {
153
- version: null,
154
- build_ts: null,
155
- generation_mode: null,
156
- checkId: "I001",
157
- checkTitle: "I/O statistics (pg_stat_io)",
158
- timestamptz: new Date("2026-01-01T00:00:00.000Z").toISOString(),
159
- nodes: { primary: "node-01", standbys: [] },
160
- results: {
161
- "node-01": {
162
- data: {
163
- available: true,
164
- by_backend_type: [{
165
- backend_type: "total",
166
- reads: 10,
167
- read_bytes_mb: 64,
168
- read_time_ms: 20,
169
- writes: 5,
170
- write_bytes_mb: 32,
171
- write_time_ms: 10,
172
- writebacks: 4,
173
- writeback_bytes_mb: 16,
174
- writeback_time_ms: 8,
175
- fsyncs: 2,
176
- fsync_time_ms: 6,
177
- extends: 3,
178
- extend_bytes_mb: 24,
179
- hits: 90,
180
- evictions: 7,
181
- reuses: 11,
182
- }],
183
- analysis: {
184
- total_read_mb: 64,
185
- total_write_mb: 32,
186
- total_io_time_ms: 30,
187
- read_hit_ratio_pct: 90,
188
- avg_read_time_ms: 2,
189
- avg_write_time_ms: 2,
190
- },
191
- stats_reset_s: 7200,
192
- },
193
- },
194
- },
195
- };
196
-
197
- validateAgainstSchema(report, "I001");
198
- });
199
-
200
- test("I001 validates with unavailable pg_stat_io data", () => {
201
- const report = {
202
- version: null,
203
- build_ts: null,
204
- generation_mode: null,
205
- checkId: "I001",
206
- checkTitle: "I/O statistics (pg_stat_io)",
207
- timestamptz: new Date("2026-01-01T00:00:00.000Z").toISOString(),
208
- nodes: { primary: "node-01", standbys: [] },
209
- results: {
210
- "node-01": {
211
- data: {
212
- available: false,
213
- min_version_required: "16",
214
- by_backend_type: [],
215
- analysis: {
216
- total_read_mb: 0,
217
- total_write_mb: 0,
218
- total_io_time_ms: 0,
219
- read_hit_ratio_pct: 0,
220
- avg_read_time_ms: null,
221
- avg_write_time_ms: null,
222
- },
223
- stats_reset_s: null,
224
- },
225
- },
226
- },
227
- };
228
-
229
- validateAgainstSchema(report, "I001");
230
- });
231
- });