Filter unattributed successful messages
This commit is contained in:
1 parent
2c100d72b6
commit
7bcdbe236a
3 files changed
+62
-1
No files matched your search
@@ -664,6 +664,7 @@ export class MessagesRepository {
|
|||||||
export class SuccessfulMessagesRepository {
|
export class SuccessfulMessagesRepository {
|
||||||
private insertStmt: Database.Statement;
|
private insertStmt: Database.Statement;
|
||||||
private getRecentStmt: Database.Statement;
|
private getRecentStmt: Database.Statement;
|
||||||
|
private getAttributedRecentStmt: Database.Statement;
|
||||||
private getBySubredditStmt: Database.Statement;
|
private getBySubredditStmt: Database.Statement;
|
||||||
private countStmt: Database.Statement;
|
private countStmt: Database.Statement;
|
||||||
private existsByMessageStmt: Database.Statement;
|
private existsByMessageStmt: Database.Statement;
|
||||||
@@ -678,6 +679,17 @@ export class SuccessfulMessagesRepository {
|
|||||||
SELECT * FROM successful_messages ORDER BY created_at DESC, id DESC LIMIT ?
|
SELECT * FROM successful_messages ORDER BY created_at DESC, id DESC LIMIT ?
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
this.getAttributedRecentStmt = db.prepare(`
|
||||||
|
SELECT successful_messages.*
|
||||||
|
FROM successful_messages
|
||||||
|
LEFT JOIN sent_messages sm ON sm.id = successful_messages.sent_message_id
|
||||||
|
WHERE successful_messages.subreddit IS NOT NULL
|
||||||
|
OR sm.post_id IS NOT NULL
|
||||||
|
OR sm.strategy_id IS NOT NULL
|
||||||
|
ORDER BY successful_messages.created_at DESC, successful_messages.id DESC
|
||||||
|
LIMIT ?
|
||||||
|
`);
|
||||||
|
|
||||||
// Get examples prioritizing same subreddit, then falling back to others
|
// Get examples prioritizing same subreddit, then falling back to others
|
||||||
this.getBySubredditStmt = db.prepare(`
|
this.getBySubredditStmt = db.prepare(`
|
||||||
SELECT *,
|
SELECT *,
|
||||||
@@ -722,6 +734,11 @@ export class SuccessfulMessagesRepository {
|
|||||||
return rows.map((row) => this.mapRow(row));
|
return rows.map((row) => this.mapRow(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAttributedRecent(limit: number = 5): SuccessfulMessageRecord[] {
|
||||||
|
const rows = this.getAttributedRecentStmt.all(limit) as Record<string, unknown>[];
|
||||||
|
return rows.map((row) => this.mapRow(row));
|
||||||
|
}
|
||||||
|
|
||||||
getWeightedExamples(subreddit: string | null, limit: number = 3): SuccessfulMessageRecord[] {
|
getWeightedExamples(subreddit: string | null, limit: number = 3): SuccessfulMessageRecord[] {
|
||||||
if (subreddit) {
|
if (subreddit) {
|
||||||
const rows = this.getBySubredditStmt.all(subreddit, limit) as Record<string, unknown>[];
|
const rows = this.getBySubredditStmt.all(subreddit, limit) as Record<string, unknown>[];
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export function createStatsRouter(ctx: WebContext): Router {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get('/successful', (_req, res) => {
|
router.get('/successful', (_req, res) => {
|
||||||
res.json(ctx.repos.successful.getRecent(10));
|
res.json(ctx.repos.successful.getAttributedRecent(10));
|
||||||
});
|
});
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
|
|||||||
@@ -431,11 +431,15 @@ describe('MessagesRepository', () => {
|
|||||||
|
|
||||||
describe('SuccessfulMessagesRepository', () => {
|
describe('SuccessfulMessagesRepository', () => {
|
||||||
let successfulMessagesRepo: SuccessfulMessagesRepository;
|
let successfulMessagesRepo: SuccessfulMessagesRepository;
|
||||||
|
let postsRepo: PostsRepository;
|
||||||
|
let messagesRepo: MessagesRepository;
|
||||||
let db: Database;
|
let db: Database;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const repos = createTestRepositories();
|
const repos = createTestRepositories();
|
||||||
successfulMessagesRepo = repos.successfulMessagesRepo;
|
successfulMessagesRepo = repos.successfulMessagesRepo;
|
||||||
|
postsRepo = repos.postsRepo;
|
||||||
|
messagesRepo = repos.messagesRepo;
|
||||||
db = repos.db;
|
db = repos.db;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -520,6 +524,46 @@ describe('SuccessfulMessagesRepository', () => {
|
|||||||
expect(recent[0].subreddit).toBeNull();
|
expect(recent[0].subreddit).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns only examples attributable to a post, strategy, or subreddit', () => {
|
||||||
|
postsRepo.insert({
|
||||||
|
id: 'source-post',
|
||||||
|
subreddit: 'example',
|
||||||
|
author: 'alice',
|
||||||
|
title: 'Source post',
|
||||||
|
imageUrl: null,
|
||||||
|
processedAt: Date.now(),
|
||||||
|
});
|
||||||
|
const sentMessageId = messagesRepo.insert({
|
||||||
|
postId: 'source-post',
|
||||||
|
recipient: 'alice',
|
||||||
|
subject: 'alice',
|
||||||
|
message: 'Attributed opener',
|
||||||
|
sentAt: Date.now(),
|
||||||
|
strategyId: 'direct',
|
||||||
|
});
|
||||||
|
successfulMessagesRepo.insert({
|
||||||
|
sentMessageId,
|
||||||
|
originalMessage: 'Attributed opener',
|
||||||
|
imageAnalysis: null,
|
||||||
|
postTitle: 'Source post',
|
||||||
|
responseSnippet: 'Hello',
|
||||||
|
subreddit: null,
|
||||||
|
});
|
||||||
|
successfulMessagesRepo.insert({
|
||||||
|
sentMessageId: null,
|
||||||
|
originalMessage: 'Legacy unknown opener',
|
||||||
|
imageAnalysis: null,
|
||||||
|
postTitle: 'Chat with t2_unknown',
|
||||||
|
responseSnippet: 'Hello',
|
||||||
|
subreddit: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(successfulMessagesRepo.getAttributedRecent(10)).toEqual([
|
||||||
|
expect.objectContaining({ originalMessage: 'Attributed opener' }),
|
||||||
|
]);
|
||||||
|
expect(successfulMessagesRepo.getRecent(10)).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
it('returns most recent examples first', () => {
|
it('returns most recent examples first', () => {
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
successfulMessagesRepo.insert({
|
successfulMessagesRepo.insert({
|
||||||
|
|||||||
Reference in new issue
Block a user