How asifahmedsahil/full-stack-developer-technical-assessment---jumatechs works
1. This repo is a two-tier support inbox: a Django REST backend exposes all data and business rules, and a Next.js 14 frontend renders the agent UI and talks to the backend over HTTP. There is no separate application server or message broker; async behavior is handled in-process.
2. The Django project is split into two domain apps:
- accounts owns identity and authentication.
- chat owns the support inbox domain: conversations, messages, locks, and sentiment records.
config is the top-level Django project that wires settings, URLs, ASGI/WGI, and app registration.
3. Authentication is JWT-based with a custom email-based user model. The flow is:
- register/login via backend auth endpoints,
- receive access/refresh tokens from SimpleJWT,
- frontend stores/uses the access token for all protected API calls,
- /api/auth/me/ returns the current agent profile.
This is the main security boundary around the rest of the API.
4. The core backend data model lives in chat. The important entities are:
- Conversation as the container for a support thread,
- Message for customer/agent messages,
- ConversationLock to enforce single-agent assignment,
- ConversationSentiment to persist background sentiment results.
The lock record is the central coordination mechanism for write access to replies.
5. Conversation access is mostly read-heavy, with a controlled write path:
- list endpoint supports pagination, search by customer_name, and status filtering,
- detail endpoint returns the full message history plus lock/sentiment state,
- reply endpoint checks that the caller owns a valid lock before allowing an agent response,
- lock endpoint acquires or refreshes a 5-minute lock and rejects conflicting ownership.
This creates a clear separation between viewing a conversation and mutating it.
6. The “AI suggestion” feature is deliberately lightweight. A backend endpoint uses a rule-based keyword matcher (refund, shipping, password) to return canned reply suggestions, rather than calling an external LLM service. That keeps the architecture self-contained and deterministic.
7. Sentiment processing is asynchronous but not externally queued. When an agent reply is saved, the backend starts a background thread that computes sentiment from the reply text and writes a ConversationSentiment row. In test mode, this work runs synchronously so the tests can assert outcomes immediately.
8. The frontend is organized by route-first App Router structure:
- /login for authentication,
- the main page for the conversation list,
- /conversation/[id] for conversation detail and replying.
Shared UI behavior is encapsulated in ConversationList, MessageComposer, AuthGuard, and Toast.
9. Frontend state is mostly server-driven through polling. The conversation detail page re-fetches the conversation every 3 seconds when the tab is visible, merges new messages by ID, and clears expired locks in the UI. Reply submission is optimistic, so the UI updates before the next poll round-trip confirms it.
10. The frontend’s data layer is small but important:
- lib/api.ts wraps fetch calls to the Django API,
- lib/auth.ts handles token storage/access,
- type definitions in src/types keep the UI aligned with API payloads.
This is the main boundary between React components and backend contract.
11. Persistence is local and simple: SQLite is the configured database, with Django migrations defining the schema. This makes the system easy to run locally and keeps the deployment story centered on the Django app plus the Next.js frontend.
12. Seed commands are part of the operational architecture:
- seed_data creates demo users,
- seed_conversations populates sample inbox data.
These commands support repeatable local setup and demo workflows without relying on external fixtures.
13. Testing is split along the same boundaries as the runtime architecture:
- Django tests cover auth, conversation rules, locking, and sentiment behavior,
- Jest/React Testing Library covers the key frontend components and interaction flows.
The tests reflect the main system seams: authentication, inbox state, locking, and reply composition.
Main entry points: page.tsx Thread page · chat/views.py Inbox API · api.ts API client · accounts/views.py Auth API
Components 21
Django backend
REST API, domain logic, persistence, and background sentiment processing.
- Config · Wires settings, ASGI/WGI, URLs, and app registration.
config - Agent model · Custom email-based user model and manager for identity.
accounts/models.py - Auth API · Register, login, and me endpoints for JWT-based authentication.
accounts/views.py - Auth serials · Shapes auth payloads for users and token responses.
accounts/serializers.py - Inbox model · Conversation, message, lock, and sentiment persistence.
chat/models.py - Inbox API · Conversation list/detail, locking, replies, and AI suggestion endpoints.
chat/views.py - Inbox serials · API payloads for conversations, messages, locks, and sentiment state.
chat/serializers.py - Sentiment worker · Runs in-process sentiment scoring after replies and writes results.
chat/sentiment.py - Chat routes · Exposes the inbox endpoints under the Django API.
chat/urls.py
Next.js frontend
Agent UI, polling, optimistic reply flow, and API client boundary.
- Login page · Authentication screen for obtaining and storing tokens.
frontend/src/app/login/page.tsx - Inbox page · Main conversation list and entry point into the inbox.
frontend/src/app/page.tsx - Thread page · Conversation detail, polling refresh, lock awareness, and reply flow.
frontend/src/app/conversation/[id]/page.tsx - Auth guard · Protects agent routes and redirects unauthenticated users.
frontend/src/components/AuthGuard.tsx - Conversation list · Renders inbox rows and search/status-driven browsing.
frontend/src/components/ConversationList.tsx - Reply composer · Optimistic message submission for agent replies.
frontend/src/components/MessageComposer.tsx - Toast · Shared transient feedback for UI actions and errors.
frontend/src/components/Toast.tsx - API client · Centralized HTTP access to the Django API.
frontend/src/lib/api.ts - Token store · Handles access-token storage and retrieval for protected calls.
frontend/src/lib/auth.ts - API types · Shared type definitions aligned with backend payloads.
frontend/src/types/index.ts
Operations
Local setup and persistence pieces that support development and demo workflows.
- Seed users · Creates demo users for local setup.
accounts/management/commands/seed_data.py - Seed inbox · Populates sample conversations and messages.
chat/management/commands/seed_conversations.py
Connections 23
- Config → Auth API: registers API · Project URLs and app wiring expose authentication endpoints.
- Config → Chat routes: registers API · Project URLs and app wiring expose inbox endpoints.
- Auth API → Auth serials: uses · Auth endpoints validate and shape request/response payloads.
- Auth API → Agent model: authenticates · JWT login and current-user lookup depend on the custom user model.
- Inbox API → Inbox serials: uses · Inbox endpoints serialize conversation, message, lock, and sentiment data.
- Inbox API → Inbox model: reads/writes · List, detail, lock, and reply flows operate on the core inbox entities.
- Inbox API → Sentiment worker: spawns · Saving an agent reply starts in-process sentiment computation.
- Sentiment worker → Inbox model: persists · Background sentiment work writes ConversationSentiment records.
- Chat routes → Inbox API: routes to · API paths dispatch into inbox handlers.
- Login page → API client: calls · Login submits credentials through the shared fetch wrapper.
- Inbox page → Auth guard: protected by · Inbox routes require authenticated access.
- Thread page → Auth guard: protected by · Conversation detail requires authenticated access.
- Inbox page → Conversation list: renders · The main page delegates inbox browsing to the list component.
- Thread page → Reply composer: renders · The thread page delegates reply entry to the composer.
- Thread page → Toast: uses · Feedback and errors surface through shared toast messaging.
- Conversation list → API client: fetches · Conversation data is loaded from the backend API.
- Thread page → API client: fetches · Thread polling and reply actions go through the API client.
- API client → Token store: reads token · Protected requests attach the stored access token.
- API client → API types: typed by · Frontend request and response handling follows shared TypeScript types.
- Thread page → Inbox API: polls/replies · Conversation detail repeatedly refreshes and posts replies over HTTP.
- Login page → Auth API: authenticates · Login and token refresh flow against backend auth endpoints.
- Seed users → Agent model: creates · Demo user seeding relies on the auth model.
- Seed inbox → Inbox model: creates · Inbox seeding populates conversations, messages, and related records.