Skip to content
This repository was archived by the owner on Jan 6, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
93389c1
Initial structure project
DuongThanhTin Jun 26, 2022
8037ea3
Create file and CHANGELOG for structure
DuongThanhTin Jun 26, 2022
f138524
Create connection to database
DuongThanhTin Jun 26, 2022
6732219
Create models and usecase for `task`, `user`
DuongThanhTin Jun 26, 2022
364a9ee
Make create uuid
DuongThanhTin Jun 26, 2022
9298f8d
Handle func in user
DuongThanhTin Jun 26, 2022
449884f
Handle func in task
DuongThanhTin Jun 26, 2022
f719e23
Add AuthUseCase and AuthRepository
DuongThanhTin Jun 26, 2022
9156ce6
Handle func on api and create router
DuongThanhTin Jun 26, 2022
78eb23b
Create middlewares
DuongThanhTin Jun 26, 2022
411ab09
Set middleware and set repository
DuongThanhTin Jun 26, 2022
3739ae3
Create migration data and makefile
DuongThanhTin Jun 26, 2022
73ff15e
Change name module
DuongThanhTin Jun 26, 2022
948aef2
Change name integrationtest
DuongThanhTin Jun 26, 2022
3132daa
Add image flow
DuongThanhTin Jun 26, 2022
7bcd0a4
Add ERD
DuongThanhTin Jun 26, 2022
16e0a81
Remove unused
DuongThanhTin Jun 26, 2022
db8bc94
Remove create record
DuongThanhTin Jun 26, 2022
46f5bdd
Add README
DuongThanhTin Jun 26, 2022
c0454f4
Remove unused
DuongThanhTin Jun 26, 2022
a994130
Add test for integration test
DuongThanhTin Jun 26, 2022
3b789b0
Add test for integration test
DuongThanhTin Jun 26, 2022
b11e666
Add test and fix status
DuongThanhTin Jun 26, 2022
b273f16
Update README
DuongThanhTin Jun 26, 2022
2244112
Change auth to authorzation
DuongThanhTin Jun 26, 2022
5f48211
Change name variable
DuongThanhTin Jun 27, 2022
6f08937
Add unit test in handler
DuongThanhTin Jun 27, 2022
2acbdec
Change name folder in api
DuongThanhTin Jun 27, 2022
1557cdb
Add unit test in handler
Jun 27, 2022
55e3f93
change to pointer
Jun 27, 2022
c71b07b
Remove unused
Jun 27, 2022
22f191e
Add datajson and add more test
Jun 27, 2022
a7628ef
add datajson
Jun 27, 2022
d16dbca
Remove unuse
Jun 27, 2022
d23f9e9
Update README
Jun 27, 2022
2171cd1
Add more in Readme
Jun 27, 2022
dedf200
Readme
Jun 27, 2022
a18559d
Add README
Jun 27, 2022
4fecb99
Add CHANGELOG
Jun 27, 2022
f6cd09b
add more utils
Jun 27, 2022
2332b06
Add .env.example
Jun 27, 2022
4e14989
remove
Jun 27, 2022
a285e7d
Add test-all in Makefile
Jun 28, 2022
1a7b3eb
Remove unuse
Jun 28, 2022
7cbb3ac
update README
Jun 28, 2022
1fd7961
Update readme to run project
Jun 28, 2022
64308a2
add more detail for env example
Jun 28, 2022
5fff17c
Update README and Makefile
Jun 29, 2022
d01d61e
Update README
Jun 29, 2022
ae910f1
wip
Jun 29, 2022
ea82500
Fix .env and add terminal test
Jun 29, 2022
76f5713
update
Jun 29, 2022
3d25bfe
Update more document
Jun 29, 2022
4ca90ba
Update more README
Jun 29, 2022
a807884
Update
Jun 29, 2022
c81307b
Update curl in README
Jun 29, 2022
682771a
Update Readme
Jun 29, 2022
1308f1d
update
Jun 29, 2022
f56ec52
update
Jun 30, 2022
26df6a3
update
Jun 30, 2022
3e180eb
update
Jun 30, 2022
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
24 changes: 24 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Common
PORT=8000

# JWT
JWT_KEY=eyJhbGciOiJIUzI1NiJ9
JWT_TIMEOUT=60

HOST=localhost

# Setup DB
DB_DRIVER=postgres
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=manabie123
DB_NAME=togo
DB_SSL_MODE=disable
DSN_POSTGRES=host=${DB_HOST} user=${DB_USER} password=${DB_PASSWORD} dbname=${DB_NAME} sslmode=${DB_SSL_MODE}

# URL for migration
POSTGRESQL_URL_MIGRATION="postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSL_MODE}"

# INTERGRATION_TEST
INTERGRATION_TEST_PORT=8080
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@

out/

.idea
.idea
.env
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### Added

- Create README
- Make create `integrationtest`
- Make create terminal in `Makefile`
- Initial and structure for project
25 changes: 25 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!make
### Export file .env
include .env
export

### Migration
migration-up:
@echo migrate -database ${POSTGRESQL_URL_MIGRATION} -path db/migrations up
@migrate -database ${POSTGRESQL_URL_MIGRATION} -path db/migrations up

migration-down:
@echo migrate -database ${POSTGRESQL_URL_MIGRATION} -path db/migrations down
@migrate -database ${POSTGRESQL_URL_MIGRATION} -path db/migrations down

### Run project
run:
go run cmd/main.go

### Unit test
test-unit:
go test -cover -coverprofile coverage.log ./internal/...

### Integraion test
test-integration:
go test -tags=integration ./integrationtest -v -count=1
231 changes: 209 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,217 @@
### Requirements
# Duong Thanh Tin - Test Manabie

- Implement one single API which accepts a todo task and records it
- There is a maximum **limit of N tasks per user** that can be added **per day**.
- Different users can have **different** maximum daily limit.
- Write integration (functional) tests
- Write unit tests
- Choose a suitable architecture to make your code simple, organizable, and maintainable
- Write a concise README
- How to run your code locally?
- A sample “curl” command to call your API
- How to run your unit tests locally?
- What do you love about your solution?
- What else do you want us to know about however you do not have enough time to complete?
## Togo Respository

### Notes
### Features
The repository have a few main features
```
- Login
- Create user
- Add task by user and create date
```

- We're using Golang at Manabie. **However**, we encourage you to use the programming language that you are most comfortable with because we want you to **shine** with all your skills and knowledge.
### Diagrams

### How to submit your solution?
1. #### Sequence Diagram For Flow Feature
- Feature Login
![Sequence](https://raw.githubusercontent.com/DuongThanhTin/togo/master/documents/Flow-Login.svg)

- Fork this repo and show us your development progress via a PR
- Feature Create User
![Sequence](https://raw.githubusercontent.com/DuongThanhTin/togo/master/documents/Flow-CreateUser.svg)

### Interesting facts about Manabie
- Feature Add Task
![Sequence](https://raw.githubusercontent.com/DuongThanhTin/togo/master/documents/Flow-AddTask.svg)

- Monthly there are about 2 million lines of code changes (inserted/updated/deleted) committed into our GitHub repositories. To avoid **regression bugs**, we write different kinds of **automated tests** (unit/integration (functionality)/end2end) as parts of the definition of done of our assigned tasks.
- We nurture the cultural values: **knowledge sharing** and **good communication**, therefore good written documents and readable, organizable, and maintainable code are in our blood when we build any features to grow our products.
- We have **collaborative** culture at Manabie. Feel free to ask trieu@manabie.com any questions. We are very happy to answer all of them.
2. #### ERD Diagram

Thank you for spending time to read and attempt our take-home assessment. We are looking forward to your submission.
![ERD](https://raw.githubusercontent.com/DuongThanhTin/togo/master/documents/ERD.svg)

### Structure Project

```
- cmd --> Main applications for this project.
|- middlewares --> Middlewares for this project
- constants --> Contain variable common
- db --> Data for migrations
|- migrations -> You can migration up or down data
- documents --> Contain detail documents for this project
- integrationtest --> Run integration test
- internal
|- api --> You can create different output commands like Api rest, web, GRPC or any other technology.
|- handlers --> Contain API
|- common --> API for common
|- tasks --> API for task
|- users --> API for user
|- routes --> Make create route for API
|- driver --> Config connection to database
|- models --> Application models
|- pkg --> Make create function to use common
|- id --> Make create uuid
|- responses --> Make create many response data
|- repositories --> Repositoryies will action to database (CRUD)
|- authorization --> Repository for auth
|- task --> Repository for task
|- user --> Repository for user
|- usecases --> Usecases to implement action for application
|- authorization --> Usecase for auth
|- task --> Usecase for task
|- user --> Usecase for user
```

### How to start

#### Prepare

- Install golang [golang](https://go.dev/doc/install)
- Install postgres [postgreSQL](https://www.postgresql.org/download)
- Install migrate If you want to migration [migration](https://github.com/golang-migrate/migrate)

. MacOS

```bash
$ brew install golang-migrate
```

. Windows

Using [scoop](https://scoop.sh/)

```bash
$ scoop install migrate
```

. Linux

```bash
$ curl -L https://packagecloud.io/golang-migrate/migrate/gpgkey | apt-key add -
$ echo "deb https://packagecloud.io/golang-migrate/migrate/ubuntu/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/migrate.list
$ apt-get update
$ apt-get install -y migrate
```
#### Start local
1. Clone repository
```bash
git clone https://github.com/DuongThanhTin/togo.git
cd togo
cp .env.example .env
```

2. Create Database postgres with your config

3. Change data variable in file .env with your config on step 2

4. Migration database with terminal (If you want to migrate)
```bash
make migration-up
```
5. Run main.go
```bash
go run cmd/main.go
```

#### Install
```bash
go install ./...
```

#### If you want to integration test after run projection
```bash
go test -tags=integration ./integrationtest -v -count=1
```

#### If you want to unit test test after run projection
```bash
go test ./internal/...
```

#### If you want to remove table on database
```bash
make migration-down
```

### Flow

You can see all flow in folder `documents`. I draw three pictures for call API and one picture for ERD.

#### Endpoints

I make create three endpoints.
```bash
POST /logins -> Login
POST /tasks -> Create task
POST /users -> Create user
```

#### Authentication token
I will create token and set data of for token in `Cookie`. You must login first if you want to create task with endpoint `POST /tasks`. The token will be generated and set in `Cookie` with key `token` and have data `user_id` and `max_task_per_day`. The task will create with data user login.

#### Call API
1. You can create user with endpoint `POST /users`. In addtion, I have validate `username`, `password` not empty in request. If `username` is exists, you can't create user.
Request JSON:
```bash
{
"username":"user-manabie-1",
"password": "123456",
"max_task_per_day": 10
}
```

2. You can login with with endpoint `POST /login`. I have validate `username` and `password` not empty in request. First of all, you must create user if you want to login with user as above.
After login, Token will be generated and set in `Cookie` with key `token` and have data `user_id` and `max_task_per_day`.
If you run terminal with `make migration-up`. I create example user for you.
User example: `id: firstUser, username: manabie, password: example, max_task_per_day: 5`
Request JSON:
```bash
{
"username":"manabie",
"password": "example",
}
```

More detail:
I will this response which have token for you. You can easily set this token in `Cookie` with key `token` if you call API with `curl`.

3. You can create task with endpoint `POST /tasks`. First of all, you must login if you want to create task. I have create token and set it in `Cookie`. This token have the information of `user` such as:
`user_id` and `max_task_per_day`. After that, you call API `POST /tasks`, i will parse this token to get data from this token so i need you login. I have validate number task of day if the number task of day is more than `max_task_per_day` of user, you can't create task.
Request JSON:
```bash
{
"content":"New task 1",
}
```

More detail:
- Field `userID` in `task` get from token
- Field `createDate` in `task` get from date call API

#### Collection postman
I make create collection postman folder `collection_postman`. You can easily see the endpoint and request json for each API.

#### CURL Example
1. Create User
```bash
curl -XPOST -d '{ "username":"manabie-user-3", "password": "123456", "max_task_per_day": 10 }' 'http://localhost:8000/users'
```

Response:
```bash
{"data":{"username":"manabie-user-3","password":"123456","max_task_per_day":10},"message":"Success","status":201}
```

2. Login
```bash
curl -XPOST -d '{ "username":"manabie", "password":"example" }' 'http://localhost:8000/login'
```
Response:
```bash
{"data":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTY1NTE4NDcsIm1heF90YXNrX3Blcl9kYXkiOiI1IiwidXNlcl9pZCI6ImZpcnN0VXNlciJ9.qwHLe5Nd1lxUJlHPh3LtJUsX68ML2foMv_yjD4x5VJY","message":"Success","status":200}
```

3. Create Task
```bash
curl -XPOST -b 'token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTY1MjIzMzYsIm1heF90YXNrX3Blcl9kYXkiOiI1IiwidXNlcl9pZCI6ImZpcnN0VXNlciJ9.RvmCCNF5vOloXQmyZEqAUcZtxQN4lN9_qhkSm4vByOE' -d '{ "content":"New task 2" }' 'http://localhost:8000/tasks'
```
Response:
```bash
{"data":null,"message":"Success","status":201}
```
12 changes: 12 additions & 0 deletions cmd/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### Added

- Make create folder `middlewares`
- Create connection to database postgres
- Create `main`
57 changes: 57 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package main

import (
"fmt"
"log"

"github.com/manabie-com/togo/cmd/middlewares"
"github.com/manabie-com/togo/constants"
"github.com/manabie-com/togo/internal/api/handlers"
"github.com/manabie-com/togo/internal/api/routes"
"github.com/manabie-com/togo/internal/driver"
"github.com/manabie-com/togo/utils"

"github.com/gin-gonic/gin"
"github.com/pkg/errors"
)

func run() error {
// Creates a new Gin instance.
r := gin.Default()

// Load File Environment
utils.LoadEnv(constants.FileEnvironment)

// Connect to Database
db, err := driver.ConnectDatabase()
if err != nil {
return errors.Wrap(err, "Fail to ConnectDatabase")
}

r.Use(func(c *gin.Context) {
c.Set("db", db)
})

{ // Set Middlewares
// Midlewares
// Recovery middleware recovers from any panics and writes a 500 if there was one.
r.Use(gin.Recovery())
r.Use(middlewares.SetDefaultMiddleWare())
}

{ //Set Repository
usecases := handlers.NewUseCase(db)
handlers.SetMainUseCase(&usecases)
//Set Route
routes.SetupRoute(r, usecases)
}

log.Fatal(r.Run(fmt.Sprintf(":%s", utils.Env.Port)))
return nil
}

func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
11 changes: 11 additions & 0 deletions cmd/middlewares/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### Added

- Make create `SetDefaultMiddleWare` and `ValidateToken` from Cookie

Loading