# Project export: LifeLine Aid

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: Cal Hacks 10.0
- Tagline: LifeLine Aid: A beacon for refugees in conflict zones. Instantly see nearby food, shelter, and aid. Get alerts on regional hazards. Direct links to humanitarian agencies. Hope in chaos.
- Devpost: https://devpost.com/software/lifeline-aid
- GitHub: https://github.com/No767/lifelineaid
- Result: winner (Best Use of CockroachDB Serverless)
- Team: 3 GitHub contributor(s) — No767 (15 commits), Javier (2 commits), sanityl0st (1 commits)

## Devpost submission (written by the team)

### Inspiration

In light of the ongoing global conflict between war-torn countries, many civilians face hardships. Recognizing these challenges, LifeLine Aid was inspired to direct vulnerable groups to essential medical care, health services, shelter, food and water assistance, and other deprivation relief.

### What it does

LifeLine Aid provides multifunctional tools that enable users in developing countries to locate resources and identify dangers nearby. Utilizing the user's location, the app alerts them about the proximity of a situation and centers for help. It also facilitates communication, allowing users to share live videos and chat updates regarding ongoing issues. An upcoming feature will highlight available resources, like nearby medical centers, and notify users if these centers are running low on supplies.

### How we built it

Originally, the web backend was to be built using Django, a trusted framework in the industry. As we progressed, we realized that the amount of effort and feasibility of exploiting Django were not sustainable; as we made no progress within the first day. Quickly turning to the in-depth knowledge of one of our team member’s extensive research into asyncio, we decided to switch to FastAPI, a trusted framework used by Microsoft. Using this framework had both its benefits and costs. Realizing after our first day, Django proved to be a roadblock, thus we ultimately decided to switch to FastAPI. Our backend proudly uses CockroachDB, an unstoppable force to be reckoned with. CockroachDB allowed our code to scale and continue to serve those who suffer from the effects of war.

### Challenges we ran into

In order to pinpoint hazards and help, we would need to obtain, store, and reverse-engineer Geospatial coordinate points which we would then present to users in a map-centric manner. We initially struggled with converting the Geospatial data from a degree, minutes, seconds format to decimal degrees and storing the converted values as points on the map which were then stored as unique 50 character long SRID values. Luckily, one of our teammates had some experience with processing GeoSpatial data so drafting coordinates on a map wasn’t our biggest hurdle to overcome. Another challenge we faced were certain edge cases in our initial Django backend that resulted in invalid data. Since some outputs would be relevant to our project, we had to make an executive decision to change backend midway through. We decided to go with FastApi. Although FastApi brought its own challenge with processing SQL to usable data, it was our way of overcoming our Jango situation. One last challenge we ran into was our overall source control. A mixture of slow and unbearable WiFi, combined with tedious local git repositories not correctly syncing create some frustrating deadlocks and holdbacks. To combat this downtime, we resort to physically drafting and planning out how each component of our code would work.

### Accomplishments we're proud of

Three out of the four in our team are attending their first hackathon. The experience of crafting an app and seeing the fruits of our labor is truly rewarding. The opportunity to acquire and apply new tools in our project has been exhilarating. Through this hackathon, our team members were all able to learn different aspects of creating an idea into a scalable application. From designing and learning UI/UX, implementing the React-Native framework, emulating iOS and Android devices to test and program compatibility, and creating communication between the frontend and backend/database.

### What we learned

This challenge aimed to dive into technologies that are used widely in our daily lives. Spearheading the competition with a framework trusted by huge companies such as Meta, Discord and others, we chose to explore the capabilities of React Native. Joining our team are three students who have attended their first hackathon, and the grateful opportunity of being able to explore these technologies have led us to take away a skillset of a lifetime. With the concept of the application, we researched and discovered that the only best way to represent our data is through the usage of Geospatial Data. CockroachDB’s extensive tooling and support allowed us to investigate the usage of geospatial data extensively; as our backend team traversed the complexity and the sheer awe of the scale of said technology. We are extremely grateful to have this opportunity to network and to use these tools that would be useful in the future.

### What's next

There are a plethora of avenues to further develop the app, which include enhanced verification, rate limiting, and many others. Other options include improved hosting using Azure Kubernetes Services (AKS), and many others. This hackathon project is planned to be maintained further into the future as a project for others who may be new or old in this field to collaborate on.

## README (from the GitHub repository)

 Lifeline Aid 

A beacon for refugees in conflict zones. Instantly see nearby food, shelter, and aid. Get alerts on regional hazards. Direct links to humanitarian agencies. Hope in chaos.

## Purpose / Movitation

This project was created for [Cal Hacks 10.0](https://www.calhacks.io/), an hackathon ran by University of California, Berkeley. The app serves as a beacon for refugees in conflict zones, where affected users can use this app to locate official places that offer humanitarian aid and other essentials (eg. food and water). 

This project is developed by Javier Miranda, Noelle Wang, Andres Yllescas and Ashly Benitez within the 30 hour time limit of Cal Hacks.

## The "techy side"

This repo serves as a monorepo, most notably these two folders:

- `multiNew` - The React Native (TS) mobile app as the frontend
- `fastapi-backend` - FastAPI application (Python w/ type hints) that uses [CockroachDB](https://www.cockroachlabs.com/). `asyncpg`-based project, as CockroachDB natively implements the PGWire Protocol (in simply terms, CockroachDB fully supports any and all PostgreSQL drivers and code).

As a part of a sponsership deal, UC Berkeley partnered up with CockroachLabs in order to provide a prize for whoever which team uses CockroachDB the best. Up to $2000 dollars.

### Mobile app

The choice of framework for us would be React Native. We needed something to deploy both to APple devices and Android devices, as people in these countries do not have easy access to the web. The mobile app presented the challenge of learning said framework, but the intergration between the mobile app and backend. 

Development of the mobile app were led by Javier Miranda and Andres Yllescas.

### Backend

Originally seltting on Django, we figured out that using Django meant wasting more time and the restrictions imposed on ORMs. After noticing the 5.8x (or 580%) performance boost over psycopg2 and 5x (or 500%) over psycopg3 (and 8.2x or 820% faster than node-js), it made sense to break out the big guns - asyncpg. Used by over 40,000 developers, asyncpg's users contain projects such as [R. Danny](https://github.com/Rapptz/RoboDanny), which are known to be extremely stable and performant. For reasons described above, along with fimliarly with asyncpg, the decision was set to switch over. 

The backend implements a connection pool of 25, which is suitable for most instances. All connections are pulled from the pool and sent back once finished. 

## The future of the app

Ultimately, this app is not finished. There are plans to maintain this as an UCMACM project, continuing the legacy of Lifeline Aid. Plans include:

- User auth
- Rewrite of some of the core parts
- User forums

and many many more.






## Detected evidence (automated analysis)

Indexed codebase: 48 recognized source files, 41 KB.
- Django (technology) — detected in the code
- FastAPI (technology) — detected in the code
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- SQL (language) — detected in the code
- TypeScript (language) — detected in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- PostgreSQL (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (60 of 60)

```
backend-django-old/.env
backend-django-old/.python-version
backend-django-old/api/__init__.py
backend-django-old/api/admin.py
backend-django-old/api/apps.py
backend-django-old/api/migrations/__init__.py
backend-django-old/api/models.py
backend-django-old/api/tests.py
backend-django-old/api/views.py
backend-django-old/backend/__init__.py
backend-django-old/backend/asgi.py
backend-django-old/backend/settings.py
backend-django-old/backend/test_path.py
backend-django-old/backend/urls.py
backend-django-old/backend/wsgi.py
backend-django-old/manage.py
backend-django-old/requirements.txt
backend-django-old/schema.sql
backend-django-old/test.py
fastapi-backend/.env.example
fastapi-backend/.gitignore
fastapi-backend/.pre-commit-config.yaml
fastapi-backend/main.py
fastapi-backend/migrations-runner.py
fastapi-backend/migrations/20231028_initial_up_rev1.sql
fastapi-backend/migrations/20231028_rev1_up_rev2.sql
fastapi-backend/pyproject.toml
fastapi-backend/requirements-dev.txt
fastapi-backend/requirements.txt
fastapi-backend/routes/__init__.py
fastapi-backend/routes/alerts.py
fastapi-backend/routes/pins.py
fastapi-backend/utils/__init__.py
fastapi-backend/utils/entries.py
fastapi-backend/utils/structs.py
multiNew/.gitignore
multiNew/app.json
multiNew/app/_layout.tsx
multiNew/app/(tabs)/_layout.tsx
multiNew/app/(tabs)/four.tsx
multiNew/app/(tabs)/index.tsx
multiNew/app/(tabs)/three.tsx
multiNew/app/(tabs)/two.tsx
multiNew/app/[...missing].tsx
multiNew/app/+html.tsx
multiNew/app/modal.tsx
multiNew/babel.config.js
multiNew/components/__tests__/StyledText-test.js
multiNew/components/alertScreenInfo.tsx
multiNew/components/contactScreenInfo.tsx
multiNew/components/ExternalLink.tsx
multiNew/components/mainScreenInfo.tsx
multiNew/components/profileScreenInfo.tsx
multiNew/components/StyledText.tsx
multiNew/components/Themed.tsx
multiNew/constants/Colors.ts
multiNew/metro.config.js
multiNew/package.json
multiNew/tsconfig.json
README.md
```

### Dependencies

- backend-django-old/requirements.txt: django, django-cockroachdb@==4.2.*, django-filter, djangorestframework, markdown, psycopg[binary], python-dotenv
- fastapi-backend/requirements.txt: asyncpg@>=0.28.0, asyncpg-trek@>=0.3.1, fastapi@>=0.104.0, hypercorn@>=0.14.4, orjson@>=3.9.10, python-dotenv@>=1.0.0, shapely@>=2.0.2, uvicorn[standard]@>=0.23.2
- multiNew/package.json: @babel/core@^7.20.0, @emotion/react@^11.11.1, @emotion/styled@^11.11.0, @expo/vector-icons@^13.0.0, @mui/material@^5.14.15, @react-navigation/native@^6.0.2, @rneui/themed@^4.0.0-rc.8, @types/react@~18.2.14, android@^0.0.8, axios@^1.6.0, expo@~49.0.15, expo-font@~11.4.0, expo-linking@~5.0.2, expo-router@^2.0.0, expo-splash-screen@~0.20.5, expo-status-bar@~1.6.0, expo-system-ui@~2.4.0, expo-web-browser@~12.3.2, jest@^29.2.1, jest-expo@~49.0.0, react@18.2.0, react-dom@18.2.0, react-native@0.72.6, react-native-elements@^3.4.3, react-native-gesture-handler@~2.12.0, react-native-maps@1.7.1, react-native-material-dropdown@^0.11.1, react-native-safe-area-context@4.6.3, react-native-screens@~3.22.0, react-native-web@~0.19.6, react-test-renderer@18.2.0, studio@^0.13.5, typescript@^5.1.3

### Recent commits (newest first)

- Edit readme
- finalized profile screen
- updated alerts screen
- finalized contact mvp
- Add latest react native app
- Merge stable FastAPI backend to main
- Replace with the correct responses for FastAPI
- Spilt up the app even more
- Add example env template
- Seperate out utils
- Get in the linters, clean some stuff
- Finish backend for now
- commit latest changes
- Ensure that the responses have some content
- Upload basic fastapi webserver
- Remove excess print statement
- Upload backend files
- init commit

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

### backend-django-old/requirements.txt

```
django
djangorestframework
markdown
django-filter
psycopg[binary]
django-cockroachdb==4.2.*
python-dotenv
```

### fastapi-backend/requirements.txt

```
hypercorn>=0.14.4
uvicorn[standard]>=0.23.2
orjson>=3.9.10
fastapi>=0.104.0
python-dotenv>=1.0.0
asyncpg>=0.28.0
asyncpg-trek>=0.3.1
shapely>=2.0.2
```

### fastapi-backend/pyproject.toml

```
# All rules based off of Catherine-Chan, Kumiko, and discord.py

[tool.isort]
profile = 'black'
combine_as_imports = true
combine_star = true
line_length = 80

[tool.pyright]
include = ["*.py"]
exclude = [
    "**/__pycache__", 
    "**/.mypy_cache", 
    "**/.dmpypy.json", 
]
reportMissingImports = true
typeCheckingMode = "basic"
reportUnnecessaryTypeIgnoreComment = "warning"

[tool.bandit]
skips = ["B311", "B101"]

[tool.ruff]
ignore = ["E501", "N999", "E402", "S101"]
select = ["E", "F", "N", "ASYNC", "S", "ERA"]
```

### multiNew/package.json

```
{
  "name": "multi",
  "main": "expo-router/entry",
  "version": "1.0.0",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "test": "jest --watchAll"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@emotion/react": "^11.11.1",
    "@emotion/styled": "^11.11.0",
    "@expo/vector-icons": "^13.0.0",
    "@mui/material": "^5.14.15",
    "@react-navigation/native": "^6.0.2",
    "@rneui/themed": "^4.0.0-rc.8",
    "android": "^0.0.8",
    "axios": "^1.6.0",
    "expo": "~49.0.15",
    "expo-font": "~11.4.0",
    "expo-linking": "~5.0.2",
    "expo-router": "^2.0.0",
    "expo-splash-screen": "~0.20.5",
    "expo-status-bar": "~1.6.0",
    "expo-system-ui": "~2.4.0",
    "expo-web-browser": "~12.3.2",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-native": "0.72.6",
    "react-native-elements": "^3.4.3",
    "react-native-gesture-handler": "~2.12.0",
    "react-native-maps": "1.7.1",
    "react-native-material-dropdown": "^0.11.1",
    "react-native-safe-area-context": "4.6.3",
    "react-native-screens": "~3.22.0",
    "react-native-web": "~0.19.6",
    "studio": "^0.13.5"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@types/react": "~18.2.14",
    "jest": "^29.2.1",
    "jest-expo": "~49.0.0",
    "react-test-renderer": "18.2.0",
    "typescript": "^5.1.3"
  },
  "overrides": {
    "react-refresh": "~0.14.0"
  },
  "resolutions": {
    "react-refresh": "~0.14.0"
  },
  "private": true
}

```

### fastapi-backend/main.py

```python
import os
from contextlib import asynccontextmanager
from typing import AsyncIterator

import asyncpg
from dotenv import load_dotenv
from fastapi import FastAPI

from routes import alerts_router, pins_router
from utils import PoolState

load_dotenv()

COCKROACH_URI = os.environ["COCKROACH_URI"]


@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncIterator[PoolState]:
    async with asyncpg.create_pool(dsn=COCKROACH_URI, max_size=25, min_size=25) as pool:
        app.pool_state = {"pool": pool}
        yield app.pool_state


app = FastAPI(lifespan=lifespan)
app.include_router(pins_router)
app.include_router(alerts_router)

```

### multiNew/app/_layout.tsx

```typescript
import FontAwesome from '@expo/vector-icons/FontAwesome';
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
import { useFonts } from 'expo-font';
import { SplashScreen, Stack } from 'expo-router';
import { useEffect } from 'react';
import { useColorScheme } from 'react-native';

export {
  // Catch any errors thrown by the Layout component.
  ErrorBoundary,
} from 'expo-router';

export const unstable_settings = {
  // Ensure that reloading on `/modal` keeps a back button present.
  initialRouteName: '(tabs)',
};

// Prevent the splash screen from auto-hiding before asset loading is complete.
SplashScreen.preventAutoHideAsync();

export default function RootLayout() {
  const [loaded, error] = useFonts({
    SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
    ...FontAwesome.font,
  });

  // Expo Router uses Error Boundaries to catch errors in the navigation tree.
  useEffect(() => {
    if (error) throw error;
  }, [error]);

  useEffect(() => {
    if (loaded) {
      SplashScreen.hideAsync();
    }
  }, [loaded]);

  if (!loaded) {
    return null;
  }

  return <RootLayoutNav />;
}

function RootLayoutNav() {
  const colorScheme = useColorScheme();

  return (
    <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
      <Stack>
        <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
        <Stack.Screen name="modal" options={{ presentation: 'modal' }} />
      </Stack>
    </ThemeProvider>
  );
}

```

### multiNew/app/(tabs)/_layout.tsx

```typescript
import FontAwesome from '@expo/vector-icons/FontAwesome';
import { Link, Tabs } from 'expo-router';
import { Pressable, useColorScheme } from 'react-native';

import Colors from '../../constants/Colors';
import React from 'react';

/**
 * You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
 */
function TabBarIcon(props: {
  name: React.ComponentProps<typeof FontAwesome>['name'];
  color: string;
}) {
  return <FontAwesome size={28} style={{ marginBottom: -3 }} {...props} />;
}

export default function TabLayout() {
  const colorScheme = useColorScheme();

  return (
    <Tabs
      screenOptions={{
        tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
      }}>
      <Tabs.Screen
        name="four"
        options={{
          title: 'Profile',
          tabBarIcon: ({ color }) => <TabBarIcon name="user-circle" color={color} />,
        }}
      />
       <Tabs.Screen
        name="two"
        options={{
          title: 'Alerts',
          tabBarIcon: ({ color }) => <TabBarIcon name="exclamation-triangle" color={color} />,
        }}
      />
      <Tabs.Screen
        name="index"
        options={{
          title: 'Maps',
          tabBarIcon: ({ color }) => <TabBarIcon name="map" color={color} />,
          headerRight: () => (
            <Link href="/modal" asChild>
              <Pressable>
                {({ pressed }) => (
                  <FontAwesome
                    name="info-circle"
                    size={35}
                    color={Colors[colorScheme ?? 'light'].text}
                    style={{ marginRight: 15, opacity: pressed ? 0.5 : 1 }}
                  />
                )}
              </Pressable>
            </Link>
          ),
        }}
      />
      <Tabs.Screen
        name="three"
        options={{
          title: 'Contacts',
          tabBarIcon: ({ color }) => <TabBarIcon name="heart" color={color} />,
        }}
      />
       
    </Tabs>
    
  );
}

```

### multiNew/app/(tabs)/index.tsx

```typescript
import { StyleSheet } from 'react-native';
import EditScreenInfo from '../../components/mainScreenInfo';
import { Text, View } from '../../components/Themed';
import React, { useState } from 'react';
//Map Imports
import MapView, { PROVIDER_GOOGLE } from "react-native-maps";
import {Marker} from 'react-native-maps';


export default function TabOneScreen() {


  return (
    
    <View style={styles.container}>
      <Text style={styles.title}>Maps</Text>
        <MapView 
          provider={PROVIDER_GOOGLE} // Specify Google Maps as the provider
          initialRegion={{
            latitude: 31.189365713577544,
            longitude: 34.81192547178498,
            latitudeDelta: 2.2922,
            longitudeDelta: 2.2421,
          }}
          style={styles.map} >
            <Marker
              coordinate={{ latitude: 31.41856120169955, longitude: 34.78162222467485}}
              title="Wildfire"
              description="Wild fire occuring in Israel. Stay Safe and Avoid Area"
              pinColor="red"
            />
            <Marker
              coordinate={{ latitude: 30.41856120169955, longitude: 35.48162222467485}}
              title="Medical Aid"
              description="Medical Aid provided by blah blah blah organization"
              pinColor="green"
            />
            <Marker
              coordinate={{ latitude:  31.5385, longitude: 34.5368}}
              title="Bombing" 
              description="Stay Away. Area in Critical Condition"
              pinColor="red"
            />
            <Marker
              coordinate={{ latitude:  31.448182743953613, longitude: 34.40736930256567}}
              title="Fire"
              description="Vehicle fire. Stay Cautious"
              pinColor="red"
            />
        </MapView>
        
      <View style={styles.separator} lightColor="#eee" darkColor="rgba(255,255,255,0.1)" />
      <EditScreenInfo path="app/(tabs)/index.tsx" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
   
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
  },
  separator: {
    marginVertical: 30,
    height: 1,
    width: '80%',
  },
  map: {
    width: '100%',
    height: '100%',
  },
});

```

### backend-django-old/test.py

```python
from urllib.parse import urlparse

DATABASE_URI = "postgresql://test:test@localhost:5432/test"

print(urlparse(DATABASE_URI))
```

### multiNew/babel.config.js

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

```

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