popeye-cli 1.7.0 → 1.9.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 +148 -7
- package/cheatsheet.md +440 -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 +3 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +3 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/review.d.ts +31 -0
- package/dist/cli/commands/review.d.ts.map +1 -0
- package/dist/cli/commands/review.js +156 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +4 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/interactive.d.ts.map +1 -1
- package/dist/cli/interactive.js +218 -61
- 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/audit.d.ts +623 -0
- package/dist/types/audit.d.ts.map +1 -0
- package/dist/types/audit.js +240 -0
- package/dist/types/audit.js.map +1 -0
- 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 +36 -0
- package/dist/types/workflow.d.ts.map +1 -1
- package/dist/types/workflow.js +7 -0
- package/dist/types/workflow.js.map +1 -1
- package/dist/workflow/audit-analyzer.d.ts +58 -0
- package/dist/workflow/audit-analyzer.d.ts.map +1 -0
- package/dist/workflow/audit-analyzer.js +420 -0
- package/dist/workflow/audit-analyzer.js.map +1 -0
- package/dist/workflow/audit-mode.d.ts +28 -0
- package/dist/workflow/audit-mode.d.ts.map +1 -0
- package/dist/workflow/audit-mode.js +169 -0
- package/dist/workflow/audit-mode.js.map +1 -0
- package/dist/workflow/audit-recovery.d.ts +61 -0
- package/dist/workflow/audit-recovery.d.ts.map +1 -0
- package/dist/workflow/audit-recovery.js +242 -0
- package/dist/workflow/audit-recovery.js.map +1 -0
- package/dist/workflow/audit-reporter.d.ts +65 -0
- package/dist/workflow/audit-reporter.d.ts.map +1 -0
- package/dist/workflow/audit-reporter.js +301 -0
- package/dist/workflow/audit-reporter.js.map +1 -0
- package/dist/workflow/audit-scanner.d.ts +87 -0
- package/dist/workflow/audit-scanner.d.ts.map +1 -0
- package/dist/workflow/audit-scanner.js +768 -0
- package/dist/workflow/audit-scanner.js.map +1 -0
- 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 +7 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +7 -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 +3 -0
- package/src/cli/commands/review.ts +187 -0
- package/src/cli/index.ts +6 -0
- package/src/cli/interactive.ts +174 -4
- 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/audit.ts +294 -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 +20 -0
- package/src/workflow/audit-analyzer.ts +491 -0
- package/src/workflow/audit-mode.ts +240 -0
- package/src/workflow/audit-recovery.ts +284 -0
- package/src/workflow/audit-reporter.ts +370 -0
- package/src/workflow/audit-scanner.ts +873 -0
- package/src/workflow/db-setup-runner.ts +391 -0
- package/src/workflow/db-state-machine.ts +58 -0
- package/src/workflow/index.ts +7 -0
- package/tests/cli/commands/review.test.ts +52 -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/audit.test.ts +250 -0
- package/tests/types/database-runtime.test.ts +158 -0
- package/tests/types/database.test.ts +187 -0
- package/tests/workflow/audit-analyzer.test.ts +281 -0
- package/tests/workflow/audit-mode.test.ts +114 -0
- package/tests/workflow/audit-recovery.test.ts +237 -0
- package/tests/workflow/audit-reporter.test.ts +254 -0
- package/tests/workflow/audit-scanner.test.ts +270 -0
- package/tests/workflow/db-setup-runner.test.ts +211 -0
- package/tests/workflow/db-state-machine.test.ts +117 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database generator orchestration module
|
|
3
|
+
* Creates complete database layers for fullstack and TS backend projects
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { promises as fs } from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import type { BackendOrm } from '../types/database.js';
|
|
9
|
+
import {
|
|
10
|
+
generateDbConnection,
|
|
11
|
+
generateDbModels,
|
|
12
|
+
generateDbInit,
|
|
13
|
+
generateDbSettings,
|
|
14
|
+
generateAlembicIni,
|
|
15
|
+
generateAlembicEnvPy,
|
|
16
|
+
generateAlembicScriptMako,
|
|
17
|
+
generateInitialMigration,
|
|
18
|
+
generateDbVectorHelpers,
|
|
19
|
+
generateDbStartupHook,
|
|
20
|
+
generateDbHealthRoute,
|
|
21
|
+
generateDbConftest,
|
|
22
|
+
} from './templates/database-python.js';
|
|
23
|
+
import {
|
|
24
|
+
generatePrismaSchema,
|
|
25
|
+
generatePrismaClient,
|
|
26
|
+
generatePrismaSeed,
|
|
27
|
+
generatePrismaDbHealth,
|
|
28
|
+
generatePrismaVectorHelpers,
|
|
29
|
+
generatePrismaDbInit,
|
|
30
|
+
} from './templates/database-typescript.js';
|
|
31
|
+
|
|
32
|
+
/** Python database dependencies */
|
|
33
|
+
export const DB_PYTHON_DEPS = [
|
|
34
|
+
'sqlalchemy[asyncio]>=2.0.0',
|
|
35
|
+
'asyncpg>=0.29.0',
|
|
36
|
+
'alembic>=1.13.0',
|
|
37
|
+
'pgvector>=0.2.5',
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Options for database layer generation
|
|
42
|
+
*/
|
|
43
|
+
interface DatabaseLayerOptions {
|
|
44
|
+
includeVector?: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Create a directory if it doesn't exist
|
|
49
|
+
*/
|
|
50
|
+
async function ensureDir(dirPath: string): Promise<void> {
|
|
51
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Write a file with content
|
|
56
|
+
*/
|
|
57
|
+
async function writeFile(filePath: string, content: string): Promise<void> {
|
|
58
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Generate the complete Python database layer for a backend project
|
|
63
|
+
*
|
|
64
|
+
* Creates database/, migrations/, and supporting files under apps/backend/
|
|
65
|
+
*
|
|
66
|
+
* @param projectDir - Root project directory (contains apps/)
|
|
67
|
+
* @param projectName - Project name (used for naming)
|
|
68
|
+
* @param packageName - Python package name (snake_case)
|
|
69
|
+
* @param options - Generation options
|
|
70
|
+
* @returns List of absolute file paths created
|
|
71
|
+
*/
|
|
72
|
+
export async function generatePythonDatabaseLayer(
|
|
73
|
+
projectDir: string,
|
|
74
|
+
_projectName: string,
|
|
75
|
+
packageName: string,
|
|
76
|
+
options: DatabaseLayerOptions = {}
|
|
77
|
+
): Promise<string[]> {
|
|
78
|
+
const includeVector = options.includeVector !== false;
|
|
79
|
+
const backendDir = path.join(projectDir, 'apps', 'backend');
|
|
80
|
+
const srcPkgDir = path.join(backendDir, 'src', packageName);
|
|
81
|
+
const filesCreated: string[] = [];
|
|
82
|
+
|
|
83
|
+
// Ensure directories exist
|
|
84
|
+
await ensureDir(path.join(srcPkgDir, 'database'));
|
|
85
|
+
await ensureDir(path.join(srcPkgDir, 'routes'));
|
|
86
|
+
await ensureDir(path.join(backendDir, 'migrations', 'versions'));
|
|
87
|
+
await ensureDir(path.join(backendDir, 'tests'));
|
|
88
|
+
|
|
89
|
+
// Define all files to generate
|
|
90
|
+
const files: Array<{ path: string; content: string }> = [
|
|
91
|
+
// Database package
|
|
92
|
+
{
|
|
93
|
+
path: path.join(srcPkgDir, 'database', '__init__.py'),
|
|
94
|
+
content: generateDbInit(packageName),
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
path: path.join(srcPkgDir, 'database', 'connection.py'),
|
|
98
|
+
content: generateDbConnection(packageName),
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
path: path.join(srcPkgDir, 'database', 'models.py'),
|
|
102
|
+
content: generateDbModels(packageName),
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
path: path.join(srcPkgDir, 'database', 'settings.py'),
|
|
106
|
+
content: generateDbSettings(packageName),
|
|
107
|
+
},
|
|
108
|
+
// Alembic migrations
|
|
109
|
+
{
|
|
110
|
+
path: path.join(backendDir, 'alembic.ini'),
|
|
111
|
+
content: generateAlembicIni(packageName),
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
path: path.join(backendDir, 'migrations', 'env.py'),
|
|
115
|
+
content: generateAlembicEnvPy(packageName),
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
path: path.join(backendDir, 'migrations', 'script.py.mako'),
|
|
119
|
+
content: generateAlembicScriptMako(),
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
path: path.join(backendDir, 'migrations', 'versions', '001_initial.py'),
|
|
123
|
+
content: generateInitialMigration(packageName),
|
|
124
|
+
},
|
|
125
|
+
// Startup hook
|
|
126
|
+
{
|
|
127
|
+
path: path.join(srcPkgDir, 'startup.py'),
|
|
128
|
+
content: generateDbStartupHook(packageName),
|
|
129
|
+
},
|
|
130
|
+
// Health route
|
|
131
|
+
{
|
|
132
|
+
path: path.join(srcPkgDir, 'routes', 'health_db.py'),
|
|
133
|
+
content: generateDbHealthRoute(packageName),
|
|
134
|
+
},
|
|
135
|
+
// Test fixtures
|
|
136
|
+
{
|
|
137
|
+
path: path.join(backendDir, 'tests', 'conftest_db.py'),
|
|
138
|
+
content: generateDbConftest(packageName),
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
// Add vector helpers if requested
|
|
143
|
+
if (includeVector) {
|
|
144
|
+
files.push({
|
|
145
|
+
path: path.join(srcPkgDir, 'database', 'vector.py'),
|
|
146
|
+
content: generateDbVectorHelpers(packageName),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Write all files
|
|
151
|
+
for (const file of files) {
|
|
152
|
+
await writeFile(file.path, file.content);
|
|
153
|
+
filesCreated.push(file.path);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Augment requirements.txt with DB deps
|
|
157
|
+
const reqPath = path.join(backendDir, 'requirements.txt');
|
|
158
|
+
try {
|
|
159
|
+
const existingReqs = await fs.readFile(reqPath, 'utf-8');
|
|
160
|
+
const augmented = augmentRequirements(existingReqs, DB_PYTHON_DEPS);
|
|
161
|
+
await writeFile(reqPath, augmented);
|
|
162
|
+
} catch {
|
|
163
|
+
// requirements.txt doesn't exist yet - will be created by the main generator
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return filesCreated;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Generate the complete TypeScript database layer for a project
|
|
171
|
+
*
|
|
172
|
+
* Creates prisma/ and src/db/ directories with Prisma-based DB files
|
|
173
|
+
* NOTE: Not wired into any generator in Phase 1
|
|
174
|
+
*
|
|
175
|
+
* @param projectDir - Project directory (where prisma/ and src/ live)
|
|
176
|
+
* @param projectName - Project name
|
|
177
|
+
* @param options - Generation options
|
|
178
|
+
* @returns List of absolute file paths created
|
|
179
|
+
*/
|
|
180
|
+
export async function generateTypeScriptDatabaseLayer(
|
|
181
|
+
projectDir: string,
|
|
182
|
+
projectName: string,
|
|
183
|
+
_options: DatabaseLayerOptions = {}
|
|
184
|
+
): Promise<string[]> {
|
|
185
|
+
const filesCreated: string[] = [];
|
|
186
|
+
|
|
187
|
+
// Ensure directories
|
|
188
|
+
await ensureDir(path.join(projectDir, 'prisma'));
|
|
189
|
+
await ensureDir(path.join(projectDir, 'src', 'db'));
|
|
190
|
+
|
|
191
|
+
const files: Array<{ path: string; content: string }> = [
|
|
192
|
+
{
|
|
193
|
+
path: path.join(projectDir, 'prisma', 'schema.prisma'),
|
|
194
|
+
content: generatePrismaSchema(projectName),
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
path: path.join(projectDir, 'prisma', 'seed.ts'),
|
|
198
|
+
content: generatePrismaSeed(),
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
path: path.join(projectDir, 'src', 'db', 'client.ts'),
|
|
202
|
+
content: generatePrismaClient(projectName),
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
path: path.join(projectDir, 'src', 'db', 'health.ts'),
|
|
206
|
+
content: generatePrismaDbHealth(),
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
path: path.join(projectDir, 'src', 'db', 'vector.ts'),
|
|
210
|
+
content: generatePrismaVectorHelpers(),
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
path: path.join(projectDir, 'src', 'db', 'index.ts'),
|
|
214
|
+
content: generatePrismaDbInit(),
|
|
215
|
+
},
|
|
216
|
+
];
|
|
217
|
+
|
|
218
|
+
for (const file of files) {
|
|
219
|
+
await writeFile(file.path, file.content);
|
|
220
|
+
filesCreated.push(file.path);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return filesCreated;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Append database dependencies to an existing requirements.txt
|
|
228
|
+
*
|
|
229
|
+
* Idempotent: checks for existing "# Database" section to avoid duplicates.
|
|
230
|
+
* Handles empty input gracefully.
|
|
231
|
+
*
|
|
232
|
+
* @param baseContent - Existing requirements.txt content
|
|
233
|
+
* @param dbDeps - Database dependency strings to add
|
|
234
|
+
* @returns Augmented requirements.txt content
|
|
235
|
+
*/
|
|
236
|
+
export function augmentRequirements(baseContent: string, dbDeps: string[]): string {
|
|
237
|
+
// Check for existing Database section
|
|
238
|
+
if (baseContent.includes('# Database')) {
|
|
239
|
+
return baseContent;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Ensure trailing newline before adding section
|
|
243
|
+
const base = baseContent.trimEnd();
|
|
244
|
+
const depsBlock = dbDeps.join('\n');
|
|
245
|
+
|
|
246
|
+
return `${base}\n\n# Database\n${depsBlock}\n`;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Get the list of relative file paths generated for a database layer
|
|
251
|
+
*
|
|
252
|
+
* @param packageName - Python package name (for sqlalchemy) or project name (for prisma)
|
|
253
|
+
* @param orm - ORM type
|
|
254
|
+
* @returns List of relative file paths
|
|
255
|
+
*/
|
|
256
|
+
export function getDatabaseFiles(packageName: string, orm: BackendOrm): string[] {
|
|
257
|
+
if (orm === 'sqlalchemy') {
|
|
258
|
+
return [
|
|
259
|
+
`apps/backend/src/${packageName}/database/__init__.py`,
|
|
260
|
+
`apps/backend/src/${packageName}/database/connection.py`,
|
|
261
|
+
`apps/backend/src/${packageName}/database/models.py`,
|
|
262
|
+
`apps/backend/src/${packageName}/database/settings.py`,
|
|
263
|
+
`apps/backend/src/${packageName}/database/vector.py`,
|
|
264
|
+
`apps/backend/src/${packageName}/routes/health_db.py`,
|
|
265
|
+
`apps/backend/src/${packageName}/startup.py`,
|
|
266
|
+
'apps/backend/alembic.ini',
|
|
267
|
+
'apps/backend/migrations/env.py',
|
|
268
|
+
'apps/backend/migrations/script.py.mako',
|
|
269
|
+
'apps/backend/migrations/versions/001_initial.py',
|
|
270
|
+
'apps/backend/tests/conftest_db.py',
|
|
271
|
+
];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (orm === 'prisma') {
|
|
275
|
+
return [
|
|
276
|
+
'prisma/schema.prisma',
|
|
277
|
+
'prisma/seed.ts',
|
|
278
|
+
'src/db/client.ts',
|
|
279
|
+
'src/db/health.ts',
|
|
280
|
+
'src/db/vector.ts',
|
|
281
|
+
'src/db/index.ts',
|
|
282
|
+
];
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
@@ -9,7 +9,6 @@ import type { ProjectSpec } from '../types/project.js';
|
|
|
9
9
|
import type { GenerationResult } from './python.js';
|
|
10
10
|
import {
|
|
11
11
|
generateWorkspaceJson,
|
|
12
|
-
generateRootDockerCompose,
|
|
13
12
|
generateRootReadme,
|
|
14
13
|
generateRootGitignore,
|
|
15
14
|
generateFrontendReadme,
|
|
@@ -19,7 +18,6 @@ import {
|
|
|
19
18
|
generateTailwindConfig,
|
|
20
19
|
generatePostcssConfig,
|
|
21
20
|
generateMainCss,
|
|
22
|
-
generateAppTsx,
|
|
23
21
|
generateMainTsx,
|
|
24
22
|
generateIndexHtml,
|
|
25
23
|
generateFrontendPackageJson,
|
|
@@ -30,10 +28,15 @@ import {
|
|
|
30
28
|
generateFrontendTest,
|
|
31
29
|
generateVitestSetup,
|
|
32
30
|
generateFrontendVitestConfig,
|
|
33
|
-
generateFastAPIMain,
|
|
34
31
|
generateBackendDockerfile,
|
|
35
32
|
generateFastAPIRequirements,
|
|
36
33
|
} from './templates/fullstack.js';
|
|
34
|
+
import { generateAppTsxWithAdmin } from './templates/admin-wizard-react.js';
|
|
35
|
+
import { generateFastAPIMainWithAdmin } from './templates/admin-wizard-python.js';
|
|
36
|
+
import { generateDockerComposeWithDb, generateDbEnvExample } from './templates/database-docker.js';
|
|
37
|
+
import { generatePythonDatabaseLayer } from './database.js';
|
|
38
|
+
import { getDatabaseFiles } from './database.js';
|
|
39
|
+
import { generateAdminWizardLayer, getAdminWizardFiles } from './admin-wizard.js';
|
|
37
40
|
|
|
38
41
|
/**
|
|
39
42
|
* Options for fullstack project generation
|
|
@@ -112,11 +115,11 @@ export async function generateFullstackProject(
|
|
|
112
115
|
// Docker
|
|
113
116
|
{
|
|
114
117
|
path: path.join(projectDir, 'infra', 'docker', 'docker-compose.yml'),
|
|
115
|
-
content:
|
|
118
|
+
content: generateDockerComposeWithDb(projectName),
|
|
116
119
|
},
|
|
117
120
|
{
|
|
118
121
|
path: path.join(projectDir, 'docker-compose.yml'),
|
|
119
|
-
content:
|
|
122
|
+
content: generateDockerComposeWithDb(projectName),
|
|
120
123
|
},
|
|
121
124
|
// Documentation
|
|
122
125
|
{
|
|
@@ -192,7 +195,7 @@ export async function generateFullstackProject(
|
|
|
192
195
|
},
|
|
193
196
|
{
|
|
194
197
|
path: path.join(frontendDir, 'src', 'App.tsx'),
|
|
195
|
-
content:
|
|
198
|
+
content: generateAppTsxWithAdmin(projectName),
|
|
196
199
|
},
|
|
197
200
|
{
|
|
198
201
|
path: path.join(frontendDir, 'src', 'index.css'),
|
|
@@ -228,7 +231,7 @@ export async function generateFullstackProject(
|
|
|
228
231
|
// Environment
|
|
229
232
|
{
|
|
230
233
|
path: path.join(frontendDir, '.env.example'),
|
|
231
|
-
content: 'VITE_API_URL=http://localhost:8000\n',
|
|
234
|
+
content: 'VITE_API_URL=http://localhost:8000\nVITE_ADMIN_TOKEN=change-me-to-a-random-string\n',
|
|
232
235
|
},
|
|
233
236
|
{
|
|
234
237
|
path: path.join(frontendDir, '.gitignore'),
|
|
@@ -265,7 +268,7 @@ export async function generateFullstackProject(
|
|
|
265
268
|
},
|
|
266
269
|
{
|
|
267
270
|
path: path.join(backendDir, 'src', packageName, 'main.py'),
|
|
268
|
-
content:
|
|
271
|
+
content: generateFastAPIMainWithAdmin(projectName, packageName),
|
|
269
272
|
},
|
|
270
273
|
// Test files
|
|
271
274
|
{
|
|
@@ -293,7 +296,7 @@ export async function generateFullstackProject(
|
|
|
293
296
|
// Environment
|
|
294
297
|
{
|
|
295
298
|
path: path.join(backendDir, '.env.example'),
|
|
296
|
-
content:
|
|
299
|
+
content: generateDbEnvExample(projectName),
|
|
297
300
|
},
|
|
298
301
|
{
|
|
299
302
|
path: path.join(backendDir, '.gitignore'),
|
|
@@ -312,6 +315,16 @@ export async function generateFullstackProject(
|
|
|
312
315
|
filesCreated.push(file.path);
|
|
313
316
|
}
|
|
314
317
|
|
|
318
|
+
// Generate database layer (SQLAlchemy + Alembic + pgvector)
|
|
319
|
+
const dbFiles = await generatePythonDatabaseLayer(
|
|
320
|
+
projectDir, projectName, packageName, { includeVector: true }
|
|
321
|
+
);
|
|
322
|
+
filesCreated.push(...dbFiles);
|
|
323
|
+
|
|
324
|
+
// Generate admin wizard layer (middleware + routes + React components)
|
|
325
|
+
const adminFiles = await generateAdminWizardLayer(projectDir, packageName);
|
|
326
|
+
filesCreated.push(...adminFiles);
|
|
327
|
+
|
|
315
328
|
return {
|
|
316
329
|
success: true,
|
|
317
330
|
projectDir,
|
|
@@ -520,6 +533,10 @@ export function getFullstackProjectFiles(projectName: string): string[] {
|
|
|
520
533
|
'apps/backend/.env.example',
|
|
521
534
|
'apps/backend/.gitignore',
|
|
522
535
|
'apps/backend/Makefile',
|
|
536
|
+
// Database layer
|
|
537
|
+
...getDatabaseFiles(packageName, 'sqlalchemy'),
|
|
538
|
+
// Admin wizard layer
|
|
539
|
+
...getAdminWizardFiles(packageName),
|
|
523
540
|
];
|
|
524
541
|
}
|
|
525
542
|
|
package/src/generators/index.ts
CHANGED
|
@@ -69,6 +69,18 @@ export {
|
|
|
69
69
|
getAllProjectFiles,
|
|
70
70
|
type AllGeneratorOptions,
|
|
71
71
|
} from './all.js';
|
|
72
|
+
export {
|
|
73
|
+
generatePythonDatabaseLayer,
|
|
74
|
+
generateTypeScriptDatabaseLayer,
|
|
75
|
+
augmentRequirements,
|
|
76
|
+
getDatabaseFiles,
|
|
77
|
+
DB_PYTHON_DEPS,
|
|
78
|
+
} from './database.js';
|
|
79
|
+
export {
|
|
80
|
+
generateAdminWizardLayer,
|
|
81
|
+
getAdminWizardFiles,
|
|
82
|
+
ADMIN_WIZARD_PYTHON_DEPS,
|
|
83
|
+
} from './admin-wizard.js';
|
|
72
84
|
export * from './templates/index.js';
|
|
73
85
|
|
|
74
86
|
/**
|