Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
157 changes: 54 additions & 103 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,103 +1,54 @@
# In name of Allah

## Introduction
We want a simple app to schedule & validate tasks for users. It should be possible to use django admin as interface for this application.

There are two kind of users:
- normal users
- admin users

**note** that each user must have below fields:
- email
- username
- password
- first name
- last name
- permissions (admin & normal)

You should extend AbstractUser for implementing user model.

normal users can only see, filter & add to their own tasks. These tasks will have a title, description, owner, time to send and precondition tasks field. the task should be scheduled to send an email to its owner at the specified time (use celery for this purpose) **Note** that every task has a set of precondition tasks (which are tasks as well) meaning for a task to be done, first, the set of tasks defined for it should have been done by the time it needs to be sent, otherwise the task will not be considered done. Also definition of done for a task is if it was sent at the specified time.

admin users have the permission to manage users, add to them and delete them. Also they can manage all tasks of users, add task for them and edit their tasks. When created or edited, scheduled tasks should be added or edited.

### Note
Write an API for validating a set of tasks (validation means if the set of tasks is possible to be done or not). If there is a precondition task which is not in the specified set of tasks, you do not need to consider it.

### Example

#### example 1
- Task
- id: 1
- title: task 1
- description: desc 1
- owner: nilva.man
- time to send: 2020-05-10 10:30
- pre-tasks:
- Task
- id: 2
- title: task 2
- description: desc 2
- owner: nilva.man
- time to send: 2020-05-06 10:30
- pre-tasks:
- 1
- 3
- Task
- id: 3
- title: task 3
- description: desc 3
- owner: nilva.man
- time to send: 2020-02-10 9:30
- pre-tasks:

result: **No**, task 1 happens after task 2, but is a precondition of task 2, which makes it impossible to happen

#### example 2
- Task
- id: 1
- title: task 1
- description: desc 1
- owner: nilva.man
- time to send: 2020-05-10 10:30
- pre-tasks:
- Task
- id: 2
- title: task 2
- description: desc 2
- owner: nilva.man
- time to send: 2020-06-10 12:30
- pre-tasks:
- 1
- 3
- Task
- id: 3
- title: task 3
- description: desc 3
- owner: nilva.man
- time to send: 2020-06-01 12:30
- pre-tasks:
- 1

result: **Yes**, First task 1 will happen, then task 3, then task 2


## Expectations

So What does matter to us?
- a clean structure of codebase & components
- clean code practices
- well written unit tests
- finally, ability to learn

## Tasks

1. Fork this repository
2. Break and specify your tasks in project management tool (append the image of your tasks to readme file of your project)
3. Learn & Develop
4. Push your code to your repository
5. Explain the roadmap of your development in readme of repository (also append the image of your specified tasks on part 2 to file)
6. Send us a pull request, we will review and get back to you
7. Enjoy

**Finally** don't be afraid to ask anything from us.
# schedular

## project setup

```
cd schedular
```

1- create your env
```
cp .env.example .env
```

2- spin off docker compose
```
docker compose -f docker-compose.yml up -d
```

3- To see the documentation, see the link below
```
127.0.0.1:8000/
```

## Road map of development
![Development Roadmap](schedular/img.png)

1- Step one
##
In the beginning, I decided to spend some time thinking about the task and write down the steps I need to take on paper. After that, I decided to break down the development process into three sections.

First, to set up the complete project structure so that I won't have to deal with it later. After that, write the code. In the final stage, for peace of mind, thoroughly test them.

Thanks to Cookie Cutter for speeding up my work
##

2- Step two
##
I have decided to use a structure that I personally prefer for my project, which is clean structure. In this structure, select queries are written inside selectors, and services are written within the service section. Serializers only handle serialization and validation tasks, so I think it's better to write them inside views for better accessibility, knowing the inputs and outputs of our code.

To start development, I implemented authentication and then moved on to implementing tasks. The most challenging part for me was how to execute tasks without Celery. In the end, I decided to create a Celery job for task serialization, and this job is created in the initial system run.

After that, I implemented the logic for executing tasks and sending emails. I had previously encountered issues with email sending during unit testing, so this time I tried to resolve it.

And a CRUD operation for the task model that was not very challenging

Then, I customized the admin panel for use by regular users and personal admin users, thanks to Django admin capabilities.

After finishing the admin panel work, I wrote tests for the services I had implemented so far. Finally, I developed an algorithm to validate whether multiple related tasks should be executed together or not.
##

3- Step three
##
In the end, I tested the functionality of the application with my post and Swagger to make sure
##
6 changes: 6 additions & 0 deletions schedular/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SECRET_KEY='=ug_ucl@yi6^mrcjyz%(u0%&g2adt#bz3@yos%#@*t#t!ypx=a'
DATABASE_URL=psql://django-schedular:amir@127.0.0.1:5432/schedular
REDIS_LOCATION=redis://localhost:6379

ALLOWED_HOSTS=127.0.0.1,localhost
DJANGO_SETTINGS_MODULE=config.django.local
129 changes: 129 additions & 0 deletions schedular/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/
8 changes: 8 additions & 0 deletions schedular/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading