feat: map shapes, image persistence, grab tool, layer rename/delete, i18n, page metadata

This commit is contained in:
AlacrisDevs
2026-02-08 23:11:09 +02:00
parent 75a2aefadb
commit f2384bceb8
125 changed files with 22605 additions and 3902 deletions

997
docs/TECHNICAL_DESIGN.md Normal file
View 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