# Project export: NexSpend – AI Financial Copilot

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: An AI-powered financial copilot that turns expense tracking into actionable financial insights through voice input, analytics, and personalized AI recommendations. 🚀💸
- Devpost: https://devpost.com/software/nexspend-ai-financial-copilot
- GitHub: https://github.com/nehalsinghpunjabi/NexSpend
- Video: https://www.youtube.com/embed/1XfF2eOBtmw?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — Nehal Singh Punjabi (8 commits)

## Devpost submission (written by the team)

No Devpost description available.

## README (from the GitHub repository)

# NexSpend

> An AI-powered personal finance companion for capturing expenses naturally and understanding where your money goes.

NexSpend helps users track expenses, understand spending habits, and make smarter financial decisions through AI-powered insights, voice expense tracking, and natural language expense entry.

**Built with:** Flutter · Riverpod · Supabase · PostgreSQL · FastAPI · Groq

## Portfolio highlights

- A full-stack mobile product, not just a user interface: Flutter client, FastAPI service and Supabase-backed data layer.
- Three ways to log an expense: manual entry, voice input and plain-language input.
- An AI copilot and visual analytics turn recorded transactions into practical spending insights.
- Privacy controls, local preferences and Android APK support are included in the v1 scope.

## Development note

GPT-5.6 (Codex) supported development, including Flutter implementation, Supabase integration, state management, debugging and UX iteration. The developer made the final product, integration, testing and architectural decisions.

## Features

### Smart Expense Tracking
- Manual expense entry
- Voice expense entry
- Natural language expense entry
- Automatic categorization

Examples:

- Spent ₹450 at Starbucks
- Uber ride ₹250
- Bought groceries for ₹1800
- Spent ₹1600 at H&M

### AI Financial Copilot

Ask questions like:

- Where did I spend the most money this month?
- How much did I spend on food?
- Can I afford AirPods next month?
- Compare this month with last month.

### Insights & Analytics

- Monthly spending trends
- Category breakdowns
- Top merchants
- Spending health indicators
- Budget tracking

### Privacy & Security

- Privacy Mode
- Local settings persistence
- Theme customization
- Currency preferences

## Tech Stack

### Frontend
- Flutter
- Riverpod
- Material 3

### Backend
- Supabase
- PostgreSQL
- FastAPI

### AI
- Groq API

## Installation

### Frontend

```bash
cd frontend
flutter pub get
flutter run --dart-define-from-file=../.env
```

### Backend

```bash
cd backend
pip install -r requirements.txt
uvicorn app.main:app --reload
```

## Environment Variables

Create a root `.env` file containing:

```env
SUPABASE_URL=
SUPABASE_ANON_KEY=
GROQ_API_KEY=
```

## Project Status

Release v1 ✅

Core features complete:
- Authentication
- Expense Tracking
- Voice Entry
- Natural Language Parsing
- AI Copilot
- Insights Dashboard
- Privacy Mode
- Android APK


## Detected evidence (automated analysis)

Indexed codebase: 98 recognized source files, 250 KB.
- C (language) — detected in the code
- C++ (language) — detected in the code
- Dart (language) — detected in the code
- FastAPI (technology) — detected in the code
- HTML (language) — detected in the code
- Kotlin (language) — detected in the code
- Python (language) — detected in the code
- SQL (language) — detected in the code
- Swift (language) — detected in the code
- PostgreSQL (technology) — claimed on Devpost, not found in the code
- Supabase (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (120 of 155)

```
.env.example
.gitignore
backend/app/__init__.py
backend/app/main.py
backend/requirements.txt
frontend/.gitignore
frontend/.metadata
frontend/.vscode/launch.json
frontend/analysis_options.yaml
frontend/android/.gitignore
frontend/android/app/build.gradle.kts
frontend/android/app/src/debug/AndroidManifest.xml
frontend/android/app/src/main/AndroidManifest.xml
frontend/android/app/src/main/kotlin/com/nexspend/nexspend/MainActivity.kt
frontend/android/app/src/main/res/drawable-v21/launch_background.xml
frontend/android/app/src/main/res/drawable/launch_background.xml
frontend/android/app/src/main/res/values-night/styles.xml
frontend/android/app/src/main/res/values/styles.xml
frontend/android/app/src/profile/AndroidManifest.xml
frontend/android/build.gradle.kts
frontend/android/gradle.properties
frontend/android/gradle/wrapper/gradle-wrapper.properties
frontend/android/settings.gradle.kts
frontend/ios/.gitignore
frontend/ios/Flutter/AppFrameworkInfo.plist
frontend/ios/Flutter/Debug.xcconfig
frontend/ios/Flutter/Release.xcconfig
frontend/ios/Runner.xcodeproj/project.pbxproj
frontend/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
frontend/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
frontend/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
frontend/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
frontend/ios/Runner.xcworkspace/contents.xcworkspacedata
frontend/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
frontend/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
frontend/ios/Runner/AppDelegate.swift
frontend/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
frontend/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
frontend/ios/Runner/Base.lproj/LaunchScreen.storyboard
frontend/ios/Runner/Base.lproj/Main.storyboard
frontend/ios/Runner/Info.plist
frontend/ios/Runner/Runner-Bridging-Header.h
frontend/ios/Runner/SceneDelegate.swift
frontend/ios/RunnerTests/RunnerTests.swift
frontend/lib/app.dart
frontend/lib/core/config/ai_config.dart
frontend/lib/core/config/supabase_config.dart
frontend/lib/core/formatters/currency_formatter.dart
frontend/lib/core/presentation/content_state.dart
frontend/lib/core/presentation/private_amount.dart
frontend/lib/core/presentation/splash_overlay.dart
frontend/lib/core/router/app_router.dart
frontend/lib/core/theme/app_theme.dart
frontend/lib/core/theme/design_tokens.dart
frontend/lib/features/auth/data/repositories/supabase_auth_repository.dart
frontend/lib/features/auth/domain/repositories/auth_repository.dart
frontend/lib/features/auth/presentation/auth_page.dart
frontend/lib/features/auth/presentation/auth_providers.dart
frontend/lib/features/copilot/data/providers/groq_provider.dart
frontend/lib/features/copilot/data/providers/openai_provider.dart
frontend/lib/features/copilot/data/repositories/provider_ai_repository.dart
frontend/lib/features/copilot/domain/analytics/financial_analytics.dart
frontend/lib/features/copilot/domain/models/ai_models.dart
frontend/lib/features/copilot/domain/models/copilot_session_memory.dart
frontend/lib/features/copilot/domain/providers/ai_provider.dart
frontend/lib/features/copilot/domain/repositories/ai_repository.dart
frontend/lib/features/copilot/domain/services/ai_service.dart
frontend/lib/features/copilot/presentation/copilot_page.dart
frontend/lib/features/copilot/presentation/copilot_providers.dart
frontend/lib/features/dashboard/presentation/dashboard_page.dart
frontend/lib/features/dashboard/presentation/dashboard_providers.dart
frontend/lib/features/dashboard/presentation/insights_page.dart
frontend/lib/features/expenses/data/repositories/supabase_expense_repository.dart
frontend/lib/features/expenses/domain/entities/expense.dart
frontend/lib/features/expenses/domain/repositories/expense_repository.dart
frontend/lib/features/expenses/domain/services/natural_language_expense_parser.dart
frontend/lib/features/expenses/presentation/add_expense_sheet.dart
frontend/lib/features/expenses/presentation/expense_card.dart
frontend/lib/features/expenses/presentation/expense_empty_state.dart
frontend/lib/features/expenses/presentation/expense_filter_sheet.dart
frontend/lib/features/expenses/presentation/expense_providers.dart
frontend/lib/features/expenses/presentation/expense_query.dart
frontend/lib/features/expenses/presentation/expense_search_field.dart
frontend/lib/features/expenses/presentation/expenses_page.dart
frontend/lib/features/home/presentation/home_page.dart
frontend/lib/features/onboarding/presentation/welcome_page.dart
frontend/lib/features/settings/presentation/settings_detail_pages.dart
frontend/lib/features/settings/presentation/settings_page.dart
frontend/lib/features/settings/presentation/settings_providers.dart
frontend/lib/main.dart
frontend/lib/shared/widgets/nexspend_mark.dart
frontend/linux/.gitignore
frontend/linux/CMakeLists.txt
frontend/linux/flutter/CMakeLists.txt
frontend/linux/flutter/generated_plugin_registrant.cc
frontend/linux/flutter/generated_plugin_registrant.h
frontend/linux/flutter/generated_plugins.cmake
frontend/linux/runner/CMakeLists.txt
frontend/linux/runner/main.cc
frontend/linux/runner/my_application.cc
frontend/linux/runner/my_application.h
frontend/macos/.gitignore
frontend/macos/Flutter/Flutter-Debug.xcconfig
frontend/macos/Flutter/Flutter-Release.xcconfig
frontend/macos/Flutter/GeneratedPluginRegistrant.swift
frontend/macos/Runner.xcodeproj/project.pbxproj
frontend/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
frontend/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
frontend/macos/Runner.xcworkspace/contents.xcworkspacedata
frontend/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
frontend/macos/Runner/AppDelegate.swift
frontend/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
frontend/macos/Runner/Base.lproj/MainMenu.xib
frontend/macos/Runner/Configs/AppInfo.xcconfig
frontend/macos/Runner/Configs/Debug.xcconfig
frontend/macos/Runner/Configs/Release.xcconfig
frontend/macos/Runner/Configs/Warnings.xcconfig
frontend/macos/Runner/DebugProfile.entitlements
frontend/macos/Runner/Info.plist
[35 more files omitted for size]
```

### Dependencies

- backend/requirements.txt: fastapi@>=0.115,<1.0, uvicorn[standard]@>=0.30,<1.0

### Recent commits (newest first)

- final polish
- Update README.md
- Update README.md
- minor changes
- Update README.md
- Release v1
- ai integration complete
- Day 1 done w structure

## Key source files (fetched from GitHub, selected and truncated for size)

### backend/requirements.txt

```
fastapi>=0.115,<1.0
uvicorn[standard]>=0.30,<1.0

```

### backend/app/main.py

```python
from fastapi import FastAPI

app = FastAPI(title="NexSpend API", version="0.1.0")


@app.get("/health", tags=["system"])
async def health_check() -> dict[str, str]:
    """Liveness endpoint; product APIs start after the Day 1 foundation."""
    return {"status": "ok"}

```

### frontend/analysis_options.yaml

```yaml
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
  # The lint rules applied to this project can be customized in the
  # section below to disable rules from the `package:flutter_lints/flutter.yaml`
  # included above or to enable additional rules. A list of all available lints
  # and their documentation is published at https://dart.dev/lints.
  #
  # Instead of disabling a lint rule for the entire project in the
  # section below, it can also be suppressed for a single line of code
  # or a specific dart file by using the `// ignore: name_of_lint` and
  # `// ignore_for_file: name_of_lint` syntax on the line or in the file
  # producing the lint.
  rules:
    # avoid_print: false  # Uncomment to disable the `avoid_print` rule
    # prefer_single_quotes: true  # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

```

### frontend/pubspec.yaml

```yaml
name: nexspend
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1

environment:
  sdk: ^3.12.2

# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.8
  flutter_riverpod: ^3.3.2
  go_router: ^17.3.0
  supabase_flutter: ^2.16.0
  fl_chart: ^1.2.0
  http: ^1.6.0
  shared_preferences: ^2.5.5
  flutter_markdown_plus: ^1.0.3
  speech_to_text: ^7.3.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^6.0.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter packages.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/to/resolution-aware-images

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/to/asset-from-package

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/to/font-from-package

```

### backend/app/__init__.py

```python
"""NexSpend backend application package."""

```

### supabase/migrations/20260715000000_remove_persona_profiles.sql

```sql
-- Personas are no longer part of NexSpend's single-user product model.
drop trigger if exists on_auth_user_created on auth.users;
drop function if exists public.create_profile_for_new_user();
drop table if exists public.profiles;

```

### frontend/test/widget_test.dart

```dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:nexspend/app.dart';

void main() {
  testWidgets('shows the NexSpend welcome screen', (tester) async {
    await tester.pumpWidget(const ProviderScope(child: NexSpendApp()));
    await tester.pump();
    expect(find.text('NexSpend'), findsOneWidget);
  });
}

```

### frontend/lib/main.dart

```dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

import 'app.dart';
import 'core/config/supabase_config.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  if (SupabaseConfig.isConfigured) {
    await Supabase.initialize(
      url: SupabaseConfig.url,
      publishableKey: SupabaseConfig.publishableKey,
    );
  }
  runApp(const ProviderScope(child: NexSpendApp()));
}

```

### frontend/android/build.gradle.kts

```kotlin
allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

val newBuildDir: Directory =
    rootProject.layout.buildDirectory
        .dir("../../build")
        .get()
rootProject.layout.buildDirectory.value(newBuildDir)

subprojects {
    val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
    project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
    project.evaluationDependsOn(":app")
}

tasks.register<Delete>("clean") {
    delete(rootProject.layout.buildDirectory)
}

```

### frontend/test/ai_models_test.dart

```dart
import 'package:flutter_test/flutter_test.dart';
import 'package:nexspend/features/copilot/domain/models/ai_models.dart';

void main() {
  test('renders only the nested answer from a raw JSON answer payload', () {
    final answer = AiAnswer.fromJson({
      'type': 'spending',
      'answer':
          '''You spent the most at Bata this month.\n{"type":"merchant","answer":"You spent ₹1,000 at Bata this month.","confidence":"high","highlights":["Bata"]}''',
      'confidence': 'medium',
      'highlights': ['debug payload'],
    });

    expect(answer.answer, 'You spent ₹1,000 at Bata this month.');
  });
}

```

[86 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]