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:
@@ -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", {
|
||||
|
||||
Reference in New Issue
Block a user