Skip to content

Commit

Permalink
Merge pull request #1 from temirovazat/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
temirovazat authored Nov 16, 2023
2 parents 50f08d1 + 12762f4 commit 8ef532e
Show file tree
Hide file tree
Showing 42 changed files with 2,465 additions and 1 deletion.
47 changes: 47 additions & 0 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: referral-api

on:
push:
branches:
- develop
- main
pull_request:
branches:
- develop
- main

jobs:
isort:
name: Sorting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Install Python
uses: actions/setup-python@v2
with:
python-version: "3.9"

- name: Install isort
run: pip install isort

- name: Run isort
run: isort --check src


flake8:
name: Linter
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Install Python
uses: actions/setup-python@v2
with:
python-version: "3.9"

- name: Install flake8
run: pip install flake8

- name: Run flake8
run: flake8 src --count --statistics --show-source
32 changes: 32 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: check-added-large-files
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- id: check-merge-conflict
- id: mixed-line-ending
args: [--fix=lf]
- id: no-commit-to-branch
args: [--branch, master, --branch, main]
- id: name-tests-test

- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
args: [--settings, setup.cfg]

- repo: https://github.com/pycqa/flake8
rev: 5.0.4
hooks:
- id: flake8
additional_dependencies:
- flake8-docstrings
- pep8-naming
- flake8-broken-line
- flake8-return
args: [--config, setup.cfg]
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM python:3.9.17-slim

WORKDIR /app

COPY /src /app/

COPY pyproject.toml poetry.lock ./

RUN pip3 install poetry

RUN poetry config virtualenvs.create false

RUN poetry install
78 changes: 77 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,77 @@
# referral-api
# Referral API

API service with phone number authentication and a simple referral system.

## Project Structure and Description

### Phone Number Authentication

Authentication in the service is based on the phone number format "+79608543017".

To start, obtain a 4-digit code by sending a POST request with the phone number to the `POST /api/v1/auth/send_code/` endpoint.

Once the code is received, submit it along with the phone number to the `POST /api/v1/auth/jwt/get_by_phone/` endpoint. Optionally, you can include an existing referral code from another user along with the phone number and 4-digit code.

If a user with the specified phone number does not exist, they are added to the database. After addition, the user is assigned a unique referral invite code.

Upon successful authentication, the response includes JWT access/refresh tokens (bearer auth). These tokens will be needed for accessing user endpoints and profile editing. Standard endpoints for token verification and refresh are also available: `POST /api/v1/auth/jwt/verify/`, `POST /api/v1/auth/jwt/refresh/`.

### Users

- `GET /api/v1/users/`: View the list of users. The `invite_code` field is the user's personal referral code, unique and assigned during user creation. The `invited_by_code` field is the referral code of another user who invited them to the service.

- `GET /api/v1/users/{id}/`: Retrieve information about a specific user.

- `GET /api/v1/users/current_user/`: Retrieve information about the current user.

On endpoints providing information about a specific/current user, there is an `invited` field with a list of user IDs and phone numbers who accepted the invitation from the viewed user.

- `PATCH /api/v1/users/current_user/`: Edit information about the current user. You can set the user's name, surname, email address, and the invite code through which they received the service invitation.

### **How to run the project:**

Clone the repository and navigate to the ```/infra ``` directory:

```bash
git clone https://github.com/temirovazat/referral-api.git
```
```
cd referral-api/infra/
```

Create a .env file and add project settings:

```bash
vi .env
```

```
# PostgreSQL
DB_ENGINE=django.db.backends.postgresql
DB_NAME=referral_db
DB_USER=postgres
DB_PASSWORD=postgres
DB_HOST=db
DB_PORT=5432
# Django
SECRET_KEY=django-insecure-szpgqvuswh#lxmzs1#l@t_meqr#l-qceo#f+zm#u5a2@w@3v9#
DEBUG=False
# Authentication
AUTH_CODE_EXPIRES_MINUTES=30
REFRESH_TOKEN_LIFETIME_DAYS=14
ACCESS_TOKEN_LIFETIME_MINUTES=600
```

Deploy and run the project in containers:

```bash
docker compose up -d
```

Creating a superuser:

```bash
docker compose exec ref-web python manage.py createsuperuser
```
16 changes: 16 additions & 0 deletions infra/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# PostgreSQL
DB_ENGINE=django.db.backends.postgresql
DB_NAME=referral_db
DB_USER=postgres
DB_PASSWORD=postgres
DB_HOST=db
DB_PORT=5432

# Django
SECRET_KEY=django-insecure-szpgqvuswh#lxmzs1#l@t_meqr#l-qceo#f+zm#u5a2@w@3v9#
DEBUG=False

# Authentication
AUTH_CODE_EXPIRES_MINUTES=30
REFRESH_TOKEN_LIFETIME_DAYS=14
ACCESS_TOKEN_LIFETIME_MINUTES=600
45 changes: 45 additions & 0 deletions infra/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
version: '3.8'

services:
db:
image: postgres:alpine
container_name: ref-postgres15
environment:
POSTGRES_PASSWORD: $DB_PASSWORD
POSTGRES_USER: $DB_USER
POSTGRES_DB: $DB_NAME
volumes:
- postgres:/var/lib/postgresql/data/
ports:
- "5432:5432"
restart: always

web:
container_name: ref-web
build: ../
restart: always
command: >
/bin/sh -c "poetry run python manage.py migrate --noinput
&& poetry run python manage.py collectstatic --noinput
&& poetry run gunicorn config.wsgi:application --bind 0.0.0.0:8000"
volumes:
- static:/app/static/
depends_on:
- db
env_file:
- ./.env

nginx:
container_name: ref-nginx
image: nginx:1.21.3-alpine
ports:
- 80:80
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- static:/var/html/static/
depends_on:
- web

volumes:
static:
postgres:
26 changes: 26 additions & 0 deletions infra/nginx/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
server {
listen 80;
client_max_body_size 4M;

server_name 127.0.0.1;
server_tokens off;

location /static/ {
root /var/html/;
}

location / {
proxy_pass http://web:8000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Referrer $http_referer;
proxy_set_header Referer $http_referer;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Loading

0 comments on commit 8ef532e

Please sign in to comment.