35 KiB
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
- Platform Overview
- Architecture
- Authentication & Authorization
- Organizations
- Organization Settings
- Documents & File Browser
- Kanban Boards
- Calendar
- Chat (Matrix)
- Events
- Event Team & Departments
- Department Dashboard
- Checklists Module
- Notes Module
- Schedule Module
- Contacts Module
- Budget & Finances Module
- Sponsors Module
- Activity Tracking
- Tags System
- Roles & Permissions
- Google Calendar Integration
- Internationalization (i18n)
- Platform Admin
- Testing Strategy
- 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
- Layout server (
[orgSlug]/+layout.server.ts) loads org data, membership, permissions, members, activity, stats, and upcoming events viaselect('*')on theorganizationstable. - Child pages call
parent()to inherit org context, then load page-specific data. - Supabase client is set via
setContext('supabase')in the root layout and retrieved viagetContextin child components. - 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
storageStatefor reuse.
Authorization Layers
- Org membership: Users must be members of an org to access it (checked in layout server).
- Role-based: Each member has a role (
owner,admin,editor,viewer). - Permission-based: Custom roles with granular permissions (e.g.,
documents.view,calendar.view,settings.view). - 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
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 ownerupdateOrganization(supabase, id, updates)— updates name, slug, avatardeleteOrganization(supabase, id)— deletes org and cascadesfetchOrgMembers(supabase, orgId)— lists members with profilesinviteMember(supabase, orgId, email, role)— sends inviteupdateMemberRole(supabase, memberId, role)— changes roleremoveMember(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-DElocale 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— sharedformatCurrency(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
initialViewprop toCalendar.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
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,deleteDocumentensureEventsFolder,createEventFolder,createDepartmentFolderfindDepartmentFolder,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
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_viewsetting
API (src/lib/api/calendar.ts)
getMonthDays(year, month)— generates date grid for month viewisSameDay(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_idon organizations table) - Users get Matrix credentials stored in
matrix_credentialstable - Chat UI at
/[orgSlug]/chat/ - Unread count badge in sidebar nav
- Feature toggle: Can be disabled per org via
feature_chatsetting
Database
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
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,deleteEventfetchEventDepartments,createDepartment,updateDepartment,deleteDepartmentupdateDepartmentPlannedBudget
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
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
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_modulesorg 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
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
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
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
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
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 widgetsrc/routes/[orgSlug]/events/[eventSlug]/finances/+page.svelte— cross-department overview
API (src/lib/api/budget.ts)
fetchEventBudgetCategories,createBudgetCategory,deleteBudgetCategoryfetchEventBudgetItems,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
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 widgetsrc/routes/[orgSlug]/events/[eventSlug]/sponsors/+page.svelte— event-level overview
API (src/lib/api/sponsors.ts)
fetchEventSponsors,createSponsor,updateSponsor,deleteSponsorfetchEventSponsorTiers,createSponsorTier,deleteSponsorTierfetchEventDeliverables,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
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 entryfetchRecentActivity(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
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
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.deletecalendar.view,calendar.editsettings.view,settings.editmembers.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 CalendargetCalendarSubscribeUrl— 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 translationsmessages/et.json— Estonian translationssrc/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
-- 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
storageStatepersistence - 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
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
- Shared
formatDate()utility consuming org'sdate_formatandtimezonesettings - Wire
week_start_dayinto Calendar grid generation - Wire
default_dept_modulesinto the department auto-create trigger - Feature toggles should also hide modules within department dashboards, not just sidebar nav
Medium Priority
- Event templates — clone event structures
- Guest list / registration — attendee management
- Document search — full-text search across documents
- Export — PDF/Excel export for budgets and sponsor reports
Low Priority
- Real-time collaboration on documents
- SSO / 2FA authentication
- Push notifications for activity
- Public event pages for attendees