Skip to content

Commit 6d123f3

Browse files
committed
feat: Add claimedAt and failedAt timestamps to campaign response (closes #235)
1 parent 3311cc6 commit 6d123f3

2 files changed

Lines changed: 28 additions & 3 deletions

File tree

backend/src/services/campaignStore.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export interface CampaignRecord {
4141
deadline: number;
4242
createdAt: number;
4343
claimedAt?: number;
44+
failedAt?: number;
4445
deletedAt?: number;
4546
metadata?: {
4647
imageUrl?: string;
@@ -94,6 +95,7 @@ interface CampaignRow {
9495
deadline: number;
9596
created_at: number;
9697
claimed_at: number | null;
98+
failed_at: number | null;
9799
deleted_at: number | null;
98100
metadata_json: string | null;
99101
max_per_contributor: number | null;
@@ -144,6 +146,7 @@ function rowToCampaign(row: CampaignRow): CampaignRecord {
144146
deadline: row.deadline,
145147
createdAt: row.created_at,
146148
claimedAt: row.claimed_at ?? undefined,
149+
failedAt: row.failed_at ?? undefined,
147150
deletedAt: row.deleted_at ?? undefined,
148151
metadata: row.metadata_json ? JSON.parse(row.metadata_json) : undefined,
149152
maxPerContributor: row.max_per_contributor ?? undefined,
@@ -394,6 +397,13 @@ export function listCampaigns(options?: ListCampaignsOptions): ListCampaignsResu
394397
const campaigns = rows.map((row) => {
395398
pledgeCounts[row.id] = row.pledge_count;
396399
const { pledge_count, ...campaignRow } = row;
400+
401+
const now = Math.floor(Date.now() / 1000);
402+
if (campaignRow.claimed_at === null && campaignRow.pledged_amount < campaignRow.target_amount && now >= campaignRow.deadline && campaignRow.failed_at === null) {
403+
campaignRow.failed_at = campaignRow.deadline;
404+
db.prepare(`UPDATE campaigns SET failed_at = ? WHERE id = ?`).run(campaignRow.deadline, campaignRow.id);
405+
}
406+
397407
return rowToCampaign(campaignRow as CampaignRow);
398408
});
399409

@@ -416,7 +426,15 @@ export function getCampaign(campaignId: string): CampaignRecord | undefined {
416426
| CampaignRow
417427
| undefined;
418428

419-
return row ? rowToCampaign(row) : undefined;
429+
if (row) {
430+
const now = Math.floor(Date.now() / 1000);
431+
if (row.claimed_at === null && row.pledged_amount < row.target_amount && now >= row.deadline && row.failed_at === null) {
432+
row.failed_at = row.deadline;
433+
db.prepare(`UPDATE campaigns SET failed_at = ? WHERE id = ?`).run(row.deadline, row.id);
434+
}
435+
return rowToCampaign(row);
436+
}
437+
return undefined;
420438
}
421439

422440
/**
@@ -580,9 +598,9 @@ export function createCampaign(input: CampaignInput): CampaignRecord {
580598

581599
db.prepare(
582600
`INSERT INTO campaigns (
583-
id, creator, title, description, accepted_tokens_json, target_amount, pledged_amount, deadline, created_at, claimed_at, metadata_json, max_per_contributor
601+
id, creator, title, description, accepted_tokens_json, target_amount, pledged_amount, deadline, created_at, claimed_at, failed_at, metadata_json, max_per_contributor
584602
) VALUES (
585-
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
603+
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
586604
)`,
587605
).run(
588606
campaign.id,
@@ -595,6 +613,7 @@ export function createCampaign(input: CampaignInput): CampaignRecord {
595613
campaign.deadline,
596614
campaign.createdAt,
597615
null,
616+
null,
598617
campaign.metadata ? JSON.stringify(campaign.metadata) : null,
599618
campaign.maxPerContributor ?? null,
600619
);

backend/src/services/db.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ function migrate(database: SQLiteDatabase): void {
8383
deadline INTEGER NOT NULL,
8484
created_at INTEGER NOT NULL,
8585
claimed_at INTEGER,
86+
failed_at INTEGER,
8687
metadata_json TEXT,
8788
max_per_contributor INTEGER
8889
);
@@ -138,6 +139,11 @@ function migrate(database: SQLiteDatabase): void {
138139
database.exec(`ALTER TABLE campaigns ADD COLUMN deleted_at INTEGER`);
139140
}
140141

142+
// Add failed_at column if not exists
143+
if (!campaignColumns.some((column) => column.name === 'failed_at')) {
144+
database.exec(`ALTER TABLE campaigns ADD COLUMN failed_at INTEGER`);
145+
}
146+
141147
// Migrate asset_code to accepted_tokens_json if needed
142148
if (
143149
campaignColumns.some((column) => column.name === 'asset_code') &&

0 commit comments

Comments
 (0)