- AttendanceSession model with open/closed status, org_id, timestamps - POST /api/v1/attendance/check-in/ – creates session, rejects duplicate open check-ins (409) - POST /api/v1/attendance/check-out/ – closes open session, validates checkout > checkin - GET /api/v1/attendance/status/ – current open session for requesting user - GET /api/v1/attendance/history/ – paginated session history per user - GET /api/v1/attendance/admin/sessions/ – admin view for managers/admins with filters - Initial migration with composite indexes on (user, status) and (user, checked_in_at) - 18 test cases covering core flows and edge cases Co-Authored-By: Paperclip <noreply@paperclip.ing>
40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
from rest_framework import serializers
|
|
|
|
from .models import AttendanceSession
|
|
|
|
|
|
class AttendanceSessionSerializer(serializers.ModelSerializer):
|
|
duration_seconds = serializers.SerializerMethodField()
|
|
user_email = serializers.EmailField(source="user.email", read_only=True)
|
|
|
|
class Meta:
|
|
model = AttendanceSession
|
|
fields = [
|
|
"id",
|
|
"user",
|
|
"user_email",
|
|
"org_id",
|
|
"status",
|
|
"checked_in_at",
|
|
"checked_out_at",
|
|
"duration_seconds",
|
|
"notes",
|
|
"created_at",
|
|
"updated_at",
|
|
]
|
|
read_only_fields = ["id", "user", "user_email", "status", "created_at", "updated_at"]
|
|
|
|
def get_duration_seconds(self, obj):
|
|
return obj.duration_seconds
|
|
|
|
|
|
class CheckInSerializer(serializers.Serializer):
|
|
org_id = serializers.UUIDField(required=False, allow_null=True)
|
|
notes = serializers.CharField(required=False, allow_blank=True, default="")
|
|
checked_in_at = serializers.DateTimeField(required=False)
|
|
|
|
|
|
class CheckOutSerializer(serializers.Serializer):
|
|
notes = serializers.CharField(required=False, allow_blank=True)
|
|
checked_out_at = serializers.DateTimeField(required=False)
|