Skip to content
Draft
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
197 changes: 197 additions & 0 deletions api/src/database.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,139 @@ export type Database = {
},
]
}
notification_preferences: {
Row: {
channel: Database["public"]["Enums"]["notification_channel"]
enabled: boolean
type: string
user_id: string
}
Insert: {
channel?: Database["public"]["Enums"]["notification_channel"]
enabled: boolean
type: string
user_id: string
}
Update: {
channel?: Database["public"]["Enums"]["notification_channel"]
enabled?: boolean
type?: string
user_id?: string
}
Relationships: [
{
foreignKeyName: "notification_preferences_type_fkey"
columns: ["type"]
isOneToOne: false
referencedRelation: "notification_types"
referencedColumns: ["type"]
},
{
foreignKeyName: "notification_preferences_user_id_fkey"
columns: ["user_id"]
isOneToOne: false
referencedRelation: "dashboard_members"
referencedColumns: ["id"]
},
{
foreignKeyName: "notification_preferences_user_id_fkey"
columns: ["user_id"]
isOneToOne: false
referencedRelation: "profiles"
referencedColumns: ["id"]
},
]
}
notification_types: {
Row: {
category: Database["public"]["Enums"]["notification_category"]
default_enabled: boolean
type: string
}
Insert: {
category: Database["public"]["Enums"]["notification_category"]
default_enabled: boolean
type: string
}
Update: {
category?: Database["public"]["Enums"]["notification_category"]
default_enabled?: boolean
type?: string
}
Relationships: []
}
notifications: {
Row: {
actor_id: string | null
data: Json
group_count: number
group_key: string | null
id: string
occurred_at: string
read_at: string | null
recipient_id: string
type: string
}
Insert: {
actor_id?: string | null
data?: Json
group_count?: number
group_key?: string | null
id?: string
occurred_at?: string
read_at?: string | null
recipient_id: string
type: string
}
Update: {
actor_id?: string | null
data?: Json
group_count?: number
group_key?: string | null
id?: string
occurred_at?: string
read_at?: string | null
recipient_id?: string
type?: string
}
Relationships: [
{
foreignKeyName: "notifications_actor_id_fkey"
columns: ["actor_id"]
isOneToOne: false
referencedRelation: "dashboard_members"
referencedColumns: ["id"]
},
{
foreignKeyName: "notifications_actor_id_fkey"
columns: ["actor_id"]
isOneToOne: false
referencedRelation: "profiles"
referencedColumns: ["id"]
},
{
foreignKeyName: "notifications_recipient_id_fkey"
columns: ["recipient_id"]
isOneToOne: false
referencedRelation: "dashboard_members"
referencedColumns: ["id"]
},
{
foreignKeyName: "notifications_recipient_id_fkey"
columns: ["recipient_id"]
isOneToOne: false
referencedRelation: "profiles"
referencedColumns: ["id"]
},
{
foreignKeyName: "notifications_type_fkey"
columns: ["type"]
isOneToOne: false
referencedRelation: "notification_types"
referencedColumns: ["type"]
},
]
}
objective_revision_edges: {
Row: {
from_node_id: string
Expand Down Expand Up @@ -1011,6 +1144,46 @@ export type Database = {
},
]
}
review_deadline_notifications: {
Row: {
expires_at: string
member_id: string
seat_id: string
}
Insert: {
expires_at: string
member_id: string
seat_id: string
}
Update: {
expires_at?: string
member_id?: string
seat_id?: string
}
Relationships: [
{
foreignKeyName: "review_deadline_notifications_member_id_fkey"
columns: ["member_id"]
isOneToOne: false
referencedRelation: "dashboard_members"
referencedColumns: ["id"]
},
{
foreignKeyName: "review_deadline_notifications_member_id_fkey"
columns: ["member_id"]
isOneToOne: false
referencedRelation: "profiles"
referencedColumns: ["id"]
},
{
foreignKeyName: "review_deadline_notifications_seat_id_fkey"
columns: ["seat_id"]
isOneToOne: false
referencedRelation: "panel_members"
referencedColumns: ["id"]
},
]
}
review_decision_reasons: {
Row: {
decision_id: string
Expand Down Expand Up @@ -1471,6 +1644,17 @@ export type Database = {
title: string
}[]
}
notify: {
Args: {
p_actor_id?: string
p_data?: Json
p_group_key?: string
p_recipient_id: string
p_type: string
}
Returns: undefined
}
notify_review_deadlines: { Args: never; Returns: undefined }
objective_closure: {
Args: { p_targets: string[] }
Returns: {
Expand Down Expand Up @@ -1559,6 +1743,12 @@ export type Database = {
edge_type: "prerequisite" | "related"
knowledge_type: "theoretical" | "practical"
node_status: "draft" | "published" | "archived"
notification_category:
| "guide_statuses"
| "variant_statuses"
| "community_engagement"
| "review_workflows"
notification_channel: "in_app"
objective_revision_status: "draft" | "published"
review_outcome: "approved" | "rejected"
revision_status: "draft" | "submitted"
Expand Down Expand Up @@ -1726,6 +1916,13 @@ export const Constants = {
edge_type: ["prerequisite", "related"],
knowledge_type: ["theoretical", "practical"],
node_status: ["draft", "published", "archived"],
notification_category: [
"guide_statuses",
"variant_statuses",
"community_engagement",
"review_workflows",
],
notification_channel: ["in_app"],
objective_revision_status: ["draft", "published"],
review_outcome: ["approved", "rejected"],
revision_status: ["draft", "submitted"],
Expand Down
6 changes: 5 additions & 1 deletion api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { ServiceError } from "./lib/service-error";
import {
assemblePendingPanels,
sweepExpiredReviewSeats,
notifyReviewDeadlines,
} from "./services/review.service";
import { promoteAllCanonicals } from "./services/promotion.service";
import type { Database } from "./database.types";
Expand All @@ -33,6 +34,7 @@ import { reviewsRouter } from "./routes/reviews";
import { mediaRouter } from "./routes/media";
import { searchRouter } from "./routes/search";
import { dashboardRouter } from "./routes/dashboard";
import { notificationsRouter } from "./routes/notifications";

let specHandler: MiddlewareHandler<HonoEnv> | undefined;
const openApiHandler: MiddlewareHandler<HonoEnv> = (c, next) => {
Expand Down Expand Up @@ -63,7 +65,8 @@ const app = new Hono<HonoEnv>()
.route("/reviews", reviewsRouter)
.route("/media", mediaRouter)
.route("/search", searchRouter)
.route("/dashboard", dashboardRouter);
.route("/dashboard", dashboardRouter)
.route("/notifications", notificationsRouter);

// Services throw ServiceError to signal HTTP-meaningful failures; map them to
// JSON here so handlers stay free of repeated `if (error) return c.json(...)`.
Expand All @@ -86,6 +89,7 @@ async function scheduled(event: ScheduledController, env: Bindings) {
await Promise.allSettled([
assemblePendingPanels(supabase),
sweepExpiredReviewSeats(supabase),
notifyReviewDeadlines(supabase),
]);
}
if (event.cron === "0 */12 * * *") await promoteAllCanonicals(supabase);
Expand Down
Loading
Loading