A production-grade offline-first mobile application built with Flutter, featuring real-time synchronization across devices, hierarchical knowledge organization, and a Slack-inspired responsive UI.
Built with Clean Architecture, PowerSync, Supabase, Drift, and BLoC (Cubit) state management.
- Local-first data storage β All operations work instantly without internet
- Automatic synchronization β Changes sync to Supabase when online
- Zero data loss β Local queue ensures no operation is ever lost
- Conflict resolution β PowerSync handles concurrent edits gracefully
- Seamless offline experience β Full CRUD operations work offline
- Workspaces β Top-level containers for different projects/contexts
- Sections β Organize content within workspaces (like Slack channels)
- Memory Boxes β Group related notes together
- Notes β Rich text notes with title and content
- Flexible navigation β Move items between sections/workspaces
- Desktop/Tablet β Persistent sidebar with workspaces and sections
- Mobile β Collapsible drawer navigation
- Adaptive layout β Automatically switches based on screen size
- Light/Dark Theme β System-aware with manual override
- Real-time updates β UI reflects changes instantly via Streams
- Supabase Authentication β Secure email/password login
- Row Level Security (RLS) β Data isolation between users
- Workspace sharing β Invite members to collaborate
- Role-based access β Owner/Member permissions
- JWT-based authentication with Supabase
- Row Level Security (RLS) policies on all tables
- Environment variables for sensitive configuration
- Secure local storage for credentials
- Real-time sync status β Visual indicators for sync state
- Pull-to-refresh β Manual refresh on all lists
- Empty states β Beautiful placeholders with CTAs
- Loading indicators β Smooth UX during operations
- Error handling β User-friendly error messages
- Confirmation dialogs β Prevent accidental deletions
Clean Architecture + Feature-Based Structure + Offline-First
lib/
βββ app/
β βββ di/ # Dependency Injection (GetIt)
β βββ router/ # GoRouter configuration
β βββ theme/ # AppTheme + AppColors (Light/Dark)
β
βββ core/
β βββ constants/ # Env keys, DB constants
β βββ database/ # Drift database + DAOs + Tables
β β βββ daos/ # Data Access Objects
β β βββ tables/ # Table definitions
β β βββ mappers/ # Entity β Row mappers
β βββ services/ # Supabase service
β βββ sync/ # PowerSync service + connector
β βββ utils/ # ID generator, validators
β
βββ features/
β βββ auth/ # Authentication (Login/Signup)
β β βββ data/ # Remote data source + repository
β β βββ domain/ # Entities + Use cases
β β βββ presentation/ # Cubits + Pages
β β
β βββ workspaces/ # Workspace management
β β βββ data/
β β βββ domain/
β β βββ presentation/
β β
β βββ sections/ # Section management
β βββ memory_boxes/ # Memory Box management
β βββ notes/ # Note CRUD + Editor
β
βββ shared/
β βββ dialogs/ # Reusable dialogs
β βββ widgets/ # Shared UI components
β βββ app_layout.dart # Responsive layout (Sidebar/Drawer)
β βββ app_sidebar.dart # Slack-style sidebar
β
βββ main.dart # App entry + initialization
| Technology | Usage |
|---|---|
| Flutter | Cross-platform UI framework |
| Dart | Programming language |
| PowerSync | Offline-first sync engine |
| Supabase | Backend (Auth + Database + RLS) |
| Drift | Type-safe SQLite ORM |
| Bloc / Cubit | State management |
| GoRouter | Declarative navigation |
| GetIt | Dependency injection |
| flutter_dotenv | Environment variables |
| Equatable | Value equality |
| UUID | Unique ID generation |
| Path Provider | File system access |
- Flutter SDK (3.11.5+)
- Supabase account
- PowerSync account
- Android Studio / VS Code
# Clone the repository
git clone https://github.com/Mo7medRef3t/memory-chat.git
# Navigate to project
cd memory-chat
# Install dependencies
flutter pub get
# Generate Drift files
dart run build_runner build --delete-conflicting-outputs
# Create .env file
cp .env.example .env
# Add your Supabase and PowerSync credentials
# Run the app
flutter runCreate a .env file in the root directory:
SUPABASE_URL=your_supabase_url
SUPABASE_ANON_KEY=your_supabase_anon_key
POWERSYNC_URL=your_powersync_url-
Create a Supabase project at supabase.com
-
Create tables in SQL Editor:
-- Profiles table
CREATE TABLE profiles (
id UUID PRIMARY KEY REFERENCES auth.users(id),
email TEXT,
full_name TEXT,
avatar_url TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Workspaces table
CREATE TABLE workspaces (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
description TEXT,
owner_id UUID REFERENCES profiles(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Workspace members table
CREATE TABLE workspace_members (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id UUID REFERENCES workspaces(id) ON DELETE CASCADE,
user_id UUID REFERENCES profiles(id),
role TEXT DEFAULT 'member',
joined_at TIMESTAMP DEFAULT NOW(),
UNIQUE(workspace_id, user_id)
);
-- Sections table
CREATE TABLE sections (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id UUID REFERENCES workspaces(id) ON DELETE CASCADE,
title TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Memory boxes table
CREATE TABLE memory_boxes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id UUID REFERENCES workspaces(id) ON DELETE CASCADE,
section_id UUID REFERENCES sections(id) ON DELETE SET NULL,
title TEXT NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Notes table
CREATE TABLE notes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
memory_box_id UUID REFERENCES memory_boxes(id) ON DELETE CASCADE,
author_id UUID REFERENCES profiles(id),
title TEXT NOT NULL,
content TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);- Enable Row Level Security (RLS) and create policies:
-- Enable RLS on all tables
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE workspaces ENABLE ROW LEVEL SECURITY;
ALTER TABLE workspace_members ENABLE ROW LEVEL SECURITY;
ALTER TABLE sections ENABLE ROW LEVEL SECURITY;
ALTER TABLE memory_boxes ENABLE ROW LEVEL SECURITY;
ALTER TABLE notes ENABLE ROW LEVEL SECURITY;
-- Example policies for notes
CREATE POLICY "Users can view notes in their workspaces"
ON notes FOR SELECT
USING (
memory_box_id IN (
SELECT mb.id FROM memory_boxes mb
WHERE mb.workspace_id IN (
SELECT workspace_id FROM workspace_members
WHERE user_id = auth.uid()
)
)
);
CREATE POLICY "Users can create notes in their workspaces"
ON notes FOR INSERT
WITH CHECK (
memory_box_id IN (
SELECT mb.id FROM memory_boxes mb
WHERE mb.workspace_id IN (
SELECT workspace_id FROM workspace_members
WHERE user_id = auth.uid()
)
)
);
-- Add similar policies for UPDATE and DELETE-
Create a PowerSync instance at powersync.com
-
Connect to Supabase in PowerSync dashboard
-
Configure Sync Rules:
config:
edition: 3
streams:
user_data:
auto_subscribe: true
queries:
- SELECT * FROM profiles
- SELECT * FROM workspace_members
- SELECT * FROM workspaces
- SELECT * FROM sections
- SELECT * FROM memory_boxes
- SELECT * FROM notes- Deploy sync rules
βββββββββββββββ
β UI Layer β
β (Flutter) β
ββββββββ¬βββββββ
β
βΌ
βββββββββββββββ
β Cubits β
β (BLoC) β
ββββββββ¬βββββββ
β
βΌ
βββββββββββββββ
β Repository β
β Layer β
ββββββββ¬βββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β PowerSync Local Database β
β (SQLite via Drift ORM) β
ββββββββ¬βββββββββββββββββββββββ¬ββββββββ
β β
βΌ βΌ
βββββββββββββββ βββββββββββββββ
β Upload β β Download β
β Queue β β Stream β
ββββββββ¬βββββββ ββββββββ¬βββββββ
β β
βΌ βΌ
βββββββββββββββββββββββββββββββββββββββ
β Supabase Backend β
β (PostgreSQL + Auth + RLS) β
βββββββββββββββββββββββββββββββββββββββ
- Write Operation: User creates/updates/deletes data
- Local Save: Data saved to PowerSync local SQLite instantly
- UI Update: UI reflects change immediately via Streams
- Upload Queue: Change added to upload queue
- Background Sync: PowerSync uploads to Supabase when online
- Download Stream: Changes from other devices sync down
- Conflict Resolution: PowerSync handles conflicts automatically
- Local-first writes β All operations save locally first
- Automatic sync β Background synchronization when online
- Upload queue β Pending operations persist across app restarts
- Conflict resolution β Automatic handling of concurrent edits
- Zero data loss β Guaranteed delivery with retry logic
- PowerSync integration β Bidirectional sync engine
- Supabase Realtime β Instant updates across devices
- Stream-based UI β Reactive updates via Dart Streams
- Checkpoint management β Efficient delta sync
- Drift ORM β Compile-time SQL validation
- Code generation β Type-safe queries and migrations
- DAO pattern β Clean separation of data access logic
- Entity mappers β Clean domain model separation
- Adaptive layout β Sidebar on desktop, drawer on mobile
- Breakpoint-based β 600px threshold for mobile/desktop
- Consistent UX β Same features across all screen sizes
- Slack-inspired β Familiar navigation pattern
- Row Level Security β Database-level data isolation
- JWT authentication β Secure token-based auth
- Environment variables β No hardcoded secrets
- RLS policies β Granular access control
- Feature-based structure β Organized by business domain
- Dependency injection β GetIt for loose coupling
- Repository pattern β Abstract data sources
- Use cases β Business logic separation
- Testable code β Easy to unit test each layer
- Repository layer tests
- Use case tests
- Entity mapper tests
- PowerSync sync tests
- Supabase integration tests
- Offline/online transition tests
- β Create workspace offline β sync when online
- β Edit note on device A β appears on device B
- β Delete section β cascades to memory boxes and notes
- β Move memory box between sections
- β Multi-user collaboration with RLS
ββββββββββββββββ
β profiles β
ββββββββββββββββ€
β id (PK) β
β email β
β full_name β
β avatar_url β
β created_at β
β updated_at β
ββββββββββββββββ
β
β owner_id
βΌ
ββββββββββββββββ ββββββββββββββββββββββ
β workspaces βββββββββ workspace_members β
ββββββββββββββββ€ ββββββββββββββββββββββ€
β id (PK) β β id (PK) β
β name β β workspace_id (FK) β
β description β β user_id (FK) β
β owner_id(FK) β β role β
β created_at β β joined_at β
β updated_at β ββββββββββββββββββββββ
ββββββββββββββββ
β
β workspace_id
βΌ
ββββββββββββββββ
β sections β
ββββββββββββββββ€
β id (PK) β
β workspace_id β
β title β
β created_at β
β updated_at β
ββββββββββββββββ
β
β section_id (nullable)
βΌ
ββββββββββββββββββ
β memory_boxes β
ββββββββββββββββββ€
β id (PK) β
β workspace_id β
β section_id β
β title β
β description β
β created_at β
β updated_at β
ββββββββββββββββββ
β
β memory_box_id
βΌ
ββββββββββββββββ
β notes β
ββββββββββββββββ€
β id (PK) β
β memory_box_idβ
β author_id β
β title β
β content β
β created_at β
β updated_at β
ββββββββββββββββ
# Install dependencies
flutter pub get
# Generate Drift files
dart run build_runner build --delete-conflicting-outputs
# Watch mode for development
dart run build_runner watch --delete-conflicting-outputs
# Run tests
flutter test
# Build APK
flutter build apk --release
# Build iOS
flutter build ios --release
# Clean build
flutter clean
flutter pub get
dart run build_runner build --delete-conflicting-outputsβββββββββββ
β Login β
ββββββ¬βββββ
β
βΌ
ββββββββββββββββ
β Workspaces ββββββββββ
β List β β
ββββββββ¬ββββββββ β
β β
βΌ β
ββββββββββββββββ β
β Workspace β β
β Details β β
β (Sections + β β
β Root Boxes) β β
ββββββββ¬ββββββββ β
β β
ββββββββββββββββββ€
β β
βΌ βΌ
ββββββββββββββββ ββββββββββββββββ
β Section β β Memory Box β
β Details β β Details β
β (Boxes) β β (Notes) β
ββββββββ¬ββββββββ ββββββββ¬ββββββββ
β β
βΌ βΌ
ββββββββββββββββ ββββββββββββββββ
β Memory Box β β Notes β
β Details β β List β
β (Notes) β ββββββββ¬ββββββββ
ββββββββ¬ββββββββ β
β β
ββββββββββ¬βββββββββ
β
βΌ
ββββββββββββββββ
β Note Editor β
β (Create/Edit)β
ββββββββββββββββ
AppLayoutβ Responsive layout (Sidebar/Drawer)AppSidebarβ Slack-style navigation sidebarAppTextFieldβ Styled text inputPrimaryButtonβ Reusable button componentLoadingIndicatorβ Loading spinnerEmptyStateCardβ Empty state placeholder
CreateWorkspaceDialogCreateSectionDialogCreateMemoryBoxDialogDeleteConfirmationDialogEditMemoryBoxDialogMoveMemoryBoxDialog
- Rich text editor for notes (Markdown support)
- File attachments in notes
- Real-time collaboration (multi-user editing)
- Search functionality across all content
- Tags and labels for organization
- Export notes to PDF/Markdown
- Mobile widgets (iOS/Android)
- Push notifications for mentions
- Workspace templates
- Import from Notion/Evernote
This project is open source and available under the MIT License.
Contributions, issues, and feature requests are welcome!
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Mohamed Refaat β @Mo7medRef3t
Project Link: https://github.com/Mo7medRef3t/memory-chat
Built with β€οΈ using Flutter, PowerSync & Supabase
```






