{"id":51489687,"url":"https://github.com/yossichakim/task-manager-api","last_synced_at":"2026-07-07T10:30:54.317Z","repository":{"id":365032139,"uuid":"1269389234","full_name":"yossichakim/task-manager-api","owner":"yossichakim","description":"Full-stack task manager built with Flask, React, SQLite, JWT authentication, Swagger documentation, automated backend tests, and Render deployment.","archived":false,"fork":false,"pushed_at":"2026-06-28T16:29:44.000Z","size":177,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T18:13:35.713Z","etag":null,"topics":["authentication","crud","full-stack","jwt","openapi","pytest","python","react","render","rest-api","sqlite","swagger","task-manager","vite"],"latest_commit_sha":null,"homepage":"https://task-manager-frontend-pkip.onrender.com/","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/yossichakim.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-14T16:48:35.000Z","updated_at":"2026-06-28T16:29:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/yossichakim/task-manager-api","commit_stats":null,"previous_names":["yossichakim/task-manager-api"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/yossichakim/task-manager-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yossichakim%2Ftask-manager-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yossichakim%2Ftask-manager-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yossichakim%2Ftask-manager-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yossichakim%2Ftask-manager-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yossichakim","download_url":"https://codeload.github.com/yossichakim/task-manager-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yossichakim%2Ftask-manager-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35225022,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-07T02:00:07.222Z","response_time":90,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["authentication","crud","full-stack","jwt","openapi","pytest","python","react","render","rest-api","sqlite","swagger","task-manager","vite"],"created_at":"2026-07-07T10:30:50.719Z","updated_at":"2026-07-07T10:30:54.307Z","avatar_url":"https://github.com/yossichakim.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Task Manager API\n\nA full-stack task manager project with a Flask/SQLite backend and a React/Vite frontend.\n\nThe backend lets users register, log in, receive a JWT access token, and perform CRUD operations only on tasks that belong to their own account.\n\n## Live Demo\n\n* Frontend application: https://task-manager-frontend-pkip.onrender.com/\n* Backend API: https://task-manager-api-yossi.onrender.com\n* API documentation (Swagger UI): https://task-manager-api-yossi.onrender.com/docs\n\n\u003e The frontend and backend are deployed as separate Render services. Depending on the service state, the first request may take some time.\n\n## Application Preview\n\n[![Task Manager application preview](docs/task-manager-preview.png)](https://task-manager-frontend-pkip.onrender.com/)\n\n## Features\n\n* User registration and login\n* Secure password hashing\n* JWT authentication, logout, and token revocation\n* User-owned task CRUD operations\n* Task filtering by status and category\n* Interactive Swagger/OpenAPI documentation\n* Automated backend tests with pytest\n* React frontend built with Vite\n* Deployed React frontend and Flask API on Render\n\n## Technologies\n\n* Python, Flask, SQLite, Flask-JWT-Extended, python-dotenv\n* Flask-Swagger-UI, OpenAPI 3.0\n* pytest, Gunicorn, Render\n* React, Vite, ESLint\n* Git and GitHub\n\n## Project Structure\n\n```text\ntask-manager-api/\n|-- .codex/\n|   `-- skills/\n|       `-- safe-frontend-change/\n|           |-- agents/\n|           |   `-- openai.yaml\n|           `-- SKILL.md\n|-- backend/\n|   |-- app/\n|   |   |-- __init__.py\n|   |   |-- auth_routes.py\n|   |   |-- database.py\n|   |   |-- jwt_handlers.py\n|   |   |-- main_routes.py\n|   |   `-- task_routes.py\n|   |-- tests/\n|   |   |-- conftest.py\n|   |   |-- test_auth.py\n|   |   |-- test_jwt.py\n|   |   |-- test_main.py\n|   |   `-- test_tasks.py\n|   |-- .env.example\n|   |-- app.py\n|   |-- openapi.yaml\n|   |-- requests.http\n|   |-- requirements.txt\n|   `-- wsgi.py\n|-- frontend/\n|   |-- public/\n|   |-- src/\n|   |   |-- assets/\n|   |   |-- App.css\n|   |   |-- App.jsx\n|   |   |-- index.css\n|   |   `-- main.jsx\n|   |-- package.json\n|   `-- vite.config.js\n|-- .gitignore\n|-- AGENTS.md\n`-- README.md\n```\n\n## Backend Architecture\n\nThe backend uses the Flask application factory pattern.\n\nThe `create_app()` function:\n\n* Creates and configures the Flask application\n* Loads the JWT secret key\n* Registers the authentication and task blueprints\n* Registers JWT error handlers\n* Initializes the SQLite database\n* Serves the OpenAPI specification\n* Configures Swagger UI\n\nThe backend is divided into separate modules for authentication, task management, database access, JWT handling, and general routes.\n\n## Backend Installation\n\nClone the repository and enter it:\n\n```bash\ngit clone https://github.com/yossichakim/task-manager-api.git\ncd task-manager-api\n```\n\nCreate and activate a virtual environment from the repository root:\n\n```bash\npython -m venv venv\n```\n\nWindows Command Prompt:\n\n```bash\nvenv\\Scripts\\activate\n```\n\nWindows PowerShell:\n\n```powershell\nvenv\\Scripts\\Activate.ps1\n```\n\nmacOS or Linux:\n\n```bash\nsource venv/bin/activate\n```\n\nInstall backend dependencies from `backend/`:\n\n```bash\ncd backend\npython -m pip install -r requirements.txt\n```\n\n## Environment Variables\n\nThe backend example configuration is available at `backend/.env.example`. For local backend development, create `backend/.env`:\n\n```env\nJWT_SECRET_KEY=your-secure-secret-key\nFRONTEND_URL=http://localhost:5173\n```\n\n`JWT_SECRET_KEY` is required and is used to sign JWT access tokens.\n\n`FRONTEND_URL` controls the additional frontend origin allowed by the backend CORS configuration. The local Vite origin, `http://localhost:5173`, is already allowed by the backend. In production, set `FRONTEND_URL` to the deployed frontend origin:\n\n```env\nFRONTEND_URL=https://task-manager-frontend-pkip.onrender.com\n```\n\nGenerate a secure secret key with:\n\n```bash\npython -c \"import secrets; print(secrets.token_hex(32))\"\n```\n\nCopy the generated value into the `.env` file.\n\nThe frontend reads its API base URL from `VITE_API_BASE_URL`. For a production build, set this variable in `frontend/.env.production` or in the frontend deployment environment:\n\n```env\nVITE_API_BASE_URL=https://task-manager-api-yossi.onrender.com\n```\n\nThe repository does not include a frontend `.env.example` file. Do not commit `.env` files or secrets to GitHub.\n\n## Database\n\nThe backend uses SQLite. The database and its required tables are initialized automatically when the Flask application starts.\n\nNo manual database setup command is required.\n\nThe main tables are:\n\n* `users`: `id`, `username`, `password_hash`\n* `tasks`: `id`, `title`, `description`, `category`, `status`, `user_id`\n* `revoked_tokens`: `id`, `jti`, `revoked_at`\n\nEach task is connected to the user who created it.\n\nThe `revoked_tokens` table stores JWT identifiers after logout so that revoked access tokens cannot be reused.\n\n## Run Backend Locally\n\nStart the development server from `backend/`:\n\n```bash\ncd backend\npython app.py\n```\n\nThe API will be available at:\n\n```text\nhttp://127.0.0.1:5000\n```\n\nSwagger UI will be available at:\n\n```text\nhttp://127.0.0.1:5000/docs\n```\n\n## Production Entry Point\n\nThe production deployment uses Gunicorn and the WSGI entry point from `backend/`:\n\n```bash\ncd backend\ngunicorn wsgi:app\n```\n\nThe `backend/wsgi.py` file creates the Flask application instance used by the production server.\n\n## Frontend\n\nThe backend must also be running during local frontend development.\n\nInstall frontend dependencies from `frontend/`:\n\n```bash\ncd frontend\nnpm install\n```\n\nRun the frontend development server:\n\n```bash\nnpm run dev\n```\n\nThe Vite development server proxies `/register`, `/login`, `/logout`, and `/tasks` requests to `http://127.0.0.1:5000`, as configured in `frontend/vite.config.js`.\n\nFor a production frontend build, configure the deployed backend URL:\n\n```env\nVITE_API_BASE_URL=https://task-manager-api-yossi.onrender.com\n```\n\nThis value can be provided through `frontend/.env.production` or the frontend deployment environment.\n\n## Frontend Validation\n\nRun the configured frontend lint and production build commands:\n\n```bash\ncd frontend\nnpm run lint\nnpm run build\n```\n\nThe repository does not currently include an automated frontend test suite.\n\n## API Documentation\n\nThe API is documented using OpenAPI 3.0 and Swagger UI.\n\nLocal documentation:\n\n```text\nhttp://127.0.0.1:5000/docs\n```\n\nProduction documentation:\n\n```text\nhttps://task-manager-api-yossi.onrender.com/docs\n```\n\nThe OpenAPI specification is available at:\n\n```text\n/openapi.yaml\n```\n\n## Authentication\n\nProtected endpoints require a JWT access token.\n\nAfter logging in, include the token in the request header:\n\n```http\nAuthorization: Bearer \u003caccess_token\u003e\n```\n\nIn Swagger UI:\n\n1. Register a user with `POST /register`\n2. Log in with `POST /login`\n3. Copy the returned access token\n4. Click `Authorize`\n5. Paste the token\n6. Execute protected task endpoints\n\nSwagger automatically adds the `Bearer` prefix.\n\n## API Endpoints\n\n| Method | Endpoint           | Authentication | Description                             |\n| ------ | ------------------ | -------------: | --------------------------------------- |\n| GET    | `/`                |             No | Check API status                        |\n| GET    | `/about`           |             No | Get project information                 |\n| POST   | `/register`        |             No | Register a user                         |\n| POST   | `/login`           |             No | Log in and receive a JWT                |\n| DELETE | `/logout`          |            Yes | Revoke the current JWT                  |\n| GET    | `/tasks`           |            Yes | Retrieve the authenticated user's tasks |\n| POST   | `/tasks`           |            Yes | Create a task                           |\n| GET    | `/tasks/{task_id}` |            Yes | Retrieve one task                       |\n| PUT    | `/tasks/{task_id}` |            Yes | Update a task                           |\n| DELETE | `/tasks/{task_id}` |            Yes | Delete a task                           |\n\n## Request Examples\n\nRegister:\n\n```http\nPOST /register\nContent-Type: application/json\n```\n\n```json\n{\n  \"username\": \"yossi\",\n  \"password\": \"secure123\"\n}\n```\n\nLog in:\n\n```http\nPOST /login\nContent-Type: application/json\n```\n\n```json\n{\n  \"username\": \"yossi\",\n  \"password\": \"secure123\"\n}\n```\n\nA successful login returns an access token.\n\nCreate a task:\n\n```http\nPOST /tasks\nAuthorization: Bearer \u003caccess_token\u003e\nContent-Type: application/json\n```\n\n```json\n{\n  \"title\": \"Finish API documentation\",\n  \"description\": \"Complete and review the project README\",\n  \"category\": \"work\"\n}\n```\n\nGet all tasks:\n\n```http\nGET /tasks\nAuthorization: Bearer \u003caccess_token\u003e\n```\n\nOptional filters:\n\n```http\nGET /tasks?status=pending\nGET /tasks?category=work\nGET /tasks?status=completed\u0026category=study\n```\n\nUpdate a task:\n\n```http\nPUT /tasks/1\nAuthorization: Bearer \u003caccess_token\u003e\nContent-Type: application/json\n```\n\n```json\n{\n  \"status\": \"completed\"\n}\n```\n\nDelete a task:\n\n```http\nDELETE /tasks/1\nAuthorization: Bearer \u003caccess_token\u003e\n```\n\n## Backend Testing\n\nRun the complete backend test suite from `backend/`:\n\n```bash\ncd backend\npython -m pytest\n```\n\nRun the tests with verbose output:\n\n```bash\ncd backend\npython -m pytest -v\n```\n\nThe test suite covers registration, login, password validation, JWT handling, logout and revocation, task CRUD operations, filtering, ownership, and access isolation.\n\n## Testing with REST Client\n\nThe `backend/requests.http` file contains development request examples for use with tools such as the REST Client extension in Visual Studio Code.\n\nProtected requests require a current JWT access token returned by `POST /login`. Some examples require updating the token or authorization header before they can be executed successfully, so the file should not be treated as a script that runs unchanged from top to bottom.\n\n## Deployment\n\nThe Flask API is deployed on Render using Gunicorn and the WSGI entry point in `backend/wsgi.py`.\n\nRender configuration:\n\n```text\nRoot Directory:\nbackend\n```\n\n```text\nBuild Command:\npip install -r requirements.txt\n```\n\n```text\nStart Command:\ngunicorn wsgi:app\n```\n\nThe backend production environment must include:\n\n```text\nJWT_SECRET_KEY\nFRONTEND_URL=https://task-manager-frontend-pkip.onrender.com\n```\n\n`FRONTEND_URL` allows the deployed frontend origin through the backend CORS configuration.\n\nThe React frontend is deployed separately at:\n\n```text\nhttps://task-manager-frontend-pkip.onrender.com/\n```\n\nIts production environment must set:\n\n```text\nVITE_API_BASE_URL=https://task-manager-api-yossi.onrender.com\n```\n\nDeployment triggers and other Render account settings are managed outside this repository and may vary by service configuration.\n\n## SQLite Deployment Limitation\n\nThis project currently uses SQLite.\n\nWithout persistent disk storage, Render's local filesystem is ephemeral. This means that registered users, revoked tokens, and tasks may be deleted after a restart, redeployment, or infrastructure replacement.\n\nThe deployed application should therefore be treated as a live demonstration rather than permanent data storage.\n\nA production-ready future version should use a persistent database such as PostgreSQL.\n\n## Security\n\n* Passwords are stored as secure hashes rather than plain text\n* JWT authentication protects task routes\n* Each user can access only their own tasks\n* JWT tokens can be revoked during logout\n* Secret keys are loaded from environment variables\n* The `.env` file is excluded from Git\n* The local SQLite database is excluded from Git\n* Protected routes verify the authenticated user's identity\n\n## Future Improvements\n\n* Replace SQLite with PostgreSQL\n* Add database migrations\n* Add token refresh support\n* Add pagination\n* Add task deadlines\n* Add task priorities\n* Add sorting options\n* Add continuous integration with GitHub Actions\n* Add Docker support\n* Add rate limiting\n* Add structured production logging\n\n## Project Status\n\nThe documented backend scope is implemented and covered by automated pytest tests. It includes user authentication, JWT authorization and revocation, user-owned task CRUD operations, filtering, OpenAPI documentation, Swagger UI, and a deployed API.\n\nThe React/Vite frontend is implemented and deployed. It provides registration and login, task creation and editing, status updates, deletion, filtering, and dashboard statistics using the existing backend API.\n\n## AI-Assisted Development\n\nThe repository includes `AGENTS.md` for repository-level AI instructions and a repository-local Codex skill for guarded frontend-only changes.\n\nAI-assisted changes are not treated as automatically trusted. The documented workflow emphasizes scoped requests, minimal diffs, Git status and diff inspection, preservation of existing work, and relevant lint and build validation before changes are accepted.\n\n## Author\n\nYossi Hakim\n\nComputer Science graduate focused on backend development and software engineering.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyossichakim%2Ftask-manager-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyossichakim%2Ftask-manager-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyossichakim%2Ftask-manager-api/lists"}