Skip to content

Commit 0c4b445

Browse files
authored
Merge pull request #19 from akirachix/develop
Develop
2 parents b7d87f6 + c1d72b7 commit 0c4b445

File tree

2 files changed

+109
-24
lines changed

2 files changed

+109
-24
lines changed

README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,101 @@
1+
# MyHaki Backend
12

3+
## Overview
4+
MyHaki is an AI-driven legal aid management system designed to streamline coordination between lawyers, families of pretrial detainees, and the Law Society of Kenya (LSK). The backend, built with Django REST Framework, provides secure API endpoints for user management, case applications, verification, assignment, tracking, and CPD points tracking. The platform leverages AI to classify and prioritize cases, enabling automated matching and assignment of lawyers to cases for efficient and transparent access to justice.
5+
6+
## Features
7+
- User registration, login, and authentication
8+
- CRUD operations for users, case applications, verification, assignment, tracking, and reporting
9+
- Modular architecture for easy extension and maintainability
10+
- Role-based access control for lawyers, LSK administrators, and detainee families
11+
- Secure endpoints protected with token-based authentication
12+
- AI-powered case classification, prioritization, and automated lawyer assignment
13+
- CPD points tracking for lawyers participating in pro bono services
14+
- Monthly analytics and reports for LSK oversight
15+
- API documentation with Swagger UI
16+
17+
## Technology Stack
18+
- Python 3.10+
19+
- Django 4.2+
20+
- Django REST Framework
21+
- drf-yasg (Swagger API docs)
22+
- PostgreSQL
23+
- Token authentication (via DRF)
24+
- Android (mobile clients for detainees/families and lawyers)
25+
- Progressive Web App (for LSK admins)
26+
27+
## Getting Started
28+
29+
### Prerequisites
30+
31+
- Python 3.10 or higher
32+
- pip package manager
33+
- Virtual environment tool
34+
- PostgreSQL database
35+
36+
### Installation
37+
38+
1. **Clone this repository:**
39+
```bash
40+
git clone https://github.com/akirachix/myhaki-backend.git
41+
cd myhaki-backend
42+
```
43+
44+
2. **Create and activate a virtual environment:**
45+
**Linux/macOS:**
46+
```bash
47+
python -m venv venv
48+
source venv/bin/activate
49+
```
50+
**Windows:**
51+
```cmd
52+
python -m venv venv
53+
venv\Scripts\activate
54+
```
55+
56+
3. **Install dependencies:**
57+
```bash
58+
pip install -r requirements.txt
59+
```
60+
61+
4. **Set environment variables and update `settings.py`:**
62+
- Configure your database connection, secret key, and any external API keys (if applicable).
63+
- Copy `.env.example` to `.env` and fill in your settings.
64+
65+
5. **Run database migrations:**
66+
```bash
67+
python manage.py migrate
68+
```
69+
70+
6. **Create a superuser for admin access:**
71+
```bash
72+
python manage.py createsuperuser
73+
```
74+
75+
7. **Collect static files:**
76+
```bash
77+
python manage.py collectstatic
78+
```
79+
80+
8. **Start the development server:**
81+
```bash
82+
python manage.py runserver
83+
```
84+
85+
## API Documentation
86+
87+
- **Swagger UI:** [https://myhaki-3e53581dd62e.herokuapp.com/swagger/](https://myhaki-3e53581dd62e.herokuapp.com/swagger/)
88+
- **Redoc:** [https://myhaki-3e53581dd62e.herokuapp.com/redoc/](https://myhaki-3e53581dd62e.herokuapp.com/redoc/)
89+
90+
## Usage
91+
92+
- Endpoints for user registration, authentication, case applications, assignment, tracking, and reporting are accessible via the API.
93+
- Mobile apps for detainees/families and lawyers communicate with the backend using secure REST endpoints.
94+
- Role-based access ensures only authorized users can access sensitive data and operations.
95+
96+
## Contribution & Contacts
97+
98+
- For questions, issues, or contributions, please open an issue or discussion in this repository.
99+
- Core team: Yordanos Hagos, Fiona Wesonga, Mahder Belete, Saloi Akeza, Lwam Bisrat
100+
101+
---

api/serializers.py

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import os
1010
from dotenv import load_dotenv
1111
from cases.tasks import async_assign_case
12+
import logging
1213

1314

1415
load_dotenv()
@@ -37,7 +38,8 @@ class Meta:
3738

3839

3940
class CaseSerializer(serializers.ModelSerializer):
40-
detainee = DetaineeSerializer(read_only=True)
41+
detainee = serializers.PrimaryKeyRelatedField(queryset=Detainee.objects.all(), required=True )
42+
detainee_details = DetaineeSerializer(source='detainee', read_only=True)
4143
assigned_lawyer = LawyerProfileSerializer(source='assignments.first.lawyer', read_only=True)
4244
predicted_case_type = serializers.CharField(required=False)
4345
predicted_urgency_level = serializers.CharField(required=False)
@@ -113,7 +115,12 @@ def create(self, validated_data):
113115
validated_data['predicted_urgency_level'] = predicted_urgency
114116

115117
case = super().create(validated_data)
116-
async_assign_case.delay(case.case_id)
118+
try:
119+
async_assign_case.delay(case.case_id)
120+
except Exception as e:
121+
logger = logging.getLogger("django")
122+
logger.error(f"Celery async_assign_case failed for case_id {case.case_id}: {e}")
123+
117124
return case
118125

119126
def update(self, instance, validated_data):
@@ -323,7 +330,6 @@ def to_representation(self, instance):
323330
data.pop(field, None)
324331
return data
325332

326-
327333
class LawyerRegistrationSerializer(serializers.ModelSerializer):
328334
email = serializers.EmailField(required=True)
329335
password = serializers.CharField(write_only=True, required=True, min_length=8)
@@ -344,8 +350,6 @@ def validate_practice_number(self, value):
344350
return value
345351
except LawyerProfile.DoesNotExist:
346352
raise serializers.ValidationError("No lawyer found with this practice number.")
347-
348-
349353
def create(self, validated_data):
350354
password = validated_data.pop('password')
351355
practice_number = validated_data.pop('practice_number')
@@ -363,25 +367,6 @@ def create(self, validated_data):
363367
user.save()
364368
lawyer_profile.verified = True
365369
lawyer_profile.save()
366-
first_name = validated_data.pop('first_name')
367-
last_name = validated_data.pop('last_name')
368-
email = validated_data.pop('email')
369-
370-
371-
lawyer_profile = LawyerProfile.objects.get(practice_number__iexact=practice_number.strip().upper())
372-
373-
user = lawyer_profile.user
374-
user.email = email
375-
user.first_name = first_name
376-
user.last_name = last_name
377-
user.role = 'lawyer'
378-
user.is_active = True
379-
user.set_password(password)
380-
user.save()
381-
382-
lawyer_profile.verified = True
383-
lawyer_profile.save()
384-
385370
return user
386371

387372

0 commit comments

Comments
 (0)