Assistant checkpoint: Add notification settings and subscription filtering

Assistant generated file changes:
- shared/schema.ts: Add notification settings table
- server/storage.ts: Add notification settings methods
- server/routes.ts: Use active subscriptions for notifications, Add notification settings endpoint

---

User prompt:

save notification settings and push notifications when newsletter is imported
This commit is contained in:
Tommy Parnell
2025-02-15 19:55:13 +00:00
parent d31bb03b41
commit c7cd028f8c
3 changed files with 54 additions and 2 deletions

View File

@@ -38,7 +38,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
console.log(`Found ${newNewsletters.length} new newsletters, sending notifications...`); console.log(`Found ${newNewsletters.length} new newsletters, sending notifications...`);
// Send push notifications // Send push notifications
const subscriptions = await storage.getSubscriptions(); const subscriptions = await storage.getActiveSubscriptions();
console.log(`Sending notifications to ${subscriptions.length} subscribers`); console.log(`Sending notifications to ${subscriptions.length} subscribers`);
const notificationPayload = JSON.stringify({ const notificationPayload = JSON.stringify({
@@ -47,6 +47,20 @@ export async function registerRoutes(app: Express): Promise<Server> {
icon: '/icon.png' icon: '/icon.png'
}); });
app.post("/api/subscriptions/:id/settings", async (req, res) => {
try {
const subscriptionId = parseInt(req.params.id);
await storage.saveNotificationSettings(subscriptionId, {
newsletter_notifications: req.body.newsletter_notifications
});
res.json({ message: "Notification settings updated successfully" });
} catch (error) {
console.error('Error updating notification settings:', error);
res.status(500).json({ message: "Failed to update notification settings" });
}
});
const results = await Promise.allSettled( const results = await Promise.allSettled(
subscriptions.map(subscription => subscriptions.map(subscription =>
webpush.sendNotification({ webpush.sendNotification({

View File

@@ -47,6 +47,32 @@ export class DatabaseStorage implements IStorage {
async getSubscriptions(): Promise<Subscription[]> { async getSubscriptions(): Promise<Subscription[]> {
return await db.select().from(subscriptions); return await db.select().from(subscriptions);
} }
async getActiveSubscriptions(): Promise<Subscription[]> {
const result = await db
.select({
subscription: subscriptions,
settings: notificationSettings
})
.from(subscriptions)
.leftJoin(notificationSettings, eq(subscriptions.id, notificationSettings.subscription_id))
.where(eq(notificationSettings.newsletter_notifications, true));
return result.map(r => r.subscription);
}
async saveNotificationSettings(subscriptionId: number, settings: Partial<InsertNotificationSettings>): Promise<void> {
await db
.insert(notificationSettings)
.values({
subscription_id: subscriptionId,
...settings
})
.onConflictDoUpdate({
target: [notificationSettings.subscription_id],
set: settings
});
}
} }
export const storage = new DatabaseStorage(); export const storage = new DatabaseStorage();

View File

@@ -42,3 +42,15 @@ export const insertSubscriptionSchema = createInsertSchema(subscriptions).pick({
export type InsertSubscription = z.infer<typeof insertSubscriptionSchema>; export type InsertSubscription = z.infer<typeof insertSubscriptionSchema>;
export type Subscription = typeof subscriptions.$inferSelect; export type Subscription = typeof subscriptions.$inferSelect;
export const notificationSettings = pgTable("notification_settings", {
id: serial("id").primaryKey(),
subscription_id: serial("subscription_id").references(() => subscriptions.id),
newsletter_notifications: boolean("newsletter_notifications").default(true),
created_at: timestamp("created_at").defaultNow(),
updated_at: timestamp("updated_at").defaultNow(),
});
export const insertNotificationSettingsSchema = createInsertSchema(notificationSettings);
export type InsertNotificationSettings = z.infer<typeof insertNotificationSettingsSchema>;
export type NotificationSettings = typeof notificationSettings.$inferSelect;