Skip to content
Open
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
41 changes: 41 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Deploy API Docs to GitHub Pages
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


on:
push:
branches:
- main
- U1_JP #TODO: remove this branch after testing
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

U1_JP branch is still in the trigger list with a #TODO: remove this branch after testing. Don't forget to pull this out before merging to main.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes will remove before merging in

paths:
- 'docs/**'
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: 'docs'

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
100 changes: 100 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# LocalStack volume data
volume/

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Virtual environments
venv/
ENV/
env/
.venv/

# AWS SAM
.aws-sam/
samconfig.toml.bak
*/build/*

# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
atlassian-ide-plugin.xml
.idea/sonarlint
*.iws

# OS
.DS_Store
Thumbs.db
.AppleDouble
.LSOverride
._*
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
Desktop.ini
$RECYCLE.BIN/
*.lnk

# Logs
*.log

# Environment variables
.env
.env.local

# Testing
.pytest_cache/
.coverage
htmlcov/
.tox/
nosetests.xml
coverage.xml
*.cover
.hypothesis/

# Jupyter Notebook
.ipynb_checkpoints

# Python additional
*.manifest
*.spec
pip-log.txt
pip-delete-this-directory.txt
*.mo
*.pot
.python-version
celerybeat-schedule.*
*.sage.py
.mypy_cache/
.spyderproject
.spyproject
.ropeproject
target/
250 changes: 249 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,249 @@
# CFM_User
# CFM_User

<p align="center">
<a href="https://www.fridgefinder.app/">
<img src="https://raw.githubusercontent.com/CollectiveFocus/CFM_Frontend/dev/public/feedback/happyFridge.svg" height="128">
</a>
<h1 align="center">FridgeFinder User Service</h1>
</p>

<p align="center">
<a aria-label="GitHub Repo stars" href="https://github.com/FridgeFinder/CFM_User/">
<img alt="" src="https://img.shields.io/github/stars/FridgeFinder/CFM_User?style=flat-square&labelColor=F6F6F6">
</a>
<img aria-label="GitHub contributors" alt="GitHub contributors" src="https://img.shields.io/github/contributors/FridgeFinder/CFM_User?style=flat-square&labelColor=F6F6F6">
<img aria-label="GitHub commit activity (dev)" alt="GitHub commit activity (dev)" src="https://img.shields.io/github/commit-activity/m/FridgeFinder/CFM_User/main?style=flat-square&labelColor=F6F6F6">
<a aria-label="Join the community on Discord" href="https://discord.com/channels/955884900655972463/955886184159125534">
<img alt="" src="https://img.shields.io/badge/Join%20the%20community-yellow.svg?style=flat-square&logo=Discord&labelColor=F6F6F6">
</a>
</p>

## Overview

Manages user profiles for FridgeFinder

📖 **[View API Documentation](https://fridgefinder.github.io/CFM_User/)**

---

## Pre-Requisites

1. AWS CLI - [Install the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
* **You DO NOT have to create an AWS account to use AWS CLI for this project, skip these steps if you don't want to create an AWS account**
* AWS CLI looks for credentials when using it, but doesn't validate. So will need to set some fake one. But the region name matters, use any valid region name.
```sh
$ aws configure
$ AWS Access Key ID: [ANYTHING YOU WANT]
$ AWS Secret Access Key: [ANYTHING YOUR HEART DESIRES]
$ Default region nam: us-east-1
$ Default output format [None]: (YOU CAN SKIP)
```
2. SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
* **You DO NOT need to create an aws account to use SAM CLI for this project, skip these steps if you don't want to create an aws account**
* Note: if you are getting the following error: `runtime is not supported` when running `sam build --use-container` make sure your SAM CLI version is up to date
3. Python 3 - [Install Python 3](https://www.python.org/downloads/)
4. Docker - [Install Docker](https://docs.docker.com/get-docker/)

---

## Setup Local Database Connection

**Guide that was used:** https://betterprogramming.pub/how-to-deploy-a-local-serverless-application-with-aws-sam-b7b314c3048c

Follow these steps to get Dynamodb running locally

1. **Start a local DynamoDB service**
```sh
$ docker compose up
# OR if you want to run it in the background:
$ docker compose up -d
```

2. **Create tables**
```sh
$ ./scripts/create_local_dynamodb_tables.py
```

---

## Build and Test Locally

### 1. Build the Application

```sh
cd user-service/
sam build --use-container
```

### 2. Test Health Check Endpoint

```sh
sam local invoke HelloWorldFunction --event events/event.json
```
Expected response: `{"statusCode": 200, "body": "{\"message\": \"hello user service\"}"}`

### 3. Test User Service Functions with Events

**Create a new user:**
```sh
sam local invoke UserServiceFunction \
--event events/create-user.json \
--parameter-overrides \
ParameterKey=DeploymentTarget,ParameterValue=local \
ParameterKey=Stage,ParameterValue=dev \
ParameterKey=FirebaseProjectId,ParameterValue=your-firebase-project-id \
--docker-network cfm-network
```

**Get user profile:**
```sh
sam local invoke UserServiceFunction \
--event events/get-user.json \
--parameter-overrides \
ParameterKey=DeploymentTarget,ParameterValue=local \
ParameterKey=Stage,ParameterValue=dev \
ParameterKey=FirebaseProjectId,ParameterValue=your-firebase-project-id \
--docker-network cfm-network
```

**Get user profile: internal**
```sh
sam local invoke InternalUserServiceFunction \
--event events/internal-get-user.json \
--parameter-overrides \
ParameterKey=DeploymentTarget,ParameterValue=local \
ParameterKey=Stage,ParameterValue=dev \
ParameterKey=FirebaseProjectId,ParameterValue=your-firebase-project-id \
--docker-network cfm-network
```

**Update user profile:**
```sh
sam local invoke UserServiceFunction \
--event events/update-user.json \
--parameter-overrides \
ParameterKey=DeploymentTarget,ParameterValue=local \
ParameterKey=Stage,ParameterValue=dev \
ParameterKey=FirebaseProjectId,ParameterValue=your-firebase-project-id \
--docker-network cfm-network
```

**Test user promotion (Neighbor → Volunteer):**
```sh
sam local invoke UserServiceFunction \
--event events/update-user-promote-steward.json \
--parameter-overrides \
ParameterKey=DeploymentTarget,ParameterValue=local \
ParameterKey=Stage,ParameterValue=dev \
ParameterKey=FirebaseProjectId,ParameterValue=your-firebase-project-id \
--docker-network cfm-network
```

**Test unauthorized access (should return 403):**
```sh
sam local invoke UserServiceFunction \
--event events/unauthorized-access.json \
--parameter-overrides \
ParameterKey=DeploymentTarget,ParameterValue=local \
ParameterKey=Stage,ParameterValue=dev \
ParameterKey=FirebaseProjectId,ParameterValue=your-firebase-project-id \
--docker-network cfm-network
```

**Note:** The `--docker-network cfm-network` flag ensures the Lambda can communicate with LocalStack DynamoDB running in Docker.

---

## Running Unit Tests

Unit tests live in `user-service/tests/unit/` and use `pytest`. They do **not** require Docker, LocalStack, or a running DynamoDB — all AWS calls are mocked.

### 1. Create and activate a virtual environment

```sh
cd user-service/
python3 -m venv .venv
source .venv/bin/activate
```

> To deactivate the virtual environment when you're done, run `deactivate`.

### 2. Install test dependencies

```sh
# From user-service/ with the virtual environment activated
pip install -r tests/requirements.txt
# Also install the layer packages used by the functions
pip install -r functions/user_service/requirements.txt
```

### 3. Run all unit tests

```sh
# From user-service/ with the virtual environment activated
pytest tests/unit/ -v
```

### 4. Run a specific test file

```sh
pytest tests/unit/test_models.py -v
pytest tests/unit/test_service.py -v
pytest tests/unit/test_repository.py -v
pytest tests/unit/test_user_service_handler.py -v
pytest tests/unit/test_internal_user_service.py -v
pytest tests/unit/test_username_check.py -v
pytest tests/unit/test_utils.py -v
```

### 5. Run with coverage

```sh
# Terminal report
pytest tests/unit/ --cov=functions --cov=layers --cov-report=term-missing

# HTML report (opens as htmlcov/index.html)
pytest tests/unit/ --cov=functions --cov=layers --cov-report=html
```

---

## Deploying to AWS

Deployments use `user-service/samconfig_local.toml`, which defines configuration for `dev`, `staging`, and `prod` environments.

> **Before deploying**, replace the placeholder values in `samconfig_local.toml`:
> - `YOUR_STAGING_FIREBASE_PROJECT_ID` — your Firebase project ID for dev/staging
> - `YOUR_PROD_FIREBASE_PROJECT_ID` — your Firebase project ID for production
> - `YOUR_HOSTED_ZONE_ID` — your Route 53 Hosted Zone ID

### 1. Build

```sh
cd user-service/
sam build --use-container
```

### 2. Deploy

```sh
# Deploy to dev
sam deploy --config-env dev --config-file samconfig_local.toml

# Deploy to staging
sam deploy --config-env staging --config-file samconfig_local.toml

# Deploy to production
sam deploy --config-env prod --config-file samconfig_local.toml
```

Each command will show a changeset and prompt for confirmation before applying changes.

---
## Test User Service with local api

1. Edit the code to not check for authenticated user

```sh
sam local start-api --parameter-overrides ParameterKey=FirebaseProjectId,ParameterValue=fakeprojectid ParameterKey=DeploymentTarget,ParameterValue=local ParameterKey=Environment,ParameterValue=dev --docker-network cfm-network
```
Loading
Loading