@zodic/shared 0.0.246 → 0.0.248

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.
@@ -10,6 +10,7 @@ import { v4 as uuidv4 } from 'uuid';
10
10
  import { cleanText, schema } from '../..';
11
11
  import {
12
12
  aspectReports,
13
+ astroFeatureReports,
13
14
  astroReports,
14
15
  conceptsData,
15
16
  houseReports,
@@ -2010,14 +2011,28 @@ export class ConceptService {
2010
2011
  params: AstroReportParams,
2011
2012
  override: boolean = false
2012
2013
  ): Promise<void> {
2013
- console.log(`🚀 Generating report content for ${JSON.stringify(params)}, override: ${override}`);
2014
+ console.log(
2015
+ `🚀 Generating report content for ${JSON.stringify(
2016
+ params
2017
+ )}, override: ${override}`
2018
+ );
2014
2019
 
2015
2020
  const db = drizzle(this.context.env.DB);
2016
2021
  let table, whereClause;
2017
2022
 
2023
+ // Log the params for debugging
2024
+ console.log(
2025
+ `🔍 Received params: reportType=${params.reportType}, featureType=${
2026
+ (params as any).featureType || 'N/A'
2027
+ }, subtype=${(params as any).subtype || 'N/A'}`
2028
+ );
2029
+
2018
2030
  // Determine table and where clause
2019
2031
  switch (params.reportType) {
2020
- case "sign":
2032
+ case 'sign':
2033
+ console.log(
2034
+ `🗂️ Handling sign report: type=${params.type}, pointName=${params.pointName}, sign=${params.sign}`
2035
+ );
2021
2036
  table = astroReports;
2022
2037
  whereClause = and(
2023
2038
  eq(astroReports.name, params.pointName),
@@ -2025,7 +2040,10 @@ export class ConceptService {
2025
2040
  isNull(astroReports.house)
2026
2041
  );
2027
2042
  break;
2028
- case "house":
2043
+ case 'house':
2044
+ console.log(
2045
+ `🗂️ Handling house report: type=${params.type}, pointName=${params.pointName}, house=${params.house}`
2046
+ );
2029
2047
  table = astroReports;
2030
2048
  whereClause = and(
2031
2049
  eq(astroReports.name, params.pointName),
@@ -2033,14 +2051,20 @@ export class ConceptService {
2033
2051
  isNull(astroReports.sign)
2034
2052
  );
2035
2053
  break;
2036
- case "signInHouse":
2054
+ case 'signInHouse':
2055
+ console.log(
2056
+ `🗂️ Handling signInHouse report: sign=${params.sign}, houseNumber=${params.houseNumber}`
2057
+ );
2037
2058
  table = houseReports;
2038
2059
  whereClause = and(
2039
2060
  eq(houseReports.sign, params.sign),
2040
2061
  eq(houseReports.house, params.houseNumber)
2041
2062
  );
2042
2063
  break;
2043
- case "aspect":
2064
+ case 'aspect':
2065
+ console.log(
2066
+ `🗂️ Handling aspect report: aspectingPlanet=${params.aspectingPlanet}, aspectedPlanet=${params.aspectedPlanet}, aspectingType=${params.aspectingType}`
2067
+ );
2044
2068
  table = aspectReports;
2045
2069
  whereClause = and(
2046
2070
  eq(aspectReports.aspectingPlanet, params.aspectingPlanet),
@@ -2048,37 +2072,61 @@ export class ConceptService {
2048
2072
  eq(aspectReports.aspect, params.aspectingType)
2049
2073
  );
2050
2074
  break;
2051
- case "feature":
2052
- table = astroFeatureReports;
2053
- let nameValue: string;
2054
- if (params.featureType === "element") {
2055
- switch (params.subtype) {
2056
- case "balanced":
2057
- nameValue = "balanced";
2058
- break;
2059
- case "pure":
2060
- nameValue = params.dominantElement;
2061
- break;
2062
- case "preponderant_lacking":
2063
- nameValue = `${params.dominantElement}-${params.lackingElement}`;
2064
- break;
2065
- default:
2066
- throw new Error(`Unknown element subtype: ${(params as any).subtype}`);
2067
- }
2068
- } else {
2069
- nameValue = params.name;
2075
+ case 'feature':
2076
+ console.log(
2077
+ `🗂️ Handling feature report: featureType=${
2078
+ params.featureType
2079
+ }, ${JSON.stringify(params)}`
2080
+ );
2081
+ table = astroFeatureReports;
2082
+ let nameValue: string;
2083
+ if (params.featureType === 'element') {
2084
+ if (!('subtype' in params))
2085
+ throw new Error('Missing subtype for element feature report');
2086
+ switch (params.subtype) {
2087
+ case 'balanced':
2088
+ nameValue = 'balanced';
2089
+ break;
2090
+ case 'pure':
2091
+ if (!('dominantElement' in params))
2092
+ throw new Error(
2093
+ 'Missing dominantElement for pure element report'
2094
+ );
2095
+ nameValue = params.dominantElement;
2096
+ break;
2097
+ case 'preponderant_lacking':
2098
+ if (
2099
+ !('dominantElement' in params) ||
2100
+ !('lackingElement' in params)
2101
+ )
2102
+ throw new Error(
2103
+ 'Missing dominantElement or lackingElement for preponderant_lacking element report'
2104
+ );
2105
+ nameValue = `${params.dominantElement}-${params.lackingElement}`;
2106
+ break;
2107
+ default:
2108
+ throw new Error(`Unknown element subtype: ${params}`);
2070
2109
  }
2071
- whereClause = and(
2072
- eq(astroFeatureReports.featureType, params.featureType),
2073
- eq(astroFeatureReports.name, nameValue)
2074
- );
2075
- break;
2110
+ } else {
2111
+ if (!('name' in params))
2112
+ throw new Error('Missing name for non-element feature report');
2113
+ nameValue = params.name;
2114
+ }
2115
+ whereClause = and(
2116
+ eq(astroFeatureReports.featureType, params.featureType),
2117
+ eq(astroFeatureReports.name, nameValue)
2118
+ );
2119
+ break;
2076
2120
  default:
2077
- throw new Error(`Unknown report type: ${(params as any).reportType}`);
2121
+ console.error(
2122
+ `❌ Unknown report type: ${params}. Params: ${JSON.stringify(params)}`
2123
+ );
2124
+ throw new Error(`Unknown report type: ${params}`);
2078
2125
  }
2079
2126
 
2080
2127
  const report = await db.select().from(table).where(whereClause).get();
2081
2128
  if (!report) {
2129
+ console.error(`❌ No report found for ${JSON.stringify(params)}`);
2082
2130
  throw new Error(`❌ No report found for ${JSON.stringify(params)}`);
2083
2131
  }
2084
2132
 
@@ -2094,21 +2142,37 @@ export class ConceptService {
2094
2142
  const maxAttempts = 2;
2095
2143
 
2096
2144
  while (attempts < maxAttempts) {
2097
- let phase = "generation";
2145
+ let phase = 'generation';
2098
2146
  try {
2099
2147
  attempts++;
2100
- console.log(`🔄 Attempt ${attempts} to generate report content...`);
2148
+ console.log(
2149
+ `🔄 Attempt ${attempts} to generate report content for ${id}...`
2150
+ );
2101
2151
 
2102
- const messages = this.context.buildLLMMessages().generateAstroReportContent({ params });
2152
+ const messages = this.context
2153
+ .buildLLMMessages()
2154
+ .generateAstroReportContent({ params });
2155
+ console.log(`📨 Sending messages to AI: ${JSON.stringify(messages)}`);
2103
2156
 
2104
- const response = await this.context.api().callTogether.single(messages, {});
2157
+ const response = await this.context
2158
+ .api()
2159
+ .callTogether.single(messages, {});
2105
2160
  if (!response) {
2106
- throw new Error(`❌ AI returned an empty response`);
2161
+ throw new Error(`❌ AI returned an empty response for ${id}`);
2107
2162
  }
2108
2163
 
2109
- phase = "parsing";
2164
+ phase = 'parsing';
2165
+ console.log(
2166
+ `📝 Received AI response for ${id}: ${response.slice(0, 200)}${
2167
+ response.length > 200 ? '...' : ''
2168
+ }`
2169
+ );
2110
2170
 
2111
- const { enReport, ptReport } = await this.parseAstrologicalReportContent(params.reportType, response);
2171
+ const { enReport, ptReport } =
2172
+ await this.parseAstrologicalReportContent(
2173
+ params.reportType,
2174
+ response
2175
+ );
2112
2176
 
2113
2177
  console.log(`💾 Storing report content for ${id}`);
2114
2178
  await db
@@ -2123,7 +2187,10 @@ export class ConceptService {
2123
2187
  console.log(`✅ Report content stored for ${id}`);
2124
2188
  return;
2125
2189
  } catch (error) {
2126
- console.error(`❌ Attempt ${attempts} failed at phase: ${phase}`, (error as Error).message);
2190
+ console.error(
2191
+ `❌ Attempt ${attempts} failed at phase: ${phase} for ${id}`,
2192
+ (error as Error).message
2193
+ );
2127
2194
 
2128
2195
  const failureKey = `failures:astro:${params.reportType}:${id}`;
2129
2196
  await this.context.kvConceptFailuresStore().put(
@@ -2138,11 +2205,15 @@ export class ConceptService {
2138
2205
  );
2139
2206
 
2140
2207
  if (attempts >= maxAttempts) {
2141
- console.error(`🚨 All ${maxAttempts} attempts failed at phase ${phase}`);
2142
- throw new Error(`Failed to generate content after ${maxAttempts} attempts`);
2208
+ console.error(
2209
+ `🚨 All ${maxAttempts} attempts failed at phase ${phase} for ${id}`
2210
+ );
2211
+ throw new Error(
2212
+ `Failed to generate content for ${id} after ${maxAttempts} attempts`
2213
+ );
2143
2214
  }
2144
2215
 
2145
- console.log("🔁 Retrying...");
2216
+ console.log('🔁 Retrying...');
2146
2217
  await new Promise((resolve) => setTimeout(resolve, 2000));
2147
2218
  }
2148
2219
  }
@@ -2199,40 +2270,48 @@ export class ConceptService {
2199
2270
  }
2200
2271
 
2201
2272
  private parseAstrologicalReport(response: string): AstrologicalReport[] {
2202
- console.log("📌 Starting parseAstrologicalReport");
2203
-
2273
+ console.log('📌 Starting parseAstrologicalReport');
2274
+
2204
2275
  const reports: AstrologicalReport[] = [];
2205
2276
  const languageSections = response
2206
2277
  .split(/--\s*(EN|PT)\s*\n/)
2207
2278
  .filter(Boolean);
2208
2279
  console.log(`🔍 Split response into ${languageSections.length} sections`);
2209
-
2280
+
2210
2281
  for (let i = 0; i < languageSections.length; i += 2) {
2211
2282
  const language = languageSections[i].trim();
2212
2283
  const content = languageSections[i + 1]?.trim();
2213
2284
  console.log(`🚀 Processing section ${i / 2 + 1}: Language = ${language}`);
2214
-
2285
+
2215
2286
  if (!content || !language.match(/^(EN|PT)$/)) {
2216
- console.warn(`⚠️ Skipping section ${i / 2 + 1}: Invalid content or language (${language})`);
2287
+ console.warn(
2288
+ `⚠️ Skipping section ${
2289
+ i / 2 + 1
2290
+ }: Invalid content or language (${language})`
2291
+ );
2217
2292
  continue;
2218
2293
  }
2219
-
2220
- console.log(`📜 Raw content for ${language}:\n${content.slice(0, 500)}${content.length > 500 ? "..." : ""}`);
2221
-
2294
+
2295
+ console.log(
2296
+ `📜 Raw content for ${language}:\n${content.slice(0, 500)}${
2297
+ content.length > 500 ? '...' : ''
2298
+ }`
2299
+ );
2300
+
2222
2301
  const report: AstrologicalReport = {
2223
2302
  language,
2224
2303
  title: [],
2225
2304
  sections: {},
2226
2305
  };
2227
-
2306
+
2228
2307
  const lines = content.split('\n').map((line) => line.trim());
2229
2308
  console.log(`🔢 Split into ${lines.length} lines`);
2230
-
2309
+
2231
2310
  let currentSection = '';
2232
2311
  for (let j = 0; j < lines.length; j++) {
2233
2312
  const line = lines[j];
2234
2313
  console.log(`📏 Processing line ${j + 1}: "${line}"`);
2235
-
2314
+
2236
2315
  if (line.startsWith('### ') && report.title.length === 0) {
2237
2316
  const titleContent = cleanText(line.replace('### ', ''));
2238
2317
  console.log(`🏷️ Found title: "${titleContent}"`);
@@ -2242,40 +2321,52 @@ export class ConceptService {
2242
2321
  });
2243
2322
  continue;
2244
2323
  }
2245
-
2324
+
2246
2325
  if (line.startsWith('#### ')) {
2247
2326
  currentSection = cleanText(line.replace('#### ', '').trim());
2248
2327
  console.log(`🗂️ New section: "${currentSection}"`);
2249
- report.sections[currentSection] = report.sections[currentSection] || [];
2328
+ report.sections[currentSection] =
2329
+ report.sections[currentSection] || [];
2250
2330
  continue;
2251
2331
  }
2252
-
2332
+
2253
2333
  if (!line || !currentSection) {
2254
- console.log(`⏩ Skipping line: ${!line ? "Empty" : "No current section"}`);
2334
+ console.log(
2335
+ `⏩ Skipping line: ${!line ? 'Empty' : 'No current section'}`
2336
+ );
2255
2337
  continue;
2256
2338
  }
2257
-
2339
+
2258
2340
  if (line.match(/^\d+\.\s/) || line.startsWith('- ')) {
2259
2341
  const listItem = line.replace(/^\d+\.\s|- /, '').trim();
2260
2342
  console.log(`🔹 Bullet point detected: "${listItem}"`);
2261
2343
  const boldMatch = listItem.match(/^\*\*(.+?)\*\*[:\s]*(.+)?$/); // Updated to allow standalone bold
2262
-
2344
+
2263
2345
  if (boldMatch) {
2264
2346
  const title = cleanText(boldMatch[1]);
2265
2347
  let content = boldMatch[2] ? cleanText(boldMatch[2]) : '';
2266
-
2348
+
2267
2349
  // Look ahead for content if none on the same line
2268
2350
  if (!content && j + 1 < lines.length) {
2269
2351
  const nextLine = lines[j + 1];
2270
2352
  console.log(`🔍 Checking next line for content: "${nextLine}"`);
2271
- if (nextLine && !nextLine.match(/^\d+\.\s|- /) && !nextLine.startsWith('#### ') && !nextLine.startsWith('### ')) {
2353
+ if (
2354
+ nextLine &&
2355
+ !nextLine.match(/^\d+\.\s|- /) &&
2356
+ !nextLine.startsWith('#### ') &&
2357
+ !nextLine.startsWith('### ')
2358
+ ) {
2272
2359
  content = cleanText(nextLine);
2273
2360
  console.log(`✅ Found content in next line: "${content}"`);
2274
2361
  j++; // Skip the next line since we’ve consumed it
2275
2362
  }
2276
2363
  }
2277
-
2278
- console.log(`✅ Bold match found - Title: "${title}", Content: "${content || 'None'}"`);
2364
+
2365
+ console.log(
2366
+ `✅ Bold match found - Title: "${title}", Content: "${
2367
+ content || 'None'
2368
+ }"`
2369
+ );
2279
2370
  report.sections[currentSection].push({
2280
2371
  type: 'bullet-point',
2281
2372
  title,
@@ -2290,18 +2381,24 @@ export class ConceptService {
2290
2381
  }
2291
2382
  continue;
2292
2383
  }
2293
-
2384
+
2294
2385
  console.log(`📝 Paragraph: "${line}"`);
2295
2386
  report.sections[currentSection].push({
2296
2387
  type: 'p',
2297
2388
  content: cleanText(line),
2298
2389
  });
2299
2390
  }
2300
-
2301
- console.log(`🏁 Finished parsing ${language} section. Result:\n${JSON.stringify(report, null, 2)}`);
2391
+
2392
+ console.log(
2393
+ `🏁 Finished parsing ${language} section. Result:\n${JSON.stringify(
2394
+ report,
2395
+ null,
2396
+ 2
2397
+ )}`
2398
+ );
2302
2399
  reports.push(report);
2303
2400
  }
2304
-
2401
+
2305
2402
  console.log(`🎉 Parsing complete. Total reports: ${reports.length}`);
2306
2403
  return reports;
2307
2404
  }
@@ -0,0 +1,13 @@
1
+ CREATE TABLE `astro_feature_reports` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `feature_type` text NOT NULL,
4
+ `name` text NOT NULL,
5
+ `en_description` text,
6
+ `pt_description` text,
7
+ `en_report` text,
8
+ `pt_report` text,
9
+ `created_at` integer DEFAULT CURRENT_TIMESTAMP,
10
+ `updated_at` integer DEFAULT CURRENT_TIMESTAMP
11
+ );
12
+ --> statement-breakpoint
13
+ CREATE INDEX `astro_feature_reports_type_name_idx` ON `astro_feature_reports` (`feature_type`,`name`);