Skip to content

Commit bb34987

Browse files
Merge branch 'prototype'
2 parents bf56143 + 614ebd3 commit bb34987

File tree

3 files changed

+213
-45
lines changed

3 files changed

+213
-45
lines changed

app/controllers/simscore/analyze_controller.rb

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,63 @@ class AnalyzeController < ::ApplicationController
55
before_action :ensure_api_key_configured
66

77
def create
8-
Rails.logger.info("SimScore: Starting analysis for topic #{params[:topic_id]}")
8+
start_time = Time.now
9+
Rails.logger.info(
10+
"SimScore: Analysis started",
11+
{
12+
topic_id: params[:topic_id],
13+
user_id: current_user.id,
14+
username: current_user.username,
15+
timestamp: Time.now,
16+
}.to_json,
17+
)
918

1019
topic = Topic.find(params[:topic_id])
1120
guardian.ensure_can_see!(topic)
1221

1322
# Get posts with their users
1423
posts = topic.posts.includes(:user).order(:post_number)
15-
Rails.logger.info("SimScore: Found #{posts.count} posts to analyze")
24+
Rails.logger.info(
25+
"SimScore: Posts loaded",
26+
{
27+
topic_id: topic.id,
28+
post_count: posts.count,
29+
topic_title: topic.title,
30+
duration_ms: ((Time.now - start_time) * 1000).to_i,
31+
}.to_json,
32+
)
1633

1734
begin
1835
# Call SimScore API
19-
Rails.logger.info("SimScore: Calling API service")
36+
Rails.logger.info(
37+
"SimScore: Calling API service",
38+
{ topic_id: topic.id, endpoint: SiteSetting.simscore_api_endpoint }.to_json,
39+
)
40+
2041
results = ApiService.analyze_posts(posts)
21-
Rails.logger.info("SimScore: API analysis complete")
42+
43+
Rails.logger.info(
44+
"SimScore: API analysis complete",
45+
{
46+
topic_id: topic.id,
47+
duration_ms: ((Time.now - start_time) * 1000).to_i,
48+
cluster_count: results["cluster_names"]&.size,
49+
}.to_json,
50+
)
2251

2352
# Format results into markdown
2453
formatted_results = ApiService.format_results(results)
25-
Rails.logger.info("SimScore: Results formatted")
54+
Rails.logger.info(
55+
"SimScore: Results formatted",
56+
{ topic_id: topic.id, result_length: formatted_results.length }.to_json,
57+
)
2658

2759
# Try to use SimScore user if available, otherwise use current user
2860
posting_user = User.find_by(username: "simscore") || current_user
29-
Rails.logger.info("SimScore: Posting as user #{posting_user.username}")
61+
Rails.logger.info(
62+
"SimScore: Selected posting user",
63+
{ topic_id: topic.id, username: posting_user.username, user_id: posting_user.id }.to_json,
64+
)
3065

3166
# Create a new post with the results
3267
creator =
@@ -40,15 +75,35 @@ def create
4075
post = creator.create
4176

4277
if post.present?
43-
Rails.logger.info("SimScore: Successfully created post #{post.id}")
78+
Rails.logger.info(
79+
"SimScore: Post created successfully",
80+
{
81+
topic_id: topic.id,
82+
post_id: post.id,
83+
duration_ms: ((Time.now - start_time) * 1000).to_i,
84+
}.to_json,
85+
)
4486
render json: { success: true, post_id: post.id }
4587
else
46-
Rails.logger.error("SimScore: Failed to create post: #{creator.errors.full_messages}")
88+
Rails.logger.error(
89+
"SimScore: Post creation failed",
90+
{
91+
topic_id: topic.id,
92+
errors: creator.errors.full_messages,
93+
duration_ms: ((Time.now - start_time) * 1000).to_i,
94+
}.to_json,
95+
)
4796
render json: { success: false, errors: creator.errors.full_messages }, status: 422
4897
end
4998
rescue StandardError => e
5099
Rails.logger.error(
51-
"SimScore: Error during analysis: #{e.message}\n#{e.backtrace.join("\n")}",
100+
"SimScore: Error during analysis",
101+
{
102+
topic_id: topic.id,
103+
error: e.message,
104+
backtrace: e.backtrace[0..5],
105+
duration_ms: ((Time.now - start_time) * 1000).to_i,
106+
}.to_json,
52107
)
53108
render json: { success: false, errors: [e.message] }, status: 422
54109
end
@@ -58,7 +113,10 @@ def create
58113

59114
def ensure_api_key_configured
60115
unless SiteSetting.simscore_api_key.present?
61-
Rails.logger.error("SimScore: API key not configured")
116+
Rails.logger.error(
117+
"SimScore: API key missing",
118+
{ user_id: current_user.id, username: current_user.username }.to_json,
119+
)
62120
render json: { success: false, errors: ["SimScore API key not configured"] }, status: 422
63121
end
64122
end
Lines changed: 142 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,163 @@
11
import Component from "@glimmer/component";
22
import { tracked } from "@glimmer/tracking";
3-
import { getOwner } from "@ember/application";
43
import { action } from "@ember/object";
54
import { service } from "@ember/service";
65
import DButton from "discourse/components/d-button";
76
import { ajax } from "discourse/lib/ajax";
87
import { popupAjaxError } from "discourse/lib/ajax-error";
9-
import { i18n } from "discourse-i18n";
108

119
export default class SimscoreButton extends Component {
1210
@service currentUser;
11+
@service siteSettings;
12+
@service dialog;
1313
@tracked loading = false;
14-
15-
get logger() {
16-
return getOwner(this).lookup("service:logger");
17-
}
14+
@tracked ideas = [];
1815

1916
@action
2017
async calculateSimScore() {
18+
// eslint-disable-next-line no-console
19+
console.info("Debug: args received:", {
20+
args: this.args,
21+
outletArgs: this.args?.outletArgs,
22+
topic: this.args?.topic,
23+
});
24+
25+
// eslint-disable-next-line no-console
26+
console.info("Debug: raw args:", this.args);
27+
2128
try {
22-
this.logger.debug(
23-
"SimScore: Starting calculation for topic",
24-
this.args.topic.id
25-
);
26-
this.loading = true;
27-
const response = await ajax(`/simscore/analyze/${this.args.topic.id}`, {
28-
type: "POST",
29+
if (!this.args?.topic?.id) {
30+
// eslint-disable-next-line no-console
31+
console.error("❌ SimScore: No topic ID found");
32+
this.dialog.alert({
33+
message: "Error: Cannot find topic ID",
34+
});
35+
return;
36+
}
37+
38+
const topicId = this.args.topic.id;
39+
const username = this.currentUser?.username;
40+
41+
// eslint-disable-next-line no-console
42+
console.info("SimScore: Button pressed", {
43+
topicId,
44+
username,
45+
timestamp: new Date().toISOString(),
46+
topicTitle: this.args.topic?.title,
47+
postCount: this.args.topic?.posts_count,
48+
});
49+
50+
// Show a notification to the user
51+
this.dialog.alert({
52+
message: `Starting SimScore analysis for topic ${this.args.topic.title}...`,
2953
});
3054

31-
this.logger.debug("SimScore: Received response", response);
32-
33-
if (response.success) {
34-
this.logger.debug(
35-
"SimScore: Calculation successful, post created with ID:",
36-
response.post_id
37-
);
38-
this.args.showSuccess?.(i18n("simscore.success"));
39-
} else {
40-
this.logger.error("SimScore: API returned error:", response.errors);
41-
this.args.showError?.(i18n("simscore.error"));
55+
this.loading = true;
56+
// eslint-disable-next-line no-console
57+
console.info("🔵 SimScore: Analysis started...");
58+
59+
// Ensure we have at least 4 ideas as per API requirements
60+
// if (this.ideas.length < 4) {
61+
// this.dialog.alert({
62+
// message: "At least 4 ideas are required for analysis",
63+
// });
64+
// this.loading = false;
65+
// return;
66+
// }
67+
68+
const formattedIdeas = [
69+
...this.ideas.map((idea, index) => ({
70+
id: String(index + 1),
71+
idea,
72+
})),
73+
{
74+
id: this.ideas.length + 1,
75+
idea: "Improve user engagement through gamification",
76+
},
77+
{
78+
id: this.ideas.length + 2,
79+
idea: "Implement a reward system for active contributors",
80+
},
81+
{
82+
id: this.ideas.length + 3,
83+
idea: "Add social sharing features",
84+
},
85+
{
86+
id: this.ideas.length + 4,
87+
idea: "Create a mobile-friendly interface",
88+
},
89+
];
90+
91+
const payload = {
92+
ideas: formattedIdeas,
93+
advanced_features: {
94+
relationship_graph: false,
95+
cluster_names: false,
96+
pairwise_similarity_matrix: false,
97+
},
98+
};
99+
100+
try {
101+
// eslint-disable-next-line no-console
102+
console.info("🔵 Debug payload:", payload);
103+
const apiUrl = "https://simscore-api-dev.fly.dev/v1/rank_ideas";
104+
// eslint-disable-next-line no-console
105+
console.info("🔵 Making API request to:", apiUrl);
106+
107+
const response = await ajax(apiUrl, {
108+
type: "POST",
109+
contentType: "application/json",
110+
dataType: "json",
111+
crossDomain: true,
112+
xhrFields: {
113+
withCredentials: true,
114+
},
115+
headers: {
116+
Accept: "application/json",
117+
"Access-Control-Allow-Origin": "*",
118+
Authorization:
119+
"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiNWNhZWU2MTQtNTEzZS00NTljLTllN2UtNDM0MzYyMGFlMjlhIiwiZW1haWwiOiJtaWtoYWlsb3YuYW50QGdtYWlsLmNvbSIsImlzX2d1ZXN0IjpmYWxzZSwia2V5X2lkIjoiNWQ2YTVhYjEtNjI2Zi00MTFmLWE2ZWYtYTg3NjBjNTVlYTI5IiwidG9rZW5fdHlwZSI6ImFwaV9rZXkifQ.k3_qSLw1NbtT65S1yC1FQbVfMm8sRgL8x4FQnDkB8n0",
120+
},
121+
data: JSON.stringify(payload),
122+
});
123+
124+
// eslint-disable-next-line no-console
125+
console.info("🟢 API Response:", response);
126+
127+
if (response.ranked_ideas) {
128+
const score = response.ranked_ideas[0].similarity_score;
129+
// eslint-disable-next-line no-console
130+
console.info("✅ SimScore: Analysis complete!", score);
131+
this.dialog.alert({
132+
message: `SimScore analysis completed! Score: ${(
133+
score * 100
134+
).toFixed(1)}%`,
135+
});
136+
} else {
137+
throw new Error("Invalid response format");
138+
}
139+
} catch (error) {
140+
// eslint-disable-next-line no-console
141+
console.error("❌ API Error:", error);
142+
// eslint-disable-next-line no-console
143+
console.error("❌ Error details:", {
144+
message: error.message,
145+
status: error.status,
146+
stack: error.stack,
147+
});
148+
throw error;
149+
} finally {
150+
// eslint-disable-next-line no-console
151+
console.info("🔵 SimScore: Operation completed");
152+
this.loading = false;
42153
}
43154
} catch (error) {
44-
this.logger.error("SimScore: Failed to calculate:", error);
155+
// eslint-disable-next-line no-console
156+
console.error("❌ SimScore: Exception:", error.message, error.stack);
157+
this.dialog.alert({
158+
message: `Error: ${error.message}`,
159+
});
45160
popupAjaxError(error);
46-
this.args.showError?.(i18n("simscore.error"));
47-
} finally {
48-
this.loading = false;
49161
}
50162
}
51163

@@ -54,7 +166,8 @@ export default class SimscoreButton extends Component {
54166
class="btn-primary simscore-button"
55167
@action={{this.calculateSimScore}}
56168
@disabled={{this.loading}}
57-
@label="simscore.calculate"
169+
@icon="calculator"
170+
@translatedLabel="Calculate SimScore"
58171
/>
59172
</template>
60173
}
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
import Component from "@glimmer/component";
21
import SimscoreButton from "../../components/simscore-button";
32

4-
export default class SimscoreButtonConnector extends Component {
5-
<template>
6-
<SimscoreButton @topic={{this.args.outletArgs.topic}} />
7-
</template>
8-
}
3+
<template>
4+
<SimscoreButton @topic={{@outletArgs.model}} />
5+
</template>

0 commit comments

Comments
 (0)