{"id":29451177,"url":"https://github.com/ecelis/luuna-backend","last_synced_at":"2025-07-13T21:10:41.207Z","repository":{"id":285872003,"uuid":"958855375","full_name":"ecelis/luuna-backend","owner":"ecelis","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-03T05:02:42.000Z","size":80,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-03T06:19:37.218Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ecelis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-04-01T21:52:16.000Z","updated_at":"2025-04-03T05:02:47.000Z","dependencies_parsed_at":"2025-04-03T06:29:48.008Z","dependency_job_id":null,"html_url":"https://github.com/ecelis/luuna-backend","commit_stats":null,"previous_names":["ecelis/luuna-backend"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ecelis/luuna-backend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecelis%2Fluuna-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecelis%2Fluuna-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecelis%2Fluuna-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecelis%2Fluuna-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ecelis","download_url":"https://codeload.github.com/ecelis/luuna-backend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecelis%2Fluuna-backend/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265205785,"owners_count":23727514,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-13T21:10:40.766Z","updated_at":"2025-07-13T21:10:41.195Z","avatar_url":"https://github.com/ecelis.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Backend Technical Test\n\nThere is a demo online at https://seal-app-6d5qj.ondigitalocean.app/docs\n\nThere are several users, `admin` is one of them, the password is `1qaz0plm_`\n\nA Postman collection is included in this repo in the `postman` directory. It should work simply by importing it in Postman wit the default \nvariable values.\n\n1. Send a request with csrf/GET csrf to get a token\n2. Send a reuqest with token/POST new token to get an authorization token for the existin `admin` user.\n3. Try other requests included now that you are authenticated.\n\nThere are some request that are labeled anonymous, these only are able to get products, there is one to create a product by anonymous,\ntry it, it should deny the create request.\n\n## Development Setup\n\nClone the repository `git clone git@github.com:ecelis/luuna-backend.git`.\n\n```sh\ncd luuna-backend\n```\n\nCopy `sample.env` to `src/api/.env`and edit it to suit your environment.\n\n```sh\ncp sample.env src/api/.env \n```\nWith the default values it should simply work in docker.\n\nBut if you also want email notifications, you need either SMTP credentialsor a sendgrid \nAPI key and fill in the variables.\n\nAnd set **EMAIL_CHANNEL** to either `smtp` or `sendgrid`.\n\n```\nAPI_DEBUG=True\nPOSTGRES_HOST=db\nPOSTGRES_PORT=5432\nPOSTGRES_PASSWORD=verysecret_password\nPOSTGRES_USER=luuna\nPOSTGRES_DB=retail\nAPI_SECRET_KEY='really_long_and_random_String'\nDJANGO_ALLOWED_HOSTS=127.0.0.1,localhost\nCSFR_TRUSTED_ORIGINS=http://localhost:8000,http://127.0.0.1:8000\nCORS_ALLOWED_ORIGINS=http://localhost:8000,http://127.0.0.1:8000\nEMAIL_CHANNEL=sendgrid\nEMAIL_HOST=smtp.gmail.com\nEMAIL_PORT=587\nEMAIL_HOST_USER=\"contact@example.com\"\nEMAIL_HOST_PASSWORD=very_secret_pwd\nEMAIL_USE_TLS=True\nSENDGRID_API_KEY=\n```\n\n## Docker\n\n```sh\ndocker compose up\n```\n\nIn a new terminal window create the first user, run the following command, it will ask for a password.\n\n```sh\ndocker compose exec -i api sh -c 'python3 manage.py createsuperuser --username admin --email admin@example.com'\n```\n\nBrowse the API http://localhost:8000\n\n## Optional Manual Setup Steps\n\nIf you can't use docker, you can instead follow the next steps to setup the\napp locally. But in this case you must provide either a PostgreSQL database\nor switch to the `sqlite` branch by running `git checkout sqlite`\n\n\nCreate a python virtual environment and activate it\n\n```sh\npython -m venv ENV\nsource ENV/bin/activate\n```\n\nInstall python dependencies\n```sh\npip install -r src/api/requirements.txt\n```\n\n\nRun migrations to bootstrap the database\n\n```sh\npython src/api/manage.py migrate\n```\n\nRun the app\n\n```sh\npython src/api/manage.py runserver\n```\n\nCreate the superuser\n\n```sh\npython src/api/manage.py createsuperuser --username admin --email admin@example.com\n```\n\n### OpenAPI Swagger\n\nUpdate the schema every time the API changes\n\n```sh\npython src/api/manage.py spectacular --color --file schema.yml\n```\n\n### Generate documentation\n\nIt requires nodejs installed!!\n\n```sh\nnpx @redocly/cli build-docs src/api/schema.yml --output docs/index.html\n```\n\n# Luuna Backend API Architecture Design\n\n## 1. Introduction\n\nThis document outlines the architecture design for the Luuna Backend API, built using Python with Django and Django REST Framework. The API leverages a PostgreSQL database and employs JWT for authentication. It includes a modular design for product catalog, user management, and notification systems, ensuring loose coupling and scalability.\n\n## 2. Goals\n\n* **Scalability:** Design an architecture capable of handling increasing user loads and data volumes.\n* **Maintainability:** Implement a modular structure to facilitate future development and maintenance.\n* **Security:** Ensure secure authentication and authorization using JWT.\n* **Flexibility:** Utilize design patterns (e.g., Factory Pattern) to enable easy extension and modification.\n* **Reliability:** Implement robust deployment processes to minimize downtime.\n\n## 3. Technology Stack\n\n* **Programming Language:** Python 3.x\n* **Web Framework:** Django 5.x\n* **API Framework:** Django REST Framework (DRF)\n* **Database:** PostgreSQL\n* **Authentication:** JSON Web Tokens (JWT)\n* **Containerization:** Docker\n* **Version Control:** Git (GitHub)\n* **Deployment:** Dockerized environment on DigitalOcean (cloud-provider agnostic)\n* **Notifications:** SMTP, SendGrid API\n\n## 4. Architecture Diagram\n\n```mermaid\ngraph LR\n    A[Client Applications (Web, Mobile)] --\u003e B(Luuna Backend API - Django/DRF);\n    B --\u003e C[PostgreSQL Database];\n    B --\u003e D[JWT Authentication];\n    B --\u003e E[Product Catalog Module];\n    B --\u003e F[User Management Module];\n    B --\u003e G[Notification System Module];\n    G --\u003e H{Notification Provider Factory};\n    H --\u003e I[SMTP Provider];\n    H --\u003e J[SendGrid Provider];\n    K[GitHub (Main Branch)] --\u003e L[CI/CD Pipeline (GitHub Actions)];\n    L --\u003e M{Build Success?};\n    M -- Yes --\u003e N[Docker Container Build \u0026 Push];\n    N --\u003e O[DigitalOcean Deployment];\n    M -- No --\u003e P[Build Failure (No Deployment)];\n```\n\n## 5. Architectural Components\n### 5.1. API Layer (Django/DRF)\n\n- Responsible for handling HTTP requests and responses.\n- Utilizes Django REST Framework for API development.\n- Implements RESTful API endpoints for products, users, and notifications.\n- Manages request validation, serialization, and deserialization.\n\n### 5.2. Database Layer (PostgreSQL)\n\n- Stores application data persistently.\n- Utilizes Django ORM for database interactions.\n- Ensures data integrity and consistency.\n- Managed PostgreSQL database for optimal performance and reliability.\n\n### 5.3. Authentication (JWT)\n\n- Provides secure authentication and authorization.\n- Generates and verifies JWT tokens.\n- Supports stateless authentication.\n- Allows a wide variety of applications to consume the API.\n\n### 5.4. Product Catalog Module\n\n- Manages product data (e.g., product details, categories, inventory).\n- Provides API endpoints for product retrieval and management.\n- Implements data models and business logic related to products.\n\n### 5.5. User Management Module\n\n- Handles user registration, authentication, and authorization.\n- Manages user profiles and permissions.\n- Provides API endpoints for user management.\n\n### 5.6. Notification System Module\n\n- Sends notifications via various providers (SMTP, SendGrid).\n\n- Utilizes Django signals to trigger notifications.\n\n- Implements the Factory Pattern for provider flexibility.\n\n- Allows to easily add or change notification providers.\n- Notification Provider Factory:\n    - Abstracts the creation of notification providers.\n    - Allows dynamic selection of providers based on configuration.\n    - Facilitates adding new providers without modifying existing code.\nSMTP Provider:\n    - Sends notifications via SMTP.\nSendGrid Provider:\n    - Sends notifications via the SendGrid API.\n\n### 5.7. Containerization (Docker)\n\n- Packages the application and its dependencies into Docker containers.\n- Ensures consistent deployment across different environments.\n- Facilitates scaling and management of the application.\n\n### 5.8. CI/CD Pipeline\n- Automates the build, test, and deployment process.\n- Triggers deployments upon successful merges to the main branch.\n- Ensures zero downtime deployments.\nAvoids deployments on build failures.\n\n## 6. Deployment\n\n- Deployed in a Dockerized environment on DigitalOcean.\n- Utilizes a managed PostgreSQL database.\n- Employs a CI/CD pipeline for automated deployments.\n- Cloud-provider agnostic to allow easy migration to AWS, Azure, or GCP.\n\n## 7. Future Enhancements\n\n- Implement caching to improve performance.\n- Add support for asynchronous tasks using Celery.\n- Integrate with a message queue (e.g., RabbitMQ, Kafka) for event-driven architecture.\n- Implement API versioning.\n- Add more notification providers.\n- Implement automatic scaling.\n\n\nHello! Thanks for your interest in applying to ZeBrands.\nAs a part of the recruiting process, we ask you to complete this task as a way for you to showcase your abilities and knowledge.\n\n# Description of the task\n\nWe need to build a basic catalog system to manage _products_. A _product_ should have basic info such as sku, name, price and brand.\n\nIn this system, we need to have at least two type of users: (i) _admins_ to create / update / delete _products_ and to create / update / delete other _admins_; and (ii) _anonymous users_ who can only retrieve _products_ information but can't make changes.\n\nAs a special requirement, whenever an _admin_ user makes a change in a product (for example, if a price is adjusted), we need to notify all other _admins_ about the change, either via email or other mechanism.\n\nWe also need to keep track of the number of times every single product is queried by an _anonymous user_, so we can build some reports in the future.\n\nYour task is to build this system implementing a REST or GraphQL API using the stack of your preference. \n\n## What we expect\nWe are going to evaluate all your choices from API design to deployment, so invest enough time in every step, not only coding. The test may feel ambiguous at points because we want you to feel obligated to make design decisions. In real life you will often find this to be the case.\n\nWe are going to evaluate these dimensions:\n- Code quality: We expect clean code and good practices\n- Technology: Use of paradigms, frameworks and libraries. Remember to use the right tool for the right problem\n- Creativity: Don't let the previous instructions to limit your choices, be free\n- Organization: Project structure, versioning, coding standards\n- Documentation: Anyone should be able to run the app and to understand the code (this doesn't mean you need to put comments everywhere :))\n\nIf you want to stand out by going the extra mile, you could do some of the following:\n- Add tests for your code\n- Containerize the app\n- Deploy the API to a real environment\n- Use AWS SES or another 3rd party API to implement the notification system\n- Provide API documentation (ideally, auto generated from code)\n- Propose an architecture design and give an explanation about how it should scale in the future\n\n## Delivering your solution\nPlease provide us with a link to your personal repository and a link to the running app if you deployed it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecelis%2Fluuna-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fecelis%2Fluuna-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecelis%2Fluuna-backend/lists"}