@zodic/shared 0.0.371 → 0.0.373
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/app/services/ArchetypeService.ts +280 -277
- package/app/services/ConceptService.ts +65 -53
- package/app/workflow/ArchetypeWorkflow.ts +179 -118
- package/package.json +1 -1
|
@@ -342,14 +342,14 @@ export class ConceptService {
|
|
|
342
342
|
console.log(
|
|
343
343
|
`[${new Date().toISOString()}] 🚀 Generating Leonardo prompt for concept: ${conceptSlug}, combination: ${combinationString}, override: ${override}`
|
|
344
344
|
);
|
|
345
|
-
|
|
345
|
+
|
|
346
346
|
const db = drizzle(this.context.env.DB); // ✅ Initialize Drizzle with Cloudflare D1
|
|
347
|
-
|
|
347
|
+
|
|
348
348
|
// ✅ Fetch concept data from D1 for both languages
|
|
349
349
|
console.log(
|
|
350
350
|
`[${new Date().toISOString()}] 📡 Fetching concept data for ${conceptSlug}:${combinationString}`
|
|
351
351
|
);
|
|
352
|
-
|
|
352
|
+
|
|
353
353
|
const conceptEntries = await db
|
|
354
354
|
.select({
|
|
355
355
|
id: conceptsData.id,
|
|
@@ -368,28 +368,34 @@ export class ConceptService {
|
|
|
368
368
|
)
|
|
369
369
|
)
|
|
370
370
|
.execute();
|
|
371
|
-
|
|
371
|
+
|
|
372
372
|
if (conceptEntries.length !== 2) {
|
|
373
373
|
throw new Error(
|
|
374
374
|
`❌ Missing concept data for ${conceptSlug}:${combinationString}. Ensure basic info is populated first.`
|
|
375
375
|
);
|
|
376
376
|
}
|
|
377
|
-
|
|
377
|
+
|
|
378
378
|
const conceptEN = conceptEntries.find((c) => c.language === 'en-us');
|
|
379
379
|
const conceptPT = conceptEntries.find((c) => c.language === 'pt-br');
|
|
380
|
-
|
|
380
|
+
|
|
381
381
|
if (!conceptEN || !conceptPT) {
|
|
382
382
|
throw new Error(`❌ Could not find both EN and PT versions.`);
|
|
383
383
|
}
|
|
384
|
-
|
|
384
|
+
|
|
385
|
+
const leonardoPromptExistsEN =
|
|
386
|
+
conceptEN.leonardoPrompt && conceptEN.leonardoPrompt.length > 4;
|
|
387
|
+
|
|
388
|
+
const leonardoPromptExistsPT =
|
|
389
|
+
conceptPT.leonardoPrompt && conceptPT.leonardoPrompt.length > 4;
|
|
390
|
+
|
|
385
391
|
// ✅ Check if prompt already exists and skip if override is false
|
|
386
|
-
if (!override &&
|
|
392
|
+
if (!override && leonardoPromptExistsEN && leonardoPromptExistsPT) {
|
|
387
393
|
console.log(
|
|
388
394
|
`[${new Date().toISOString()}] ⚡ Leonardo prompt already exists for ${conceptSlug}, skipping.`
|
|
389
395
|
);
|
|
390
|
-
return { generatedPrompt: conceptEN.leonardoPrompt };
|
|
396
|
+
return { generatedPrompt: conceptEN.leonardoPrompt! };
|
|
391
397
|
}
|
|
392
|
-
|
|
398
|
+
|
|
393
399
|
// ✅ Ensure basic info is present
|
|
394
400
|
if (
|
|
395
401
|
!conceptEN.name ||
|
|
@@ -403,7 +409,7 @@ export class ConceptService {
|
|
|
403
409
|
`❌ Basic info must be populated before generating Leonardo prompt for concept: ${conceptSlug}`
|
|
404
410
|
);
|
|
405
411
|
}
|
|
406
|
-
|
|
412
|
+
|
|
407
413
|
// ✅ Generate prompt request
|
|
408
414
|
const messages = this.context
|
|
409
415
|
.buildLLMMessages()
|
|
@@ -411,7 +417,7 @@ export class ConceptService {
|
|
|
411
417
|
conceptSlug,
|
|
412
418
|
combination: combinationString,
|
|
413
419
|
});
|
|
414
|
-
|
|
420
|
+
|
|
415
421
|
// ✅ Call ChatGPT API
|
|
416
422
|
const response = await this.context.api().callTogether.single(messages, {});
|
|
417
423
|
if (!response) {
|
|
@@ -419,25 +425,28 @@ export class ConceptService {
|
|
|
419
425
|
`❌ Failed to generate Leonardo prompt for concept: ${conceptSlug}`
|
|
420
426
|
);
|
|
421
427
|
}
|
|
422
|
-
|
|
428
|
+
|
|
423
429
|
// Clean the response to remove unwanted elements
|
|
424
430
|
let generatedPrompt = response.trim();
|
|
425
|
-
|
|
431
|
+
|
|
426
432
|
// Step 1: Remove **Prompt:** or Prompt: from the start
|
|
427
|
-
generatedPrompt = generatedPrompt.replace(
|
|
428
|
-
|
|
433
|
+
generatedPrompt = generatedPrompt.replace(
|
|
434
|
+
/^(?:\*\*Prompt:\*\*|Prompt:)\s*/,
|
|
435
|
+
''
|
|
436
|
+
);
|
|
437
|
+
|
|
429
438
|
// Step 2: Remove character count suffix (e.g., *(Character count: 749)* or *(1498 characters)*)
|
|
430
439
|
generatedPrompt = generatedPrompt.replace(/\s*\*\([^()]*\)*\s*$/, '');
|
|
431
|
-
|
|
440
|
+
|
|
432
441
|
// Step 3: Remove surrounding quotes if they wrap the entire prompt
|
|
433
442
|
if (generatedPrompt.startsWith('"') && generatedPrompt.endsWith('"')) {
|
|
434
443
|
generatedPrompt = generatedPrompt.slice(1, -1).trim();
|
|
435
444
|
}
|
|
436
|
-
|
|
445
|
+
|
|
437
446
|
console.log(
|
|
438
447
|
`[${new Date().toISOString()}] ✨ Cleaned generated prompt: "${generatedPrompt}"`
|
|
439
448
|
);
|
|
440
|
-
|
|
449
|
+
|
|
441
450
|
// ✅ Store the generated prompt in D1 for both languages
|
|
442
451
|
console.log(
|
|
443
452
|
`[${new Date().toISOString()}] 💾 Storing Leonardo prompt for ${conceptSlug}:${combinationString} in D1...`
|
|
@@ -462,11 +471,11 @@ export class ConceptService {
|
|
|
462
471
|
)
|
|
463
472
|
),
|
|
464
473
|
]);
|
|
465
|
-
|
|
474
|
+
|
|
466
475
|
console.log(
|
|
467
476
|
`[${new Date().toISOString()}] ✅ Leonardo prompt stored for concept: ${conceptSlug}, combination: ${combinationString}, in both languages.`
|
|
468
477
|
);
|
|
469
|
-
|
|
478
|
+
|
|
470
479
|
return { generatedPrompt };
|
|
471
480
|
}
|
|
472
481
|
|
|
@@ -1817,41 +1826,44 @@ export class ConceptService {
|
|
|
1817
1826
|
.limit(1)
|
|
1818
1827
|
.execute();
|
|
1819
1828
|
|
|
1820
|
-
return
|
|
1829
|
+
return (
|
|
1830
|
+
!!conceptData?.leonardoPrompt && conceptData.leonardoPrompt.length > 10
|
|
1831
|
+
);
|
|
1821
1832
|
}
|
|
1822
1833
|
|
|
1823
|
-
// src/services/ConceptService.ts
|
|
1824
|
-
async checkConceptCompletion(
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
): Promise<boolean> {
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1834
|
+
// src/services/ConceptService.ts
|
|
1835
|
+
async checkConceptCompletion(
|
|
1836
|
+
conceptSlug: Concept,
|
|
1837
|
+
combinationString: string,
|
|
1838
|
+
lang: string = 'en-us'
|
|
1839
|
+
): Promise<boolean> {
|
|
1840
|
+
const db = this.context.drizzle();
|
|
1841
|
+
const [conceptData] = await db
|
|
1842
|
+
.select({
|
|
1843
|
+
leonardoPrompt: schema.conceptsData.leonardoPrompt,
|
|
1844
|
+
postImages: schema.conceptsData.postImages,
|
|
1845
|
+
reelImages: schema.conceptsData.reelImages,
|
|
1846
|
+
})
|
|
1847
|
+
.from(schema.conceptsData)
|
|
1848
|
+
.where(
|
|
1849
|
+
and(
|
|
1850
|
+
eq(schema.conceptsData.conceptSlug, conceptSlug),
|
|
1851
|
+
eq(schema.conceptsData.combination, combinationString),
|
|
1852
|
+
eq(schema.conceptsData.language, lang)
|
|
1853
|
+
)
|
|
1842
1854
|
)
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
.execute();
|
|
1846
|
-
|
|
1847
|
-
if (!conceptData) return false; // No concept data found
|
|
1855
|
+
.limit(1)
|
|
1856
|
+
.execute();
|
|
1848
1857
|
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1858
|
+
if (!conceptData) return false; // No concept data found
|
|
1859
|
+
const hasPrompt =
|
|
1860
|
+
!!conceptData?.leonardoPrompt && conceptData.leonardoPrompt.length > 10;
|
|
1861
|
+
// Check if postImages and reelImages are valid non-empty JSON arrays
|
|
1862
|
+
const hasPostImages =
|
|
1863
|
+
conceptData.postImages &&
|
|
1864
|
+
conceptData.postImages.trim().length > 4 && // Ensures length > 4 to exclude "[]"
|
|
1865
|
+
JSON.parse(conceptData.postImages).length > 2;
|
|
1854
1866
|
|
|
1855
|
-
|
|
1856
|
-
}
|
|
1867
|
+
return hasPrompt && !!hasPostImages;
|
|
1868
|
+
}
|
|
1857
1869
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { and, eq
|
|
1
|
+
import { and, eq } from 'drizzle-orm';
|
|
2
2
|
import { inject, injectable } from 'inversify';
|
|
3
3
|
import { schema } from '../..';
|
|
4
4
|
import { Gender } from '../../types';
|
|
@@ -20,7 +20,7 @@ export class ArchetypeWorkflow {
|
|
|
20
20
|
context: Record<string, any> = {}
|
|
21
21
|
) {
|
|
22
22
|
const logId = `archetype-workflow:${Date.now()}`;
|
|
23
|
-
const logMessage = `[${level.toUpperCase()}] ${message}`;
|
|
23
|
+
const logMessage = `[${new Date().toISOString()}] [${level.toUpperCase()}] ${message}`;
|
|
24
24
|
|
|
25
25
|
console[level](logMessage, context);
|
|
26
26
|
const db = this.context.drizzle();
|
|
@@ -48,167 +48,228 @@ export class ArchetypeWorkflow {
|
|
|
48
48
|
async execute(
|
|
49
49
|
combinationString: string,
|
|
50
50
|
gender: Gender,
|
|
51
|
-
language: string = 'en-us'
|
|
51
|
+
language: string = 'en-us',
|
|
52
|
+
override: boolean = false
|
|
52
53
|
) {
|
|
53
54
|
await this.log('info', 'Starting ArchetypeWorkflow', {
|
|
54
55
|
combinationString,
|
|
55
56
|
gender,
|
|
56
57
|
language,
|
|
58
|
+
override,
|
|
57
59
|
});
|
|
58
|
-
|
|
59
|
-
// Step 1:
|
|
60
|
+
|
|
61
|
+
// Step 1: Fetch existing archetypes
|
|
60
62
|
let archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
61
63
|
combinationString,
|
|
62
64
|
gender,
|
|
63
65
|
language
|
|
64
66
|
);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
await this.log('info', 'Fetched existing archetypes', {
|
|
68
|
+
archetypesCount: archetypes.length,
|
|
69
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Step 2: Generate or update archetype names and essence lines
|
|
73
|
+
if (
|
|
74
|
+
override ||
|
|
75
|
+
archetypes.length === 0 ||
|
|
76
|
+
archetypes.some((a) => !a.name || !a.essenceLine)
|
|
77
|
+
) {
|
|
78
|
+
await this.log('info', 'Generating or updating archetype names', {
|
|
67
79
|
combinationString,
|
|
68
80
|
gender,
|
|
69
81
|
language,
|
|
82
|
+
override,
|
|
70
83
|
});
|
|
71
|
-
await this.archetypeService.generateArchetypeNames(
|
|
84
|
+
await this.archetypeService.generateArchetypeNames(
|
|
85
|
+
combinationString,
|
|
86
|
+
override
|
|
87
|
+
);
|
|
72
88
|
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
73
89
|
combinationString,
|
|
74
90
|
gender,
|
|
75
91
|
language
|
|
76
92
|
);
|
|
93
|
+
await this.log('info', 'Refetched archetypes after name generation', {
|
|
94
|
+
archetypesCount: archetypes.length,
|
|
95
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
await this.log('info', 'Skipping archetype names generation', {
|
|
99
|
+
reason: 'Names and essence lines already exist',
|
|
100
|
+
});
|
|
77
101
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
inArray(
|
|
97
|
-
schema.generations.archetypeDataId,
|
|
98
|
-
archetypes.map((a) => a.id)
|
|
99
|
-
)
|
|
100
|
-
)
|
|
101
|
-
)
|
|
102
|
-
.execute();
|
|
103
|
-
|
|
104
|
-
if (inProgressGenerations.length > 0) {
|
|
105
|
-
await this.log(
|
|
106
|
-
'warn',
|
|
107
|
-
`Images are already being processed for ${combinationString}, gender: ${gender}`,
|
|
108
|
-
{
|
|
109
|
-
inProgressGenerationsCount: inProgressGenerations.length,
|
|
110
|
-
generationIds: inProgressGenerations.map((g) => g.id),
|
|
111
|
-
}
|
|
102
|
+
|
|
103
|
+
// Step 3: Generate or update descriptions and virtues
|
|
104
|
+
let descVirtues: any[] = [];
|
|
105
|
+
if (
|
|
106
|
+
override ||
|
|
107
|
+
archetypes.some((a) => !a.description || a.virtues === '[]')
|
|
108
|
+
) {
|
|
109
|
+
await this.log('info', 'Generating or updating descriptions and virtues', {
|
|
110
|
+
combinationString,
|
|
111
|
+
gender,
|
|
112
|
+
language,
|
|
113
|
+
override,
|
|
114
|
+
});
|
|
115
|
+
descVirtues = await this.archetypeService.generateDescriptionsAndVirtues(
|
|
116
|
+
combinationString,
|
|
117
|
+
gender,
|
|
118
|
+
language,
|
|
119
|
+
override
|
|
112
120
|
);
|
|
113
|
-
|
|
121
|
+
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
122
|
+
combinationString,
|
|
123
|
+
gender,
|
|
124
|
+
language
|
|
125
|
+
);
|
|
126
|
+
await this.log('info', 'Refetched archetypes after descriptions and virtues', {
|
|
127
|
+
archetypesCount: archetypes.length,
|
|
128
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
129
|
+
});
|
|
130
|
+
} else {
|
|
131
|
+
await this.log('info', 'Skipping descriptions and virtues generation', {
|
|
132
|
+
reason: 'Descriptions and virtues already exist',
|
|
133
|
+
});
|
|
114
134
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
// Step 3: Generate missing textual content (description, virtues, content, leonardoPrompt)
|
|
121
|
-
const archetypesNeedingText = archetypes.filter(
|
|
122
|
-
(arc) =>
|
|
123
|
-
!arc.description ||
|
|
124
|
-
arc.virtues === '[]' ||
|
|
125
|
-
arc.content === '[]' ||
|
|
126
|
-
!arc.leonardoPrompt
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
if (archetypesNeedingText.length > 0) {
|
|
130
|
-
await this.log('info', 'Generating missing textual content', {
|
|
135
|
+
|
|
136
|
+
// Step 4: Generate or update content
|
|
137
|
+
if (override || archetypes.some((a) => a.content === '[]')) {
|
|
138
|
+
await this.log('info', 'Generating or updating content', {
|
|
131
139
|
combinationString,
|
|
132
140
|
gender,
|
|
133
141
|
language,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
const descVirtues =
|
|
139
|
-
await this.archetypeService.generateDescriptionsAndVirtues(
|
|
140
|
-
combinationString,
|
|
141
|
-
gender,
|
|
142
|
-
language
|
|
143
|
-
);
|
|
142
|
+
override,
|
|
143
|
+
});
|
|
144
144
|
await this.archetypeService.generateContent(
|
|
145
145
|
combinationString,
|
|
146
146
|
gender,
|
|
147
147
|
language,
|
|
148
|
-
descVirtues
|
|
148
|
+
descVirtues,
|
|
149
|
+
override
|
|
149
150
|
);
|
|
150
|
-
await this.archetypeService.
|
|
151
|
+
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
151
152
|
combinationString,
|
|
152
153
|
gender,
|
|
153
|
-
language
|
|
154
|
-
descVirtues
|
|
154
|
+
language
|
|
155
155
|
);
|
|
156
|
+
await this.log('info', 'Refetched archetypes after content generation', {
|
|
157
|
+
archetypesCount: archetypes.length,
|
|
158
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
159
|
+
});
|
|
156
160
|
} else {
|
|
157
|
-
await this.log('info', '
|
|
161
|
+
await this.log('info', 'Skipping content generation', {
|
|
162
|
+
reason: 'Content already exists',
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Step 5: Generate or update Leonardo prompts
|
|
167
|
+
if (override || archetypes.some((a) => !a.leonardoPrompt)) {
|
|
168
|
+
await this.log('info', 'Generating or updating Leonardo prompts', {
|
|
158
169
|
combinationString,
|
|
159
170
|
gender,
|
|
160
171
|
language,
|
|
172
|
+
override,
|
|
173
|
+
});
|
|
174
|
+
await this.archetypeService.generateLeonardoPrompts(
|
|
175
|
+
combinationString,
|
|
176
|
+
gender,
|
|
177
|
+
language,
|
|
178
|
+
descVirtues,
|
|
179
|
+
override
|
|
180
|
+
);
|
|
181
|
+
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
182
|
+
combinationString,
|
|
183
|
+
gender,
|
|
184
|
+
language
|
|
185
|
+
);
|
|
186
|
+
await this.log('info', 'Refetched archetypes after Leonardo prompts', {
|
|
187
|
+
archetypesCount: archetypes.length,
|
|
188
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
189
|
+
});
|
|
190
|
+
} else {
|
|
191
|
+
await this.log('info', 'Skipping Leonardo prompts generation', {
|
|
192
|
+
reason: 'Leonardo prompts already exist',
|
|
161
193
|
});
|
|
162
194
|
}
|
|
163
|
-
|
|
164
|
-
//
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
gender,
|
|
168
|
-
language
|
|
169
|
-
);
|
|
170
|
-
await this.log('info', 'Refetched archetypes', {
|
|
171
|
-
updatedArchetypesCount: updatedArchetypes.length,
|
|
172
|
-
archetypeIds: updatedArchetypes.map((a) => a.id),
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// Step 4: Queue image generation if needed
|
|
176
|
-
const archetypesNeedingImages = updatedArchetypes.filter(
|
|
177
|
-
(arc) => JSON.parse(arc.images).length < 3
|
|
195
|
+
|
|
196
|
+
// Step 6: Process image generation if needed
|
|
197
|
+
const archetypesNeedingImages = archetypes.filter(
|
|
198
|
+
(arc) => JSON.parse(arc.images).length < 3 || (override && arc.images !== '[]')
|
|
178
199
|
);
|
|
179
|
-
|
|
200
|
+
|
|
180
201
|
if (archetypesNeedingImages.length > 0) {
|
|
181
|
-
await this.log(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
202
|
+
await this.log('info', 'Processing image generation for archetypes', {
|
|
203
|
+
archetypesNeedingImagesCount: archetypesNeedingImages.length,
|
|
204
|
+
archetypeIds: archetypesNeedingImages.map((a) => a.id),
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
for (const archetype of archetypesNeedingImages) {
|
|
208
|
+
await this.log('debug', 'Processing image generation', {
|
|
209
|
+
archetypeId: archetype.id,
|
|
210
|
+
leonardoPrompt: archetype.leonardoPrompt,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Reset images and status if override is true
|
|
214
|
+
if (override) {
|
|
215
|
+
await this.context.drizzle()
|
|
216
|
+
.update(schema.archetypesData)
|
|
217
|
+
.set({
|
|
218
|
+
images: '[]',
|
|
219
|
+
status: 'idle',
|
|
220
|
+
updatedAt: new Date().getTime(),
|
|
221
|
+
})
|
|
222
|
+
.where(eq(schema.archetypesData.id, archetype.id))
|
|
223
|
+
.execute();
|
|
224
|
+
await this.log('info', 'Reset images and status for archetype', {
|
|
225
|
+
archetypeId: archetype.id,
|
|
226
|
+
});
|
|
187
227
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
228
|
+
|
|
229
|
+
// Process image generation directly
|
|
230
|
+
await this.leonardoService.processArchetypePopulation({
|
|
231
|
+
archetypeDataId: archetype.id,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Note: processArchetypePopulation sets status to 'pending' in the generations table
|
|
235
|
+
// Update archetype status to 'pending' for consistency
|
|
236
|
+
await this.context.drizzle()
|
|
237
|
+
.update(schema.archetypesData)
|
|
238
|
+
.set({
|
|
239
|
+
status: 'pending',
|
|
240
|
+
updatedAt: new Date().getTime(),
|
|
241
|
+
})
|
|
242
|
+
.where(eq(schema.archetypesData.id, archetype.id))
|
|
243
|
+
.execute();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
await this.log('info', 'Image generation processing initiated', {
|
|
247
|
+
archetypesProcessed: archetypesNeedingImages.length,
|
|
248
|
+
});
|
|
249
|
+
return {
|
|
250
|
+
message: 'Image generation has been queued. Please try again later.',
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Step 7: Verify all archetypes are complete
|
|
255
|
+
const incompleteArchetypes = archetypes.filter((a) => a.status !== 'generated');
|
|
256
|
+
if (incompleteArchetypes.length > 0) {
|
|
257
|
+
await this.log('warn', 'Some archetypes are not complete', {
|
|
258
|
+
incompleteArchetypeIds: incompleteArchetypes.map((a) => a.id),
|
|
259
|
+
statuses: incompleteArchetypes.map((a) => a.status),
|
|
260
|
+
});
|
|
261
|
+
return {
|
|
262
|
+
message: 'Archetype generation is still in progress. Please try again later.',
|
|
263
|
+
};
|
|
205
264
|
}
|
|
206
|
-
|
|
207
|
-
await this.log('info', '
|
|
208
|
-
|
|
265
|
+
|
|
266
|
+
await this.log('info', 'All archetypes are complete', {
|
|
267
|
+
archetypesCount: archetypes.length,
|
|
268
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
209
269
|
});
|
|
270
|
+
|
|
210
271
|
return {
|
|
211
|
-
archetypes:
|
|
272
|
+
archetypes: archetypes.map(
|
|
212
273
|
({ id, name, essenceLine, description, virtues, images }) => ({
|
|
213
274
|
id,
|
|
214
275
|
name,
|
|
@@ -220,4 +281,4 @@ export class ArchetypeWorkflow {
|
|
|
220
281
|
),
|
|
221
282
|
};
|
|
222
283
|
}
|
|
223
|
-
}
|
|
284
|
+
}
|