prjct-cli 0.8.8 → 0.9.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/CHANGELOG.md +194 -0
- package/core/__tests__/agentic/agent-router.test.js +398 -0
- package/core/__tests__/agentic/context-filter.test.js +494 -0
- package/core/__tests__/domain/analyzer.test.js +324 -0
- package/core/__tests__/infrastructure/author-detector.test.js +103 -0
- package/core/__tests__/infrastructure/config-manager.test.js +454 -0
- package/core/__tests__/infrastructure/path-manager.test.js +412 -0
- package/core/__tests__/utils/jsonl-helper.test.js +387 -0
- package/core/agentic/agent-router.js +482 -0
- package/core/agentic/command-executor.js +70 -15
- package/core/agentic/context-filter.js +549 -0
- package/core/agentic/prompt-builder.js +48 -38
- package/core/command-registry.js +104 -164
- package/core/domain/agent-generator.js +55 -44
- package/core/domain/architecture-generator.js +561 -0
- package/core/domain/task-stack.js +496 -0
- package/package.json +2 -1
- package/templates/commands/analyze.md +10 -53
- package/templates/commands/bug.md +11 -70
- package/templates/commands/build.md +7 -37
- package/templates/commands/cleanup.md +9 -32
- package/templates/commands/dash.md +241 -0
- package/templates/commands/design.md +5 -28
- package/templates/commands/done.md +6 -20
- package/templates/commands/feature.md +11 -83
- package/templates/commands/help.md +9 -38
- package/templates/commands/idea.md +7 -28
- package/templates/commands/init.md +10 -89
- package/templates/commands/next.md +6 -26
- package/templates/commands/now.md +6 -26
- package/templates/commands/pause.md +18 -0
- package/templates/commands/progress.md +5 -50
- package/templates/commands/recap.md +5 -54
- package/templates/commands/resume.md +97 -0
- package/templates/commands/ship.md +13 -68
- package/templates/commands/status.md +7 -32
- package/templates/commands/sync.md +7 -24
- package/templates/commands/work.md +44 -0
- package/templates/commands/workflow.md +3 -25
- package/templates/planning-methodology.md +195 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Architecture Generator - Transforms ideas into complete technical specifications
|
|
3
|
+
* Uses AI-driven methodology to develop ideas through discovery, design, and planning phases
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const fs = require('fs').promises;
|
|
8
|
+
|
|
9
|
+
class ArchitectureGenerator {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.phases = [
|
|
12
|
+
'discovery',
|
|
13
|
+
'user-flows',
|
|
14
|
+
'domain-modeling',
|
|
15
|
+
'api-design',
|
|
16
|
+
'architecture',
|
|
17
|
+
'data-design',
|
|
18
|
+
'tech-stack',
|
|
19
|
+
'roadmap'
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Generate complete architecture from an idea
|
|
25
|
+
* @param {string} idea - The initial idea description
|
|
26
|
+
* @param {object} context - Project context and constraints
|
|
27
|
+
* @returns {Promise<object>} Complete architecture specification
|
|
28
|
+
*/
|
|
29
|
+
async generateArchitecture(idea, context = {}) {
|
|
30
|
+
const architecture = {
|
|
31
|
+
id: `arch-${Date.now()}`,
|
|
32
|
+
idea,
|
|
33
|
+
createdAt: new Date().toISOString(),
|
|
34
|
+
phases: {}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Phase 1: Discovery & Problem Definition
|
|
38
|
+
architecture.phases.discovery = await this.discovery(idea, context);
|
|
39
|
+
|
|
40
|
+
// Phase 2: User Flows & Journeys
|
|
41
|
+
architecture.phases.userFlows = await this.userFlows();
|
|
42
|
+
|
|
43
|
+
// Phase 3: Domain Modeling
|
|
44
|
+
architecture.phases.domainModel = await this.domainModeling();
|
|
45
|
+
|
|
46
|
+
// Phase 4: API Contract Design
|
|
47
|
+
architecture.phases.apiDesign = await this.apiDesign();
|
|
48
|
+
|
|
49
|
+
// Phase 5: System Architecture
|
|
50
|
+
architecture.phases.systemArchitecture = await this.systemArchitecture();
|
|
51
|
+
|
|
52
|
+
// Phase 6: Data Architecture
|
|
53
|
+
architecture.phases.dataArchitecture = await this.dataArchitecture(
|
|
54
|
+
architecture.phases.domainModel
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// Phase 7: Tech Stack Decision
|
|
58
|
+
architecture.phases.techStack = await this.techStackDecision();
|
|
59
|
+
|
|
60
|
+
// Phase 8: Implementation Roadmap
|
|
61
|
+
architecture.phases.roadmap = await this.roadmap();
|
|
62
|
+
|
|
63
|
+
return architecture;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Phase 1: Discovery & Problem Definition
|
|
68
|
+
*/
|
|
69
|
+
async discovery(idea, context) {
|
|
70
|
+
return {
|
|
71
|
+
problemStatement: {
|
|
72
|
+
problem: `Analyzing: ${idea}`,
|
|
73
|
+
currentPainPoint: 'To be determined through analysis',
|
|
74
|
+
impact: 'To be evaluated'
|
|
75
|
+
},
|
|
76
|
+
targetUsers: {
|
|
77
|
+
primary: {
|
|
78
|
+
persona: 'Primary User',
|
|
79
|
+
goals: [],
|
|
80
|
+
frustrations: [],
|
|
81
|
+
technicalProficiency: 'medium'
|
|
82
|
+
},
|
|
83
|
+
secondary: []
|
|
84
|
+
},
|
|
85
|
+
constraints: {
|
|
86
|
+
budget: context.budget || 'bootstrapped',
|
|
87
|
+
timeline: context.timeline || 'MVP in 4 weeks',
|
|
88
|
+
teamSize: context.teamSize || 1,
|
|
89
|
+
regulatory: context.regulatory || []
|
|
90
|
+
},
|
|
91
|
+
successMetrics: {
|
|
92
|
+
primary: 'User adoption rate',
|
|
93
|
+
secondary: ['engagement', 'retention'],
|
|
94
|
+
mvpThreshold: '100 active users'
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Phase 2: User Flows & Journeys
|
|
101
|
+
*/
|
|
102
|
+
async userFlows() {
|
|
103
|
+
return {
|
|
104
|
+
coreJourneys: [
|
|
105
|
+
{
|
|
106
|
+
name: 'Primary User Flow',
|
|
107
|
+
entryPoint: 'Landing page or direct link',
|
|
108
|
+
steps: [
|
|
109
|
+
{ action: 'Arrive', response: 'Show welcome', next: 'Onboarding' },
|
|
110
|
+
{ action: 'Complete onboarding', response: 'Create account', next: 'Dashboard' },
|
|
111
|
+
{ action: 'Use core feature', response: 'Process request', next: 'Results' }
|
|
112
|
+
],
|
|
113
|
+
successState: 'Task completed successfully',
|
|
114
|
+
errorStates: ['Network error', 'Validation error', 'Permission denied']
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
jobsToBeDone: [
|
|
118
|
+
{
|
|
119
|
+
situation: 'When I need to solve the core problem',
|
|
120
|
+
motivation: 'I want to use this solution',
|
|
121
|
+
expectedOutcome: 'So I can achieve my goal efficiently'
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Phase 3: Domain Modeling
|
|
129
|
+
*/
|
|
130
|
+
async domainModeling() {
|
|
131
|
+
return {
|
|
132
|
+
entities: [
|
|
133
|
+
{
|
|
134
|
+
name: 'User',
|
|
135
|
+
description: 'System user account',
|
|
136
|
+
attributes: [
|
|
137
|
+
{ name: 'id', type: 'uuid', constraints: 'primary key' },
|
|
138
|
+
{ name: 'email', type: 'string', constraints: 'unique, not null' },
|
|
139
|
+
{ name: 'createdAt', type: 'timestamp', constraints: 'not null' }
|
|
140
|
+
],
|
|
141
|
+
relationships: [],
|
|
142
|
+
businessRules: ['Email must be verified', 'User must accept terms'],
|
|
143
|
+
lifecycle: ['pending', 'active', 'suspended', 'deleted']
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
boundedContexts: [
|
|
147
|
+
{
|
|
148
|
+
name: 'User Management',
|
|
149
|
+
entities: ['User', 'Profile', 'Session'],
|
|
150
|
+
dependencies: [],
|
|
151
|
+
eventsPublished: ['UserCreated', 'UserUpdated'],
|
|
152
|
+
eventsConsumed: []
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Phase 4: API Design
|
|
160
|
+
*/
|
|
161
|
+
async apiDesign() {
|
|
162
|
+
return {
|
|
163
|
+
style: 'REST',
|
|
164
|
+
reasoning: 'Simple CRUD operations with broad compatibility',
|
|
165
|
+
endpoints: [
|
|
166
|
+
{
|
|
167
|
+
name: 'Create User',
|
|
168
|
+
method: 'POST',
|
|
169
|
+
path: '/api/users',
|
|
170
|
+
authentication: 'Optional',
|
|
171
|
+
inputSchema: {
|
|
172
|
+
email: 'string',
|
|
173
|
+
password: 'string'
|
|
174
|
+
},
|
|
175
|
+
outputSchema: {
|
|
176
|
+
id: 'string',
|
|
177
|
+
email: 'string',
|
|
178
|
+
createdAt: 'string'
|
|
179
|
+
},
|
|
180
|
+
errorResponses: [
|
|
181
|
+
{ code: 400, description: 'Invalid input' },
|
|
182
|
+
{ code: 409, description: 'Email already exists' }
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
],
|
|
186
|
+
authentication: {
|
|
187
|
+
method: 'JWT',
|
|
188
|
+
implementation: 'Lucia',
|
|
189
|
+
tokenStorage: 'httpOnly cookie',
|
|
190
|
+
sessionDuration: '7 days'
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Phase 5: System Architecture
|
|
197
|
+
*/
|
|
198
|
+
async systemArchitecture() {
|
|
199
|
+
return {
|
|
200
|
+
pattern: 'Modular Monolith',
|
|
201
|
+
reasoning: 'Fast iteration for MVP with small team',
|
|
202
|
+
components: {
|
|
203
|
+
frontend: 'Next.js App',
|
|
204
|
+
backend: 'Next.js API Routes',
|
|
205
|
+
database: 'PostgreSQL',
|
|
206
|
+
cache: 'Redis',
|
|
207
|
+
storage: 'S3-compatible'
|
|
208
|
+
},
|
|
209
|
+
deploymentModel: 'Serverless (Vercel)',
|
|
210
|
+
scalingStrategy: 'Horizontal with auto-scaling'
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Phase 6: Data Architecture
|
|
216
|
+
*/
|
|
217
|
+
async dataArchitecture(domainModel) {
|
|
218
|
+
const schemas = [];
|
|
219
|
+
|
|
220
|
+
for (const entity of domainModel.entities) {
|
|
221
|
+
schemas.push({
|
|
222
|
+
table: entity.name.toLowerCase() + 's',
|
|
223
|
+
columns: entity.attributes,
|
|
224
|
+
indexes: [
|
|
225
|
+
{ name: `idx_${entity.name.toLowerCase()}_created`, columns: ['createdAt'] }
|
|
226
|
+
],
|
|
227
|
+
relationships: entity.relationships
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
primaryDatabase: 'PostgreSQL',
|
|
233
|
+
reasoning: 'ACID compliance, complex queries, proven reliability',
|
|
234
|
+
schemas,
|
|
235
|
+
caching: {
|
|
236
|
+
strategy: 'Cache-aside',
|
|
237
|
+
ttl: {
|
|
238
|
+
user: 3600,
|
|
239
|
+
session: 1800
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
migration: {
|
|
243
|
+
tool: 'Drizzle Kit',
|
|
244
|
+
strategy: 'Forward-only migrations'
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Phase 7: Tech Stack Decision
|
|
251
|
+
*/
|
|
252
|
+
async techStackDecision() {
|
|
253
|
+
return {
|
|
254
|
+
frontend: {
|
|
255
|
+
framework: 'Next.js 14',
|
|
256
|
+
styling: 'Tailwind CSS',
|
|
257
|
+
state: 'Zustand',
|
|
258
|
+
forms: 'React Hook Form',
|
|
259
|
+
dataFetching: 'TanStack Query',
|
|
260
|
+
ui: 'shadcn/ui'
|
|
261
|
+
},
|
|
262
|
+
backend: {
|
|
263
|
+
runtime: 'Node.js',
|
|
264
|
+
framework: 'Next.js API Routes',
|
|
265
|
+
orm: 'Drizzle',
|
|
266
|
+
validation: 'Zod',
|
|
267
|
+
auth: 'Lucia',
|
|
268
|
+
background: 'Inngest'
|
|
269
|
+
},
|
|
270
|
+
infrastructure: {
|
|
271
|
+
hosting: 'Vercel',
|
|
272
|
+
database: 'Neon',
|
|
273
|
+
cache: 'Upstash Redis',
|
|
274
|
+
storage: 'Cloudflare R2',
|
|
275
|
+
monitoring: 'Sentry'
|
|
276
|
+
},
|
|
277
|
+
reasoning: {
|
|
278
|
+
frontend: 'Type-safe, modern DX, strong ecosystem',
|
|
279
|
+
backend: 'Unified codebase, serverless-first',
|
|
280
|
+
infrastructure: 'Cost-effective for MVP, scales well'
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Phase 8: Implementation Roadmap
|
|
287
|
+
*/
|
|
288
|
+
async roadmap() {
|
|
289
|
+
return {
|
|
290
|
+
mvpScope: {
|
|
291
|
+
goal: 'Validate core value proposition',
|
|
292
|
+
features: [
|
|
293
|
+
'User authentication',
|
|
294
|
+
'Core feature implementation',
|
|
295
|
+
'Basic dashboard',
|
|
296
|
+
'Essential API endpoints'
|
|
297
|
+
],
|
|
298
|
+
excluded: [
|
|
299
|
+
'Advanced analytics',
|
|
300
|
+
'Third-party integrations',
|
|
301
|
+
'Mobile app'
|
|
302
|
+
],
|
|
303
|
+
successCriteria: {
|
|
304
|
+
users: 100,
|
|
305
|
+
retention: '40% weekly active'
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
phases: [
|
|
309
|
+
{
|
|
310
|
+
name: 'Phase 1: Foundation',
|
|
311
|
+
duration: '1 week',
|
|
312
|
+
tasks: [
|
|
313
|
+
'Project setup and configuration',
|
|
314
|
+
'Database schema and migrations',
|
|
315
|
+
'Authentication system',
|
|
316
|
+
'Basic UI components'
|
|
317
|
+
],
|
|
318
|
+
deliverable: 'Working authentication and base UI'
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: 'Phase 2: Core Features',
|
|
322
|
+
duration: '2 weeks',
|
|
323
|
+
tasks: [
|
|
324
|
+
'Implement core domain logic',
|
|
325
|
+
'API endpoints',
|
|
326
|
+
'User dashboard',
|
|
327
|
+
'Data validation'
|
|
328
|
+
],
|
|
329
|
+
deliverable: 'Functional MVP'
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: 'Phase 3: Polish & Launch',
|
|
333
|
+
duration: '1 week',
|
|
334
|
+
tasks: [
|
|
335
|
+
'Error handling',
|
|
336
|
+
'Performance optimization',
|
|
337
|
+
'Security audit',
|
|
338
|
+
'Production deployment'
|
|
339
|
+
],
|
|
340
|
+
deliverable: 'Production-ready application'
|
|
341
|
+
}
|
|
342
|
+
],
|
|
343
|
+
estimatedTotal: '4 weeks',
|
|
344
|
+
risks: [
|
|
345
|
+
{
|
|
346
|
+
risk: 'Scope creep',
|
|
347
|
+
mitigation: 'Strict MVP feature set'
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
risk: 'Technical complexity',
|
|
351
|
+
mitigation: 'Use proven patterns and libraries'
|
|
352
|
+
}
|
|
353
|
+
]
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Save architecture to files
|
|
359
|
+
*/
|
|
360
|
+
async saveArchitecture(architecture, projectPath) {
|
|
361
|
+
const archPath = path.join(projectPath, 'planning', 'architectures', architecture.id);
|
|
362
|
+
await fs.mkdir(archPath, { recursive: true });
|
|
363
|
+
|
|
364
|
+
// Save each phase as a separate markdown file
|
|
365
|
+
const files = {
|
|
366
|
+
'discovery.md': this.formatDiscovery(architecture.phases.discovery),
|
|
367
|
+
'user-flows.md': this.formatUserFlows(architecture.phases.userFlows),
|
|
368
|
+
'domain-model.md': this.formatDomainModel(architecture.phases.domainModel),
|
|
369
|
+
'api-spec.md': this.formatApiSpec(architecture.phases.apiDesign),
|
|
370
|
+
'architecture.md': this.formatArchitecture(architecture.phases.systemArchitecture),
|
|
371
|
+
'database.sql': this.generateSQLSchema(architecture.phases.dataArchitecture),
|
|
372
|
+
'tech-stack.md': this.formatTechStack(architecture.phases.techStack),
|
|
373
|
+
'roadmap.md': this.formatRoadmap(architecture.phases.roadmap),
|
|
374
|
+
'summary.json': JSON.stringify(architecture, null, 2)
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
for (const [filename, content] of Object.entries(files)) {
|
|
378
|
+
await fs.writeFile(path.join(archPath, filename), content);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return archPath;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Formatting methods for each phase
|
|
385
|
+
formatDiscovery(discovery) {
|
|
386
|
+
return `# Discovery & Problem Definition
|
|
387
|
+
|
|
388
|
+
## Problem Statement
|
|
389
|
+
|
|
390
|
+
**Problem**: ${discovery.problemStatement.problem}
|
|
391
|
+
**Current Pain Point**: ${discovery.problemStatement.currentPainPoint}
|
|
392
|
+
**Impact**: ${discovery.problemStatement.impact}
|
|
393
|
+
|
|
394
|
+
## Target Users
|
|
395
|
+
|
|
396
|
+
### Primary User
|
|
397
|
+
- **Persona**: ${discovery.targetUsers.primary.persona}
|
|
398
|
+
- **Technical Proficiency**: ${discovery.targetUsers.primary.technicalProficiency}
|
|
399
|
+
|
|
400
|
+
## Constraints
|
|
401
|
+
- **Budget**: ${discovery.constraints.budget}
|
|
402
|
+
- **Timeline**: ${discovery.constraints.timeline}
|
|
403
|
+
- **Team Size**: ${discovery.constraints.teamSize}
|
|
404
|
+
|
|
405
|
+
## Success Metrics
|
|
406
|
+
- **Primary KPI**: ${discovery.successMetrics.primary}
|
|
407
|
+
- **MVP Threshold**: ${discovery.successMetrics.mvpThreshold}
|
|
408
|
+
`;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
formatUserFlows(userFlows) {
|
|
412
|
+
let content = '# User Flows & Journeys\n\n';
|
|
413
|
+
|
|
414
|
+
for (const journey of userFlows.coreJourneys) {
|
|
415
|
+
content += `## ${journey.name}\n\n`;
|
|
416
|
+
content += `**Entry Point**: ${journey.entryPoint}\n\n`;
|
|
417
|
+
content += '### Steps\n';
|
|
418
|
+
for (const step of journey.steps) {
|
|
419
|
+
content += `1. **${step.action}** → ${step.response} → ${step.next}\n`;
|
|
420
|
+
}
|
|
421
|
+
content += `\n**Success State**: ${journey.successState}\n\n`;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
return content;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
formatDomainModel(domainModel) {
|
|
428
|
+
let content = '# Domain Model\n\n## Entities\n\n';
|
|
429
|
+
|
|
430
|
+
for (const entity of domainModel.entities) {
|
|
431
|
+
content += `### ${entity.name}\n`;
|
|
432
|
+
content += `${entity.description}\n\n`;
|
|
433
|
+
content += '**Attributes**:\n';
|
|
434
|
+
for (const attr of entity.attributes) {
|
|
435
|
+
content += `- ${attr.name}: ${attr.type} (${attr.constraints})\n`;
|
|
436
|
+
}
|
|
437
|
+
content += '\n';
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return content;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
formatApiSpec(apiDesign) {
|
|
444
|
+
let content = `# API Specification\n\n`;
|
|
445
|
+
content += `**Style**: ${apiDesign.style}\n`;
|
|
446
|
+
content += `**Reasoning**: ${apiDesign.reasoning}\n\n`;
|
|
447
|
+
content += '## Endpoints\n\n';
|
|
448
|
+
|
|
449
|
+
for (const endpoint of apiDesign.endpoints) {
|
|
450
|
+
content += `### ${endpoint.name}\n`;
|
|
451
|
+
content += `- **Method**: ${endpoint.method}\n`;
|
|
452
|
+
content += `- **Path**: ${endpoint.path}\n`;
|
|
453
|
+
content += `- **Authentication**: ${endpoint.authentication}\n\n`;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return content;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
formatArchitecture(architecture) {
|
|
460
|
+
return `# System Architecture
|
|
461
|
+
|
|
462
|
+
**Pattern**: ${architecture.pattern}
|
|
463
|
+
**Reasoning**: ${architecture.reasoning}
|
|
464
|
+
|
|
465
|
+
## Components
|
|
466
|
+
- **Frontend**: ${architecture.components.frontend}
|
|
467
|
+
- **Backend**: ${architecture.components.backend}
|
|
468
|
+
- **Database**: ${architecture.components.database}
|
|
469
|
+
- **Cache**: ${architecture.components.cache}
|
|
470
|
+
|
|
471
|
+
## Deployment
|
|
472
|
+
- **Model**: ${architecture.deploymentModel}
|
|
473
|
+
- **Scaling**: ${architecture.scalingStrategy}
|
|
474
|
+
`;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
generateSQLSchema(dataArchitecture) {
|
|
478
|
+
let sql = '-- Generated Database Schema\n\n';
|
|
479
|
+
|
|
480
|
+
for (const schema of dataArchitecture.schemas) {
|
|
481
|
+
sql += `CREATE TABLE ${schema.table} (\n`;
|
|
482
|
+
for (const col of schema.columns) {
|
|
483
|
+
sql += ` ${col.name} ${this.sqlType(col.type)} ${col.constraints || ''},\n`;
|
|
484
|
+
}
|
|
485
|
+
sql = sql.slice(0, -2) + '\n);\n\n';
|
|
486
|
+
|
|
487
|
+
for (const index of schema.indexes) {
|
|
488
|
+
sql += `CREATE INDEX ${index.name} ON ${schema.table}(${index.columns.join(', ')});\n`;
|
|
489
|
+
}
|
|
490
|
+
sql += '\n';
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return sql;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
sqlType(type) {
|
|
497
|
+
const typeMap = {
|
|
498
|
+
'uuid': 'UUID',
|
|
499
|
+
'string': 'VARCHAR(255)',
|
|
500
|
+
'text': 'TEXT',
|
|
501
|
+
'int': 'INTEGER',
|
|
502
|
+
'timestamp': 'TIMESTAMP',
|
|
503
|
+
'boolean': 'BOOLEAN',
|
|
504
|
+
'json': 'JSONB'
|
|
505
|
+
};
|
|
506
|
+
return typeMap[type] || 'TEXT';
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
formatTechStack(techStack) {
|
|
510
|
+
return `# Tech Stack Decision
|
|
511
|
+
|
|
512
|
+
## Frontend
|
|
513
|
+
- **Framework**: ${techStack.frontend.framework}
|
|
514
|
+
- **Styling**: ${techStack.frontend.styling}
|
|
515
|
+
- **State Management**: ${techStack.frontend.state}
|
|
516
|
+
- **Forms**: ${techStack.frontend.forms}
|
|
517
|
+
- **Data Fetching**: ${techStack.frontend.dataFetching}
|
|
518
|
+
- **UI Library**: ${techStack.frontend.ui}
|
|
519
|
+
|
|
520
|
+
## Backend
|
|
521
|
+
- **Runtime**: ${techStack.backend.runtime}
|
|
522
|
+
- **Framework**: ${techStack.backend.framework}
|
|
523
|
+
- **ORM**: ${techStack.backend.orm}
|
|
524
|
+
- **Validation**: ${techStack.backend.validation}
|
|
525
|
+
- **Auth**: ${techStack.backend.auth}
|
|
526
|
+
|
|
527
|
+
## Infrastructure
|
|
528
|
+
- **Hosting**: ${techStack.infrastructure.hosting}
|
|
529
|
+
- **Database**: ${techStack.infrastructure.database}
|
|
530
|
+
- **Cache**: ${techStack.infrastructure.cache}
|
|
531
|
+
- **Monitoring**: ${techStack.infrastructure.monitoring}
|
|
532
|
+
`;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
formatRoadmap(roadmap) {
|
|
536
|
+
let content = `# Implementation Roadmap\n\n`;
|
|
537
|
+
content += `## MVP Scope\n\n`;
|
|
538
|
+
content += `**Goal**: ${roadmap.mvpScope.goal}\n\n`;
|
|
539
|
+
content += '### Included Features\n';
|
|
540
|
+
for (const feature of roadmap.mvpScope.features) {
|
|
541
|
+
content += `- ${feature}\n`;
|
|
542
|
+
}
|
|
543
|
+
content += '\n## Development Phases\n\n';
|
|
544
|
+
|
|
545
|
+
for (const phase of roadmap.phases) {
|
|
546
|
+
content += `### ${phase.name}\n`;
|
|
547
|
+
content += `**Duration**: ${phase.duration}\n\n`;
|
|
548
|
+
content += '**Tasks**:\n';
|
|
549
|
+
for (const task of phase.tasks) {
|
|
550
|
+
content += `- ${task}\n`;
|
|
551
|
+
}
|
|
552
|
+
content += `\n**Deliverable**: ${phase.deliverable}\n\n`;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
content += `## Total Estimate: ${roadmap.estimatedTotal}\n`;
|
|
556
|
+
|
|
557
|
+
return content;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
module.exports = ArchitectureGenerator;
|