# asifahmedsahil/full-stack-developer-technical-assessment---jumatechs architecture

> Architecture diagram of the GitHub repository asifahmedsahil/full-stack-developer-technical-assessment---jumatechs, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs
- Repository: https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs

## Overview

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: [`frontend/src/app/conversation/[id]/page.tsx`](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/app/conversation/[id]/page.tsx) (Thread page), [`chat/views.py`](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/views.py) (Inbox API), [`frontend/src/lib/api.ts`](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/lib/api.ts) (API client), [`accounts/views.py`](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/accounts/views.py) (Auth API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_backend["Django backend"]
  node_config["Config<br/>django project"]
  node_accounts_models[("Agent model<br/>auth model<br/>[models.py]")]
  node_accounts_views["Auth API<br/>jwt auth<br/>[views.py]"]
  node_accounts_serializers["Auth serials<br/>drf serializers<br/>[serializers.py]"]
  node_chat_models[("Inbox model<br/>domain model<br/>[models.py]")]
  node_chat_views["Inbox API<br/>drf views<br/>[views.py]"]
  node_chat_serializers["Inbox serials<br/>drf serializers<br/>[serializers.py]"]
  node_chat_sentiment(("Sentiment worker<br/>background thread<br/>[sentiment.py]"))
  node_chat_urls["Chat routes<br/>routing<br/>[urls.py]"]
end

subgraph group_frontend["Next.js frontend"]
  node_frontend_login["Login page<br/>route<br/>[page.tsx]"]
  node_frontend_list["Inbox page<br/>route<br/>[page.tsx]"]
  node_frontend_detail["Thread page<br/>route<br/>[page.tsx]"]
  node_frontend_authguard["Auth guard<br/>ui guard<br/>[AuthGuard.tsx]"]
  node_frontend_list_comp["Conversation list<br/>ui component"]
  node_frontend_composer["Reply composer<br/>ui component"]
  node_frontend_toast(("Toast<br/>ui feedback<br/>[Toast.tsx]"))
  node_frontend_api["API client<br/>fetch wrapper<br/>[api.ts]"]
  node_frontend_auth["Token store<br/>auth storage<br/>[auth.ts]"]
  node_frontend_types["API types<br/>ts types<br/>[index.ts]"]
end

subgraph group_ops["Operations"]
  node_seed_data["Seed users<br/>manage command<br/>[seed_data.py]"]
  node_seed_conversations["Seed inbox<br/>manage command"]
end

node_config -->|"registers API"| node_accounts_views
node_config -->|"registers API"| node_chat_urls
node_accounts_views -->|"uses"| node_accounts_serializers
node_accounts_views -->|"authenticates"| node_accounts_models
node_chat_views -->|"uses"| node_chat_serializers
node_chat_views -->|"reads/writes"| node_chat_models
node_chat_views -.->|"spawns"| node_chat_sentiment
node_chat_sentiment -->|"persists"| node_chat_models
node_chat_urls -->|"routes to"| node_chat_views
node_frontend_login -->|"calls"| node_frontend_api
node_frontend_list -->|"protected by"| node_frontend_authguard
node_frontend_detail -->|"protected by"| node_frontend_authguard
node_frontend_list -->|"renders"| node_frontend_list_comp
node_frontend_detail -->|"renders"| node_frontend_composer
node_frontend_detail -->|"uses"| node_frontend_toast
node_frontend_list_comp -->|"fetches"| node_frontend_api
node_frontend_detail -->|"fetches"| node_frontend_api
node_frontend_api -->|"reads token"| node_frontend_auth
node_frontend_api -->|"typed by"| node_frontend_types
node_frontend_detail -->|"polls/replies"| node_chat_views
node_frontend_login -->|"authenticates"| node_accounts_views
node_seed_data -->|"creates"| node_accounts_models
node_seed_conversations -->|"creates"| node_chat_models

click node_config "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/tree/main/config"
click node_accounts_models "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/accounts/models.py"
click node_accounts_views "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/accounts/views.py"
click node_accounts_serializers "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/accounts/serializers.py"
click node_chat_models "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/models.py"
click node_chat_views "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/views.py"
click node_chat_serializers "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/serializers.py"
click node_chat_sentiment "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/sentiment.py"
click node_chat_urls "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/urls.py"
click node_frontend_login "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/app/login/page.tsx"
click node_frontend_list "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/app/page.tsx"
click node_frontend_detail "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/app/conversation/[id]/page.tsx"
click node_frontend_authguard "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/components/AuthGuard.tsx"
click node_frontend_list_comp "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/components/ConversationList.tsx"
click node_frontend_composer "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/components/MessageComposer.tsx"
click node_frontend_toast "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/components/Toast.tsx"
click node_frontend_api "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/lib/api.ts"
click node_frontend_auth "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/lib/auth.ts"
click node_frontend_types "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/types/index.ts"
click node_seed_data "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/accounts/management/commands/seed_data.py"
click node_seed_conversations "https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/management/commands/seed_conversations.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_config,node_accounts_models,node_accounts_views,node_accounts_serializers,node_chat_models,node_chat_views,node_chat_serializers,node_chat_sentiment,node_chat_urls toneBlue
class node_frontend_login,node_frontend_list,node_frontend_detail,node_frontend_authguard,node_frontend_list_comp,node_frontend_composer,node_frontend_toast,node_frontend_api,node_frontend_auth,node_frontend_types toneAmber
class node_seed_data,node_seed_conversations toneMint
```

## Components

### Django backend

REST API, domain logic, persistence, and background sentiment processing.

- [Config](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/tree/main/config): django project · Wires settings, ASGI/WGI, URLs, and app registration. · `config`
- [Agent model](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/accounts/models.py): auth model · Custom email-based user model and manager for identity. · `accounts/models.py`
- [Auth API](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/accounts/views.py): jwt auth · Register, login, and me endpoints for JWT-based authentication. · `accounts/views.py`
- [Auth serials](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/accounts/serializers.py): drf serializers · Shapes auth payloads for users and token responses. · `accounts/serializers.py`
- [Inbox model](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/models.py): domain model · Conversation, message, lock, and sentiment persistence. · `chat/models.py`
- [Inbox API](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/views.py): drf views · Conversation list/detail, locking, replies, and AI suggestion endpoints. · `chat/views.py`
- [Inbox serials](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/serializers.py): drf serializers · API payloads for conversations, messages, locks, and sentiment state. · `chat/serializers.py`
- [Sentiment worker](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/sentiment.py): background thread · Runs in-process sentiment scoring after replies and writes results. · `chat/sentiment.py`
- [Chat routes](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/urls.py): routing · 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](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/app/login/page.tsx): route · Authentication screen for obtaining and storing tokens. · `frontend/src/app/login/page.tsx`
- [Inbox page](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/app/page.tsx): route · Main conversation list and entry point into the inbox. · `frontend/src/app/page.tsx`
- [Thread page](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/app/conversation/[id]/page.tsx): route · Conversation detail, polling refresh, lock awareness, and reply flow. · `frontend/src/app/conversation/[id]/page.tsx`
- [Auth guard](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/components/AuthGuard.tsx): ui guard · Protects agent routes and redirects unauthenticated users. · `frontend/src/components/AuthGuard.tsx`
- [Conversation list](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/components/ConversationList.tsx): ui component · Renders inbox rows and search/status-driven browsing. · `frontend/src/components/ConversationList.tsx`
- [Reply composer](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/components/MessageComposer.tsx): ui component · Optimistic message submission for agent replies. · `frontend/src/components/MessageComposer.tsx`
- [Toast](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/components/Toast.tsx): ui feedback · Shared transient feedback for UI actions and errors. · `frontend/src/components/Toast.tsx`
- [API client](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/lib/api.ts): fetch wrapper · Centralized HTTP access to the Django API. · `frontend/src/lib/api.ts`
- [Token store](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/lib/auth.ts): auth storage · Handles access-token storage and retrieval for protected calls. · `frontend/src/lib/auth.ts`
- [API types](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/frontend/src/types/index.ts): ts 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](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/accounts/management/commands/seed_data.py): manage command · Creates demo users for local setup. · `accounts/management/commands/seed_data.py`
- [Seed inbox](https://github.com/asifahmedsahil/full-stack-developer-technical-assessment---jumatechs/blob/main/chat/management/commands/seed_conversations.py): manage command · Populates sample conversations and messages. · `chat/management/commands/seed_conversations.py`

## Connections

- 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.
