Add active outreach funnel dashboard
This commit is contained in:
1 parent
deaf86c364
commit
f55ae7ddf8
15 files changed
+519
-1
No files matched your search
@@ -243,6 +243,14 @@ export class CandidateQueueRepository {
|
||||
.get() as { count: number }).count;
|
||||
}
|
||||
|
||||
getOldestActiveAt(): number | null {
|
||||
const row = this.db.prepare(`
|
||||
SELECT MIN(discovered_at) AS at FROM candidate_queue
|
||||
WHERE status IN (${ACTIVE_STATUSES.map(() => '?').join(', ')})
|
||||
`).get(...ACTIVE_STATUSES) as { at: number | null };
|
||||
return row.at;
|
||||
}
|
||||
|
||||
getStats(): CandidateQueueStats {
|
||||
const statuses: CandidateStatus[] = ['discovered', 'screening', 'ready', 'sending', 'retryable', 'sent', 'rejected'];
|
||||
const byStatus = Object.fromEntries(statuses.map((status) => [status, 0])) as Record<CandidateStatus, number>;
|
||||
@@ -265,6 +273,29 @@ export class CandidateQueueRepository {
|
||||
};
|
||||
}
|
||||
|
||||
listActive(limit = 500): CandidateQueueRecord[] {
|
||||
if (!Number.isInteger(limit) || limit < 1 || limit > 500) {
|
||||
throw new Error('Candidate queue limit must be an integer between 1 and 500');
|
||||
}
|
||||
const rows = this.db.prepare(`
|
||||
SELECT * FROM candidate_queue
|
||||
WHERE status IN (${ACTIVE_STATUSES.map(() => '?').join(', ')})
|
||||
ORDER BY
|
||||
CASE status
|
||||
WHEN 'sending' THEN 1
|
||||
WHEN 'screening' THEN 2
|
||||
WHEN 'ready' THEN 3
|
||||
WHEN 'retryable' THEN 4
|
||||
ELSE 5
|
||||
END,
|
||||
priority DESC,
|
||||
post_created_at DESC,
|
||||
discovered_at ASC
|
||||
LIMIT ?
|
||||
`).all(...ACTIVE_STATUSES, limit) as Array<Record<string, unknown>>;
|
||||
return rows.map((row) => this.mapRow(row));
|
||||
}
|
||||
|
||||
private claim(
|
||||
from: 'discovered' | 'ready',
|
||||
to: 'screening' | 'sending',
|
||||
@@ -298,6 +329,10 @@ export class CandidateQueueRepository {
|
||||
const row = this.db.prepare('SELECT * FROM candidate_queue WHERE post_id = ?')
|
||||
.get(postId) as Record<string, unknown> | undefined;
|
||||
if (!row) return null;
|
||||
return this.mapRow(row);
|
||||
}
|
||||
|
||||
private mapRow(row: Record<string, unknown>): CandidateQueueRecord {
|
||||
return {
|
||||
postId: row.post_id as string,
|
||||
subreddit: row.subreddit as string,
|
||||
|
||||
Reference in new issue
Block a user