Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/backend/drizzle/0010_add_content_updated_at.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE "chapters" ADD COLUMN "content_updated_at" timestamp;--> statement-breakpoint

-- Initialize content_updated_at with updated_at for existing chapters that have content
UPDATE "chapters" SET "content_updated_at" = "updated_at" WHERE "content" IS NOT NULL AND "content" != '';
7 changes: 7 additions & 0 deletions apps/backend/drizzle/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@
"when": 1772625679467,
"tag": "0009_typical_thor_girl",
"breakpoints": true
},
{
"idx": 10,
"version": "5",
"when": 1775800000000,
"tag": "0010_add_content_updated_at",
"breakpoints": true
}
]
}
1 change: 1 addition & 0 deletions apps/backend/src/database/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ export const chapters = pgTable("chapters", {
status: chapterStatusEnum("status").default("pending"),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
contentUpdatedAt: timestamp("content_updated_at"), // Only updates when content actually changes (for word count stats)
});

// Chapter Snapshots table (Version History)
Expand Down
1 change: 1 addition & 0 deletions apps/backend/src/queue/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ export function startWorker(io: Server) {
wordCount: result.content.length,
status: "completed",
updatedAt: new Date(),
contentUpdatedAt: new Date(),
})
.where(eq(schema.chapters.id, chapterId!));
break;
Expand Down
19 changes: 14 additions & 5 deletions apps/backend/src/routes/chapter.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ router.patch("/:id", async (req: AuthRequest, res, next) => {
const { id } = req.params;
const { title, content, outline } = req.body;

const existingChapter = await db.query.chapters.findFirst({
where: eq(schema.chapters.id, id),
});

if (!existingChapter) {
res.status(404).json({ error: "Chapter not found" });
return;
}

const contentChanged =
content !== undefined && content !== existingChapter.content;

const [chapter] = await db
.update(schema.chapters)
.set({
Expand All @@ -106,15 +118,11 @@ router.patch("/:id", async (req: AuthRequest, res, next) => {
outline,
wordCount: content ? content.length : undefined,
updatedAt: new Date(),
...(contentChanged && { contentUpdatedAt: new Date() }),
})
.where(eq(schema.chapters.id, id))
.returning();

if (!chapter) {
res.status(404).json({ error: "Chapter not found" });
return;
}

res.json(chapter);
} catch (error) {
next(error);
Expand Down Expand Up @@ -261,6 +269,7 @@ router.post(
content: snapshot.content,
wordCount: snapshot.wordCount,
updatedAt: new Date(),
contentUpdatedAt: new Date(),
})
.where(eq(schema.chapters.id, id))
.returning();
Expand Down
6 changes: 4 additions & 2 deletions apps/frontend/app/stats/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ interface Chapter {
order: number;
status: string;
updatedAt: string;
contentUpdatedAt: string | null;
}

interface Volume {
Expand Down Expand Up @@ -156,10 +157,11 @@ export default function StatsPage() {
).length;
const totalNovels = novels.length;

// Calculate today's words from database (chapters updated today)
// Calculate today's words from database (chapters with content updated today)
// Use contentUpdatedAt to only count actual content changes, not just viewing
const todayWords = useMemo(() => {
return allChapters.reduce((sum, chapter) => {
if (chapter.updatedAt && isToday(chapter.updatedAt)) {
if (chapter.contentUpdatedAt && isToday(chapter.contentUpdatedAt)) {
return sum + (chapter.wordCount || 0);
}
return sum;
Expand Down