> ## Documentation Index
> Fetch the complete documentation index at: https://docu.shippil.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview and Setup

Let's start with the big picture: the project structure.

### development files

Open the `backend` folder.
As a Flask developer you will immediately see a familiar pattern:

* a `templates` with your HTML Jinja templates
* our Flask application in `app.py`
* a `requirements.txt` file for our python dependencies
* a `gunicorn_config.py` file which configures our Gunicorn WSGI
* a `Dockerfile` to containarize the application for easier development and deployment
* a `static` folder holding the bundled `.js` and `.css` files, they will be imported in our HTML
* a `serverless.yml` file which defines our IAS (Infrastructure As Code), we will use it later to deploy a Lambda function

### secrets

One thing is missing though: the `.env` file. You will see an `.env.example` file with keys and empty values.
Rename it to `.env.local` and fill it with the according values througout the rest of this documentation. When
you are ready to deploy to production, you will create a `.env` file and copy the info there.

Open `app.py`, you will see that if we run the file locally with `bash local.sh`, we will
use the `.env.local` file, otherwise we use the default `.env` file.

```python app.py theme={null}
if __name__ == "__main__":
    dotenv.load_dotenv(".env.local")
    print("Loading development environment", flush=True)
else:
    dotenv.load_dotenv(".env")
    print("Loading production environment", flush=True)
```

Over the course I will refer to both as the `.env` file, use the one according
to your current stage. At the top of your `.env` file will be a "SECRET\_KEY", used by your Flask application.
Make sure to change to something secure, like a UUID4 from [here](https://www.uuidgenerator.net/version4).

### bundling

Now let's look at the most interesting part: the bundling.
Open `package.json` and take a look at:

```json package.json theme={null}
  "scripts": {
    "watch-js": "node build.mjs",
    "watch-css": "postcss ./src/css/*.css --dir ./backend/static/css --watch",
    "build-css": "postcss ./src/css/*.css --dir ./backend/static/css",
    "watch": "npm-run-all --parallel watch-css watch-js"
  },
```

You can run `watch-css`, `watch-js` or `watch` to watch and bundle the corresponding file types.
As you can see we use PostCSS and a `build.mjs` file to transpile our content from our `src` to our `static` folder.
Open `postcss.config.js`, here you can see the plugins that we use to:

* allow importing other `.css` files
* reduce our bundle size to a minimum
* use modern CSS features while making the bundle usable by legacy browsers

```js postcss.config.js theme={null}
module.exports = {
    plugins: [
        require('postcss-import'),
        require('cssnano')({ // https://github.com/cssnano/cssnano
            preset: 'default',
        }),
        require('postcss-preset-env')({ // https://preset-env.cssdb.org/features/
            stage: 2
        })
    ],
};
```

Now take a look at the `build.mjs` file. Here we loop over each file in our `src/js` directory
and start watching them for changes, when one occurs we create bundle with the same name.

```js build.mjs theme={null}
import * as esbuild from 'esbuild'
import fs from "fs";

const srcDir = "./src/js/"
const distDir = "./backend/static/js/"
const entryPoints = fs.readdirSync(srcDir);
console.log(entryPoints);

for (const entryPoint of entryPoints) {
  if (entryPoint.endsWith(".jsx") || entryPoint.endsWith(".js")) {
    let ctx = await esbuild.context({
      entryPoints: [srcDir + entryPoint],
      outfile: `${distDir}${entryPoint.split('.')[0]}.js`,
      bundle: true,
    });
  
    await ctx.watch();
    console.log(`Watching ${entryPoint}...`);
  } else {
    console.log("Skipping " + entryPoint)
  }
}
```

All of this combined allows you to write advanced JS and CSS and see it in realtime.

### deployment files

Besides the Dockerfile in `backend` we have a few more files, which we will need for deploying our Docker containers in a
provisioned way, for example the `nginx` folder, which holds all the Configuration for our web server.
In the root dir you can see the Dockerfile for that.
When building, Docker copies the static files and serves them through Nginx
instead of our Flask application, since this is more efficient.

Besides that we have a `docker-compose.yml` file, for managing multiple Docker containers and making the communicate.

### Requirements

While developing you will need:

* [Node and NPM](https://nodejs.org/en/download)
* [Python](https://www.python.org/downloads/)
* [Stripe CLI](https://docs.stripe.com/stripe-cli)

For deployment install:

* [Docker](https://docs.docker.com/get-docker/)
* [AWS-CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
* [Serverless CLI](https://www.serverless.com/framework/docs-getting-started)

### Running the application

Once we are done with configuration, you will have two choices to start the app:

* WHEN WORKING LOCALLY: `bash local.sh` will start a local (!DEVELOPMENT!) server which listens on Port 8080
  or
* WHEN DEPLOYING: `bash docker.sh` will run the same application with a propper WSGI and
  a production-ready Nginx web-server

Before we can do that, there is just a bit more configuration to do:

* Setup and connect our database
* Configure Stripe
* Create an OAuth application for authentification
* setup emails

Continue reading the next section to learn how to do this
