Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.38.4'
channel: 'stable'

- name: Install dependencies
run: flutter pub get

- name: Verify formatting
run: dart format --output=none --set-exit-if-changed .

- name: Analyze code
run: flutter analyze

- name: Run tests
run: flutter test
81 changes: 81 additions & 0 deletions ADR/001-hybrid-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# ADR 001: Use Hybrid (Local-First + Cloud Sync) Architecture

**Status:** Accepted

**Date:** 2026-02-11

**Context:**

When building Second Brain, we needed to choose between three architectural approaches:

1. **Pure Local**: All data stored locally with no cloud integration
2. **Pure Cloud**: All data stored in the cloud, requiring constant internet connection
3. **Hybrid (Local-First + Cloud Sync)**: Local storage with optional cloud synchronization

Key considerations:
- User experience and app responsiveness
- Offline capability requirements
- Cross-device synchronization needs
- Privacy and data ownership concerns
- Demonstration of technical skills
- Scalability and future features (RAG, embeddings)

**Decision:**

We will implement a **Hybrid (Local-First + Cloud Sync)** architecture using:
- **Isar DB** for local storage (fast, NoSQL, embedded database)
- **Supabase** with **pgvector** for optional cloud sync and vector embeddings

**Rationale:**

1. **Best User Experience**
- Instant app response with local data access
- No loading spinners for basic operations
- Works perfectly offline

2. **Optional Cloud Sync**
- Users can enable sync for cross-device access
- Privacy-focused: users control their data
- Graceful degradation when offline

3. **Technical Excellence**
- Demonstrates proficiency with both local and cloud databases
- Showcases sync conflict resolution skills
- Enables advanced features (pgvector for semantic search)

4. **Future-Proof**
- Scalable for RAG features (embeddings need vector DB)
- Supports collaborative features in future
- Easy to add cloud-only features later

**Consequences:**

### Positive
- ✅ Superior user experience with instant local operations
- ✅ Works offline by default
- ✅ Demonstrates advanced technical skills
- ✅ Enables semantic search with vector embeddings
- ✅ Users maintain data ownership

### Negative
- ❌ Increased complexity in implementation
- ❌ Need to handle sync conflicts
- ❌ More testing scenarios (online/offline states)
- ❌ Requires maintaining two database schemas

### Mitigation
- Use proven sync patterns (CRDTs or timestamp-based)
- Implement comprehensive error handling
- Create thorough test coverage for sync scenarios
- Document sync behavior clearly for users

**Alternatives Considered:**

1. **Pure Local** — Simpler but no cross-device sync
2. **Pure Cloud** — Poor offline experience, slower operations
3. **Firebase** — Considered but Supabase chosen for pgvector support

**Related Decisions:**
- Technology choice: Isar DB for local storage
- Technology choice: Supabase + pgvector for cloud
- Will require: Sync strategy ADR in future (Phase 4)
157 changes: 155 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,155 @@
# second_brain
🧠 RAG-Powered Note Taking App — Chat with your notes using AI
# 🧠 Second Brain

**RAG-Powered Note Taking App — Chat with your notes using AI**

[![Flutter](https://img.shields.io/badge/Flutter-3.38.4-02569B?logo=flutter)](https://flutter.dev)
[![Dart](https://img.shields.io/badge/Dart-3.10.3-0175C2?logo=dart)](https://dart.dev)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![CI](https://github.com/Muhammad-Bilal-03/second_brain/actions/workflows/ci.yml/badge.svg)](https://github.com/Muhammad-Bilal-03/second_brain/actions/workflows/ci.yml)

## 📖 Overview

Second Brain is a local-first, AI-powered note-taking application that lets you "chat" with your notes using Retrieval Augmented Generation (RAG). Built with Flutter for cross-platform support, it combines the power of local storage with optional cloud sync for a seamless note-taking experience.

## ✨ Features (Planned)

- 📝 **Notes CRUD** — Create, read, update, and delete notes with a clean interface
- 🔍 **Semantic Search** — Find notes using natural language queries powered by embeddings
- 💬 **RAG Chat** — Have conversations with your notes using AI (Google Gemini)
- 🎤 **Voice-to-Note** — Convert speech to text for quick note capture
- ☁️ **Cloud Sync** — Optional synchronization with Supabase (pgvector for embeddings)
- 🌓 **Dark Mode** — Beautiful Material 3 theme with light and dark modes

## 🛠️ Tech Stack

| Category | Technology |
|----------|-----------|
| **Framework** | Flutter 3.38.4 |
| **Language** | Dart 3.10.3 |
| **State Management** | Riverpod 2.6+ |
| **Local Database** | Isar DB 4.0 |
| **AI Framework** | LangChain.dart |
| **LLM** | Google Gemini API |
| **Cloud Backend** | Supabase (pgvector) |

## 🏗️ Architecture

Second Brain follows **Clean Architecture** principles combined with **MVVM** pattern in a feature-based folder structure:

```
lib/
├── app.dart # App root widget
├── main.dart # Entry point
├── core/ # Core utilities
│ ├── constants/ # App constants
│ ├── errors/ # Error handling
│ ├── theme/ # App theme
│ └── utils/ # Extensions & helpers
├── features/ # Feature modules
│ ├── notes/ # Notes feature
│ │ ├── data/ # Data sources & models
│ │ ├── domain/ # Entities & use cases
│ │ └── presentation/ # UI & state
│ ├── chat/ # AI chat feature
│ ├── search/ # Semantic search
│ └── voice/ # Voice input
└── shared/ # Shared widgets & providers
```

### Key Architecture Decisions

- **Local-First**: All data stored locally in Isar DB for instant access
- **Optional Cloud Sync**: Supabase integration for cross-device synchronization
- **Clean Separation**: Domain logic isolated from UI and data layers
- **Testable**: Architecture enables comprehensive unit and integration testing

## 🚀 Getting Started

### Prerequisites

- Flutter SDK 3.38.4 or higher
- Dart SDK 3.10.3 or higher
- Android Studio / VS Code with Flutter extensions
- Git

### Installation

1. **Clone the repository**
```bash
git clone https://github.com/Muhammad-Bilal-03/second_brain.git
cd second_brain
```

2. **Install dependencies**
```bash
flutter pub get
```

3. **Run the app**
```bash
flutter run
```

### Running Tests

```bash
flutter test
```

### Code Generation

For Riverpod and Isar code generation:

```bash
dart run build_runner build --delete-conflicting-outputs
```

## 🗺️ Roadmap

### Phase 1: Foundation (Notes CRUD) ⬅️ **Current**
- [x] Project setup with clean architecture
- [x] Core dependencies and folder structure
- [x] CI/CD with GitHub Actions
- [ ] Basic notes CRUD with Isar DB
- [ ] Material 3 UI with dark mode

### Phase 2: Intelligence Layer (Embeddings + Vector Search)
- [ ] Text embedding generation
- [ ] Vector similarity search
- [ ] Semantic search UI

### Phase 3: RAG Chat (LangChain.dart + Gemini)
- [ ] LangChain.dart integration
- [ ] Google Gemini API setup
- [ ] RAG pipeline implementation
- [ ] Chat UI with conversation history

### Phase 4: Cloud Sync (Supabase + pgvector)
- [ ] Supabase backend setup
- [ ] pgvector for cloud embeddings
- [ ] Sync engine implementation
- [ ] Conflict resolution

### Phase 5: Voice-to-Note
- [ ] Speech-to-text integration
- [ ] Voice recording UI
- [ ] Real-time transcription

### Phase 6: Polish & Ship
- [ ] Performance optimization
- [ ] Comprehensive testing
- [ ] User documentation
- [ ] App store deployment

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 👨‍💻 Author

**Muhammad Bilal**
- GitHub: [@Muhammad-Bilal-03](https://github.com/Muhammad-Bilal-03)

---

*Built with ❤️ using Flutter*
63 changes: 63 additions & 0 deletions lib/app.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:second_brain/core/constants/app_constants.dart';
import 'package:second_brain/core/theme/app_theme.dart';

class App extends ConsumerWidget {
const App({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
return MaterialApp(
title: AppConstants.appName,
debugShowCheckedModeBanner: false,
theme: AppTheme.lightTheme,
darkTheme: AppTheme.darkTheme,
themeMode: ThemeMode.system,
home: const PlaceholderHome(),
);
}
}

/// Placeholder home screen
class PlaceholderHome extends StatelessWidget {
const PlaceholderHome({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('🧠 Second Brain'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.psychology,
size: 100,
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 24),
Text(
'Welcome to Second Brain',
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 8),
Text(
'Your AI-powered note-taking companion',
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
),
),
const SizedBox(height: 32),
const Text(
'Coming soon...',
style: TextStyle(fontStyle: FontStyle.italic),
),
],
),
),
);
}
}
14 changes: 14 additions & 0 deletions lib/core/constants/app_constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class AppConstants {
// App Information
static const String appName = 'Second Brain';
static const String appVersion = '0.1.0';

// Database
static const String dbName = 'second_brain_db';

// API
static const int apiTimeout = 30;

// Private constructor to prevent instantiation
AppConstants._();
}
24 changes: 24 additions & 0 deletions lib/core/errors/failures.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/// Base class for all failures in the application
abstract class Failure {
final String message;

const Failure(this.message);

@override
String toString() => message;
}

/// Failure when server communication fails
class ServerFailure extends Failure {
const ServerFailure([String message = 'Server error occurred']) : super(message);
}

/// Failure when cache operations fail
class CacheFailure extends Failure {
const CacheFailure([String message = 'Cache error occurred']) : super(message);
}

/// General failure for unexpected errors
class GeneralFailure extends Failure {
const GeneralFailure([String message = 'An unexpected error occurred']) : super(message);
}
Loading
Loading