feat: add daily summaries feature

- Backend: daily_summaries table, API routes (GET/POST/PATCH) at /api/summaries
- Frontend: SummariesPage with calendar view, markdown rendering, stats bar, highlights
- Sidebar nav: added Summaries link between Activity and Chat
- Data population script for importing from memory files
- Bearer token + session auth support
This commit is contained in:
2026-01-30 04:42:10 +00:00
parent b5066a0d33
commit d5693a7624
8 changed files with 2012 additions and 0 deletions

View File

@@ -117,6 +117,64 @@ export const taskComments = pgTable("task_comments", {
export type TaskComment = typeof taskComments.$inferSelect;
export type NewTaskComment = typeof taskComments.$inferInsert;
// ─── Security Audits ───
export const securityAuditStatusEnum = pgEnum("security_audit_status", [
"strong",
"needs_improvement",
"critical",
]);
export interface SecurityFinding {
id: string;
status: "strong" | "needs_improvement" | "critical";
title: string;
description: string;
recommendation: string;
}
export const securityAudits = pgTable("security_audits", {
id: uuid("id").defaultRandom().primaryKey(),
projectName: text("project_name").notNull(),
category: text("category").notNull(),
findings: jsonb("findings").$type<SecurityFinding[]>().default([]),
score: integer("score").notNull().default(0), // 0-100
lastAudited: timestamp("last_audited", { withTimezone: true }).defaultNow().notNull(),
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(),
});
export type SecurityAudit = typeof securityAudits.$inferSelect;
export type NewSecurityAudit = typeof securityAudits.$inferInsert;
// ─── Daily Summaries ───
export interface SummaryHighlight {
text: string;
}
export interface SummaryStats {
deploys?: number;
commits?: number;
tasksCompleted?: number;
featuresBuilt?: number;
bugsFixed?: number;
[key: string]: number | undefined;
}
export const dailySummaries = pgTable("daily_summaries", {
id: uuid("id").defaultRandom().primaryKey(),
date: text("date").notNull().unique(), // YYYY-MM-DD
content: text("content").notNull(),
highlights: jsonb("highlights").$type<SummaryHighlight[]>().default([]),
stats: jsonb("stats").$type<SummaryStats>().default({}),
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(),
});
export type DailySummary = typeof dailySummaries.$inferSelect;
export type NewDailySummary = typeof dailySummaries.$inferInsert;
// ─── BetterAuth tables ───
export const users = pgTable("users", {