Skip to content

Commit

Permalink
Update README
Browse files Browse the repository at this point in the history
  • Loading branch information
roperi committed Dec 9, 2023
1 parent 3166a19 commit e375a07
Showing 1 changed file with 375 additions and 0 deletions.
375 changes: 375 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,379 @@



https://github.com/roperi/yasaas/assets/9901508/f7d47c5d-953f-49aa-bade-41fe3aee13f9


<h1 align="center">YaSaaS - Monetize your data</h1>
<h2 align="center">Open-source Django REST Framework + React SaaS Boilerplate</h2>

---

Yasaas is an open-source SaaS boilerplate built on Django REST Framework and React, offering a flexible foundation for entrepreneurs looking to monetize their data.

With seamless integration of Stripe subscriptions and leveraging Django admin functionalities, Yasaas simplifies the process of selling various data products. Whether it's financial data, market insights, or custom datasets, Yasaas provides a practical starting point for individuals keen on exploring data monetization.

As an open-source solution, Yasaas is freely available, making it accessible for those who want to kickstart their data-driven ventures.


### Rationale: Or why YaSaas uses Django Admin for end-users

Yasaas leverages Django's robust permission system, utilizing Groups and User permissions for precise data access control. In Django, a Group is a collection of Users, and permissions can be assigned to both Users and Groups. Yasaas utilizes Django admin's intuitive interface to manage these permissions effectively.

Entrepreneurs can create Groups representing different roles or access levels within their application. For example, a "Data Access" Group can be defined. Within this Group, specific permissions related to data access are assigned, ensuring that only authorized users can view or modify sensitive data.

By giving staff privileges to end-users and associating them with relevant Groups, Yasaas provides a flexible and secure way to control access to valuable data. This approach ensures that each user, based on their role or responsibilities, has precisely defined permissions, aligning with the principle of least privilege. This technical foundation empowers entrepreneurs to tailor access controls according to their specific data product offerings.

---



## Features

* Authentication and authorization: User signup, login, logout, email verification, account management, social login support.
* Subscription: Set up plans and collect recurring payments with Stripe.
* Admin panel
* Emails
* Admin dashboard to edit data
* Others: Contact form
* Light/dark mode


---

## Tech stack
### Front-end stack
* React 18
* Typescript 4
* Material UI 5

### Backend stack
* Django 4
* Django Rest Framework 3

### Third-party
* Stripe
* AWS Simple Email Service
* Google Analytics

---

### Prerequisites

Install the following prerequisites:

1. [Python 3.8, 3.9, 3.10 or 3.11](https://www.python.org/downloads/)
<br> This project uses **Django v4.2.4**. For Django to work, you must install a correct version of Python on your machine. More information [here](https://django.readthedocs.io/en/stable/faq/install.html).
2. [Node.js](https://nodejs.org/en/)
3. [Visual Studio Code](https://code.visualstudio.com/download) (Windows)
---

### Installation

#### Backend

#### 1. Create a virtual environment

From the **root** directory, run:

```bash
cd backend
```
```bash
python -m venv venv
# or
virtualenv -p python3.8 ~/.virtualenvs/yasaas # Example using python3.8.
```

#### 2. Activate the virtual environment

From the **backend** directory, run:

On macOS:

```bash
source venv/bin/activate
```

On Windows:

```bash
venv\scripts\activate
```

#### 3. Install required backend dependencies

From the **backend** directory, run:

```bash
pip install -r requirements.txt
```

#### 4. Run migrations

From the **backend** directory, run:

```bash
python manage.py makemigrations
```
```bash
python manage.py migrate
```

#### 5. Create an admin user to access the Django Admin interface

From the **backend** directory, run:

```bash
python manage.py createsuperuser
```

When prompted, enter a username, email, and password.

#### Frontend

#### 1. Install required frontend dependencies

From the **root** directory, run:

```bash
cd frontend
```
```bash
npm install
```

### Run the application

To run the application, you need to have both the backend and the frontend up and running.

#### 1. Run backend

From the **backend** directory, run:

```bash
python manage.py runserver
```

#### 2. Run frontend

From the **frontend** directory, run:

```bash
npm start
```

#### 3. View the application

Go to http://localhost:3000/ to view the application.

### Add data to the application

Add data through Django Admin.

Go to http://127.0.0.1:8000/admin to access the Django Admin interface and sign in using the admin credentials.

### Customize the application

This section describes how to customize the application.

#### Changing Section Titles and Subtitles

#### 1. Products

To modify the title and subtitle of the **Products** section, make changes in the ```frontend/src/components/Products.tsx``` file.

#### 2. Services

To modify the title and subtitle of the **Services** section, make changes in the ```frontend/src/components/Services.tsx``` file.

#### 3. Pricing

To modify the title and subtitle of the **Pricing** section, make changes in the ```frontend/src/components/Pricing.tsx``` file.

#### 4. About

To modify the title and subtitle of the **About** section, make changes in the ```frontend/src/components/About.tsx``` file.

#### 5. Contact

To modify the title and subtitle of the **Contact** section, make changes in the ```frontend/src/components/Contact.tsx``` file.

#### Changing Colors

To modify the colors in the application, make changes in the ```frontend/src/theme/palette.ts``` file.

#### Changing Fonts

To modify the fonts in the application, first, add a new font to the ```frontend/public/index.html``` file, and then make changes in the ```frontend/src/theme/theme.ts``` file.

#### Changing Logo

To modify the logo in the application, make changes in the ```frontend/src/layout/Header.tsx``` and ```frontend/src/layout/Sidebar.tsx``` files.

#### Changing Buttons in the Hero Section

To modify the two buttons in the Hero section, make changes in the ```frontend/src/components/HeroButtons.tsx``` file.


### Configurations

1. Append to the virtual environment file you created above (either `~/.virtualenvs/yasaas/bin/activate`, `venv/bin/activate`, or `venv\scripts\activate`). Make sure to put your own Stripe and AWS keys.
```
# Django
export DJANGO_SECRET_KEY='YOUR-DJANGO-SECRET-KEY'
# Stripe
export STRIPE_PUBLISHABLE_KEY='YOUR-STRIPE-PUBLISHABLE-KEY'
export STRIPE_SECRET_KEY='YOUR-STRIPE-SECRET-KEY'
export STRIPE_ENDPOINT_SECRET='YOUR-STRIPE-ENDPOINT-SECRET'
export STRIPE_CUSTOMER_PORTAL_LINK=https://billing.stripe.com/p/login/test_YOUR-CUSTOMER-PORTAL-ID
export STRIPE_PRICING_TABLE_ID='YOUR-STRIPE-PRICING-TABLE-ID'
# AWS Email
export AWS_SES_ACCESS_KEY_ID='YOUR-SES-ACCESS-KEY' # You can also use the AWS access key
export AWS_SES_SECRET_ACCESS_KEY='YOUR-SES-SECRET-ACCESS-KEY' # You can also use the AWS Secret Key
```

2. As for the frontend, create a `.env` file to hold the env variables used by React in the frontend and put the following in it (put your Stripe keys). Save it on the frontend root folder (i.e. `frontend/.env`).
```
REACT_APP_BASE_URL=http://127.0.0.1:8000/
REACT_APP_REDIRECT_SIGNUP_URL=http://127.0.0.1:8000/accounts/signup
REACT_APP_DASHBOARD_URL=http://localhost:8000/
REACT_APP_SITE_URL=http://localhost:3000/
REACT_APP_PUBLISHABLE_KEY='YOUR-STRIPE-PUBLISHABLE-KEY'
REACT_APP_PRICING_TABLE_ID='YOUR-STRIPE-PRICING-TABLE-ID'
```

3. Update Google-Analytics references

Update the following three files located in the frontend folder and put your Google Measurement ID in each of them.
```
# frontend/public/index.html
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=YOUR-GOOGLE-MEASUREMENT-ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'YOUR-GOOGLE-MEASUREMENT-ID');
# src/App.tsx
ReactGA.initialize('YOUR-GOOGLE-ANALYTICS-MEASUREMENT-ID');
# src/index.tsx
ReactGA.initialize('YOUR-GOOGLE-ANALYTICS-MEASUREMENT-ID');
```

4. Customise Django Admin with Jazzmin
* Jazzmin spices up the "ugly" Django Admin styles.
* Some configurations were already applied in YaSaas (see bottom of `backend/settings.py` file).
* See [Django Jazzmin](https://django-jazzmin.readthedocs.io/) for further customisation.

5. Customising django-allauth
* django-allauth is an integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication
* Already installed and working in YaSaas.
* See [Django All-auth docs](https://docs.allauth.org/en/latest/account/configuration.html) for further customisation.

6. Styling the Django-allauth templates with django-auth-style
* All django-allauth rendered templates will automatically be overridden with styled alternatives.
* Already installed and working in YaSaas.
* For further customisation see [Django-auth-style](https://github.com/girder/django-auth-style)

7. Update `backend/settings.py` to your liking.
```
# CUSTOM TITLES AND HEADERS
INDEX_TITLE = "Data Dynamo"
SITE_TITLE = "API Portal"
SITE_HEADER = "Data Dynamo API"
```

8. Update the title tag in `frontend/public/index.html` to your liking.
```
<title>Data Dynamo</title>
```

9. In the `frontend/public/` folder update the favicon.ico and logo.svg with your own ones.

```
# frontend/public/img/logo.svg
# frontend/public/favicon.ico
```

### Stripe Subscriptions Workflow (see video at the top)
1. User clicks on a place-holder pricing table in homepage
2. User gets redirected to a signup page to give email, username and password.
3. User gets redirected to another page holding Stripe's pricing table
4. User selects a subscription plan
5. User gets redirected to a Stripe checkout page
6. User pays - Stripe will send us a checkout event and our event handler will give staff status and grant Group permission to the user).
7. User gets redirected to Django admin interface already logged-in as staff and with Group permission to see his or her data.
8. User's subscription ends - Stripe will send an event telling us the subscription is over and our handler will then revoke user's staff and group permissions.

_IMPORTANT_: The reason why there's place-holder pricing table in the homepage, and not the proper Stripe's pricing table in the homepage is to force the user to a signup page in order to get their user ID which Stripe pricing table script requires (in our case we use the ID from the newly registered user). If we don't do this the user will end up paying as anonymous and he or she will end up in some sort of limbo and YaSaas won't be able to grant staff or Group permissions to the user.


### Stripe webhooks for local development

* Install stripe client (linux)
```
cd ~/opt
wget https://github.com/stripe/stripe-cli/releases/download/v1.18.0/stripe_1.18.0_linux_x86_64.tar.gz
tar -xvf stripe_1.18.0_linux_x86_64.tar.gz
mv stripe /usr/local/bin
```

* In order to test the Stripe webhook we need to open up our computer to listen for Stripe events. In terminal execute the following:

```
stripe listen --forward-to localhost:8000/webhook
```

* All the logic related to handling Stripe events is in the `backend/subscriptions/views.py` module. The most basic events are already being handled by YaSaas (like `checkout.session.completed` or `customer.subscription.deleted`). Please feel free to expand the if/else clauses to handle your specific use-cases (there are tons of events!).

### Structure your Stripe subscription plans around Django Groups and User models
This is the most crucial aspect for monetising your data using Django Admin. YaSaas leverages the Django Admin to provide access to end-users as staff members with Group privileges. That way you can group users based on how much data access you want to give them. For instance, a subscription named "Basic Plan" might give a user permission to view a single table. Whereas a subscription named "Premium Level" might give a user permission to view multiple tables.

Things to consider:

* In Stripe lingo Pricing Tables are made up Products. Say, your Pricing Table "A" contains three products: "Basic Plan", "Advanced Plan" and "Premium Plan".
* YaSaas gives end-users staff privileges otherwise they won't be able to access Django Admin. End-users will be able to enter the Django Admin interface but they will only be able to view whatever you give them permission to view.
* __Make sure to name your Django User Groups exactly as your Stripe subscription plan's products__
* For instance, if you name the Product in your plan as "Basic Plan" then your User Group must be named "Basic Plan" too.
* Review the following code to make sure you understand how Staff and Group permissions are granted to the user after he/she pays:

```
## Excerpt from backend/subscriptions/views.py
...
product_name = stripe.Product.retrieve(subscription.plan.product).name
# Add Group to user
logger.info(f'Adding {user.username} (user #{user.id}) to Group `{product_name}`')
user.groups.add(Group.objects.get(name=product_name))
# Add staff status to user
logger.info(f'Granting {user.username} (user #{user.id}) with staff status')
user.is_staff = True
user.save()
...
```


### Deployment

To deploy you could use Nginx, Gunicorn and Django in tandem.


### TODO
* Expand more on the Stripe subscriptions topic.
* Expand deployment section.s
* Adding an email confirmation page
---


### Copyright and licences
Copyright © 2022 Bob's Programming Academy. MIT Licence.

Copyright © 2023 Roperi. MIT Licence.

0 comments on commit e375a07

Please sign in to comment.