feat: Phase 1+2 - JWT auth, dashboard metrics API, DB indexes

Phase 1 - JWT Auth Foundation:
- Replace token auth with djangorestframework-simplejwt
- POST /api/v1/admin/auth/login/ - returns access + refresh JWT
- POST /api/v1/auth/refresh/ - JWT refresh
- GET /api/v1/auth/me/ - current admin profile
- GET /api/v1/health/ - DB health check
- Add ledger app to INSTALLED_APPS

Phase 2 - Dashboard Metrics API:
- GET /api/v1/dashboard/metrics/ - revenue, partners, events, tickets
- GET /api/v1/dashboard/revenue/ - 7-day revenue vs payouts chart data
- GET /api/v1/dashboard/activity/ - last 10 platform events feed
- GET /api/v1/dashboard/actions/ - KYC queue, flagged events, pending payouts

DB Indexes (dashboard query optimisation):
- RazorpayTransaction: status, captured_at
- Partner: status, kyc_compliance_status
- Event: event_status, start_date, created_date
- Booking: created_date
- PaymentTransaction: payment_type, payment_transaction_status, payment_transaction_date

Infra:
- Add Dockerfile for eventify-backend container
- Add simplejwt to requirements.txt
- All 4 dashboard views use IsAuthenticated permission class
This commit is contained in:
Ubuntu
2026-03-24 17:46:41 +00:00
parent 37001f8e70
commit b60d03142c
14 changed files with 416 additions and 94 deletions

View File

@@ -1,9 +1,20 @@
{% extends 'base.html' %}
{% block content %}
<div class="d-flex justify-content-between mb-3">
<h3>Events</h3>
<a class="btn btn-success" href="{% url 'events:event_add' %}">Add Event</a>
<div class="row mb-3">
<div class="col-md-6">
<h3>Events</h3>
</div>
<div class="col-md-4">
<form method="get" action="." class="d-flex">
<input class="form-control me-2" type="search" name="q" placeholder="Search events..." aria-label="Search" value="{{ request.GET.q }}">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
<div class="col-md-2 text-end">
<a class="btn btn-success" href="{% url 'events:event_add' %}">Add Event</a>
</div>
</div>
<table class="table table-hover">
<thead>
<tr>
@@ -44,4 +55,35 @@
{% endfor %}
</tbody>
</table>
<!-- Pagination -->
{% if is_paginated %}
<nav aria-label="Page navigation">
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">&laquo; First</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">Previous</a>
</li>
{% endif %}
<li class="page-item disabled">
<span class="page-link">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
</span>
</li>
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">Next</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">Last &raquo;</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% endblock %}