Files
Tomas Dvorak 462a70933d feat(ui,api,db): implement notifications and custom templates with hand-drawn aesthetic
This commit introduces a significant update to both the frontend and backend, focusing on enhanced user engagement and a consistent visual identity.

Key changes include:

- **Frontend UI/UX Refactor**:
  - Implemented a "hand-drawn" aesthetic across the entire application using CSS overrides, custom SVG charts, and specific border/shadow styles to match the Excalidraw experience.
  - Added a new notification system in the Header to display user updates.
  - Enhanced the Template Picker with more variety and improved interaction models.
  - Added a "Presentation Mode" in the Editor.
  - Improved Dashboard visualizations with hand-drawn style sparklines and charts.
  - Added modal dialogs for creating drawings and templates with custom names.

- **Backend & API Enhancements**:
  - Implemented full CRUD support for custom templates, allowing users to save their drawings as reusable templates.
  - Added a notification service with endpoints to list, mark as read, and mark all as read.
  - Updated the API client to handle more robust JSON responses and error states.
  - Improved CORS/Origin validation in the HTTP middleware to handle proxy headers (`X-Forwarded-Host`, `X-Forwarded-Proto`) more reliably.

- **Database & Infrastructure**:
  - Added a new PostgreSQL migration for the `notifications` table.
  - Updated the data models in the workspace to support templates (including snapshot storage) and notifications.
  - Updated `.gitignore` to exclude graphify cache and AST files.
2026-05-01 15:07:38 +02:00

20 lines
671 B
SQL

-- +goose Up
CREATE TABLE IF NOT EXISTS workspace_notifications (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL REFERENCES workspace_users(id) ON DELETE CASCADE,
type TEXT NOT NULL,
title TEXT NOT NULL,
description TEXT NOT NULL,
resource_type TEXT,
resource_id TEXT,
read BOOLEAN NOT NULL DEFAULT FALSE,
metadata_json TEXT NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_workspace_notifications_user ON workspace_notifications(user_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_workspace_notifications_unread ON workspace_notifications(user_id, read);
-- +goose Down
DROP TABLE IF EXISTS workspace_notifications;