# Project export: Solace

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: UC Berkeley AI Hackathon 2025
- Tagline: SOLACE is a mobile app that empowers social workers nationwide with AI-powered tools for case management, documentation, and collaboration.
- Devpost: https://devpost.com/software/solace-yqirtb
- GitHub: https://github.com/DianaTao/solace
- Demo: https://solace-nu.vercel.app/
- Team: 4 GitHub contributor(s) — DianaTao (22 commits), Ava Rouzmehr (9 commits), JoyceQiao7 (4 commits), Vitamoon (1 commits)

## Devpost submission (written by the team)

### Inspiration

Social workers are the unsung heroes of our society—balancing large caseloads, bureaucratic hurdles, and emotionally draining tasks, often without the tools to match their mission. We wanted to build something that doesn’t just “use AI,” but genuinely serves the people who serve others. We were inspired by real interviews and research that revealed how overburdened systems leave both social workers and their clients underserved. SOLACE was born to fill that gap with empathy-driven AI tools.

### What it does

SOLACE is an AI-powered assistant designed to support social workers with their most time-consuming responsibilities. Our platform allows social workers to: Log and manage important tasks (to-dos, deadlines, appointments) Auto-summarize long case notes using state-of-the-art AI Surface key client needs and connect them to local resources Work faster, with more clarity—without compromising on care

### How we built it

Frontend: React + Tailwind CSS for a clean, mobile-responsive UI Mobile:React Native, Expo SDK 51+, React Navigation -Web: Next.js 15, React 18+, TypeScript, Tailwind CSS, Vercel deployment Backend: Node.js for routing and Python for AI processing AI Integration: Hugging Face BART model for classifying client case notes Sentence transformers for contextual resource matching Claude AI for monthly and quarterly report insight generation Data Design: Local-only sensitive data handling to preserve privacy

### Challenges we ran into

Privacy vs Personalization: Designing a system that respects confidentiality while remaining context-aware Multiple AI Pipelines: Combining different models (NLP, embeddings) into a single cohesive product Time Constraints: Training useful models and implementing them meaningfully under strict hackathon time limits

### Accomplishments we're proud of

Successfully integrating AI APIs and models for the first time as a team Implementing real-time voice input and processing tools Creating a product that doesn’t just look polished—but serves a purpose

### What we learned

How to fine-tune and use pretrained NLP models for real-world tasks Key frontend skills in React and Tailwind Voice AI tools and how to work with APIs under pressure Collaborative development and ethical AI thinking, all under 36 hours

### What's next

Expand to include appointment scheduling, live calling, and multi-user collaboration Build a client-facing version of the app so individuals can find help directly Improve AI accuracy with more training data, and add support for multilingual and mobile accessibility Launch a beta program with real social workers and gather feedback

## README (from the GitHub repository)

# SOLACE - Social Work Operations Assistant

**Social Work Operations and Link-up Assistant for Collaborative Excellence**

Empowering social workers in the San Francisco Bay Area with AI-powered tools for case management, documentation, and collaboration.

## 📁 Project Structure

```
solace/
├── 📱 mobile/          # React Native mobile app (Expo)
├── 🌐 web/             # Next.js web application  
├── 🗄️ backend/         # Python FastAPI backend & database setup
└── 📚 README.md        # This comprehensive guide
```

## 🚀 Quick Start

### Prerequisites
- Node.js 18+ and npm
- Python 3.8+ (for backend)
- Expo CLI (for mobile development)
- Supabase account

### 1. Database Setup (Required First!)
```bash
cd backend
pip install -r requirements.txt

# Set up Supabase:
# 1. Create project at supabase.com
# 2. Run setup-database.sql in SQL Editor
# 3. Update credentials in backend/.env and mobile/lib/supabase.js
```

### 2. Backend API (Python FastAPI)
```bash
cd backend
python start.py
# API runs at http://localhost:8000
```

### 3. Web Application
```bash
cd web
npm install
npm run dev
# Visit http://localhost:3000
```

### 4. Mobile Application
```bash
cd mobile
npm install
npx expo start
# Use Expo Go app or simulator
```

## 🏗️ Architecture

### 🌐 Web App (`/web`)
- **Framework**: Next.js 15 with JavaScript
- **Styling**: Tailwind CSS
- **Features**: PWA-ready, responsive design
- **Authentication**: Supabase Auth
- **Database**: Supabase PostgreSQL

### 📱 Mobile App (`/mobile`)
- **Framework**: React Native with Expo SDK 51
- **Platform**: iOS and Android
- **Features**: Native mobile experience
- **Authentication**: Supabase Auth (shared with web)
- **API**: Connects to Python FastAPI backend

### 🗄️ Backend (`/backend`)
- **Framework**: Python FastAPI
- **Database**: Supabase PostgreSQL
- **Authentication**: JWT with Supabase Auth
- **AI Services**: Claude 4 (Anthropic), Vapi (Voice)
- **Caching**: Redis (optional)
- **Features**: Client management, case notes, task management, reports

## 🔧 Technology Stack

- **Frontend**: React, Next.js, React Native, Tailwind CSS
- **Backend**: Python FastAPI, Supabase PostgreSQL
- **AI/ML**: Claude 4, Vapi Voice Services
- **Auth**: Supabase Auth (JWT)
- **Mobile**: Expo SDK 51
- **Deployment**: Vercel (web), Expo (mobile), any Python host (backend)

## 📊 Features

### Core Functionality
- ✅ **User Authentication** - Secure login/signup across platforms
- ✅ **Cross-Platform** - Web and mobile apps with shared backend
- ✅ **Real-time Sync** - Data synced across all devices
- ✅ **PWA Support** - Installable web app
- ✅ **Responsive Design** - Works on all screen sizes

### Social Work Tools
- 📋 **Client Management** - Complete CRUD operations for client records
- 📝 **Case Notes** - Digital documentation with voice-to-text
- ✅ **Task Management** - AI-powered task generation and tracking
- 📊 **Reports** - Multi-model AI analysis and report generation
- 🔔 **Notifications** - Task and appointment reminders

### AI-Powered Features
- 🎤 **Voice Notes** - Convert speech to case notes
- 🤖 **Task Generation** - AI suggests tasks based on case context
- 📈 **Report Analysis** - Intelligent report generation
- 🔍 **Classification** - Automated case categorization

## 🔐 Configuration

### Environment Variables

**Backend** (create `backend/.env`):
```env
# Application Settings
NODE_ENV=development
PORT=8000
LOG_LEVEL=INFO

# Database Configuration
SUPABASE_URL=your_supabase_url_here
SUPABASE_ANON_KEY=your_supabase_anon_key_here
SUPABASE_JWT_SECRET=your_supabase_jwt_secret_here

# Redis Configuration (Optional)
REDIS_URL=redis://localhost:6379

# AI Services Configuration
ANTHROPIC_API_KEY=your_anthropic_api_key_here
```

**Web App** (create `web/.env.local`):
```env
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url_here
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key_here
```

**Mobile App** (update `mobile/lib/supabase.js`):
```javascript
const supabaseUrl = 'your_supabase_url_here';
const supabaseAnonKey = 'your_supabase_anon_key_here';
```

### Supabase Setup

1. **Create Supabase Project**:
   - Go to [supabase.com](https://supabase.com)
   - Create new project
   - Note your Project URL and anon key

2. **Run Database Setup**:
   ```sql
   -- In Supabase SQL Editor, run:
   -- backend/setup-database.sql
   -- backend/setup-tasks-schema.sql  
   -- backend/setup-case-notes-schema.sql
   ```

3. **Configure Authentication**:
   - Enable email/password auth in Supabase dashboard
   - Set up row-level security policies

## 🔌 API Endpoints

### Health & Info
- `GET /health` - Health check
- `GET /api` - API information

### Clients
- `GET /api/clients` - List clients
- `GET /api/clients/{id}` - Get client details
- `POST /api/clients` - Create client
- `PUT /api/clients/{id}` - Update client
- `DELETE /api/clients/{id}` - Delete client

### Case Notes
- `GET /api/case-notes` - List case notes
- `POST /api/case-notes` - Create case note

### Tasks
- `GET /api/tasks` - List tasks
- `POST /api/tasks` - Create task

### Reports
- `GET /api/reports` - List reports
- `POST /api/reports/generate` - Generate report

## 🧪 Testing

### Demo Credentials
For testing both web and mobile apps:
- **Email**: `demo@solace.app`
- **Password**: `demo123`

### Development Testing
```bash
# Backend API testing
curl http://localhost:8000/health

# Web app testing
cd web && npm run build && npm run dev

# Mobile app testing  
cd mobile && npx expo start --clear
```

## 🚀 Deployment

### Web App (Vercel)
```bash
cd web
npm install -g vercel
vercel --prod
```

### Mobile App (Expo)
```bash
cd mobile
npx expo build:android  # or build:ios
```

### Backend (Python)
```bash
cd backend
python start.py production
# Deploy to any Python hosting service (Heroku, Railway, etc.)
```

## 🐛 Troubleshooting

### Database Issues
```bash
cd backend
# Run database-fix.sql if user profiles aren't being created
```

### Web App Issues
```bash
cd web
rm -rf .next node_modules
npm install && npm run dev
```

### Mobile App Issues
```bash
cd mobile
rm -rf node_modules
npm install && npx expo start --clear
```

### Backend Connection Issues
- For physical devices: Replace `localhost` with your computer's IP address
- Check firewall settings for port 8000
- Verify Supabase credentials and network connectivity

## 🛡️ Security & Privacy

- **Authentication**: Secure Supabase Auth with JWT tokens
- **Data Protection**: Row Level Security (RLS) policies
- **HIPAA Considerations**: Designed with privacy best practices
- **Encryption**: Data encrypted in transit and at rest
- **Rate Limiting**: API rate limiting and request validation

## 🔄 Data Flow

1. **Authentication**: Users log in via Supabase Auth (web/mobile)
2. **API Requests**: Frontend apps call Python FastAPI backend
3. **Database**: Backend queries Supabase PostgreSQL with RLS
4. **Real-time**: Changes sync across web and mobile via Supabase
5. **AI Processing**: Voice notes and reports processed via Claude/Vapi

## 📱 Development URLs

- **Web App**: http://localhost:3000
- **Backend API**: http://localhost:8000
- **API Docs**: http://localhost:8000/docs
- **Supabase Dashboard**: Your project dashboard URL

## 🤝 Contributing

1. Choose your development area:
   - `/web` - Web application features
   - `/mobile` - Mobile app features  
   - `/backend` - API and database changes

2. Follow the setup instructions for your chosen area
3. Make changes and test thoroughly across platforms
4. Submit pull requests with clear descriptions

## 📄 License

This project is designed for social work professionals in the San Francisco Bay Area. Please ensure compliance with local regulations and privacy requirements.

## 🆘 Support

For technical support:
1. Check this README for setup instructions
2. Review the development setup for your specific platform
3. Check console logs and error messages
4. Verify Supabase configuration and connectivity

---

**Built with ❤️ for social workers making a diffe

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 86 recognized source files, 669 KB.
- Anthropic (technology) — detected in the code
- CSS (language) — detected in the code
- FastAPI (technology) — detected in the code
- Hugging Face (technology) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- PyTorch (technology) — detected in the code
- React (technology) — detected in the code
- Redis (technology) — detected in the code
- SQL (language) — detected in the code
- Supabase (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- Vercel (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (99 of 99)

```
.expo/devices.json
.expo/README.md
.github/workflows/pdd-secrets-dispatch.yml
.gitignore
backend/.gitignore
backend/package.json
backend/requirements.txt
backend/setup-case-notes-schema.sql
backend/setup-database.sql
backend/setup-tasks-schema.sql
backend/src/config/__init__.py
backend/src/config/database.py
backend/src/config/redis_client.py
backend/src/main.py
backend/src/middleware/__init__.py
backend/src/middleware/auth.py
backend/src/middleware/error_handler.py
backend/src/middleware/rate_limiter.py
backend/src/models/__init__.py
backend/src/models/case_note.py
backend/src/models/client.py
backend/src/models/task.py
backend/src/routers/__init__.py
backend/src/routers/case_notes.py
backend/src/routers/classify.py
backend/src/routers/clients.py
backend/src/routers/google_calendar.py
backend/src/routers/reports.py
backend/src/routers/tasks.py
backend/src/services/__init__.py
backend/src/services/case_notes_service.py
backend/src/services/classification_service.py
backend/src/services/client_service.py
backend/src/services/report_analysis_service.py
backend/src/services/task_management_service.py
backend/src/services/voice_service.py
backend/src/utils/__init__.py
backend/src/utils/logger.py
backend/start.py
mobile/App.js
mobile/app.json
mobile/babel.config.js
mobile/components/VoiceNoteRecorder.js
mobile/config/env.js
mobile/lib/api.js
mobile/lib/auth.js
mobile/lib/supabase.js
mobile/package.json
mobile/screens/ClientManagementScreen.js
mobile/screens/CreateTaskScreen.js
mobile/screens/HomeScreen.js
mobile/screens/LoginScreen.js
mobile/screens/ReportsScreen.js
mobile/screens/ReportViewerScreen.js
mobile/screens/SignupScreen.js
mobile/screens/TasksScreen.js
mobile/screens/WelcomeScreen.js
package.json
README.md
web/.gitignore
web/eslint.config.mjs
web/next.config.js
web/package.json
web/postcss.config.mjs
web/public/manifest.json
web/src/app/globals.css
web/src/app/layout.jsx
web/src/app/page.jsx
web/src/components/ArtisticAuth.module.css
web/src/components/ClientForms.jsx
web/src/components/ClientManagement.jsx
web/src/components/ClientProfile.jsx
web/src/components/HomeScreen.jsx
web/src/components/LoginPage.jsx
web/src/components/ReportsScreen.jsx
web/src/components/SignupPage.jsx
web/src/components/TasksScreen.jsx
web/src/components/ui/Avatar.jsx
web/src/components/ui/Badge.jsx
web/src/components/ui/Button.jsx
web/src/components/ui/Card.jsx
web/src/components/ui/Dialog.jsx
web/src/components/ui/Input.jsx
web/src/components/ui/Label.jsx
web/src/components/ui/Progress.jsx
web/src/components/ui/Select.jsx
web/src/components/ui/Separator.jsx
web/src/components/ui/Sheet.jsx
web/src/components/ui/Tabs.jsx
web/src/components/ui/Textarea.jsx
web/src/components/VoiceNoteRecorder.jsx
web/src/components/WelcomeScreen.jsx
web/src/lib/api.js
web/src/lib/auth.js
web/src/lib/logger.js
web/src/lib/store.js
web/src/lib/supabase.js
web/src/lib/utils.js
web/tailwind.config.js
```

### Dependencies

- backend/package.json: anthropic@^0.7.8, black@^23.11.0, fastapi@^0.104.1, flake8@^6.1.0, google-generativeai@^0.3.2, httpx@^0.25.2, mypy@^1.7.1, openai@^1.3.7, pydantic@^2.5.0, pytest@^7.4.3, pytest-asyncio@^0.21.1, python-dotenv@^1.0.0, python-multipart@^0.0.6, redis@^5.0.1, supabase@^2.0.2, uvicorn@^0.24.0
- backend/requirements.txt: aiofiles@==23.2.1, aiohttp@==3.9.1, anthropic@==0.7.8, cryptography@==41.0.7, email-validator@==2.1.0, fastapi@==0.104.1, google-api-python-client@==2.108.0, google-auth@==2.23.4, google-auth-httplib2@==0.2.0, google-auth-oauthlib@==1.1.0, httpx@==0.24.1, jsonschema@==4.20.0, mutagen@==1.47.0, passlib[bcrypt]@==1.7.4, pydantic@==2.10.4, pydub@==0.25.1, PyJWT, pytest@==7.4.3, pytest-asyncio@==0.21.1, python-dateutil@==2.8.2, python-dotenv@==1.0.0, python-jose[cryptography]@==3.3.0, python-multipart@==0.0.6, redis@==5.0.1, rq, supabase@==2.0.2, torch, transformers, uvicorn[standard]@==0.24.0, wave@==0.0.2, websockets@==12.0
- mobile/package.json: @babel/core@^7.20.0, @expo/vector-icons@^14.1.0, @react-native-async-storage/async-storage@2.1.2, @supabase/supabase-js@^2.50.0, expo@~53.0.0, expo-av@^15.1.6, expo-document-picker@^13.1.6, expo-file-system@^18.1.10, expo-linear-gradient@~14.1.5, expo-status-bar@~2.2.3, react@19.0.0, react-native@0.79.4, react-native-vector-icons@^10.2.0
- package.json: @supabase/supabase-js@^2.50.0
- web/package.json: @eslint/eslintrc@^3, @headlessui/react@^2.2.4, @heroicons/react@^2.2.0, @supabase/supabase-js@^2.50.0, @tailwindcss/forms@^0.5.10, @tailwindcss/typography@^0.5.16, autoprefixer@^10.4.20, clsx@^2.1.1, date-fns@^4.1.0, eslint@^9, eslint-config-next@15.3.4, lucide-react@^0.522.0, next@15.3.4, postcss@^8.4.49, react@^19.0.0, react-dom@^19.0.0, react-hot-toast@^2.5.2, tailwind-merge@^3.3.1, tailwindcss@^3.4.17, uuid@^11.1.0, zustand@^5.0.5

### Recent commits (newest first)

- chore: add PDD secrets dispatch workflow [automated]
- test connection
- clean up codebase
- added model, running server to test
- added one more change, frontend mobile
- organized repo
- stashing this
- fixed UI, working on model
- Merge branch 'main' of github.com:DianaTao/solace
- fixed UI/UX issues, finetuning
- Merge remote changes with Vapi integration and voice features
- add voice backend
- Remove redundant code and template files
- tweaking frontend, UI/UX
- Fix authentication to use Supabase client validation instead of JWT secret
- task
- web app report finished
- report using llm finished for mobile
- llm report
- web and mobile for client managament

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

### package.json

```
{
  "dependencies": {
    "@supabase/supabase-js": "^2.50.0"
  }
}

```

### mobile/package.json

```
{
  "name": "solace-mobile",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@expo/vector-icons": "^14.1.0",
    "@react-native-async-storage/async-storage": "2.1.2",
    "@supabase/supabase-js": "^2.50.0",
    "expo": "~53.0.0",
    "expo-av": "^15.1.6",
    "expo-document-picker": "^13.1.6",
    "expo-file-system": "^18.1.10",
    "expo-linear-gradient": "~14.1.5",
    "expo-status-bar": "~2.2.3",
    "react": "19.0.0",
    "react-native": "0.79.4",
    "react-native-vector-icons": "^10.2.0"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0"
  },
  "private": true
}

```

### web/package.json

```
{
  "name": "solace",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@headlessui/react": "^2.2.4",
    "@heroicons/react": "^2.2.0",
    "@supabase/supabase-js": "^2.50.0",
    "@tailwindcss/forms": "^0.5.10",
    "@tailwindcss/typography": "^0.5.16",
    "autoprefixer": "^10.4.20",
    "clsx": "^2.1.1",
    "date-fns": "^4.1.0",
    "lucide-react": "^0.522.0",
    "next": "15.3.4",
    "postcss": "^8.4.49",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "react-hot-toast": "^2.5.2",
    "tailwind-merge": "^3.3.1",
    "tailwindcss": "^3.4.17",
    "uuid": "^11.1.0",
    "zustand": "^5.0.5"
  },
  "devDependencies": {
    "@eslint/eslintrc": "^3",
    "eslint": "^9",
    "eslint-config-next": "15.3.4"
  }
}

```

### backend/package.json

```
{
  "name": "solace-backend",
  "version": "1.0.0",
  "description": "Social Work Operations and Link-up Assistant for Collaborative Excellence - Python Backend",
  "main": "src/main.py",
  "scripts": {
    "start": "python src/main.py",
    "dev": "uvicorn src.main:app --reload --host 0.0.0.0 --port 8000",
    "test": "pytest",
    "test:watch": "pytest --watch",
    "lint": "flake8 src/",
    "lint:fix": "black src/",
    "format": "black src/",
    "type-check": "mypy src/",
    "install-deps": "pip install -r requirements.txt",
    "setup": "python -m pip install --upgrade pip && pip install -r requirements.txt"
  },
  "keywords": [
    "social-work",
    "ai",
    "automation",
    "coordination",
    "voice",
    "agents",
    "multimodal",
    "python",
    "fastapi",
    "supabase"
  ],
  "author": "SOLACE Development Team",
  "license": "MIT",
  "engines": {
    "python": ">=3.9.0"
  },
  "dependencies": {
    "fastapi": "^0.104.1",
    "uvicorn": "^0.24.0",
    "supabase": "^2.0.2",
    "openai": "^1.3.7",
    "anthropic": "^0.7.8",
    "google-generativeai": "^0.3.2",
    "python-multipart": "^0.0.6",
    "httpx": "^0.25.2",
    "redis": "^5.0.1",
    "pydantic": "^2.5.0",
    "python-dotenv": "^1.0.0"
  },
  "devDependencies": {
    "pytest": "^7.4.3",
    "pytest-asyncio": "^0.21.1",
    "black": "^23.11.0",
    "flake8": "^6.1.0",
    "mypy": "^1.7.1"
  }
} 
```

### backend/requirements.txt

```
# Core FastAPI dependencies
fastapi==0.104.1
uvicorn[standard]==0.24.0
pydantic==2.10.4
python-multipart==0.0.6

# Database
supabase==2.0.2
redis==5.0.1

# AI and ML - Only using Claude 4
anthropic==0.7.8  # Claude 4
httpx==0.24.1     # For Vapi and Fetch AI API calls

# ===== VOICE INTEGRATION DEPENDENCIES =====
# Vapi.ai integration for voice operations and TTS
aiohttp==3.9.1         # Async HTTP client for Vapi API
aiofiles==23.2.1       # Async file operations for audio handling
websockets==12.0       # WebSocket support for real-time voice events

# Audio processing and validation
pydub==0.25.1          # Audio file manipulation and conversion
wave==0.0.2            # WAV file support
mutagen==1.47.0        # Audio metadata handling

# Enhanced JSON and data validation
jsonschema==4.20.0     # JSON schema validation for webhooks
email-validator==2.1.0 # Email validation for Pydantic models

# Google Calendar Integration
google-api-python-client==2.108.0  # Google Calendar API
google-auth==2.23.4                # Google authentication
google-auth-oauthlib==1.1.0        # OAuth flow for Google
google-auth-httplib2==0.2.0        # HTTP library for Google APIs

# Utilities
python-dotenv==1.0.0
python-jose[cryptography]==3.3.0
passlib[bcrypt]==1.7.4
python-dateutil==2.8.2

# Development and testing
pytest==7.4.3
pytest-asyncio==0.21.1

# Security
cryptography==41.0.7

torch
transformers

rq
PyJWT 
```

### mobile/App.js

```javascript
import React, { useState, useEffect } from 'react';
import { Alert } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { AuthService } from './lib/auth';
import HomeScreen from './screens/HomeScreen';
import WelcomeScreen from './screens/WelcomeScreen';
import LoginScreen from './screens/LoginScreen';
import SignupScreen from './screens/SignupScreen';

export default function App() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [name, setName] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [user, setUser] = useState(null);
  const [isSignUpMode, setIsSignUpMode] = useState(false);
  const [showWelcome, setShowWelcome] = useState(true);
  
  // Console log for app initialization
  useEffect(() => {
    console.log('🚀 SOLACE Mobile App initialized');
    checkWelcomeStatus();
    checkCurrentUser();
  }, []);

  // Check if user has already seen the welcome screen
  const checkWelcomeStatus = async () => {
    try {
      const hasSeenWelcome = await AsyncStorage.getItem('hasSeenWelcome');
      if (hasSeenWelcome === 'true') {
        setShowWelcome(false);
      }
    } catch (error) {
      console.log('ℹ️ Could not check welcome status:', error.message);
    }
  };

  // Mark welcome as seen
  const markWelcomeAsSeen = async () => {
    try {
      await AsyncStorage.setItem('hasSeenWelcome', 'true');
      setShowWelcome(false);
    } catch (error) {
      console.log('ℹ️ Could not save welcome status:', error.message);
      setShowWelcome(false); // Continue anyway
    }
  };

  // Check if user is already logged in
  const checkCurrentUser = async () => {
    try {
      console.log('🔍 Checking current user session...');
      
      // First check if there's a valid Supabase session
      const session = await AuthService.getCurrentSession();
      if (!session) {
        console.log('ℹ️ No active session found');
        return;
      }
      
      // Validate that it's not just an anon session
      const anonKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNjb3RrcmhycWtsZGdmZGpubGVhIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTA0ODM4MDgsImV4cCI6MjA2NjA1OTgwOH0.-Q3LvNkbaNvfjnEoKwY53BNLPVIEvxoDzRD9z3-5NO0';
      
      if (session.access_token === anonKey) {
        console.log('ℹ️ Found anon session, not authenticated user session');
        return;
      }
      
      // Now get the user profile
      const currentUser = await AuthService.getCurrentUser();
      if (currentUser) {
        console.log('👤 User already logged in:', currentUser.email);
        setUser(currentUser);
      }
    } catch (error) {
      console.log('ℹ️ No current user session:', error.message);
    }
  };

  const handleLogin = async () => {
    console.log('🔐 Login attempt:', { email, password: password ? '***hidden***' : 'empty' });
    
    // Validation
    if (!email || !password) {
      Alert.alert('❌ Validation Error', 'Please enter both email and password.', [
        { text: 'OK', style: 'cancel' }
      ]);
      return;
    }

    // Supabase authentication
    setIsLoading(true);
    try {
      const result = await AuthService.signIn({ email, password });
      
      if (result.user) {
        console.log('✅ Supabase login successful:', result.user.email);
        setUser(result.user);
        Alert.alert('✅ Login successful!', `Welcome back, ${result.user.name || result.user.email}!`, [
          { text: 'Continue', style: 'default' }
        ]);
      }
    } catch (error) {
      console.error('❌ Login failed:', error.message);
      
      // Provide helpful error messages
      let errorMessage = 'Please check your credentials and try again.';
      let alertButtons = [{ text: 'Try Again', style: 'cancel' }];
      
      if (error.message.includes('Invalid login credentials')) {
        errorMessage = `Invalid email or password for ${email}. Please check your credentials or sign up if you don't have an account.`;
        alertButtons = [
          { text: 'Try Again', style: 'cancel' },
          { 
            text: 'Sign Up', 
            style: 'default',
            onPress: () => {
              setIsSignUpMode(true);
              setPassword('');
            }
          }
        ];
      } else if (error.message.includes('Email not confirmed')) {
        errorMessage = 'Please check your email and click the confirmation link before signing in. Check your spam folder if you don\'t see it.';
      }
      
      Alert.alert('❌ Login Failed', errorMessage, alertButtons);
    } finally {
      setIsLoading(false);
    }
  };

  const handleSignUp = async () => {
    console.log('📝 Sign up attempt:', { email, name, password: password ? '***hidden***' : 'empty' });
    
    // Validation
    if (!email || !password || !name) {
      Alert.alert('❌ Validation Error', 'Please fill in all required fields.', [
        { text: 'OK', style: 'cancel' }
      ]);
      return;
    }

    if (password !== confirmPassword) {
      Alert.alert('❌ Validation Error', 'Passwords do not match.', [
        { text: 'OK', style: 'cancel' }
      ]);
      return;
    }

    if (password.length < 6) {
      Alert.alert('❌ Validation Error', 'Password must be at least 6 characters long.', [
        { text: 'OK', style: 'cancel' }
      ]);
      return;
    }

    // Supabase sign up
    setIsLoading(true);
    try {
      const result = await AuthService.signUp(email, password, {
        name: name,
        role: 'social_worker'
      });
      
      if (result.user) {
        console.log('✅ Supabase signup successful:', result.user.email);
        Alert.alert(
          '✅ Account Created!', 
          'Please check your email for a confirmation link before signing in.',
          [
            { 
              text: 'OK', 
              style: 'default',
              onPress: () 
[truncated — 5061 more characters]
```

### backend/src/main.py

```python
import sys
import os
from pathlib import Path
import logging
from typing import Dict, Any

# Add the current directory to the Python path
current_dir = Path(__file__).parent
sys.path.insert(0, str(current_dir))

# Load environment variables
from dotenv import load_dotenv
load_dotenv()

# Configure logging first
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# Now import everything else
from fastapi import FastAPI, HTTPException, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import uvicorn

# Import our modules
from config.database import get_supabase, test_database_connection
from routers import clients, case_notes, tasks, reports, google_calendar, classify
from middleware.auth import get_current_user

# Log startup information
logger.info("🚀 Starting SOLACE Backend API...")
logger.info(f"🔧 Python Path: {sys.path[:3]}...")  # Show first 3 path entries
logger.info(f"🔧 Current Directory: {current_dir}")

# Check environment variables
env_vars = {
    'SUPABASE_URL': os.getenv("SUPABASE_URL"),
    'SUPABASE_ANON_KEY': os.getenv("SUPABASE_ANON_KEY"),
    'SUPABASE_JWT_SECRET': os.getenv("SUPABASE_JWT_SECRET"),
    'PORT': os.getenv("PORT", "8000"),
    'LOG_LEVEL': os.getenv("LOG_LEVEL", "INFO"),
    'NODE_ENV': os.getenv("NODE_ENV", "development")
}

logger.info("🔧 Environment Variables Status:")
for key, value in env_vars.items():
    if value:
        if 'KEY' in key or 'SECRET' in key:
            logger.info(f"   ✅ {key}: {value[:20]}...{value[-10:] if len(value) > 30 else value}")
        else:
            logger.info(f"   ✅ {key}: {value}")
    else:
        logger.warning(f"   ⚠️ {key}: NOT SET")

# Test database connection
logger.info("🔍 Testing database connection...")
db_status = test_database_connection()
logger.info(f"🔧 Database Status: {'✅ Connected' if db_status else '❌ Failed'}")

# Create FastAPI app
app = FastAPI(
    title="SOLACE Backend API",
    description="Backend API for SOLACE Social Work Case Management System",
    version="1.0.0",
    docs_url="/docs",
    redoc_url="/redoc",
    redirect_slashes=False  # Disable automatic slash redirects
)

# Configure CORS
cors_origins = os.getenv("CORS_ORIGIN", "http://localhost:3000").split(",")
logger.info(f"🔧 CORS Origins: {cors_origins}")

app.add_middleware(
    CORSMiddleware,
    allow_origins=cors_origins + ["*"],  # Allow all origins for development
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Health check endpoint (no authentication required)
@app.get("/api/health")
async def health_check():
    """Health check endpoint"""
    logger.info("🔍 Health check requested")
    
    # Test database connectivity
    db_connected = test_database_connection()
    
    health_status = {
        "status": "healthy" if db_connected else "degraded",
        "timestamp": "2024-01-01T00:00:00Z",
        "services": {
            "database": db_connected,
            "clients": True,
            "case_notes": True,
            "tasks": True,
            "reports": True
        }
    }
    
    logger.info(f"📊 Health Status: {health_status}")
    return health_status

# Include routers with authentication
logger.info("🔄 Setting up API routes...")

app.include_router(
    clients.router,
    prefix="/api/clients",
    tags=["clients"],
    dependencies=[Depends(get_current_user)]
)

app.include_router(
    case_notes.router,
    prefix="/api/case-notes",
    tags=["case_notes"],
    dependencies=[Depends(get_current_user)]
)

app.include_router(
    tasks.router,
    prefix="/api/tasks",
    tags=["tasks"],
    dependencies=[Depends(get_current_user)]
)

app.include_router(
    reports.router,
    prefix="/api/reports",
    tags=["reports"],
    dependencies=[Depends(get_current_user)]
)

app.include_router(
    google_calendar.router,
    prefix="/api/google-calendar",
    tags=["google_calendar"],
    dependencies=[Depends(get_current_user)]
)

app.include_router(
    classify.router,
    prefix="/api/classify",
    tags=["classification"],
    dependencies=[Depends(get_current_user)]
)

logger.info("✅ API routes configured successfully")

@app.get("/")
async def root():
    """Root endpoint"""
    return {
        "message": "SOLACE Backend API",
        "version": "1.0.0",
        "status": "running",
        "docs": "/docs"
    }

if __name__ == "__main__":
    port = int(os.getenv("PORT", 8000))
    logger.info(f"🚀 Starting server on port {port}")
    logger.info("📋 Server endpoints will be available at:")
    logger.info(f"   🌐 API Health: http://localhost:{port}/api/health")
    logger.info(f"   📚 API Docs: http://localhost:{port}/docs")
    logger.info(f"   📖 ReDoc: http://localhost:{port}/redoc")
    
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=port,
        reload=True,
        log_level="info"
    ) 
```

### web/src/app/layout.jsx

```javascript
import { Geist, Geist_Mono } from "next/font/google";
import { Toaster } from 'react-hot-toast';
import "./globals.css";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

export const viewport = {
  width: 'device-width',
  initialScale: 1,
  maximumScale: 1,
  themeColor: [
    { media: '(prefers-color-scheme: light)', color: '#ffffff' },
    { media: '(prefers-color-scheme: dark)', color: '#000000' }
  ],
};

export const metadata = {
  title: "SOLACE - Social Work Operations Assistant",
  description: "Social Work Operations and Link-up Assistant for Collaborative Excellence. Empowering social workers in the San Francisco Bay Area with AI-powered tools for case management, documentation, and collaboration.",
  keywords: "social work, case management, AI assistant, documentation, collaboration, San Francisco Bay Area",
  authors: [{ name: "SOLACE Team" }],
  creator: "SOLACE",
  publisher: "SOLACE",
  formatDetection: {
    email: false,
    address: false,
    telephone: false,
  },

  manifest: '/manifest.json',
  appleWebApp: {
    capable: true,
    statusBarStyle: 'default',
    title: 'SOLACE',
  },
  other: {
    'mobile-web-app-capable': 'yes',
  },
};

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        {children}
        <Toaster
          position="top-right"
          toastOptions={{
            duration: 4000,
            style: {
              background: '#363636',
              color: '#fff',
            },
            success: {
              style: {
                background: '#10b981',
              },
            },
            error: {
              style: {
                background: '#ef4444',
              },
            },
          }}
        />
      </body>
    </html>
  );
}

```

### web/src/app/page.jsx

```javascript
'use client';

import { useState, useEffect } from 'react';
import { AuthService } from '../lib/auth';
import HomeScreen from '../components/HomeScreen';
import WelcomeScreen from '../components/WelcomeScreen';
import LoginPage from '../components/LoginPage';
import SignupPage from '../components/SignupPage';

export default function HomePage() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [name, setName] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [user, setUser] = useState(null);
  const [isSignUpMode, setIsSignUpMode] = useState(false);
  const [deferredPrompt, setDeferredPrompt] = useState(null);
  const [isInstallable, setIsInstallable] = useState(false);
  const [showWelcome, setShowWelcome] = useState(true);

  useEffect(() => {
    console.log('🚀 SOLACE Web App initialized');
    
    // Check if user has seen welcome screen
    checkWelcomeStatus();
    
    // Add a small delay to ensure Supabase is fully initialized
    const initializeAuth = async () => {
      try {
        // Wait a moment for the client to be ready
        await new Promise(resolve => setTimeout(resolve, 100));
        await checkCurrentUser();
      } catch (error) {
        console.log('ℹ️ Auth initialization completed with no active session');
      }
    };
    
    initializeAuth();
    
    const handler = (e) => {
      e.preventDefault();
      setDeferredPrompt(e);
      setIsInstallable(true);
    };

    window.addEventListener('beforeinstallprompt', handler);
    return () => window.removeEventListener('beforeinstallprompt', handler);
  }, []);

  // Check if user has already seen the welcome screen
  const checkWelcomeStatus = () => {
    try {
      const hasSeenWelcome = localStorage.getItem('hasSeenWelcome');
      if (hasSeenWelcome === 'true') {
        setShowWelcome(false);
      }
    } catch (error) {
      console.log('ℹ️ Could not check welcome status:', error.message);
    }
  };

  // Mark welcome as seen
  const markWelcomeAsSeen = () => {
    try {
      localStorage.setItem('hasSeenWelcome', 'true');
      setShowWelcome(false);
    } catch (error) {
      console.log('ℹ️ Could not save welcome status:', error.message);
      setShowWelcome(false); // Continue anyway
    }
  };

  // Check if user is already logged in
  const checkCurrentUser = async () => {
    try {
      console.log('🔍 Checking for existing user session...');
      const currentUser = await AuthService.getCurrentUser();
      if (currentUser) {
        console.log('👤 User already logged in:', currentUser.email);
        setUser(currentUser);
      } else {
        console.log('ℹ️ No current user session found');
      }
    } catch (error) {
      // Handle any authentication errors gracefully
      if (error.message && error.message.includes('Auth session missing')) {
        console.log('ℹ️ No auth session (user not logged in)');
      } else {
        console.log('ℹ️ Error checking user session:', error.message || 'Unknown error');
      }
      // Ensure user state is null if there's any error
      setUser(null);
    }
  };

  const handleInstall = async () => {
    if (deferredPrompt) {
      deferredPrompt.prompt();
      const { outcome } = await deferredPrompt.userChoice;
      if (outcome === 'accepted') {
        setIsInstallable(false);
        alert('SOLACE app installed successfully! 🎉');
      }
      setDeferredPrompt(null);
    }
  };

  const handleLogin = async (userOrEvent) => {
    // If this is called with a user object directly (from LoginPage component)
    if (userOrEvent && userOrEvent.email && !userOrEvent.preventDefault) {
      console.log('✅ Login successful via LoginPage component:', userOrEvent.email);
      setUser(userOrEvent);
      return;
    }

    // If this is called with an event object (old form-based flow)
    if (userOrEvent && userOrEvent.preventDefault) {
      userOrEvent.preventDefault();
    }
    
    console.log('🔐 Login attempt:', { email, password: password ? '***hidden***' : 'empty' });
    
    // Demo credentials fallback
    if (email === 'demo@solace.app' && password === 'demo123') {
      alert('✅ Demo Login successful! Welcome to SOLACE web app! (Demo Mode)');
      return;
    }

    // Validation
    if (!email || !password) {
      alert('❌ Validation Error: Please enter both email and password.');
      return;
    }

    // Supabase authentication
    setIsLoading(true);
    try {
      const result = await AuthService.signIn({ email, password });
      
      if (result.user) {
        console.log('✅ Supabase login successful:', result.user.email);
        setUser(result.user);
        alert(`✅ Login successful! Welcome back, ${result.user.name || result.user.email}!`);
      }
    } catch (error) {
      console.error('❌ Login failed:', error.message);
      
      // Provide helpful error messages
      let errorMessage = 'Please check your credentials and try again.';
      if (error.message.includes('Invalid login credentials')) {
        errorMessage = `Invalid email or password for ${email}. Please check your credentials or sign up if you don't have an account.`;
        if (confirm(`${errorMessage}\n\nWould you like to sign up instead?`)) {
          setIsSignUpMode(true);
          setPassword('');
        }
      } else if (error.message.includes('Email not confirmed')) {
        errorMessage = 'Please check your email and click the confirmation link before signing in. Check your spam folder if you don\'t see it.';
        alert(errorMessage);
      } else {
        alert(`❌ Login Failed: ${errorMessage}`);
      }
    } finally {
      setIsLoading(false);
    }
  };

  const handleSignUp = async (e) => {
    e.preventDefault();
    console.log('📝 Sign up attempt:', { email, name, password: password ? '***hidden***' : 'empty' });
    
    // Validation
    if (!email || !password |
[truncated — 3763 more characters]
```

### mobile/babel.config.js

```javascript
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
  };
}; 
```

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