Skip to content
Open
Changes from all 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
284 changes: 283 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,283 @@
# backend

# hot-coffee-sql
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe give it more entertaining name like frappuccino or cold-coffee or hottest-coffe


## Learning Objectives

- SQL
- PostgreSQL
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this project also needs to show the difference between SQLite and PostgeSQL as databases and to do so, it should require such things, that is featured only in PostgreSQL, like it's scalability, concurrent queries, unique data types, range of tools and etc.

- CRUD
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, they've already learned the crud in foundation and even in sprint sql with basic crud and advanced ones at the end of the sprint and I think it would be better to make it Advanced CRUD and change requirements to have much more complicated endpoints, handling business logic and using complex queries that would require thorough planning of the tables as for example idea for one of the endpoints could the full text search:

Full-Text Search

  • Implement menu search using PostgreSQL's full-text search capabilities
  • Add endpoint GET /menu/search that allows searching by:
    • Item name
    • Ingredients
    • Description
    • Handling partial matches and typos

- ERD
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing about ERD in the project, I guess it should be necessary for them to make ERD diagram and submit it with the work, because it really helps in organizing tables and relationships before impelmenting them


## Abstract

In this project, you will rewrite the existing [hot-coffee](https://github.com/alem-platform/foundation/tree/main/hot-coffee) project to work with a PostgreSQL database. The main task is to modify the current handlers in hot-coffee so that they execute SQL queries instead of working with JSON.

In addition to refactoring the existing handlers, you will add several new ones related to aggregation and reporting. Throughout this project, you will learn to perform basic SQL operations and explore aggregation tools provided by PostgreSQL.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"basic operations" they have learned it in sprint-sql, they should be learning more advanced stuff, maybe refactor this section as "basic and advanced SQL operations"


## Context

Systems become more complex and modernized over time, and the hot-coffee project is no exception. While using a JSON-based database is convenient, it is not scalable and makes maintenance difficult for other developers. Moving to a PostgreSQL database is the better solution.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is a* better solution


Fortunately, since the project was initially built using a layered architecture, the transition will be easier. You will need to add a new Data Access Layer (Repositories) and integrate it into the project.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not add, but change Data Access Layer, because they've already implemented it


As part of this project, you must design tables correctly and define relationships between them appropriately.

## General Criteria

- Your code MUST be written in accordance with [gofumpt](https://github.com/mvdan/gofumpt). If not, you will be graded `0` automatically.
- Your program MUST be able to compile successfully.
- Your program MUST not exit unexpectedly (any panics: `nil-pointer dereference`, `index out of range` etc.). If so, you will get `0` during the defence.
- Only built-in packages are allowed, except for the PostgreSQL driver. Using any other external packages will result in a grade of 0.
- The project MUST be run by the following command in the project's root directory:

```shell
$ docker compose up
```

## Mandatory Part

Your task is to rewrite the existing endpoints in the **hot-coffee** project to work with a PostgreSQL database. To do this, you may use a third-party PostgreSQL driver as part of your solution.

You need to create the following tables: `user`, `order`, `menu`, `menu_item`, `inventory`, and `ingredient`, and define the relationships between them. You are not limited to only these tables; you may create additional ones if necessary for implementing the required functionality. The design and relationships of the tables are at your discretion.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

names of tables in plural?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I think the number of tables are too low, even though it is correlated to the project itself. In the sprint sql they've already faced more complex schemas and this looks as a little downgrade in comparison, I think addition of several new tables as required is necessary


Pay special attention to designing the relationships between tables (e.g., one-to-many, one-to-one). For instance, the `menu` and `menu_item` tables will have a "one-to-many" relationship, meaning the `menu_item` table should include a column with the following constraint:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it shouldn't be necessary to add following line as it is, but rather "...table MAY include a column..."

```sql
menu_id INT NOT NULL CONSTRAINT fk_menu FOREIGN KEY(menu_id) REFERENCES menu(id)
```
Plan your data structure carefully to ensure the project's scalability and maintainability.

Since adding a database dependency to your project makes it more challenging for auditor to run and test it, you need to containerize your service and database into separate containers and write a `docker-compose.yml` file. This will allow the project to be started with a single command:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is too hard for them to containerization for their own, considering it is their first project and that they will learn this topic much later in the course. I think they would spend much more time than intended in this section (I personally would, if it was the first time for me facing this topic)

Either one of this solution could be applied:

  1. Provide detailed guide on how to setup the project in docker-compose
  2. Do not include docker and leave the testing part as it is, considering that authors would provide mock data in init.sql that would used to quickly setup the database for testing

```bash
docker compose up
```

As part of the task, the following endpoints must be rewritten to work using SQL queries:

- **Orders:**

- `POST /orders`: Create a new order.
- `GET /orders`: Retrieve all orders.
- `GET /orders/{id}`: Retrieve a specific order by ID.
- `PUT /orders/{id}`: Update an existing order.
- `DELETE /orders/{id}`: Delete an order.
- `POST /orders/{id}/close`: Close an order.
- **Menu Items:**

- `POST /menu`: Add a new menu item.
- `GET /menu`: Retrieve all menu items.
- `GET /menu/{id}`: Retrieve a specific menu item.
- `PUT /menu/{id}`: Update a menu item.
- `DELETE /menu/{id}`: Delete a menu item.
- **Inventory:**

- `POST /inventory`: Add a new inventory item.
- `GET /inventory`: Retrieve all inventory items.
- `GET /inventory/{id}`: Retrieve a specific inventory item.
- `PUT /inventory/{id}`: Update an inventory item.
- `DELETE /inventory/{id}`: Delete an inventory item.
- **Aggregations:**

- `GET /reports/total-sales`: Get the total sales amount.
- `GET /reports/popular-items`: Get a list of popular menu items.

In addition to rewriting the existing endpoints, you must also develop the following new ones:
#### 1. Number of ordered items
`GET /numberOfOrderedItems?startDate={startDate}&endDate={endDate}`: Returns a list of ordered items and their quantities for a specified time period. If the `startDate` and `endDate` parameters are not provided, the endpoint should return data for the entire time span.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

guess it should be part of /orders group -> GET /orders/numberOfOrderedItems?startDate={startDate}&endDate={endDate}

or a part of /reports group

##### **Parameters**:
- `startDate` _(optional)_: The start date of the period in `YYYY-MM-DD` format.
- `endDate` _(optional)_: The end date of the period in `YYYY-MM-DD` format.

response:
```shell
GET /numberOfOrderedItems?startDate=10.11.2024&endDate=11.11.2024
HTTP/1.1 200 OK
Content-Type: application/json

{
"latte": 109,
"muffin": 56,
"espresso": 120,
"raff": 0,
...
}
```

#### 2. Cash flow
`GET /cashFlow?startDate={startDate}&endDate={endDate}`: Returns the total sales amount for a specified period. If the `startDate` and `endDate` parameters are not provided, the endpoint should return data for the entire time span.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't it the same thing as /reports/total-sales but with filters?

##### **Parameters**:
- `startDate` _(optional)_: The start date of the period in `YYYY-MM-DD` format.
- `endDate` _(optional)_: The end date of the period in `YYYY-MM-DD` format.

response:
```json
GET /cashFlow?startDate=10.11.2024&endDate=11.11.2024`
HTTP/1.1 200 OK
Content-Type: application/json

{
"cashFlow": 159940.56,
}
```

#### 3. Ordered items by period
`GET /orderedItemsByPeriod?period={day|month}&month={month}`: Returns the number of orders for the specified period, grouped by day within a month or by month within a year. The `period` parameter can take the value `day` or `month`. The `month` parameter is optional and used only when `period=day`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, I think it should be either in /orders or in /reports groups

##### **Parameters**:
- `period` _(required)_:
- `day`: Groups data by day within the specified month.
- `month`: Groups data by month within the specified year.
- `month` _(optional)_: Specifies the month (e.g., `october`). Used only if `period=day`.
- `year` _(optional)_: Specifies the year. Used only if `period=month`.

response:
```json
GET /orderedItemsByPeriod?period=day&month=october
HTTP/1.1 200 OK
Content-Type: application/json

{
"period": "day",
"month": "october",
"orderedItems": [
{ "1": 109 },
{ "2": 234 },
{ "3": 198 },
{ "4": 157 },
{ "5": 223 },
{ "6": 143 },
{ "7": 256 },
{ "8": 199 },
{ "9": 275 },
{ "10": 187 },
{ "11": 234 },
{ "12": 150 },
{ "13": 178 },
{ "14": 210 },
{ "15": 202 },
{ "16": 190 },
{ "17": 260 },
{ "18": 215 },
{ "19": 240 },
{ "20": 180 },
{ "21": 300 },
{ "22": 250 },
{ "23": 199 },
{ "24": 210 },
{ "25": 220 },
{ "26": 190 },
{ "27": 170 },
{ "28": 260 },
{ "29": 230 },
{ "30": 210 },
{ "31": 180 }
]
}

```

response:
```json
GET /orderedItemsByPeriod?period=month&year=2023
HTTP/1.1 200 OK
Content-Type: application/json

{
"period": "month",
"year": "2023",
"orderedItems": [
{ "january": 6528 },
{ "february": 7324 },
{ "march": 8452 },
{ "april": 7890 },
{ "may": 9103 },
{ "june": 8675 },
{ "july": 9234 },
{ "august": 8820 },
{ "september": 9345 },
{ "october": 8901 },
{ "november": 8123 },
{ "december": 9576 }
]
}
```

#### 4. Get leftovers
`GET /getLeftOvers?sortBy={value}&page={page}&pageSize={pageSize}`: Returns the inventory leftovers in the coffee shop, including sorting and pagination options.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be in /inventory /reports group

##### **Parameters**:
- `sortBy` _(optional)_: Determines the sorting method. Can be either:
- `price`: Sort by item price.
- `quantity`: Sort by item quantity.
- `page` _(optional)_: Current page number, starting from 1.
- `pageSize` _(optional)_: Number of items per page. Default value: `10`.
##### **Response**:
- Includes:
- A list of leftovers sorted and paginated.
- `currentPage`: The current page number.
- `hasNextPage`: Boolean indicating whether there is a next page.
- `totalPages`: Total number of pages.

response example:
```json
GET /getLeftOvers?sortBy=quantity?page=1&pageSize=4
HTTP/1.1 200 OK
Content-Type: application/json

{
"currentPage": 1,
"hasNextPage": true,
"pageSize": 4,
"totalPages": 10,
"data": [
{
"name": "croissant",
"quantity": 109,
"price": 950
},
{
"name": "sugar",
"quantity": 93,
"price": 50
},
{
"name": "muffin",
"quantity": 63,
"price": 350
},
{
"name": "milk",
"quantity": 1,
"price": 200
}
]
}
```


Since the auditor will not have access to your local database and its data, you need to create a migration file named `init.sql`. This file should include:

1. Scripts to Create All Required Tables
Define the structure of the tables (`user`, `order`, `menu`, `menu_item`, `inventory`, `ingredient`, etc.) in SQL, including column definitions, data types, and constraints.

2. Definition of Relationships Between Tables
Ensure that relationships such as `FOREIGN KEY` constraints are properly defined.
3. Mock Data
Include sample data for testing purposes:
- Test users
- Sample orders
- Menu items
- Inventory records
- Ingredients

## Guidelines from Author

In the initial stages of working with tables and relationships, it can be challenging to understand and organize everything. Therefore, it is recommended to use **pgAdmin**
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could use first person instead of the third person to be to make guideline more personal and less formal


## Author

This project has been created by:

Askaruly Nurislam, alumni of Alem school
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alem School*


Contacts:

- Email: [askaruly@hotmail.com](mailto:askaruly@hotmail.com)
- [GitHub](https://github.com/darwin939/)