feat: map shapes, image persistence, grab tool, layer rename/delete, i18n, page metadata
This commit is contained in:
997
docs/TECHNICAL_DESIGN.md
Normal file
997
docs/TECHNICAL_DESIGN.md
Normal file
@@ -0,0 +1,997 @@
|
||||
# Root — Technical Design Document
|
||||
|
||||
> Comprehensive documentation of every feature, how it works, what problems it solves, and where there is room for improvement.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Platform Overview](#1-platform-overview)
|
||||
2. [Architecture](#2-architecture)
|
||||
3. [Authentication & Authorization](#3-authentication--authorization)
|
||||
4. [Organizations](#4-organizations)
|
||||
5. [Organization Settings](#5-organization-settings)
|
||||
6. [Documents & File Browser](#6-documents--file-browser)
|
||||
7. [Kanban Boards](#7-kanban-boards)
|
||||
8. [Calendar](#8-calendar)
|
||||
9. [Chat (Matrix)](#9-chat-matrix)
|
||||
10. [Events](#10-events)
|
||||
11. [Event Team & Departments](#11-event-team--departments)
|
||||
12. [Department Dashboard](#12-department-dashboard)
|
||||
13. [Checklists Module](#13-checklists-module)
|
||||
14. [Notes Module](#14-notes-module)
|
||||
15. [Schedule Module](#15-schedule-module)
|
||||
16. [Contacts Module](#16-contacts-module)
|
||||
17. [Budget & Finances Module](#17-budget--finances-module)
|
||||
18. [Sponsors Module](#18-sponsors-module)
|
||||
19. [Activity Tracking](#19-activity-tracking)
|
||||
20. [Tags System](#20-tags-system)
|
||||
21. [Roles & Permissions](#21-roles--permissions)
|
||||
22. [Google Calendar Integration](#22-google-calendar-integration)
|
||||
23. [Internationalization (i18n)](#23-internationalization-i18n)
|
||||
24. [Platform Admin](#24-platform-admin)
|
||||
25. [Testing Strategy](#25-testing-strategy)
|
||||
26. [Database Migrations](#26-database-migrations)
|
||||
|
||||
---
|
||||
|
||||
## 1. Platform Overview
|
||||
|
||||
### What It Is
|
||||
Root is an **event organizing platform** built for teams and organizations that plan events. It provides a unified workspace where teams can manage documents, tasks, budgets, sponsors, schedules, contacts, and communications — all scoped to specific events and departments.
|
||||
|
||||
### Problems It Solves
|
||||
- **Fragmented tooling**: Event teams typically juggle Google Sheets, Slack, Trello, email, and spreadsheets. Root consolidates these into one platform.
|
||||
- **No event-scoped context**: Generic project tools don't understand the concept of "events with departments." Root's data model is purpose-built for this.
|
||||
- **Budget opacity**: Planned vs. actual spending is hard to track across departments. Root provides real-time financial rollups.
|
||||
- **Sponsor management**: No lightweight CRM exists for event sponsorships. Root provides tier-based sponsor tracking with deliverables.
|
||||
|
||||
### Tech Stack
|
||||
| Layer | Technology |
|
||||
|-------|-----------|
|
||||
| Frontend | SvelteKit (Svelte 5), TailwindCSS |
|
||||
| Backend | Supabase (PostgreSQL, Auth, Storage, Realtime) |
|
||||
| Chat | Matrix protocol (Synapse server) |
|
||||
| Calendar | Google Calendar API (OAuth2) |
|
||||
| i18n | Paraglide v2 (en, et) |
|
||||
| Icons | Material Symbols (variable font) |
|
||||
| Testing | Vitest (unit), Playwright (E2E) |
|
||||
| Deployment | Vercel / Netlify |
|
||||
|
||||
---
|
||||
|
||||
## 2. Architecture
|
||||
|
||||
### Routing Structure
|
||||
```
|
||||
/ → Landing / login
|
||||
/[orgSlug]/ → Organization overview
|
||||
/[orgSlug]/documents/ → File browser (root)
|
||||
/[orgSlug]/documents/folder/[id] → Folder view
|
||||
/[orgSlug]/documents/file/[id] → Document / kanban viewer
|
||||
/[orgSlug]/calendar/ → Calendar page
|
||||
/[orgSlug]/chat/ → Matrix chat
|
||||
/[orgSlug]/events/ → Event list
|
||||
/[orgSlug]/events/[eventSlug]/ → Event detail
|
||||
/[orgSlug]/events/[eventSlug]/team/ → Team management
|
||||
/[orgSlug]/events/[eventSlug]/finances/ → Financial overview
|
||||
/[orgSlug]/events/[eventSlug]/sponsors/ → Sponsor CRM
|
||||
/[orgSlug]/events/[eventSlug]/contacts/ → Contact directory
|
||||
/[orgSlug]/events/[eventSlug]/schedule/ → Schedule builder
|
||||
/[orgSlug]/events/[eventSlug]/dept/[deptId]/ → Department dashboard
|
||||
/[orgSlug]/settings/ → Organization settings
|
||||
/[orgSlug]/account/ → User account settings
|
||||
/admin/ → Platform admin panel
|
||||
```
|
||||
|
||||
### Data Flow
|
||||
1. **Layout server** (`[orgSlug]/+layout.server.ts`) loads org data, membership, permissions, members, activity, stats, and upcoming events via `select('*')` on the `organizations` table.
|
||||
2. **Child pages** call `parent()` to inherit org context, then load page-specific data.
|
||||
3. **Supabase client** is set via `setContext('supabase')` in the root layout and retrieved via `getContext` in child components.
|
||||
4. **Realtime** subscriptions use Supabase channels for live updates (kanban cards, chat presence).
|
||||
|
||||
### Key Files
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/routes/[orgSlug]/+layout.server.ts` | Loads org, membership, permissions, members, stats |
|
||||
| `src/routes/[orgSlug]/+layout.svelte` | Sidebar navigation, user menu, org header |
|
||||
| `src/lib/supabase/types.ts` | Auto-generated + manual TypeScript types |
|
||||
| `src/lib/utils/currency.ts` | Shared currency formatting, timezone, date format constants |
|
||||
| `src/lib/utils/permissions.ts` | Permission checking utility |
|
||||
| `src/lib/stores/toast.svelte` | Toast notification store |
|
||||
| `src/lib/paraglide/messages.ts` | Generated i18n message functions |
|
||||
|
||||
---
|
||||
|
||||
## 3. Authentication & Authorization
|
||||
|
||||
### How It Works
|
||||
- **Supabase Auth** handles email/password login with session management.
|
||||
- Sessions are persisted via cookies; `locals.safeGetSession()` validates on every server load.
|
||||
- **Playwright tests** use a setup project that logs in once and saves `storageState` for reuse.
|
||||
|
||||
### Authorization Layers
|
||||
1. **Org membership**: Users must be members of an org to access it (checked in layout server).
|
||||
2. **Role-based**: Each member has a role (`owner`, `admin`, `editor`, `viewer`).
|
||||
3. **Permission-based**: Custom roles with granular permissions (e.g., `documents.view`, `calendar.view`, `settings.view`).
|
||||
4. **Row-Level Security (RLS)**: All Supabase tables have RLS policies scoped to org membership.
|
||||
|
||||
### Room for Improvement
|
||||
- **Invite flow**: Currently email-based; could add link-based invites.
|
||||
- **SSO**: No SAML/OIDC support yet.
|
||||
- **2FA**: Not implemented.
|
||||
|
||||
---
|
||||
|
||||
## 4. Organizations
|
||||
|
||||
### What It Is
|
||||
The top-level entity. Every user belongs to one or more organizations. All data (events, documents, members) is scoped to an org.
|
||||
|
||||
### Database Schema
|
||||
```sql
|
||||
CREATE TABLE organizations (
|
||||
id UUID PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
slug TEXT UNIQUE NOT NULL,
|
||||
avatar_url TEXT,
|
||||
theme_color TEXT DEFAULT '#00a3e0',
|
||||
icon_url TEXT,
|
||||
description TEXT DEFAULT '',
|
||||
currency TEXT NOT NULL DEFAULT 'EUR',
|
||||
date_format TEXT NOT NULL DEFAULT 'DD/MM/YYYY',
|
||||
timezone TEXT NOT NULL DEFAULT 'Europe/Tallinn',
|
||||
week_start_day TEXT NOT NULL DEFAULT 'monday',
|
||||
default_calendar_view TEXT NOT NULL DEFAULT 'month',
|
||||
default_event_color TEXT NOT NULL DEFAULT '#7986cb',
|
||||
default_event_status TEXT NOT NULL DEFAULT 'planning',
|
||||
default_dept_modules TEXT[] NOT NULL DEFAULT ARRAY['kanban','files','checklist'],
|
||||
default_dept_layout TEXT NOT NULL DEFAULT 'split',
|
||||
feature_chat BOOLEAN NOT NULL DEFAULT true,
|
||||
feature_sponsors BOOLEAN NOT NULL DEFAULT true,
|
||||
feature_contacts BOOLEAN NOT NULL DEFAULT true,
|
||||
feature_budget BOOLEAN NOT NULL DEFAULT true,
|
||||
matrix_space_id TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
```
|
||||
|
||||
### API (`src/lib/api/organizations.ts`)
|
||||
- `createOrganization(supabase, name, slug, userId)` — creates org + adds creator as owner
|
||||
- `updateOrganization(supabase, id, updates)` — updates name, slug, avatar
|
||||
- `deleteOrganization(supabase, id)` — deletes org and cascades
|
||||
- `fetchOrgMembers(supabase, orgId)` — lists members with profiles
|
||||
- `inviteMember(supabase, orgId, email, role)` — sends invite
|
||||
- `updateMemberRole(supabase, memberId, role)` — changes role
|
||||
- `removeMember(supabase, memberId)` — removes member
|
||||
|
||||
### Overview Page (`/[orgSlug]/`)
|
||||
Displays:
|
||||
- **Stat cards**: Events, members, documents, kanban boards
|
||||
- **Upcoming events**: Next 5 events with status badges
|
||||
- **Recent activity**: Last 10 activity log entries
|
||||
- **Member list**: First 6 members with avatars
|
||||
|
||||
---
|
||||
|
||||
## 5. Organization Settings
|
||||
|
||||
### What It Is
|
||||
Configurable preferences that affect the entire organization. Accessible at `/[orgSlug]/settings` under the "General" tab.
|
||||
|
||||
### Sections
|
||||
|
||||
#### Organization Details
|
||||
- **Name** and **URL slug** — core identity
|
||||
- **Avatar** — upload/remove via Supabase Storage
|
||||
- **Description** — free-text org description
|
||||
- **Theme color** — color picker, stored as hex
|
||||
|
||||
#### Preferences
|
||||
- **Currency** — ISO 4217 code (EUR, USD, GBP, etc.). Affects all financial displays via `formatCurrency()` utility. Uses locale-aware formatting (EUR → `de-DE` locale puts € after number).
|
||||
- **Date format** — DD/MM/YYYY, MM/DD/YYYY, or YYYY-MM-DD
|
||||
- **Timezone** — grouped by region (Europe, Americas, Asia/Pacific)
|
||||
- **Week start day** — Monday or Sunday
|
||||
- **Default calendar view** — Month, Week, or Day
|
||||
|
||||
#### Event Defaults
|
||||
- **Default event color** — preset palette + custom color picker
|
||||
- **Default event status** — Planning or Active
|
||||
- **Default department layout** — Single, Split, Grid, or Focus+Sidebar
|
||||
- **Default department modules** — toggle grid for: Kanban, Files, Checklist, Notes, Schedule, Contacts, Budget, Sponsors
|
||||
|
||||
#### Feature Toggles
|
||||
- **Chat** — show/hide Matrix chat in sidebar
|
||||
- **Budget & Finances** — enable/disable budget module
|
||||
- **Sponsors** — enable/disable sponsor CRM
|
||||
- **Contacts** — enable/disable contact directory
|
||||
|
||||
#### Danger Zone
|
||||
- Delete organization (owner only)
|
||||
- Leave organization (non-owners)
|
||||
|
||||
### Implementation
|
||||
- **Settings UI**: `src/lib/components/settings/SettingsGeneral.svelte`
|
||||
- **Currency utility**: `src/lib/utils/currency.ts` — shared `formatCurrency(amount, currency)` function with locale map
|
||||
- **Feature toggles**: Wired into sidebar nav in `[orgSlug]/+layout.svelte` — conditionally shows/hides nav items
|
||||
- **Calendar default**: Passed as `initialView` prop to `Calendar.svelte`
|
||||
- **Event color default**: Used in event creation form (`events/+page.svelte`)
|
||||
|
||||
### Room for Improvement
|
||||
- **Date format** is stored but not yet consumed by all date displays (calendar, activity feed, event cards). Need a shared `formatDate()` utility.
|
||||
- **Timezone** is stored but not yet used for server-side date rendering.
|
||||
- **Week start day** is stored but Calendar grid is still hardcoded to Monday.
|
||||
- **Feature toggles** hide sidebar nav but don't yet block API access or hide modules within department dashboards.
|
||||
- **Default dept modules/layout** are stored but not yet consumed by the department auto-create trigger.
|
||||
|
||||
---
|
||||
|
||||
## 6. Documents & File Browser
|
||||
|
||||
### What It Is
|
||||
A hierarchical file system with folders, rich-text documents, and kanban boards. Supports org-wide and event-scoped views.
|
||||
|
||||
### Problems It Solves
|
||||
- Centralized document storage per organization
|
||||
- Auto-created folder structure for events and departments
|
||||
- In-browser document editing without external tools
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE documents (
|
||||
id UUID PRIMARY KEY,
|
||||
org_id UUID REFERENCES organizations(id),
|
||||
parent_id UUID REFERENCES documents(id), -- folder hierarchy
|
||||
type TEXT NOT NULL, -- 'folder' | 'document' | 'kanban'
|
||||
title TEXT NOT NULL,
|
||||
content JSONB, -- TipTap JSON for documents
|
||||
position INTEGER,
|
||||
event_id UUID REFERENCES events(id), -- event scoping
|
||||
department_id UUID REFERENCES event_departments(id), -- dept scoping
|
||||
created_by UUID,
|
||||
created_at TIMESTAMPTZ,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
```
|
||||
|
||||
### Routing
|
||||
- `/documents` — root file browser
|
||||
- `/documents/folder/[id]` — folder contents
|
||||
- `/documents/file/[id]` — document editor or kanban board
|
||||
|
||||
### Auto-Folder System
|
||||
When events/departments are created, folders are auto-created:
|
||||
```
|
||||
📁 Events/
|
||||
📁 [Event Name]/ (event_id FK)
|
||||
📁 [Department Name]/ (department_id FK)
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- **Drag-and-drop** file/folder reordering
|
||||
- **Breadcrumb** navigation
|
||||
- **Document locking** — prevents concurrent edits
|
||||
- **Single-click** folder → navigate; document → inline editor; kanban → full page
|
||||
- **Double-click** → open in new tab
|
||||
|
||||
### API (`src/lib/api/documents.ts`)
|
||||
- `fetchDocuments`, `createDocument`, `moveDocument`, `deleteDocument`
|
||||
- `ensureEventsFolder`, `createEventFolder`, `createDepartmentFolder`
|
||||
- `findDepartmentFolder`, `fetchFolderContents`
|
||||
|
||||
### Room for Improvement
|
||||
- **Real-time collaboration**: Currently single-user editing with locks. Could add CRDT-based collaborative editing.
|
||||
- **Search**: No full-text search across documents.
|
||||
- **Version history**: No document versioning.
|
||||
- **File uploads**: Only structured documents; no raw file upload (PDF, images).
|
||||
|
||||
---
|
||||
|
||||
## 7. Kanban Boards
|
||||
|
||||
### What It Is
|
||||
Drag-and-drop task boards with columns, cards, labels, checklists, and comments.
|
||||
|
||||
### Problems It Solves
|
||||
- Visual task management within the document system
|
||||
- Scoped task tracking per department
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE kanban_columns (id, document_id, title, position, color);
|
||||
CREATE TABLE kanban_cards (id, column_id, title, description, position, due_date, assigned_to);
|
||||
CREATE TABLE kanban_labels (id, document_id, name, color);
|
||||
CREATE TABLE card_checklists (id, card_id, title);
|
||||
CREATE TABLE card_checklist_items (id, checklist_id, text, completed, position);
|
||||
CREATE TABLE task_comments (id, card_id, user_id, content, created_at);
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- **Optimistic drag-and-drop**: Cards move instantly; DB persists fire-and-forget
|
||||
- **Realtime**: Incremental handlers for INSERT/UPDATE/DELETE via Supabase channels
|
||||
- **Labels**: Color-coded tags per board
|
||||
- **Card detail**: Description, due date, assignee, checklists, comments
|
||||
- **Drop indicators**: CSS box-shadow based (no layout shift)
|
||||
|
||||
### API (`src/lib/api/kanban.ts`)
|
||||
- `fetchBoard`, `createColumn`, `moveColumn`, `createCard`, `moveCard`, `updateCard`
|
||||
|
||||
### Room for Improvement
|
||||
- **Swimlanes**: No horizontal grouping by assignee or label.
|
||||
- **Filters**: No filtering by label, assignee, or due date on the board view.
|
||||
- **Card templates**: No reusable card templates.
|
||||
|
||||
---
|
||||
|
||||
## 8. Calendar
|
||||
|
||||
### What It Is
|
||||
A month/week/day calendar view showing org events and optionally synced Google Calendar events.
|
||||
|
||||
### Problems It Solves
|
||||
- Unified view of all organization events
|
||||
- Google Calendar sync for external event visibility
|
||||
|
||||
### Implementation
|
||||
- **Component**: `src/lib/components/calendar/Calendar.svelte`
|
||||
- **Views**: Month (grid), Week (7-column), Day (single column with time slots)
|
||||
- **Props**: `events`, `onDateClick`, `onEventClick`, `initialView`
|
||||
- **Default view**: Configurable per org via `default_calendar_view` setting
|
||||
|
||||
### API (`src/lib/api/calendar.ts`)
|
||||
- `getMonthDays(year, month)` — generates date grid for month view
|
||||
- `isSameDay(date1, date2)` — date comparison utility
|
||||
|
||||
### Room for Improvement
|
||||
- **Week start day**: Setting exists but calendar grid is hardcoded to Monday start.
|
||||
- **Timezone**: Events display in browser timezone; should respect org timezone setting.
|
||||
- **Recurring events**: Not supported.
|
||||
- **Drag to create**: Can't drag across time slots to create events.
|
||||
|
||||
---
|
||||
|
||||
## 9. Chat (Matrix)
|
||||
|
||||
### What It Is
|
||||
Real-time messaging powered by the Matrix protocol, using a self-hosted Synapse server.
|
||||
|
||||
### Problems It Solves
|
||||
- Team communication without leaving the platform
|
||||
- Org-scoped chat rooms (no cross-org leakage)
|
||||
|
||||
### Implementation
|
||||
- Each org gets a Matrix space (`matrix_space_id` on organizations table)
|
||||
- Users get Matrix credentials stored in `matrix_credentials` table
|
||||
- Chat UI at `/[orgSlug]/chat/`
|
||||
- Unread count badge in sidebar nav
|
||||
- **Feature toggle**: Can be disabled per org via `feature_chat` setting
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE matrix_credentials (user_id, matrix_user_id, access_token, device_id);
|
||||
ALTER TABLE organizations ADD COLUMN matrix_space_id TEXT;
|
||||
```
|
||||
|
||||
### Room for Improvement
|
||||
- **Event-scoped channels**: Currently org-wide only; could auto-create channels per event/department.
|
||||
- **File sharing**: No in-chat file upload.
|
||||
- **Threads**: Matrix supports threads but UI doesn't expose them.
|
||||
- **Push notifications**: Not implemented.
|
||||
|
||||
---
|
||||
|
||||
## 10. Events
|
||||
|
||||
### What It Is
|
||||
The core entity of the platform. Events are projects that contain departments, budgets, schedules, sponsors, and more.
|
||||
|
||||
### Problems It Solves
|
||||
- Structured project management for event planning
|
||||
- Status tracking (planning → active → completed → archived)
|
||||
- Cross-department coordination
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE events (
|
||||
id UUID PRIMARY KEY,
|
||||
org_id UUID REFERENCES organizations(id),
|
||||
name TEXT NOT NULL,
|
||||
slug TEXT NOT NULL,
|
||||
description TEXT,
|
||||
status TEXT DEFAULT 'planning', -- planning, active, completed, archived
|
||||
start_date TIMESTAMPTZ,
|
||||
end_date TIMESTAMPTZ,
|
||||
venue_name TEXT,
|
||||
venue_address TEXT,
|
||||
color TEXT,
|
||||
created_by UUID,
|
||||
created_at TIMESTAMPTZ,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- **Status pipeline**: Planning → Active → Completed → Archived with tab filtering
|
||||
- **Color coding**: Each event has a color (defaults to org's `default_event_color`)
|
||||
- **Auto-folder creation**: Creating an event auto-creates `Events/[EventName]/` folder
|
||||
- **Event detail page**: Overview with status, dates, venue, team, and navigation to sub-pages
|
||||
|
||||
### API (`src/lib/api/events.ts`)
|
||||
- `fetchEvents`, `fetchEventBySlug`, `createEvent`, `updateEvent`, `deleteEvent`
|
||||
- `fetchEventDepartments`, `createDepartment`, `updateDepartment`, `deleteDepartment`
|
||||
- `updateDepartmentPlannedBudget`
|
||||
|
||||
### Room for Improvement
|
||||
- **Event templates**: No way to clone an event structure.
|
||||
- **Guest list / registration**: Not yet implemented (on roadmap).
|
||||
- **Public event page**: No public-facing event page for attendees.
|
||||
|
||||
---
|
||||
|
||||
## 11. Event Team & Departments
|
||||
|
||||
### What It Is
|
||||
Team management within events. Each event has departments (e.g., "Marketing", "Logistics") with assigned members.
|
||||
|
||||
### Problems It Solves
|
||||
- Clear ownership of event responsibilities
|
||||
- Department-scoped modules (each dept gets its own dashboard)
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE event_departments (
|
||||
id UUID PRIMARY KEY,
|
||||
event_id UUID REFERENCES events(id),
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
color TEXT,
|
||||
head_user_id UUID,
|
||||
planned_budget NUMERIC DEFAULT 0,
|
||||
created_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE event_members (
|
||||
id UUID PRIMARY KEY,
|
||||
event_id UUID REFERENCES events(id),
|
||||
user_id UUID,
|
||||
department_id UUID REFERENCES event_departments(id),
|
||||
role TEXT DEFAULT 'member'
|
||||
);
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- **Department creation**: Auto-creates folder + dashboard
|
||||
- **Department head**: Assignable lead per department
|
||||
- **Planned budget**: Per-department budget allocation
|
||||
- **Member assignment**: Assign org members to specific departments
|
||||
|
||||
### Room for Improvement
|
||||
- **Shift scheduling**: No volunteer shift management.
|
||||
- **Department templates**: Can't save/reuse department structures.
|
||||
|
||||
---
|
||||
|
||||
## 12. Department Dashboard
|
||||
|
||||
### What It Is
|
||||
A composable, layout-configurable dashboard per department with drag-and-drop module panels.
|
||||
|
||||
### Problems It Solves
|
||||
- Each department needs different tools (marketing needs contacts, logistics needs schedules)
|
||||
- Customizable workspace per team
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE department_dashboards (
|
||||
id UUID PRIMARY KEY,
|
||||
department_id UUID REFERENCES event_departments(id),
|
||||
layout TEXT DEFAULT 'split' -- single, split, grid, focus_sidebar
|
||||
);
|
||||
|
||||
CREATE TABLE dashboard_panels (
|
||||
id UUID PRIMARY KEY,
|
||||
dashboard_id UUID REFERENCES department_dashboards(id),
|
||||
module TEXT NOT NULL, -- kanban, files, checklist, notes, schedule, contacts, budget, sponsors
|
||||
position INTEGER,
|
||||
config JSONB
|
||||
);
|
||||
```
|
||||
|
||||
### Layout Presets
|
||||
- **Single**: One full-width panel
|
||||
- **Split**: Two equal columns
|
||||
- **Grid**: 2×2 grid
|
||||
- **Focus + Sidebar**: Large left panel + narrow right panel
|
||||
|
||||
### Auto-Creation
|
||||
A PostgreSQL trigger (`on_department_created_setup_dashboard`) auto-creates a dashboard with default panels when a department is inserted.
|
||||
|
||||
### Key Features
|
||||
- **Add/remove modules**: Click to add any available module
|
||||
- **Expand to fullscreen**: Each panel can expand to full-screen mode
|
||||
- **Layout switching**: Change layout preset from dashboard header
|
||||
|
||||
### Room for Improvement
|
||||
- **Drag-and-drop panel reordering**: Currently position is fixed by creation order.
|
||||
- **Custom panel sizing**: All panels are equal size within a layout.
|
||||
- **Default modules from org settings**: The `default_dept_modules` org setting is stored but not yet consumed by the auto-create trigger.
|
||||
|
||||
---
|
||||
|
||||
## 13. Checklists Module
|
||||
|
||||
### What It Is
|
||||
Task checklists within department dashboards. Multiple checklists per department, each with ordered items.
|
||||
|
||||
### Problems It Solves
|
||||
- Simple task tracking without full kanban overhead
|
||||
- Pre-event preparation checklists
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE department_checklists (id, department_id, title, position);
|
||||
CREATE TABLE department_checklist_items (id, checklist_id, text, completed, position);
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- Multiple checklists per department
|
||||
- Add/rename/delete checklists
|
||||
- Toggle item completion with progress bar
|
||||
- Drag-to-reorder items
|
||||
|
||||
### Component: `src/lib/components/modules/ChecklistWidget.svelte`
|
||||
|
||||
---
|
||||
|
||||
## 14. Notes Module
|
||||
|
||||
### What It Is
|
||||
Rich-text notes per department with auto-save.
|
||||
|
||||
### Problems It Solves
|
||||
- Meeting notes, decision logs, and documentation per department
|
||||
- No need for external note-taking tools
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE department_notes (id, department_id, title, content, position, created_at, updated_at);
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- Note list sidebar + textarea editor
|
||||
- **Auto-save** with 500ms debounce
|
||||
- Create/rename/delete notes
|
||||
|
||||
### Component: `src/lib/components/modules/NotesWidget.svelte`
|
||||
|
||||
### Room for Improvement
|
||||
- **Rich text editor**: Currently plain textarea; could use TipTap like documents.
|
||||
- **Collaborative editing**: No real-time collaboration.
|
||||
|
||||
---
|
||||
|
||||
## 15. Schedule Module
|
||||
|
||||
### What It Is
|
||||
A timeline/program builder for event schedules with stages (rooms/tracks) and time blocks.
|
||||
|
||||
### Problems It Solves
|
||||
- Event program planning with multiple parallel tracks
|
||||
- Visual timeline view of the event day
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE schedule_stages (id, department_id, name, color, position);
|
||||
CREATE TABLE schedule_blocks (
|
||||
id, department_id, stage_id, title, description,
|
||||
start_time TIMESTAMPTZ, end_time TIMESTAMPTZ,
|
||||
speaker TEXT, color TEXT
|
||||
);
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- **Stages bar**: Color-coded tracks (e.g., "Main Stage", "Workshop Room")
|
||||
- **Time blocks**: Scheduled items with start/end times, speaker, description
|
||||
- **Date grouping**: Blocks grouped by date
|
||||
- **Color picker**: Per-block color customization
|
||||
|
||||
### Component: `src/lib/components/modules/ScheduleWidget.svelte`
|
||||
|
||||
### Room for Improvement
|
||||
- **Drag-and-drop timeline**: Currently list-based; could use a visual timeline grid.
|
||||
- **Conflict detection**: No warning when blocks overlap on the same stage.
|
||||
- **Public schedule**: No attendee-facing schedule view.
|
||||
|
||||
---
|
||||
|
||||
## 16. Contacts Module
|
||||
|
||||
### What It Is
|
||||
A searchable vendor/contact directory per department.
|
||||
|
||||
### Problems It Solves
|
||||
- Centralized vendor management for event logistics
|
||||
- Quick access to contact info during event planning
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE department_contacts (
|
||||
id, department_id, name, email, phone, company,
|
||||
role TEXT, category TEXT, notes TEXT, website TEXT
|
||||
);
|
||||
```
|
||||
|
||||
### Categories
|
||||
Predefined categories: Venue, Catering, AV/Tech, Security, Transport, Decoration, Photography, Entertainment, Printing, Accommodation, Sponsor, Speaker, Other.
|
||||
|
||||
### Key Features
|
||||
- Search by name/company/email
|
||||
- Filter by category
|
||||
- Expandable detail rows
|
||||
- CRUD modal with all contact fields
|
||||
|
||||
### Component: `src/lib/components/modules/ContactsWidget.svelte`
|
||||
|
||||
### Room for Improvement
|
||||
- **Org-level contacts**: Currently department-scoped; could have a shared org contact book.
|
||||
- **Import/export**: No CSV import/export.
|
||||
- **Deduplication**: No duplicate detection.
|
||||
|
||||
---
|
||||
|
||||
## 17. Budget & Finances Module
|
||||
|
||||
### What It Is
|
||||
Income/expense tracking with categories, planned vs. actual amounts, and cross-department financial overview.
|
||||
|
||||
### Problems It Solves
|
||||
- Budget planning and tracking across departments
|
||||
- Planned vs. actual variance analysis
|
||||
- Receipt management
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE budget_categories (id, event_id, name, color);
|
||||
CREATE TABLE budget_items (
|
||||
id, event_id, department_id, category_id,
|
||||
description TEXT, item_type TEXT, -- 'income' | 'expense'
|
||||
planned_amount NUMERIC, actual_amount NUMERIC,
|
||||
notes TEXT, receipt_document_id UUID
|
||||
);
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- **Overview/Income/Expense tabs**: Filtered views
|
||||
- **Category management**: Color-coded budget categories
|
||||
- **Planned vs. Actual**: Side-by-side comparison with diff column
|
||||
- **Receipt linking**: Attach receipt documents to budget items
|
||||
- **Department rollup**: Finances page shows cross-department totals
|
||||
- **Sponsor allocation**: Link sponsor funds to specific departments
|
||||
- **Currency formatting**: Uses org's currency setting via shared `formatCurrency()` utility
|
||||
|
||||
### Components
|
||||
- `src/lib/components/modules/BudgetWidget.svelte` — department-level widget
|
||||
- `src/routes/[orgSlug]/events/[eventSlug]/finances/+page.svelte` — cross-department overview
|
||||
|
||||
### API (`src/lib/api/budget.ts`)
|
||||
- `fetchEventBudgetCategories`, `createBudgetCategory`, `deleteBudgetCategory`
|
||||
- `fetchEventBudgetItems`, `createBudgetItem`, `updateBudgetItem`, `deleteBudgetItem`
|
||||
|
||||
### Room for Improvement
|
||||
- **Budget approval workflow**: No approval process for expenses.
|
||||
- **Currency conversion**: No multi-currency support within a single org.
|
||||
- **Export**: No PDF/Excel export of financial reports.
|
||||
- **Recurring items**: No support for recurring budget items.
|
||||
|
||||
---
|
||||
|
||||
## 18. Sponsors Module
|
||||
|
||||
### What It Is
|
||||
A lightweight CRM for managing event sponsors with tiers, status pipeline, deliverables tracking, and fund allocation.
|
||||
|
||||
### Problems It Solves
|
||||
- Sponsor relationship management
|
||||
- Deliverable tracking (what was promised vs. delivered)
|
||||
- Fund allocation across departments
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE sponsor_tiers (id, event_id, name, amount, color, position);
|
||||
CREATE TABLE sponsors (
|
||||
id, event_id, department_id, tier_id,
|
||||
name, contact_name, contact_email, contact_phone, website,
|
||||
status TEXT, -- prospect, contacted, negotiating, confirmed, declined, active, completed
|
||||
amount NUMERIC, notes TEXT
|
||||
);
|
||||
CREATE TABLE sponsor_deliverables (id, sponsor_id, description, completed);
|
||||
CREATE TABLE sponsor_allocations (id, event_id, sponsor_id, department_id, amount, notes);
|
||||
```
|
||||
|
||||
### Status Pipeline
|
||||
`prospect` → `contacted` → `negotiating` → `confirmed` → `declined` → `active` → `completed`
|
||||
|
||||
### Key Features
|
||||
- **Tier management**: Gold/Silver/Bronze with amounts and colors
|
||||
- **Status pipeline**: Visual status badges with color coding
|
||||
- **Deliverables checklist**: Per-sponsor deliverable tracking
|
||||
- **Contact info**: Name, email, phone, website per sponsor
|
||||
- **Filter**: By status and tier
|
||||
- **Fund allocation**: Allocate sponsor funds to specific departments
|
||||
- **Currency formatting**: Uses org's currency setting
|
||||
|
||||
### Components
|
||||
- `src/lib/components/modules/SponsorsWidget.svelte` — department-level widget
|
||||
- `src/routes/[orgSlug]/events/[eventSlug]/sponsors/+page.svelte` — event-level overview
|
||||
|
||||
### API (`src/lib/api/sponsors.ts`)
|
||||
- `fetchEventSponsors`, `createSponsor`, `updateSponsor`, `deleteSponsor`
|
||||
- `fetchEventSponsorTiers`, `createSponsorTier`, `deleteSponsorTier`
|
||||
- `fetchEventDeliverables`, `createDeliverable`, `toggleDeliverable`, `deleteDeliverable`
|
||||
|
||||
### Room for Improvement
|
||||
- **Email integration**: No automated sponsor outreach.
|
||||
- **Contract management**: No contract status tracking.
|
||||
- **Sponsor portal**: No external-facing sponsor dashboard.
|
||||
|
||||
---
|
||||
|
||||
## 19. Activity Tracking
|
||||
|
||||
### What It Is
|
||||
An audit log of all significant actions within an organization.
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE activity_log (
|
||||
id UUID PRIMARY KEY,
|
||||
org_id UUID, user_id UUID,
|
||||
action TEXT, entity_type TEXT, entity_id UUID, entity_name TEXT,
|
||||
metadata JSONB, created_at TIMESTAMPTZ
|
||||
);
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- Tracks: create, update, delete actions on all entity types
|
||||
- Displayed on org overview page as "Recent Activity"
|
||||
- Shows user name, action, entity, and timestamp
|
||||
|
||||
### API (`src/lib/api/activity.ts`)
|
||||
- `logActivity(supabase, params)` — creates activity log entry
|
||||
- `fetchRecentActivity(supabase, orgId, limit)` — fetches recent entries
|
||||
|
||||
### Room for Improvement
|
||||
- **Granular tracking**: Not all actions are logged (e.g., budget item edits).
|
||||
- **Notifications**: No push/email notifications based on activity.
|
||||
- **Filtering**: No filtering by entity type or user on the overview page.
|
||||
|
||||
---
|
||||
|
||||
## 20. Tags System
|
||||
|
||||
### What It Is
|
||||
Organization-wide tags that can be applied to various entities for categorization.
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE org_tags (id, org_id, name, color);
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- Create/edit/delete tags with colors
|
||||
- Managed in Settings → Tags tab
|
||||
|
||||
### Room for Improvement
|
||||
- **Tag application**: Tags exist but aren't yet applied to events, documents, or other entities.
|
||||
- **Tag filtering**: No cross-entity filtering by tag.
|
||||
|
||||
---
|
||||
|
||||
## 21. Roles & Permissions
|
||||
|
||||
### What It Is
|
||||
A flexible role-based access control system with custom roles and granular permissions.
|
||||
|
||||
### Database
|
||||
```sql
|
||||
CREATE TABLE org_roles (
|
||||
id UUID PRIMARY KEY,
|
||||
org_id UUID, name TEXT, color TEXT,
|
||||
permissions TEXT[],
|
||||
is_default BOOLEAN, is_system BOOLEAN, position INTEGER
|
||||
);
|
||||
|
||||
-- org_members has role (text) and role_id (FK to org_roles)
|
||||
```
|
||||
|
||||
### Built-in Roles
|
||||
- **Owner**: Full access, can delete org
|
||||
- **Admin**: Full access except org deletion
|
||||
- **Editor**: Can create/edit content
|
||||
- **Viewer**: Read-only access
|
||||
|
||||
### Custom Roles
|
||||
Admins can create custom roles with specific permissions:
|
||||
- `documents.view`, `documents.edit`, `documents.delete`
|
||||
- `calendar.view`, `calendar.edit`
|
||||
- `settings.view`, `settings.edit`
|
||||
- `members.view`, `members.invite`, `members.remove`
|
||||
|
||||
### Implementation
|
||||
- `src/lib/utils/permissions.ts` — `hasPermission(userRole, userPermissions, permission)` utility
|
||||
- Layout uses `canAccess()` to conditionally show nav items
|
||||
|
||||
### Room for Improvement
|
||||
- **Event-level roles**: Permissions are org-wide; no per-event role assignment.
|
||||
- **Department-level permissions**: No per-department access control.
|
||||
|
||||
---
|
||||
|
||||
## 22. Google Calendar Integration
|
||||
|
||||
### What It Is
|
||||
Two-way sync between Root's calendar and Google Calendar.
|
||||
|
||||
### Implementation
|
||||
- OAuth2 flow for connecting Google account
|
||||
- Org-level Google Calendar connection (stored in org settings)
|
||||
- Syncs events bidirectionally
|
||||
- Subscribe URL for external calendar apps
|
||||
|
||||
### API (`src/lib/api/google-calendar.ts`)
|
||||
- `fetchGoogleCalendarEvents` — fetches events from connected Google Calendar
|
||||
- `getCalendarSubscribeUrl` — generates iCal subscribe URL
|
||||
- Push notifications for real-time sync
|
||||
|
||||
### Room for Improvement
|
||||
- **Per-user sync**: Currently org-level only.
|
||||
- **Outlook/iCal**: Only Google Calendar supported.
|
||||
- **Conflict resolution**: No handling of concurrent edits.
|
||||
|
||||
---
|
||||
|
||||
## 23. Internationalization (i18n)
|
||||
|
||||
### What It Is
|
||||
Full UI translation support using Paraglide v2.
|
||||
|
||||
### Supported Languages
|
||||
- **English** (`en`) — base locale
|
||||
- **Estonian** (`et`)
|
||||
|
||||
### Implementation
|
||||
- ~248 message keys covering all UI strings
|
||||
- Import pattern: `import * as m from "$lib/paraglide/messages"`
|
||||
- Parameterized messages: `{m.key({ param: value })}`
|
||||
- Config: `project.inlang/settings.json`
|
||||
- Vite plugin: `paraglideVitePlugin`
|
||||
|
||||
### Key Files
|
||||
- `messages/en.json` — English translations
|
||||
- `messages/et.json` — Estonian translations
|
||||
- `src/lib/paraglide/` — generated output
|
||||
|
||||
### Room for Improvement
|
||||
- **Language picker**: No in-app language switcher (uses browser locale).
|
||||
- **More languages**: Only 2 languages supported.
|
||||
- **RTL support**: No right-to-left language support.
|
||||
|
||||
---
|
||||
|
||||
## 24. Platform Admin
|
||||
|
||||
### What It Is
|
||||
A super-admin panel for managing all organizations on the platform.
|
||||
|
||||
### Route: `/admin/`
|
||||
|
||||
### Database
|
||||
```sql
|
||||
-- Migration 030: platform_admin
|
||||
-- Migration 031: platform_admin_rls
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- View all organizations
|
||||
- Platform-level statistics
|
||||
|
||||
### Room for Improvement
|
||||
- **User management**: No platform-level user management.
|
||||
- **Billing**: No subscription/billing management.
|
||||
- **Analytics**: No usage analytics dashboard.
|
||||
|
||||
---
|
||||
|
||||
## 25. Testing Strategy
|
||||
|
||||
### Unit Tests (Vitest)
|
||||
- **Location**: `src/lib/api/*.test.ts`
|
||||
- **Coverage**: All API modules have unit tests
|
||||
- **Count**: 112+ tests across 9 files
|
||||
- **Run**: `npm test`
|
||||
|
||||
### E2E Tests (Playwright)
|
||||
- **Location**: `tests/e2e/`
|
||||
- **Key files**: `features.spec.ts`, `events.spec.ts`
|
||||
- **Setup**: Auth setup project with `storageState` persistence
|
||||
- **Important**: Uses `waitUntil: 'networkidle'` for Svelte 5 hydration timing
|
||||
|
||||
### Key Testing Notes
|
||||
- Svelte 5 uses event delegation — handlers only work after hydration
|
||||
- Serial test suites can cascade failures if early tests fail
|
||||
- Database triggers (auto-create dashboard) can be flaky in test environments
|
||||
|
||||
---
|
||||
|
||||
## 26. Database Migrations
|
||||
|
||||
### Migration History
|
||||
| # | Name | Description |
|
||||
|---|------|-------------|
|
||||
| 001 | initial_schema | Organizations, org_members, profiles, documents |
|
||||
| 002 | card_checklists | Kanban card checklists |
|
||||
| 003 | google_calendar | Google Calendar integration |
|
||||
| 004 | org_google_calendar | Org-level Google Calendar |
|
||||
| 005 | roles_and_invites | Custom roles, invites |
|
||||
| 006 | simplify_google_calendar | Simplified Google Calendar schema |
|
||||
| 007 | org_theme | Theme color, icon_url |
|
||||
| 008 | kanban_enhancements | Kanban improvements |
|
||||
| 009 | activity_tracking | Activity log table |
|
||||
| 010 | tags_system | Org tags |
|
||||
| 011 | teams_roles | Team roles |
|
||||
| 012 | task_comments | Kanban card comments |
|
||||
| 013 | kanban_labels | Kanban labels |
|
||||
| 014 | document_enhancements | Document improvements |
|
||||
| 015 | migrate_kanban_to_documents | Kanban as document type |
|
||||
| 016 | document_locks | Document locking |
|
||||
| 017 | avatars_storage | Avatar storage bucket |
|
||||
| 018 | user_avatars_storage | User avatar storage |
|
||||
| 019 | fix_org_members_profiles_fk | FK fix |
|
||||
| 020 | matrix_credentials | Matrix chat credentials |
|
||||
| 021 | org_matrix_space | Org Matrix space |
|
||||
| 022 | events | Events table |
|
||||
| 023 | event_team_management | Departments, event members |
|
||||
| 024 | profile_extended_fields | Extended profile fields |
|
||||
| 025 | event_tasks | Event tasks |
|
||||
| 026 | department_dashboards | Dashboard, panels, checklists, notes |
|
||||
| 027 | remove_default_seeds | Remove seed data |
|
||||
| 028 | schedule_and_contacts | Schedule stages/blocks, contacts |
|
||||
| 029 | budget_and_sponsors | Budget, sponsors, deliverables |
|
||||
| 030 | platform_admin | Platform admin |
|
||||
| 031 | platform_admin_rls | Platform admin RLS |
|
||||
| 032 | document_event_dept_fks | Document event/dept FKs |
|
||||
| 033 | files_storage | File storage |
|
||||
| 034 | layout_triple | Triple layout preset |
|
||||
| 035 | budget_receipts | Budget receipt linking |
|
||||
| 036 | finance_enhancements | Finance improvements |
|
||||
| 037 | org_settings | Organization settings expansion |
|
||||
|
||||
### DB Workflow
|
||||
```bash
|
||||
npm run db:push # Push pending migrations
|
||||
npm run db:types # Regenerate TypeScript types
|
||||
npm run db:migrate # Push + regenerate in one step
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary of Improvement Priorities
|
||||
|
||||
### High Priority
|
||||
1. **Shared `formatDate()` utility** consuming org's `date_format` and `timezone` settings
|
||||
2. **Wire `week_start_day`** into Calendar grid generation
|
||||
3. **Wire `default_dept_modules`** into the department auto-create trigger
|
||||
4. **Feature toggles** should also hide modules within department dashboards, not just sidebar nav
|
||||
|
||||
### Medium Priority
|
||||
5. **Event templates** — clone event structures
|
||||
6. **Guest list / registration** — attendee management
|
||||
7. **Document search** — full-text search across documents
|
||||
8. **Export** — PDF/Excel export for budgets and sponsor reports
|
||||
|
||||
### Low Priority
|
||||
9. **Real-time collaboration** on documents
|
||||
10. **SSO / 2FA** authentication
|
||||
11. **Push notifications** for activity
|
||||
12. **Public event pages** for attendees
|
||||
Reference in New Issue
Block a user