Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change favicon and title #32

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 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
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=securing-safe-food
DATABASE_USERNAME=postgres
DATABASE_PASSWORD=PLACEHOLDER_PASSWORD
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ Thumbs.db
# Environment file
*.env
*.env.*
!.env.example
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
# Scaffolding
# Securing Safe Food

<a alt="Nx logo" href="https://nx.dev" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-logo.png" width="45"></a>

✨ **This workspace has been generated by [Nx, a Smart, fast and extensible build system.](https://nx.dev)** ✨

## Environment Setup

Install app dependencies by running this at the repo root (`ssf`)

```
yarn install
```

To setup your backend, follow the backend-specific instructions [here](apps/backend/README.md)

*Note: you may need to prefix your `nx` commands with `npx`. For example, to serve the frontend, if:
```
nx serve frontend
```

doesn't work, try:

```
npx nx serve frontend
```

## Start the app

To start the development server run `nx serve frontend`. Open your browser and navigate to http://localhost:4200/. Happy coding!
Expand Down
28 changes: 28 additions & 0 deletions apps/backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Backend Setup

This part can be a little tricky! If you run into some confusing errors along the way, don't be afraid to reach out if have any trouble!

You'll need to download:

1. [PostgreSQL](https://www.postgresql.org/download/)
2. [PgAdmin 4](https://www.pgadmin.org/download/) (if PostgreSQL didn't come with it)

Then, set up a database called `securing-safe-food`. If you're not familiar with how to do so, it's easy to do through PgAdmin

1. Open PgAdmin and configure your credentials (if necessary). Then, right click on the `Databases` dropdown (under `Servers` > `PostgreSQL [version]`)

![alt text](resources/pg-setup-1.png)

2. Enter "securing-safe-food" as the database name

![alt text](resources/pg-setup-2.png)

Next, create a file called `.env` in the **root directory** (under `ssf/`) and copy over the contents from `.env.example`. Replace `DATABASE_PASSWORD` with the password you entered for the `postgres` user (NOT necessarily your PgAdmin master password!)

You can check that your database connection details are correct by running `nx serve backend` - if you can see the following line in the terminal, then you've got it right!

```
"LOG 🚀 Application is running on: http://localhost:3000/api"
```

Finally, run `yarn run typeorm:migrate` to load all the tables into your database. If everything is set up correctly, you should see "Migration ... has been executed successfully." in the terminal.
Binary file added apps/backend/resources/pg-setup-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/backend/resources/pg-setup-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 11 additions & 13 deletions apps/backend/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,20 @@ import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { AuthModule } from './auth/auth.module';
import { PluralNamingStrategy } from './strategies/plural-naming.strategy';
import { ConfigModule, ConfigService } from '@nestjs/config';
import typeorm from './config/typeorm';

@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mongodb',
host: '127.0.0.1',
port: 27017,
database: 'c4cOpsTest',
// username: 'root',
// password: 'root',
autoLoadEntities: true,
// entities: [join(__dirname, '**/**.entity.{ts,js}')],
// Setting synchronize: true shouldn't be used in production - otherwise you can lose production data
synchronize: true,
namingStrategy: new PluralNamingStrategy(),
ConfigModule.forRoot({
isGlobal: true,
load: [typeorm],
}),
// Load TypeORM config async so we can target the config file (config/typeorm.ts) for migrations
TypeOrmModule.forRootAsync({
inject: [ConfigService],
useFactory: async (configService: ConfigService) =>
configService.get('typeorm'),
}),
UsersModule,
AuthModule,
Expand Down
23 changes: 23 additions & 0 deletions apps/backend/src/config/typeorm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { registerAs } from '@nestjs/config';
import { PluralNamingStrategy } from '../strategies/plural-naming.strategy';
import { DataSource, DataSourceOptions } from 'typeorm';
import { User1725726359198 } from '../migrations/1725726359198-User';
import { AddTables1726524792261 } from '../migrations/1726524792261-addTables';

const config = {
type: 'postgres',
host: `${process.env.DATABASE_HOST}`,
port: parseInt(`${process.env.DATABASE_PORT}`, 10),
database: `${process.env.DATABASE_NAME}`,
username: `${process.env.DATABASE_USERNAME}`,
password: `${process.env.DATABASE_PASSWORD}`,
autoLoadEntities: true,
synchronize: false,
namingStrategy: new PluralNamingStrategy(),
// Glob patterns (e.g. ../migrations/**.ts) are deprecated, so we have to manually specify each migration
// TODO: see if there's still a way to dynamically load all migrations
migrations: [User1725726359198, AddTables1726524792261],
};

export default registerAs('typeorm', () => config);
export const connectionSource = new DataSource(config as DataSourceOptions);
19 changes: 19 additions & 0 deletions apps/backend/src/migrations/1725726359198-User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class User1725726359198 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
status VARCHAR(20),
first_name VARCHAR(255),
last_name VARCHAR(255),
email VARCHAR(255)
)`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE IF EXISTS users`);
}
}
39 changes: 39 additions & 0 deletions apps/backend/src/migrations/1726524792261-addTables.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddTables1726524792261 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS pantries (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
address VARCHAR(255) NOT NULL,
approved BOOLEAN NOT NULL,
ssf_representative_id INT NOT NULL,
pantry_representative_id INT NOT NULL,
restrictions TEXT[] NOT NULL,

CONSTRAINT fk_ssf_representative_id FOREIGN KEY(ssf_representative_id) REFERENCES users(id),
CONSTRAINT fk_pantry_representative_id FOREIGN KEY(pantry_representative_id) REFERENCES users(id)
);

CREATE TABLE IF NOT EXISTS donations (
id SERIAL PRIMARY KEY,
restrictions TEXT[] NOT NULL,
due_date TIMESTAMP NOT NULL,
pantry_id INT NOT NULL,
status VARCHAR(50) NOT NULL,
feedback TEXT,
contents TEXT NOT NULL,

CONSTRAINT fk_pantry_id FOREIGN KEY(pantry_id) REFERENCES pantries(id)
);
`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DROP TABLE IF EXISTS pantries; DROP TABLE IF EXISTS donations;`,
);
}
}
26 changes: 7 additions & 19 deletions apps/backend/src/strategies/plural-naming.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
import { DefaultNamingStrategy, NamingStrategyInterface } from 'typeorm';
import { SnakeNamingStrategy } from 'typeorm-naming-strategies';

export class PluralNamingStrategy
extends DefaultNamingStrategy
implements NamingStrategyInterface
{
tableName(targetName: string, userSpecifiedName: string | undefined): string {
return userSpecifiedName || targetName.toLowerCase() + 's'; // Pluralize the table name
}

columnName(
propertyName: string,
customName: string,
embeddedPrefixes: string[],
): string {
return propertyName;
}

relationName(propertyName: string): string {
return propertyName;
// Extend SnakeNamingStrategy to follow Postgres naming conventions
export class PluralNamingStrategy extends SnakeNamingStrategy {
tableName(targetName: string, userSpecifiedName: string): string {
return (
userSpecifiedName || super.tableName(targetName, userSpecifiedName) + 's'
); // Pluralize the table name
}
}
15 changes: 8 additions & 7 deletions apps/backend/src/users/user.entity.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { Entity, Column, ObjectIdColumn, ObjectId } from 'typeorm';
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

import type { Status } from './types';
import { Status } from './types';

@Entity()
export class User {
@ObjectIdColumn()
_id: ObjectId;

@Column({ primary: true })
@PrimaryGeneratedColumn()
id: number;

@Column()
@Column({
type: 'varchar',
length: 20,
default: Status.STANDARD,
})
status: Status;

@Column()
Expand Down
1 change: 1 addition & 0 deletions apps/frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<title>SSF</title>
<title>Frontend</title>
<base href="/" />

Expand Down
Binary file modified apps/frontend/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions apps/frontend/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const router = createBrowserRouter([

export const App: React.FC = () => {
useEffect(() => {
document.title = 'SSF';
apiClient.getHello().then((res) => console.log(res));
}, []);

Expand Down
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
"lint": "eslint apps/frontend --ext .ts,.tsx --fix && eslint apps/backend --ext .ts,.tsx --fix",
"prepush": "yarn run format:check && yarn run lint:check",
"prepush:fix": "yarn run format && yarn run lint",
"prepare": "husky install"
"prepare": "husky install",
"typeorm:migrate": "npx ts-node -r dotenv/config ./node_modules/typeorm/cli.js migration:run -d apps/backend/src/config/typeorm.ts"
},
"private": true,
"dependencies": {
"@aws-sdk/client-cognito-identity-provider": "^3.410.0",
"@nestjs/cli": "^10.1.17",
"@nestjs/common": "^10.0.2",
"@nestjs/config": "^3.2.3",
"@nestjs/core": "^10.0.2",
"@nestjs/passport": "^10.0.2",
"@nestjs/platform-express": "^10.0.2",
Expand All @@ -26,17 +28,20 @@
"axios": "^1.5.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"dotenv": "^16.4.5",
"global": "^4.4.0",
"jwks-rsa": "^3.1.0",
"mongodb": "^6.1.0",
"passport": "^0.6.0",
"passport-jwt": "^4.0.1",
"pg": "^8.12.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.15.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.0",
"typeorm": "^0.3.17"
"typeorm": "^0.3.17",
"typeorm-naming-strategies": "^4.1.0"
},
"devDependencies": {
"@nestjs/schematics": "^10.0.2",
Expand Down Expand Up @@ -74,6 +79,8 @@
"nx-cloud": "^16.4.0",
"prettier": "^2.6.2",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3",
"vite": "^4.3.9",
"vitest": "^0.32.0"
Expand Down
Loading
Loading