Skip to content

Commit

Permalink
Merge pull request #50 from n30w/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
n30w authored May 13, 2024
2 parents c457617 + cb5d96a commit 60b5328
Show file tree
Hide file tree
Showing 114 changed files with 13,814 additions and 1,412 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ frontend/next-env.d.ts

# Jetbrains IDE
/.idea
backend/.env

# testing
backend/resources/test
84 changes: 71 additions & 13 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,73 @@
{
"cSpell.words": [
"cmds",
"coursepage",
"corepack",
"Darkspace",
"healthcheck",
"idnum",
"Lihua",
"netid",
"Taskfile",
"taskfiles",
"Vercel"
]
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
},
"[css]": {
"editor.defaultFormatter": "vscode.css-language-features",
"editor.formatOnSave": true,
"editor.suggest.insertMode": "replace",
"cSpell.fixSpellingWithRenameProvider": false
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": false,
},
"go.toolsManagement.autoUpdate": true,
"[go]": {
"editor.insertSpaces": false,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
},
"editor.defaultFormatter": "golang.go"
},
"[markdown]": {
"editor.unicodeHighlight.ambiguousCharacters": false,
"editor.unicodeHighlight.invisibleCharacters": false,
"editor.wordWrap": "on",
"editor.quickSuggestions": {
"comments": "off",
"strings": "off",
"other": "off"
}
},
"git.autofetch": true,
"editor.formatOnSave": true,
"cSpell.words": [
"cmds",
"corepack",
"courseid",
"coursepage",
"Darkspace",
"dbname",
"excelize",
"godotenv",
"healthcheck",
"idnum",
"Lihua",
"netid",
"realip",
"sslmode",
"Taskfile",
"taskfiles",
"userid",
"Vercel"
]
}
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ We are using ```yarn``` and NOT npm.
Our database for the backend is SQL based.

- Go
- Gin
- pq
- Postgresql
- Nginx
Expand All @@ -84,6 +83,18 @@ The backend directory is structured in this manner:

```remote``` contains Docker files and anything needed for deployment purposes, like setup scripts.

#### Understanding the Backend **internal** Package

```internal``` has three packages inside it:

- dal
- domain
- models

```dal``` stands for Data Access Layer, and is what directly interfaces with any database implementation. ```domain``` contains services that interface with the ```dal``` package.

#### Authentication vs Authorization

## Getting Started

This project uses [Taskfile](https://taskfile.dev) as a Makefile replacement. This is used to run tests and synchronize docker containers. Unless specified otherwise, all task commands must be run in the root directory of the project.
Expand All @@ -104,6 +115,21 @@ There are several types of tasks, some of which are ```dev```, ```build```, ```t

The frontend exists at http://localhost:3000/ and the backend exists at http://localhost:6789/api/v1/

#### PostgreSQL Docker Database

To connect directly to the database from the command-line, run the command: ```psql postgresql://{username}:{password}@{host}:{port}/{database name}```. The parameters in brackets are for you to set.

A ```compose.yaml``` file exists in backend/remote, which defines a backend docker compose structure for the API and the PostgreSQL database. To run the database, execute ```task back:db-up``` in the root directory.

To access the running container from the command line, do these series of steps:

1. Run ```docker ps``` to see running containers' IDs. Find the entry for the container named ```db-postgres```.
2. If our container's ID was abcdef1234, run the command ```docker exec -it abdef1234 bash``` to enter the container's shell environment.
3. In the shell, enter the command ```su postgres``` to change the current user from root to postgres. Postgres cannot be accessed from root.
4. Now enter ```psql -U postgres```. This lets us into the postgresql command line environment. You can now execute psql commands.

To exit out of this environment, type ```exit```.

## Testing

We must implement endpoint testing.
Expand All @@ -117,20 +143,32 @@ We must implement endpoint testing.
- [Setting up and using postgresql on Mac](https://www.sqlshack.com/setting-up-a-postgresql-database-on-mac/)
- [Setting postgresql on Windows](https://www.prisma.io/dataguide/postgresql/setting-up-a-local-postgresql-database#setting-up-postgresql-on-windows)

### Go

- [Connecting to postgresql database](https://www.calhoun.io/connecting-to-a-postgresql-database-with-gos-database-sql-package/)

### Postgresql

- [Tuning postgresql for memory](https://www.enterprisedb.com/postgres-tutorials/how-tune-postgresql-memory)
- [Postgresql tuner webapp](https://pgtune.leopard.in.ua/)
- [How to Create an identity column in Postgres](https://www.commandprompt.com/education/how-do-i-create-an-identity-column-in-postgresql/)

### Docker

- [Running postgresql in a Docker container](https://www.docker.com/blog/how-to-use-the-postgres-docker-official-image/)
- [Golang-Nginx-Postgres Docker Compose](https://github.com/docker/awesome-compose/tree/master/nginx-golang-postgres)
- [Init script for docker postgres](https://mkyong.com/docker/how-to-run-an-init-script-for-docker-postgres/)
- [Custom dockerfile for postgres container](https://forums.docker.com/t/how-to-make-a-docker-file-for-your-own-postgres-container/126526/8)
- [Docker compose env file](https://www.warp.dev/terminus/docker-compose-env-file)

- [Docker credential desktop - executable not found in PATH](https://blog.saintmalik.me/docs/docker-credential-desktop/)
- As the article states: just edit your ~/.docker/config.json and remove the "credsStore" : "desktop" and leave the "credStore" : "desktop"

## Ideas

- Invite students through link or code
- Need auth for API routes
- Need to clarify what specific elements the frontend needs after calling API endpoints

## Glossary

Expand Down
12 changes: 12 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ tasks:
test:
cmds:
- task back:test
- task front:test

# Starts dev servers for both frontend and backend
dev:
Expand All @@ -28,3 +29,14 @@ tasks:
cmds:
- task front:install
- task back:tidy

# DB up
dbu:
cmds:
- task back:db-up -s
dbd:
cmds:
- task back:db-down
dbdc:
cmds:
- task back:db-down-clean
50 changes: 50 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# ======================================================================= #
# Storage Environment Variables #
# ======================================================================= #

# LOCAL_STORAGE_DIRECTORY is the directory where the server will store
# local files, such as media, data, or templates.
LOCAL_STORAGE_DIRECTORY=

# S3_TOKEN and S3_URL are both used to access a remote S3 object storage
# hosted by Amazon.
S3_TOKEN=
S3_URL=

# EXCEL_TEMPLATE_PATH is the path of the excel template
EXCEL_TEMPLATE_PATH=

# ======================================================================= #
# Postgresql Environment Variables #
# ======================================================================= #

# DB_NAME is the name of the database in the postgresql instance.
# This will be used to connect to a database named "development".
# In a production environment, this would be different, according to
# the deployment name, whatever that may be.
DB_NAME=development

# The postgresql image requires a set username and password to setup.
# Therefore, these are required if running development locally. They can
# be anything one wishes. In production environments though, its necessary
# to use the actual credentials that will be used to connect to the
# database.
DB_USERNAME=
DB_PASSWORD=

# DB_HOST will usually be "localhost" in a development environment.
# The port may also be arbitrary. The port is the one on the host
# that docker will bind the container's port to. Sometimes, your
# machine might already have an instance of postgresql running without
# docker. Postgresql's default port is 5432. The example here sets the
# DB_PORT to 6543 to avoid this port collision.
DB_HOST=localhost
DB_PORT=6543

# This is a field that disables SSL mode to remove the error:
# "SSL is not enabled on this server/database" during development.
# In a production environment, this would be enabled.
DB_SSL_MODE=disable

# URL Example
DB_DSN="postgres://postgres:password@localhost:6543/development"
82 changes: 82 additions & 0 deletions backend/cmd/api/application.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package main

import (
"context"
"database/sql"
"github.com/n30w/Darkspace/internal/dal"
"log"
"time"

"github.com/n30w/Darkspace/internal/domain"

// This import fixes the error: "unknown driver "postgres" (forgotten import?)"
_ "github.com/lib/pq"
)

type config struct {
// Port the server will run on.
port int

// Runtime environment, either "development", "staging", or "production".
env string

// Database configurations
db dal.DBConfig

// limiter is limiter information for rate limiting.
limiter struct {
// rps is requests per second.
rps float64
burst int

// enabled either disables or enables rate limiting altogether.
enabled bool
}
}

// openDB opens a connection to the database using a certain config.
func openDB(cfg config) (*sql.DB, error) {
db, err := sql.Open(cfg.db.Driver, cfg.createDataSourceName())
if err != nil {
return nil, err
}

// Passing a value less than or equal to 0 means no limit.
db.SetMaxOpenConns(cfg.db.MaxOpenConns)

// Passing a value less than or equal to 0 means no limit.
db.SetMaxIdleConns(cfg.db.MaxIdleConns)

duration, err := time.ParseDuration(cfg.db.MaxIdleTime)
if err != nil {
return nil, err
}

db.SetConnMaxIdleTime(duration)

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

err = db.PingContext(ctx)
if err != nil {
return nil, err
}

return db, nil
}

// createDataSourceName creates the dataSourceName parameter of the
// sql.Open function.
func (cfg config) createDataSourceName() string {
return cfg.db.CreateDataSourceName()
}

func (cfg config) SetFromEnv() {
cfg.db.SetFromEnv()
}

type application struct {
config config
logger *log.Logger
services *domain.Service
}
28 changes: 28 additions & 0 deletions backend/cmd/api/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import (
"context"
"github.com/n30w/Darkspace/internal/models"
"net/http"
)

type contextKey string

const userContextKey = contextKey("user")

func (app *application) contextSetUser(
r *http.Request,
user *models.User,
) *http.Request {
ctx := context.WithValue(r.Context(), userContextKey, user)
return r.WithContext(ctx)
}

func (app *application) contextGetUser(r *http.Request) *models.User {
user, ok := r.Context().Value(userContextKey).(*models.User)
if !ok {
panic("missing user value in request context")
}

return user
}
Loading

0 comments on commit 60b5328

Please sign in to comment.