popeye-cli 1.7.0 → 1.8.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/README.md +102 -5
- package/cheatsheet.md +407 -0
- package/dist/cli/commands/db.d.ts +10 -0
- package/dist/cli/commands/db.d.ts.map +1 -0
- package/dist/cli/commands/db.js +240 -0
- package/dist/cli/commands/db.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +18 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +255 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/index.d.ts +2 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +2 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +3 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/interactive.d.ts.map +1 -1
- package/dist/cli/interactive.js +96 -0
- package/dist/cli/interactive.js.map +1 -1
- package/dist/generators/admin-wizard.d.ts +25 -0
- package/dist/generators/admin-wizard.d.ts.map +1 -0
- package/dist/generators/admin-wizard.js +123 -0
- package/dist/generators/admin-wizard.js.map +1 -0
- package/dist/generators/all.d.ts.map +1 -1
- package/dist/generators/all.js +10 -3
- package/dist/generators/all.js.map +1 -1
- package/dist/generators/database.d.ts +58 -0
- package/dist/generators/database.d.ts.map +1 -0
- package/dist/generators/database.js +229 -0
- package/dist/generators/database.js.map +1 -0
- package/dist/generators/fullstack.d.ts.map +1 -1
- package/dist/generators/fullstack.js +23 -7
- package/dist/generators/fullstack.js.map +1 -1
- package/dist/generators/index.d.ts +2 -0
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +2 -0
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/templates/admin-wizard-python.d.ts +32 -0
- package/dist/generators/templates/admin-wizard-python.d.ts.map +1 -0
- package/dist/generators/templates/admin-wizard-python.js +425 -0
- package/dist/generators/templates/admin-wizard-python.js.map +1 -0
- package/dist/generators/templates/admin-wizard-react.d.ts +48 -0
- package/dist/generators/templates/admin-wizard-react.d.ts.map +1 -0
- package/dist/generators/templates/admin-wizard-react.js +554 -0
- package/dist/generators/templates/admin-wizard-react.js.map +1 -0
- package/dist/generators/templates/database-docker.d.ts +23 -0
- package/dist/generators/templates/database-docker.d.ts.map +1 -0
- package/dist/generators/templates/database-docker.js +221 -0
- package/dist/generators/templates/database-docker.js.map +1 -0
- package/dist/generators/templates/database-python.d.ts +54 -0
- package/dist/generators/templates/database-python.d.ts.map +1 -0
- package/dist/generators/templates/database-python.js +723 -0
- package/dist/generators/templates/database-python.js.map +1 -0
- package/dist/generators/templates/database-typescript.d.ts +34 -0
- package/dist/generators/templates/database-typescript.d.ts.map +1 -0
- package/dist/generators/templates/database-typescript.js +232 -0
- package/dist/generators/templates/database-typescript.js.map +1 -0
- package/dist/generators/templates/fullstack.d.ts.map +1 -1
- package/dist/generators/templates/fullstack.js +29 -0
- package/dist/generators/templates/fullstack.js.map +1 -1
- package/dist/generators/templates/index.d.ts +5 -0
- package/dist/generators/templates/index.d.ts.map +1 -1
- package/dist/generators/templates/index.js +5 -0
- package/dist/generators/templates/index.js.map +1 -1
- package/dist/state/index.d.ts +10 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +21 -0
- package/dist/state/index.js.map +1 -1
- package/dist/types/database-runtime.d.ts +86 -0
- package/dist/types/database-runtime.d.ts.map +1 -0
- package/dist/types/database-runtime.js +61 -0
- package/dist/types/database-runtime.js.map +1 -0
- package/dist/types/database.d.ts +85 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/database.js +71 -0
- package/dist/types/database.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/workflow.d.ts +21 -0
- package/dist/types/workflow.d.ts.map +1 -1
- package/dist/types/workflow.js +2 -0
- package/dist/types/workflow.js.map +1 -1
- package/dist/workflow/db-setup-runner.d.ts +63 -0
- package/dist/workflow/db-setup-runner.d.ts.map +1 -0
- package/dist/workflow/db-setup-runner.js +336 -0
- package/dist/workflow/db-setup-runner.js.map +1 -0
- package/dist/workflow/db-state-machine.d.ts +30 -0
- package/dist/workflow/db-state-machine.d.ts.map +1 -0
- package/dist/workflow/db-state-machine.js +51 -0
- package/dist/workflow/db-state-machine.js.map +1 -0
- package/dist/workflow/index.d.ts +2 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +2 -0
- package/dist/workflow/index.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/db.ts +281 -0
- package/src/cli/commands/doctor.ts +273 -0
- package/src/cli/commands/index.ts +2 -0
- package/src/cli/index.ts +4 -0
- package/src/cli/interactive.ts +102 -0
- package/src/generators/admin-wizard.ts +146 -0
- package/src/generators/all.ts +10 -3
- package/src/generators/database.ts +286 -0
- package/src/generators/fullstack.ts +26 -9
- package/src/generators/index.ts +12 -0
- package/src/generators/templates/admin-wizard-python.ts +431 -0
- package/src/generators/templates/admin-wizard-react.ts +560 -0
- package/src/generators/templates/database-docker.ts +227 -0
- package/src/generators/templates/database-python.ts +734 -0
- package/src/generators/templates/database-typescript.ts +238 -0
- package/src/generators/templates/fullstack.ts +29 -0
- package/src/generators/templates/index.ts +5 -0
- package/src/state/index.ts +28 -0
- package/src/types/database-runtime.ts +69 -0
- package/src/types/database.ts +84 -0
- package/src/types/index.ts +29 -0
- package/src/types/workflow.ts +5 -0
- package/src/workflow/db-setup-runner.ts +391 -0
- package/src/workflow/db-state-machine.ts +58 -0
- package/src/workflow/index.ts +2 -0
- package/tests/generators/admin-wizard-orchestrator.test.ts +64 -0
- package/tests/generators/admin-wizard-templates.test.ts +366 -0
- package/tests/generators/cross-phase-integration.test.ts +383 -0
- package/tests/generators/database.test.ts +456 -0
- package/tests/generators/fe-be-db-integration.test.ts +613 -0
- package/tests/types/database-runtime.test.ts +158 -0
- package/tests/types/database.test.ts +187 -0
- package/tests/workflow/db-setup-runner.test.ts +211 -0
- package/tests/workflow/db-state-machine.test.ts +117 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript backend database template functions
|
|
3
|
+
* Generates Prisma + pgvector files for future TS backend projects
|
|
4
|
+
* NOT wired into any generator in Phase 1 - templates exist for future use
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generate Prisma schema with PostgreSQL datasource and pgvector
|
|
9
|
+
*/
|
|
10
|
+
export function generatePrismaSchema(projectName: string): string {
|
|
11
|
+
return `// Prisma schema for ${projectName}
|
|
12
|
+
// Learn more: https://pris.ly/d/prisma-schema
|
|
13
|
+
|
|
14
|
+
generator client {
|
|
15
|
+
provider = "prisma-client-js"
|
|
16
|
+
previewFeatures = ["postgresqlExtensions"]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
datasource db {
|
|
20
|
+
provider = "postgresql"
|
|
21
|
+
url = env("DATABASE_URL")
|
|
22
|
+
extensions = [pgvector(map: "vector", schema: "public")]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
model AppSettings {
|
|
26
|
+
id Int @id @default(autoincrement())
|
|
27
|
+
key String @unique
|
|
28
|
+
value String
|
|
29
|
+
createdAt DateTime @default(now()) @map("created_at")
|
|
30
|
+
updatedAt DateTime @updatedAt @map("updated_at")
|
|
31
|
+
|
|
32
|
+
@@map("app_settings")
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Generate PrismaClient singleton with connection handling
|
|
39
|
+
*/
|
|
40
|
+
export function generatePrismaClient(projectName: string): string {
|
|
41
|
+
return `/**
|
|
42
|
+
* Prisma client singleton for ${projectName}.
|
|
43
|
+
*
|
|
44
|
+
* Ensures a single PrismaClient instance is reused across the application.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
import { PrismaClient } from "@prisma/client";
|
|
48
|
+
|
|
49
|
+
const globalForPrisma = globalThis as unknown as {
|
|
50
|
+
prisma: PrismaClient | undefined;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const prisma =
|
|
54
|
+
globalForPrisma.prisma ??
|
|
55
|
+
new PrismaClient({
|
|
56
|
+
log:
|
|
57
|
+
process.env.NODE_ENV === "development"
|
|
58
|
+
? ["query", "error", "warn"]
|
|
59
|
+
: ["error"],
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (process.env.NODE_ENV !== "production") {
|
|
63
|
+
globalForPrisma.prisma = prisma;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export default prisma;
|
|
67
|
+
`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Generate .env.example additions for Prisma
|
|
72
|
+
*/
|
|
73
|
+
export function generatePrismaEnv(): string {
|
|
74
|
+
return `# Database
|
|
75
|
+
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/mydb?schema=public"
|
|
76
|
+
`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Generate Prisma seed script
|
|
81
|
+
*/
|
|
82
|
+
export function generatePrismaSeed(): string {
|
|
83
|
+
return `/**
|
|
84
|
+
* Prisma seed script.
|
|
85
|
+
*
|
|
86
|
+
* Seeds the database with initial data using upsert pattern.
|
|
87
|
+
* Run with: npx prisma db seed
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
import { PrismaClient } from "@prisma/client";
|
|
91
|
+
|
|
92
|
+
const prisma = new PrismaClient();
|
|
93
|
+
|
|
94
|
+
async function main() {
|
|
95
|
+
console.log("Seeding database...");
|
|
96
|
+
|
|
97
|
+
// Upsert default app settings
|
|
98
|
+
await prisma.appSettings.upsert({
|
|
99
|
+
where: { key: "app_version" },
|
|
100
|
+
update: { value: "1.0.0" },
|
|
101
|
+
create: { key: "app_version", value: "1.0.0" },
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
console.log("Seeding complete.");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
main()
|
|
108
|
+
.then(async () => {
|
|
109
|
+
await prisma.$disconnect();
|
|
110
|
+
})
|
|
111
|
+
.catch(async (e) => {
|
|
112
|
+
console.error(e);
|
|
113
|
+
await prisma.$disconnect();
|
|
114
|
+
process.exit(1);
|
|
115
|
+
});
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Generate database health check for Prisma
|
|
121
|
+
*/
|
|
122
|
+
export function generatePrismaDbHealth(): string {
|
|
123
|
+
return `/**
|
|
124
|
+
* Database health check utilities.
|
|
125
|
+
*
|
|
126
|
+
* Tests connection and checks migration status.
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
import prisma from "./client";
|
|
130
|
+
|
|
131
|
+
export interface DbHealthResult {
|
|
132
|
+
connected: boolean;
|
|
133
|
+
migrations?: { current: string | null };
|
|
134
|
+
error?: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Check database connectivity and migration status.
|
|
139
|
+
*/
|
|
140
|
+
export async function checkDbHealth(): Promise<DbHealthResult> {
|
|
141
|
+
try {
|
|
142
|
+
// Test basic connectivity
|
|
143
|
+
await prisma.$queryRaw\`SELECT 1\`;
|
|
144
|
+
|
|
145
|
+
// Check migration status
|
|
146
|
+
let currentMigration: string | null = null;
|
|
147
|
+
try {
|
|
148
|
+
const result = await prisma.$queryRaw<
|
|
149
|
+
Array<{ migration_name: string }>
|
|
150
|
+
>\`SELECT migration_name FROM _prisma_migrations ORDER BY finished_at DESC LIMIT 1\`;
|
|
151
|
+
currentMigration = result[0]?.migration_name ?? null;
|
|
152
|
+
} catch {
|
|
153
|
+
// _prisma_migrations table may not exist yet
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
connected: true,
|
|
158
|
+
migrations: { current: currentMigration },
|
|
159
|
+
};
|
|
160
|
+
} catch (error) {
|
|
161
|
+
return {
|
|
162
|
+
connected: false,
|
|
163
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Generate pgvector raw query helpers for Prisma
|
|
172
|
+
*/
|
|
173
|
+
export function generatePrismaVectorHelpers(): string {
|
|
174
|
+
return `/**
|
|
175
|
+
* pgvector helpers using Prisma raw queries.
|
|
176
|
+
*
|
|
177
|
+
* Provides cosine similarity search and vector extension checks.
|
|
178
|
+
*/
|
|
179
|
+
|
|
180
|
+
import prisma from "./client";
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Perform cosine similarity search against a vector column.
|
|
184
|
+
*/
|
|
185
|
+
export async function cosineSimilaritySearch(
|
|
186
|
+
tableName: string,
|
|
187
|
+
columnName: string,
|
|
188
|
+
queryVector: number[],
|
|
189
|
+
limit: number = 10
|
|
190
|
+
): Promise<Array<{ id: number; similarity: number }>> {
|
|
191
|
+
const vectorStr = \`[\${queryVector.join(",")}]\`;
|
|
192
|
+
|
|
193
|
+
const results = await prisma.$queryRawUnsafe<
|
|
194
|
+
Array<{ id: number; similarity: number }>
|
|
195
|
+
>(
|
|
196
|
+
\`SELECT id, 1 - (\${columnName} <=> $1::vector) AS similarity \` +
|
|
197
|
+
\`FROM \${tableName} \` +
|
|
198
|
+
\`ORDER BY \${columnName} <=> $1::vector \` +
|
|
199
|
+
\`LIMIT $2\`,
|
|
200
|
+
vectorStr,
|
|
201
|
+
limit
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
return results;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Check if the pgvector extension is installed.
|
|
209
|
+
*/
|
|
210
|
+
export async function checkVectorExtension(): Promise<boolean> {
|
|
211
|
+
try {
|
|
212
|
+
const result = await prisma.$queryRaw<Array<{ extname: string }>>\`
|
|
213
|
+
SELECT extname FROM pg_extension WHERE extname = 'vector'
|
|
214
|
+
\`;
|
|
215
|
+
return result.length > 0;
|
|
216
|
+
} catch {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
`;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Generate Prisma DB index.ts with re-exports
|
|
225
|
+
*/
|
|
226
|
+
export function generatePrismaDbInit(): string {
|
|
227
|
+
return `/**
|
|
228
|
+
* Database package re-exports.
|
|
229
|
+
*/
|
|
230
|
+
|
|
231
|
+
export { prisma, default as PrismaClient } from "./client";
|
|
232
|
+
export { checkDbHealth, type DbHealthResult } from "./health";
|
|
233
|
+
export {
|
|
234
|
+
cosineSimilaritySearch,
|
|
235
|
+
checkVectorExtension,
|
|
236
|
+
} from "./vector";
|
|
237
|
+
`;
|
|
238
|
+
}
|
|
@@ -212,6 +212,35 @@ cd apps/frontend && npm run lint
|
|
|
212
212
|
cd apps/backend && ruff check .
|
|
213
213
|
\`\`\`
|
|
214
214
|
|
|
215
|
+
## Database
|
|
216
|
+
|
|
217
|
+
Database is **UNCONFIGURED** by default. The app runs without a database in limited mode.
|
|
218
|
+
|
|
219
|
+
### Local Docker (recommended for development)
|
|
220
|
+
|
|
221
|
+
\`\`\`bash
|
|
222
|
+
# docker-compose starts PostgreSQL automatically
|
|
223
|
+
docker-compose up
|
|
224
|
+
\`\`\`
|
|
225
|
+
|
|
226
|
+
### Managed Database
|
|
227
|
+
|
|
228
|
+
Set \`DATABASE_URL\` in \`apps/backend/.env\` to connect to a managed PostgreSQL instance (Neon, Supabase, etc.).
|
|
229
|
+
|
|
230
|
+
### Health Check
|
|
231
|
+
|
|
232
|
+
\`\`\`bash
|
|
233
|
+
# Check database connectivity and migration status
|
|
234
|
+
curl http://localhost:8000/health/db
|
|
235
|
+
\`\`\`
|
|
236
|
+
|
|
237
|
+
### Migrations
|
|
238
|
+
|
|
239
|
+
\`\`\`bash
|
|
240
|
+
cd apps/backend
|
|
241
|
+
alembic upgrade head
|
|
242
|
+
\`\`\`
|
|
243
|
+
|
|
215
244
|
## Apps
|
|
216
245
|
|
|
217
246
|
### Frontend (apps/frontend)
|
|
@@ -14,3 +14,8 @@ export * as websiteLandingTemplates from './website-landing.js';
|
|
|
14
14
|
export * as websitePricingTemplates from './website-pricing.js';
|
|
15
15
|
export * as websiteLayoutTemplates from './website-layout.js';
|
|
16
16
|
export * as websiteSectionTemplates from './website-sections.js';
|
|
17
|
+
export * as databasePythonTemplates from './database-python.js';
|
|
18
|
+
export * as databaseTypescriptTemplates from './database-typescript.js';
|
|
19
|
+
export * as databaseDockerTemplates from './database-docker.js';
|
|
20
|
+
export * as adminWizardPythonTemplates from './admin-wizard-python.js';
|
|
21
|
+
export * as adminWizardReactTemplates from './admin-wizard-react.js';
|
package/src/state/index.ts
CHANGED
|
@@ -15,6 +15,9 @@ import type {
|
|
|
15
15
|
} from '../types/workflow.js';
|
|
16
16
|
import type { ConsensusIteration } from '../types/consensus.js';
|
|
17
17
|
import type { ProjectSpec } from '../types/project.js';
|
|
18
|
+
import { isWorkspace } from '../types/project.js';
|
|
19
|
+
import { DEFAULT_DB_CONFIG } from '../types/database.js';
|
|
20
|
+
import type { DbConfig } from '../types/database.js';
|
|
18
21
|
import {
|
|
19
22
|
loadState,
|
|
20
23
|
saveState,
|
|
@@ -63,6 +66,11 @@ export async function createProject(
|
|
|
63
66
|
qaEnabled: true,
|
|
64
67
|
};
|
|
65
68
|
|
|
69
|
+
// Set default DB config for workspace projects (fullstack / all)
|
|
70
|
+
if (isWorkspace(spec.language)) {
|
|
71
|
+
state.dbConfig = { ...DEFAULT_DB_CONFIG };
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
await saveState(projectDir, state);
|
|
67
75
|
|
|
68
76
|
// Register project in global registry
|
|
@@ -395,6 +403,26 @@ export async function storeWebsiteStrategyPath(
|
|
|
395
403
|
return updateState(projectDir, { websiteStrategy: strategyPath });
|
|
396
404
|
}
|
|
397
405
|
|
|
406
|
+
/**
|
|
407
|
+
* Update database configuration with partial updates
|
|
408
|
+
* Merges partial DbConfig updates into the existing config
|
|
409
|
+
*
|
|
410
|
+
* @param projectDir - The project root directory
|
|
411
|
+
* @param updates - Partial DbConfig updates to merge
|
|
412
|
+
* @returns The updated project state
|
|
413
|
+
*/
|
|
414
|
+
export async function updateDbConfig(
|
|
415
|
+
projectDir: string,
|
|
416
|
+
updates: Partial<DbConfig>
|
|
417
|
+
): Promise<ProjectState> {
|
|
418
|
+
const current = await loadProject(projectDir);
|
|
419
|
+
const currentDbConfig = current.dbConfig || { ...DEFAULT_DB_CONFIG };
|
|
420
|
+
|
|
421
|
+
return updateState(projectDir, {
|
|
422
|
+
dbConfig: { ...currentDbConfig, ...updates },
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
|
|
398
426
|
/**
|
|
399
427
|
* Mark the project as complete
|
|
400
428
|
*
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database runtime types and Zod schemas for Phase 2
|
|
3
|
+
* Defines setup pipeline results, readiness checks, and doctor output
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { DbStatusSchema, DbSetupStepSchema } from './database.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Result of a single setup pipeline step
|
|
11
|
+
*/
|
|
12
|
+
export const SetupStepResultSchema = z.object({
|
|
13
|
+
/** Which pipeline step */
|
|
14
|
+
step: DbSetupStepSchema,
|
|
15
|
+
/** Whether the step succeeded */
|
|
16
|
+
success: z.boolean(),
|
|
17
|
+
/** Human-readable status message */
|
|
18
|
+
message: z.string(),
|
|
19
|
+
/** Duration in milliseconds */
|
|
20
|
+
durationMs: z.number(),
|
|
21
|
+
/** Error details if step failed */
|
|
22
|
+
error: z.string().optional(),
|
|
23
|
+
});
|
|
24
|
+
export type SetupStepResult = z.infer<typeof SetupStepResultSchema>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Full setup pipeline result
|
|
28
|
+
*/
|
|
29
|
+
export const SetupResultSchema = z.object({
|
|
30
|
+
/** Whether the entire pipeline succeeded */
|
|
31
|
+
success: z.boolean(),
|
|
32
|
+
/** Individual step results */
|
|
33
|
+
steps: z.array(SetupStepResultSchema),
|
|
34
|
+
/** Total pipeline duration in milliseconds */
|
|
35
|
+
totalDurationMs: z.number(),
|
|
36
|
+
/** Final DB status after pipeline */
|
|
37
|
+
finalStatus: DbStatusSchema,
|
|
38
|
+
/** Error message if pipeline failed */
|
|
39
|
+
error: z.string().optional(),
|
|
40
|
+
});
|
|
41
|
+
export type SetupResult = z.infer<typeof SetupResultSchema>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Single readiness check (used by doctor command)
|
|
45
|
+
*/
|
|
46
|
+
export const ReadinessCheckSchema = z.object({
|
|
47
|
+
/** Check name */
|
|
48
|
+
name: z.string(),
|
|
49
|
+
/** Whether the check passed */
|
|
50
|
+
passed: z.boolean(),
|
|
51
|
+
/** Human-readable result message */
|
|
52
|
+
message: z.string(),
|
|
53
|
+
/** Severity level */
|
|
54
|
+
severity: z.enum(['critical', 'warning', 'info']),
|
|
55
|
+
});
|
|
56
|
+
export type ReadinessCheck = z.infer<typeof ReadinessCheckSchema>;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Full doctor readiness result
|
|
60
|
+
*/
|
|
61
|
+
export const ReadinessResultSchema = z.object({
|
|
62
|
+
/** Overall health status */
|
|
63
|
+
healthy: z.boolean(),
|
|
64
|
+
/** Individual check results */
|
|
65
|
+
checks: z.array(ReadinessCheckSchema),
|
|
66
|
+
/** ISO timestamp of when checks ran */
|
|
67
|
+
timestamp: z.string(),
|
|
68
|
+
});
|
|
69
|
+
export type ReadinessResult = z.infer<typeof ReadinessResultSchema>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database configuration types and Zod schemas
|
|
3
|
+
* Defines DB lifecycle states, provisioning modes, and config tracking
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Database lifecycle status
|
|
10
|
+
*/
|
|
11
|
+
export const DbStatusSchema = z.enum([
|
|
12
|
+
'unconfigured',
|
|
13
|
+
'configured',
|
|
14
|
+
'applying',
|
|
15
|
+
'ready',
|
|
16
|
+
'error',
|
|
17
|
+
]);
|
|
18
|
+
export type DbStatus = z.infer<typeof DbStatusSchema>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Database provisioning mode
|
|
22
|
+
* - local_docker: PostgreSQL runs in Docker Compose
|
|
23
|
+
* - managed: External managed database (Neon, Supabase, etc.)
|
|
24
|
+
*/
|
|
25
|
+
export const DbModeSchema = z.enum(['local_docker', 'managed']);
|
|
26
|
+
export type DbMode = z.infer<typeof DbModeSchema>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Database provider (informational only)
|
|
30
|
+
*/
|
|
31
|
+
export const DbProviderSchema = z.enum(['neon', 'supabase', 'other']);
|
|
32
|
+
export type DbProvider = z.infer<typeof DbProviderSchema>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Backend ORM choice
|
|
36
|
+
*/
|
|
37
|
+
export const BackendOrmSchema = z.enum(['sqlalchemy', 'prisma', 'drizzle']);
|
|
38
|
+
export type BackendOrm = z.infer<typeof BackendOrmSchema>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Setup pipeline steps (forward compat for Phase 2)
|
|
42
|
+
*/
|
|
43
|
+
export const DbSetupStepSchema = z.enum([
|
|
44
|
+
'check_connection',
|
|
45
|
+
'ensure_extensions',
|
|
46
|
+
'apply_migrations',
|
|
47
|
+
'seed_minimal',
|
|
48
|
+
'readiness_tests',
|
|
49
|
+
'mark_ready',
|
|
50
|
+
]);
|
|
51
|
+
export type DbSetupStep = z.infer<typeof DbSetupStepSchema>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Main database configuration tracking object
|
|
55
|
+
*/
|
|
56
|
+
export const DbConfigSchema = z.object({
|
|
57
|
+
/** Whether DB layer was generated */
|
|
58
|
+
designed: z.boolean(),
|
|
59
|
+
/** Provisioning mode - unset until user configures */
|
|
60
|
+
mode: DbModeSchema.optional(),
|
|
61
|
+
/** Whether pgvector is included */
|
|
62
|
+
vectorRequired: z.boolean(),
|
|
63
|
+
/** Current lifecycle state */
|
|
64
|
+
status: DbStatusSchema,
|
|
65
|
+
/** Last error message */
|
|
66
|
+
lastError: z.string().optional(),
|
|
67
|
+
/** Number of migrations applied (updated by runner, not generator) */
|
|
68
|
+
migrationsApplied: z.number(),
|
|
69
|
+
/** ISO timestamp of last readiness check */
|
|
70
|
+
readinessCheckedAt: z.string().optional(),
|
|
71
|
+
});
|
|
72
|
+
export type DbConfig = z.infer<typeof DbConfigSchema>;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Default DB config for new fullstack/all projects
|
|
76
|
+
* vectorRequired: true because fullstack/all projects get pgvector by default
|
|
77
|
+
* mode is intentionally absent (unset until user configures provisioning)
|
|
78
|
+
*/
|
|
79
|
+
export const DEFAULT_DB_CONFIG: DbConfig = {
|
|
80
|
+
designed: true,
|
|
81
|
+
status: 'unconfigured',
|
|
82
|
+
vectorRequired: true,
|
|
83
|
+
migrationsApplied: 0,
|
|
84
|
+
};
|
package/src/types/index.ts
CHANGED
|
@@ -101,6 +101,35 @@ export {
|
|
|
101
101
|
type DiscoveredTestCommands,
|
|
102
102
|
} from './tester.js';
|
|
103
103
|
|
|
104
|
+
// Database types
|
|
105
|
+
export {
|
|
106
|
+
DbStatusSchema,
|
|
107
|
+
DbModeSchema,
|
|
108
|
+
DbProviderSchema,
|
|
109
|
+
BackendOrmSchema,
|
|
110
|
+
DbSetupStepSchema,
|
|
111
|
+
DbConfigSchema,
|
|
112
|
+
DEFAULT_DB_CONFIG,
|
|
113
|
+
type DbStatus,
|
|
114
|
+
type DbMode,
|
|
115
|
+
type DbProvider,
|
|
116
|
+
type BackendOrm,
|
|
117
|
+
type DbSetupStep,
|
|
118
|
+
type DbConfig,
|
|
119
|
+
} from './database.js';
|
|
120
|
+
|
|
121
|
+
// Database runtime types
|
|
122
|
+
export {
|
|
123
|
+
SetupStepResultSchema,
|
|
124
|
+
SetupResultSchema,
|
|
125
|
+
ReadinessCheckSchema,
|
|
126
|
+
ReadinessResultSchema,
|
|
127
|
+
type SetupStepResult,
|
|
128
|
+
type SetupResult,
|
|
129
|
+
type ReadinessCheck,
|
|
130
|
+
type ReadinessResult,
|
|
131
|
+
} from './database-runtime.js';
|
|
132
|
+
|
|
104
133
|
// CLI types
|
|
105
134
|
export {
|
|
106
135
|
EXIT_CODES,
|
package/src/types/workflow.ts
CHANGED
|
@@ -9,6 +9,8 @@ import type { OutputLanguage, OpenAIModel } from './project.js';
|
|
|
9
9
|
import type { ConsensusIteration } from './consensus.js';
|
|
10
10
|
import type { TestPlanOutput } from './tester.js';
|
|
11
11
|
import { TestPlanOutputSchema, TestVerdictSchema } from './tester.js';
|
|
12
|
+
import type { DbConfig } from './database.js';
|
|
13
|
+
import { DbConfigSchema } from './database.js';
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* Workflow phases
|
|
@@ -230,6 +232,8 @@ export interface ProjectState {
|
|
|
230
232
|
sourceDocPaths?: string[];
|
|
231
233
|
/** Whether QA Tester skill is active (default: true for new projects, undefined/false for existing) */
|
|
232
234
|
qaEnabled?: boolean;
|
|
235
|
+
/** Database configuration tracking (workspace projects only) */
|
|
236
|
+
dbConfig?: DbConfig;
|
|
233
237
|
}
|
|
234
238
|
|
|
235
239
|
/**
|
|
@@ -276,6 +280,7 @@ export const ProjectStateSchema = z.object({
|
|
|
276
280
|
strategyError: z.string().optional(),
|
|
277
281
|
sourceDocPaths: z.array(z.string()).optional(),
|
|
278
282
|
qaEnabled: z.boolean().optional(),
|
|
283
|
+
dbConfig: DbConfigSchema.optional(),
|
|
279
284
|
});
|
|
280
285
|
|
|
281
286
|
/**
|