{"id":30176100,"url":"https://github.com/emhash/subscription-management-system","last_synced_at":"2026-02-08T08:05:20.463Z","repository":{"id":307662803,"uuid":"1030283702","full_name":"emhash/Subscription-Management-System","owner":"emhash","description":"Subscription mangement MVT and RESTApi project","archived":false,"fork":false,"pushed_at":"2025-08-29T10:06:39.000Z","size":542,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-29T14:03:42.689Z","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/emhash.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}},"created_at":"2025-08-01T11:33:52.000Z","updated_at":"2025-08-29T09:58:55.000Z","dependencies_parsed_at":"2025-08-29T12:05:00.079Z","dependency_job_id":"729c81a9-91df-460c-a65c-4dca795b4919","html_url":"https://github.com/emhash/Subscription-Management-System","commit_stats":null,"previous_names":["emhash/subscription-management-system"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/emhash/Subscription-Management-System","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emhash%2FSubscription-Management-System","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emhash%2FSubscription-Management-System/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emhash%2FSubscription-Management-System/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emhash%2FSubscription-Management-System/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emhash","download_url":"https://codeload.github.com/emhash/Subscription-Management-System/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emhash%2FSubscription-Management-System/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29225039,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-08T06:05:31.539Z","status":"ssl_error","status_checked_at":"2026-02-08T05:58:33.853Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2025-08-12T02:19:57.396Z","updated_at":"2026-02-08T08:05:20.444Z","avatar_url":"https://github.com/emhash.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Subscription Management System\nA subscription management system with MVT architecture and REST API\n\n\n## Highlighted Features\n\n### 1. Environment-Based Settings Management\nThe system supports multiple environment configurations for flexible deployment:\n\n**Development (Default):**\n```bash\nSETTINGS_MODULE=core.settings.local\n```\n- Uses SQLite3 database\n- Debug mode enabled\n- Local development optimizations\n\n**Production:**\n```bash\nSETTINGS_MODULE=core.settings.production\n```\n- Uses MySQL database\n- Debug mode disabled\n- Production security settings\n\n### 2. Centralized API Response Management\nThe `respond` folder contains a sophisticated response management system:\n\n**StandardizedJSONRenderer** (`respond/renderers.py`):\n- Automatically standardizes all API responses\n- Consistent response format across all endpoints\n- Proper error handling and validation\n- Clean JSON structure with success/error indicators\n\n**Response Format:**\n```json\n{\n    \"success\": true,\n    \"status_code\": 200,\n    \"message\": \"Operation successful\",\n    \"data\": {...}\n}\n```\n\n**Error Handling:**\n```json\n{\n    \"success\": false,\n    \"status_code\": 400,\n    \"message\": \"Validation error occurred.\",\n    \"error_details\": {\n        \"field\": \"plan_id\",\n        \"message\": \"This field is required.\"\n    }\n}\n```\n\n## Setup Instructions\n\n### 1. Clone the Repository\n```bash\ngit clone https://github.com/emhash/Subscription-Management-System.git\ncd subscribe\n```\n\n### 2. Environment Setup\n```bash\npython -m venv venv\nsource venv/bin/activate\n```\nOn Windows:\n```bash\nsource venv\\Scripts\\activate\n```\n\n### 3. Install Dependencies\n```bash\npip install -r requirements.txt\n```\n\n### 4. Environment Configuration\n```bash\ncp .env.save .env\n```\nEdit `.env` with your configuration\n\n### 5. Database Setup\n```bash\npython manage.py migrate\npython manage.py create_sample_data\npython manage.py createsuperuser\n```\n\n### Management Commands\nCustom Django management commands for system administration:\n\n**Create Sample Data:**\n```bash\npython manage.py create_sample_data\n```\n- Creates test users, plans, and subscriptions\n- Populates database with realistic data\n- Perfect for development and testing\n\n**Test Celery Tasks:**\n```bash\npython manage.py test_celery\n```\n- Tests background task execution\n- Validates Celery configuration\n- Ensures periodic tasks are working\n\n### 6. Run the Server\n```bash\npython manage.py runserver\n```\nRun Celery:\n```bash\ncelery -A core worker --loglevel=INFO --pool=solo\n```\nRun Celery Beat:\n```bash\ncelery -A core beat --scheduler django_celery_beat.schedulers:DatabaseScheduler\n```\n\n## Project Architecture:\n\n### Directory Structure\n```\nsubscribe/\n├── core/\n│   ├── settings/\n│   │   ├── configurations/\n│   │   │   ├── restapi.py\n│   │   │   ├── celery_settings.py\n│   │   │   └── content_path.py\n│   │   ├── credentials/\n│   │   │   ├── stripe.py\n│   │   │   └── sslcommerz.py\n│   │   ├── base.py\n│   │   ├── local.py\n│   │   └── production.py\n│   ├── urls.py\n│   ├── wsgi.py\n│   ├── asgi.py\n│   └── celery.py\n├── apps/\n│   └── subscription/\n│       ├── management/\n│       │   └── commands/\n│       │       ├── create_sample_data.py\n│       │       └── test_celery.py\n│       ├── views/\n│       │   ├── api_view.py\n│       │   └── mvt_view.py\n│       ├── migrations/\n│       ├── models.py\n│       ├── serializers.py\n│       ├── tasks.py\n│       ├── utils.py\n│       ├── admin.py\n│       ├── urls.py\n│       ├── views.py\n│       ├── apps.py\n│       └── tests.py\n├── templates/\n│   ├── base.html\n│   └── subscriptions/\n│       └── subscription_list.html\n├── static/\n├── staticfiles/\n├── media/\n├── respond/\n│   ├── renderers.py\n│   └── utils.py\n├── scripts/\n├── manage.py\n├── requirements.txt\n└── db.sqlite3\n```\n\n### Technology Stack\n- **Backend**: Django 5.2.4, Django REST Framework\n- **Database**: SQLite3 (local), MySQL (production)\n- **Authentication**: JWT (JSON Web Tokens)\n- **Background Tasks**: Celery with Redis\n- **Frontend**: Bootstrap 5, Django Templates\n- **API Documentation**: DRF Spectacular (Swagger/OpenAPI)\n\n## Snippets for Clone and Run the Project:\n\n### Quick Start Commands\n\nClone and setup:\n```bash\ngit clone https://github.com/emhash/Subscription-Management-System.git\ncd subscribe\n```\n```\npython -m venv venv\nsource venv/bin/activate  \n```\n\nor, On Windows:\n```bash\nsource venv\\Scripts\\activate\n```\n\nInstall dependencies:\n```bash\npip install -r requirements.txt\n```\n\nEnvironment setup (Edit .env with your configuration):\n```bash\ncp .env.save .env\n```\n\nDatabase setup:\n```bash\npython manage.py migrate\npython manage.py create_sample_data\npython manage.py createsuperuser\n```\n\nRun the server:\n```bash\npython manage.py runserver\n```\n\n## API Testing\n\nGet JWT token:\n```bash\ncurl -X POST http://127.0.0.1:8000/api/auth/token/ \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"username\": \"sampleuser\", \"password\": \"testuser1234\"}'\n```\n\nList plans:\n```bash\ncurl -X GET http://127.0.0.1:8000/api/plans/ \\\n  -H \"Authorization: Bearer YOUR_TOKEN\"\n```\n\nCreate subscription:\n```bash\ncurl -X POST http://127.0.0.1:8000/api/subscribe/ \\\n  -H \"Authorization: Bearer YOUR_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"plan_id\": 1}'\n```\n\nList user subscriptions:\n```bash\ncurl -X GET http://127.0.0.1:8000/api/subscriptions/ \\\n  -H \"Authorization: Bearer YOUR_TOKEN\"\n```\n\nCancel subscription:\n```bash\ncurl -X POST http://127.0.0.1:8000/api/cancel/ \\\n  -H \"Authorization: Bearer YOUR_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"subscription_id\": 1}'\n```\n\nGet exchange rate:\n```bash\ncurl -X GET \"http://127.0.0.1:8000/api/exchange-rate/?base=USD\u0026target=BDT\" \\\n  -H \"Authorization: Bearer YOUR_TOKEN\"\n```\n\nGet exchange rate history:\n```bash\ncurl -X GET \"http://127.0.0.1:8000/api/exchange-rate/history/?base=USD\u0026target=BDT\" \\\n  -H \"Authorization: Bearer YOUR_TOKEN\"\n```\n\n## About The Project Flow\n\n### Models (MVT Pattern) Flow:\n1. **User Model**: Django's built-in User model for authentication\n2. **Plan Model**: Defines subscription plans with name, price, and duration\n3. **Subscription Model**: Links users to plans with status tracking\n4. **ExchangeRateLog Model**: Stores currency exchange rate history\n\n### REST API Testing Flow:\n1. **Authentication**: Obtain JWT token via `/api/auth/token/`\n2. **Plan Management**: List available plans via `/api/plans/`\n3. **Subscription Operations**:\n   - Create: `POST /api/subscribe/`\n   - List: `GET /api/subscriptions/`\n   - Cancel: `POST /api/cancel/`\n4. **Exchange Rates**: `GET /api/exchange-rate/?base=USD\u0026target=BDT`\n\n### Currency Exchange API Integration Flow:\n1. **External API**: Integrates with exchangerate-api.com\n2. **Real-time Fetching**: API calls for current exchange rates\n3. **Database Storage**: All rates stored in ExchangeRateLog model\n4. **History Tracking**: Historical rate data available via API\n\n### Celery Task (Celery+Redis) Flow:\n1. **Background Processing**: Periodic exchange rate fetching\n2. **Task Scheduling**: Hourly updates via Celery Beat\n3. **Database Updates**: Automatic logging of exchange rates\n4. **Error Handling**: Robust error handling and logging\n\n## API Endpoints\n\n### Authentication\n- `POST /api/auth/token/` - Get JWT access token\n- `POST /api/auth/token/refresh/` - Refresh JWT token\n\n### Subscription Management\n- `GET /api/plans/` - List all subscription plans\n- `POST /api/subscribe/` - Create new subscription\n- `GET /api/subscriptions/` - List user's subscriptions\n- `POST /api/cancel/` - Cancel active subscription\n\n### Exchange Rates\n- `GET /api/exchange-rate/` - Get current exchange rate\n- `GET /api/exchange-rate/history/` - Get exchange rate history\n\n### Documentation\n- `GET /api/docs/` - Swagger UI documentation\n- `GET /api/schema/` - OpenAPI schema\n- `GET /api/redoc/` - ReDoc documentation\n\n## API Sample Responses\n\n### Authentication Responses\n\n**Success - JWT Token:**\n```json\n{\n    \"success\": true,\n    \"status_code\": 200,\n    \"message\": \"\",\n    \"data\": {\n        \"refresh\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n        \"access\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\n    }\n}\n```\n\n**Error - Invalid Credentials:**\n```json\n{\n    \"success\": false,\n    \"status_code\": 401,\n    \"message\": \"Invalid credentials\",\n    \"error_details\": {\n        \"detail\": \"No active account found with the given credentials\"\n    }\n}\n```\n\n### Subscription Management Responses\n\n**Success - List Plans:**\n```json\n{\n    \"success\": true,\n    \"status_code\": 200,\n    \"message\": \"Plans retrieved successfully\",\n    \"data\": {\n        \"count\": 5,\n        \"data\": [\n            {\n                \"id\": 1,\n                \"name\": \"Basic Plan\",\n                \"price\": \"9.99\",\n                \"duration_days\": 30,\n                \"created_at\": \"2025-08-03T13:45:50.107637+06:00\",\n                \"updated_at\": \"2025-08-03T13:45:50.107637+06:00\"\n            },\n            {\n                \"id\": 2,\n                \"name\": \"Premium Plan\",\n                \"price\": \"19.99\",\n                \"duration_days\": 30,\n                \"created_at\": \"2025-08-03T13:45:50.195691+06:00\",\n                \"updated_at\": \"2025-08-03T13:45:50.195691+06:00\"\n            }\n        ]\n    }\n}\n```\n\n**Success - Create Subscription:**\n```json\n{\n    \"success\": true,\n    \"status_code\": 201,\n    \"message\": \"Subscription created successfully\",\n    \"data\": {\n        \"data\": {\n            \"id\": 5,\n            \"user\": {\n                \"id\": 5,\n                \"username\": \"testuser\",\n                \"email\": \"test@example.com\",\n                \"first_name\": \"\",\n                \"last_name\": \"\"\n            },\n            \"plan\": {\n                \"id\": 1,\n                \"name\": \"Basic Plan\",\n                \"price\": \"9.99\",\n                \"duration_days\": 30\n            },\n            \"plan_name\": \"Basic Plan\",\n            \"plan_price\": \"9.99\",\n            \"start_date\": \"2025-08-03T14:43:13.306213+06:00\",\n            \"end_date\": \"2025-09-02T14:43:13.306213+06:00\",\n            \"status\": \"active\",\n            \"days_remaining\": 29,\n            \"is_expired\": false,\n            \"created_at\": \"2025-08-03T14:43:13.306213+06:00\",\n            \"updated_at\": \"2025-08-03T14:43:13.306213+06:00\"\n        }\n    }\n}\n```\n\n**Success - List User Subscriptions:**\n```json\n{\n    \"success\": true,\n    \"status_code\": 200,\n    \"message\": \"Subscriptions retrieved successfully\",\n    \"data\": {\n        \"count\": 1,\n        \"data\": [\n            {\n                \"id\": 4,\n                \"user\": {\n                    \"id\": 5,\n                    \"username\": \"testuser\",\n                    \"email\": \"test@example.com\"\n                },\n                \"plan\": {\n                    \"id\": 1,\n                    \"name\": \"Basic Plan\",\n                    \"price\": \"9.99\",\n                    \"duration_days\": 30\n                },\n                \"plan_name\": \"Basic Plan\",\n                \"plan_price\": \"9.99\",\n                \"start_date\": \"2025-08-03T14:43:13.306213+06:00\",\n                \"end_date\": \"2025-09-02T14:43:13.306213+06:00\",\n                \"status\": \"active\",\n                \"days_remaining\": 29,\n                \"is_expired\": false\n            }\n        ]\n    }\n}\n```\n\n**Success - Cancel Subscription:**\n```json\n{\n    \"success\": true,\n    \"status_code\": 200,\n    \"message\": \"Subscription cancelled successfully\",\n    \"data\": {\n        \"data\": {\n            \"id\": 4,\n            \"user\": {\n                \"id\": 5,\n                \"username\": \"testuser\",\n                \"email\": \"test@example.com\"\n            },\n            \"plan\": {\n                \"id\": 1,\n                \"name\": \"Basic Plan\",\n                \"price\": \"9.99\",\n                \"duration_days\": 30\n            },\n            \"plan_name\": \"Basic Plan\",\n            \"plan_price\": \"9.99\",\n            \"start_date\": \"2025-08-03T14:43:13.306213+06:00\",\n            \"end_date\": \"2025-09-02T14:43:13.306213+06:00\",\n            \"status\": \"cancelled\",\n            \"days_remaining\": 0,\n            \"is_expired\": false\n        }\n    }\n}\n```\n\n### Exchange Rate Responses\n\n**Success - Get Exchange Rate:**\n```json\n{\n    \"success\": true,\n    \"status_code\": 200,\n    \"message\": \"Exchange rate retrieved successfully\",\n    \"data\": {\n        \"data\": {\n            \"base_currency\": \"USD\",\n            \"target_currency\": \"BDT\",\n            \"rate\": 122.332526,\n            \"fetched_at\": \"2025-08-03T08:43:45.888163Z\",\n            \"message\": \"Exchange rate fetched successfully\"\n        }\n    }\n}\n```\n\n**Success - Exchange Rate History:**\n```json\n{\n    \"success\": true,\n    \"status_code\": 200,\n    \"message\": \"Exchange rate history retrieved successfully\",\n    \"data\": {\n        \"count\": 1,\n        \"data\": [\n            {\n                \"id\": 1,\n                \"base_currency\": \"USD\",\n                \"target_currency\": \"BDT\",\n                \"rate\": \"122.332526\",\n                \"fetched_at\": \"2025-08-03T14:43:45.888163+06:00\"\n            }\n        ]\n    }\n}\n```\n\n### Error Responses\n\n**Validation Error:**\n```json\n{\n    \"success\": false,\n    \"status_code\": 400,\n    \"message\": \"Validation error occurred.\",\n    \"error_details\": {\n        \"field\": \"plan_id\",\n        \"message\": \"This field is required.\"\n    }\n}\n```\n\n**Authentication Error:**\n```json\n{\n    \"success\": false,\n    \"status_code\": 401,\n    \"message\": \"Authentication credentials were not provided.\",\n    \"error_details\": {\n        \"detail\": \"Authentication credentials were not provided.\"\n    }\n}\n```\n\n**Not Found Error:**\n```json\n{\n    \"success\": false,\n    \"status_code\": 404,\n    \"message\": \"Plan not found.\",\n    \"error_details\": {\n        \"field\": \"plan_id\",\n        \"message\": \"Plan not found.\"\n    }\n}\n```\n\n**Unsupported Currency Error:**\n```json\n{\n    \"success\": false,\n    \"status_code\": 400,\n    \"message\": \"Currency pair EUR/USD not supported yet\",\n    \"error_details\": {\n        \"success\": false\n    }\n}\n```\n\n**Server Error:**\n```json\n{\n    \"success\": false,\n    \"status_code\": 500,\n    \"message\": \"Failed to create subscription: Database error\",\n    \"error_details\": {\n        \"message\": \"Failed to create subscription: Database error\"\n    }\n}\n```\n\n## Frontend Pages\n- `/` - Main subscription list page (no login required)\n- `/admin/` - Django admin interface\n\n\n## Screenshots\n\n### Sample Data Creation\n![Create Sample Data](xtra(Screen%20Shots)/creates-sample-data.jpg)\n*Management command to create sample data for testing the system*\n\n### Celery Beat Success\n![Celery Beat Success](xtra(Screen%20Shots)/celery-beat-success-sample.jpg)\n*Background task execution showing successful periodic exchange rate fetching*\n\n### Celery Test Management Command\n![Celery Test](xtra(Screen%20Shots)/celery-test-management-command.jpg)\n*Testing Celery background tasks using Django management commands*\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femhash%2Fsubscription-management-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femhash%2Fsubscription-management-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femhash%2Fsubscription-management-system/lists"}