Skip to content

Commit

Permalink
Add code_structure & database_design doc
Browse files Browse the repository at this point in the history
Signed-off-by: Arnob kumar saha <arnob@appscode.com>
  • Loading branch information
ArnobKumarSaha committed May 12, 2024
1 parent 50b155d commit 01764b5
Show file tree
Hide file tree
Showing 3 changed files with 215 additions and 1 deletion.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
# praromvik
# praromvik

The staring point, that will define your path on the DevOps journey !

## Contribution guidelines

Want to help improve praromvik? Please read the design docs [here](https://github.com/Praromvik/praromvik/tree/master/docs).

## Support

To speak with us, please leave a message on our email `praromvik.hq@gmail.com`.
To receive product announcements, follow us on [Twitter](https://twitter.com/PraromvikHq), [LinkedIn](https://www.linkedin.com/company/praromvik/), [Facebook](https://www.facebook.com/profile.php?id=61557462003505).

If you have found a bug with Praromvik or want to request for new features, please [file an issue](https://github.com/praromvik/praromvik/issues/new).
77 changes: 77 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
Description on each of the packages

# cmd
Under the root command, there is only one subcommand named start_server. We use the routers package from it & start the server.

# routes
We have these types of routes:

`user_auth`: signUp, signIn, signOut

`course`:
i) get/list -> general authenticated users can do it.
ii) create/update -> admin or moderators can do.
iii) delete -> only admin can do it.

For get,update & delete calls(those work on a specific course uid), we utilize a context middleware for injecting context data.

There is one special route for providing role to a user. It requires the admin access.

# pkg
-`pkg.auth`:

We store these fields in the redis session:
i) authenticated, ii) role, iii) userName, iv) userIP, v) user_agent
There are some getters implemented in the session.go file.



-`pkg.error`

-`pkg.middleware`:

There are 4 types of middlewares in this package.
i) global middleware: For example logger, urlFormatter etc.

ii) common security middleware: To check if a session is valid & authenticated.

iii) access related middleware: To check if the role(in session) is matched.

iv) context middleware: To append additional info to the context.


# handlers
`routes -> handlers -> models`

Routes package will call functions from handlers package. And handlers package will call functions from models package.
We should be strict to this design principle to avoid implementation complexity & circular dependencies.

In general, the handlers are pretty straight-forward. They contain functions like Create, Get, List, Update, Delete etc.

# models
This is the actual working unit. The API & common constants are declared here. Also, it is responsible for all the database calls.


1) `models.db.client`:
A special package only to initialize the db clients thorough init().

2) `models.db`:
DB calls are implemented here. No one calls the DB directly except this package.

3) `models.course`:
Dedicated package for course related methods. Intended to only be called from `handlers/course`.

4) `models.user`:
Dedicated package for user related methods. Intended to only be called from `handlers/user`.


---
There are some other non-code packages/files worth mentioning.

`docs`: Holds the documentation files.

`hack`: Holds the utility script files.

`.env` file: Export the required ENVs to run this backend server.

`req.http` file: Holds the curl request-response examples for the implemented http routes.
124 changes: 124 additions & 0 deletions docs/database_design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
## API
```
type Course struct {
CourseId string `json:"_id" bson:"_id"`
Title string `json:"title" bson:"title"`
Description string `json:"description" bson:"description"`
Instructors []string `json:"instructors" bson:"instructors"`
Moderators []string `json:"moderators" bson:"moderators"`
StartDate date.Date `json:"startDate" bson:"startDate"`
EndDate date.Date `json:"endDate" bson:"endDate"`
Duration int `json:"duration" bson:"duration"` // Duration in week
Capacity int `json:"capacity" bson:"capacity"`
Students []string `json:"students" bson:"students"`
Price int `json:"price" bson:"price"`
Image []byte `json:"image" bson:"-"`
}
```

```
type Lesson struct {
LessonID string `json:"_id" bson:"_id"`
Title string `json:"title" bson:"title"`
Contents []ContentRef `json:"contents" bson:"contents"`
}
type ContentRef struct {
ID string `json:"id" bson:"id"`
Title string `json:"title" bson:"title"`
}
type Content struct {
ContentID string `json:"_id" bson:"_id"`
Title string `json:"title" bson:"title"`
Type string `json:"type" bson:"type"` // video, resource, quiz, lab
Data []byte `json:"data" bson:"data"`
LessonRef UUID `json:"lessonRef" bson:"lessonRef"`
}
```


## A concrete Example
```
Course name: Mastering golang
<Lessons>:
Introduction:
Why Go?
Installation
<resources>
<quiz>
Concurrency in Go:
channels
mutex
<lab1>
<resources>
go routines
<lab2>
Conclusion
thank you
```

For the `lab1` under 'Concurrency in Go', url will be like:
http://praromvik.com/course/mastering_golang/concurrency_lab_1/
Intentionally cutting off the lesson id part to keep the url shorter.

---

We have divided a single course into 2 different databases. One for holding the metadata, & one for holding the actual information.
Again the actual information is divided into two collections. One will be called once, & the other one will be called several times (with specific contentID) from the frontend.
### `praromvik.courses` collection
This will hold the metadata information only.
```
{
"_id": "mastering_golang",
"title": "Mastering Golang",
"instructors": []string{<some_user_ids>},
"students": []string{<some_user_ids>}
}
```
Removed the lessons slice above to avoid multiple reference update on create/delete calls.

### `mastering_golang.lessons` collection
The _id format is `<4_digit_serial_number>_<epoch_time>`
```
{
"_id": "<0001_1715524983>",
"title": "Introduction",
"contents": []string{<_ids>}
},
{
"_id": "<0002_1715527643>",
"title": "Concurrency in Go",
"contents": []string{"channel", "concurrency_lab_1", "resouce_from_doc"}
}
```

### `mastering_golang.contents` collection
```
{
"_id": "channel",
"title": "Channel",
"type": "Video",
"lessonRef": "0002_1715527643"
},
{
"_id": "concurrency_lab_1",
"title": "Hands-on the Go channel",
"type": "Lab",
"lessonRef": "0002_1715527643"
},
{
"_id": "resouce_from_doc",
"title": "Additional learing resouces",
"type": "Written",
"lessonRef": "0002_1715527643"
},
```

So the `RESTRICTIONS` are:

i) course ids have to be unique.

ii) content ids within a course have to be unique.

iii) both course & content ids have to be <= 24 characters, as they will be used as _id in mongodb.

0 comments on commit 01764b5

Please sign in to comment.