A real-time web-based chat application built with Django, Django Channels, PostgreSQL, and Redis.
| Feature | Description |
|---|---|
| Real-time Messaging | Instant messaging powered by WebSockets via Django Channels and Redis |
| Read Receipts | One tick for sent, two for delivered, two coloured once the message has been seen, on both the bubble and the conversation card |
| Friend System | Send, accept, decline, and cancel friend requests effortlessly |
| OTP Authentication | Passwordless login using single-use codes sent by email, with expiry and attempt limits |
| Profile Sharing | Generate and share your profile using automatically generated QR codes and encrypted links |
| Dark / Light Mode | Toggle between responsive light and dark themes |
| Secure Link Encryption | Profile and conversation links are authenticated with Fernet (AES-CBC + HMAC) |
| Non-blocking Architecture | Asynchronous WebSocket consumer with synchronous database work offloaded |
Real-time chat interface featuring instant message delivery, timestamps, and active status.
Easily connect with others using encrypted QR codes or direct profile links.
Manage your connections, view active friends, and handle incoming requests on the fly.
The fastest path is Docker, which brings PostgreSQL and Redis with it. Nothing else to install.
git clone <repository-url>
cd orca
cp .env.example .env
# Edit .env: set SECRET_KEY, FERNET_KEY, and your Gmail app password.
# Leave DATABASE_URL and REDIS_URL blank to use the bundled database containers.
# To use a hosted PostgreSQL instead, set DATABASE_URL and adjust COMPOSE_PROFILES.
# Add pgadmin to COMPOSE_PROFILES for a web UI on http://127.0.0.1:5050
# See docs/DEVELOPMENT.md#choosing-your-databases
docker compose up --build -dOpen http://127.0.0.1:8004/.
Prefer to run it directly? You will need Python 3.12+, PostgreSQL, and Redis. The databases can still be the bundled containers:
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # then fill it in
docker compose up -d postgres redis # or use your own servers
python manage.py migrate
python manage.py runasgiSign-in sends a one-time code by email, so working EMAIL_HOST_USER and
EMAIL_HOST_PASSWORD values are required to get past the login screen.
Full setup, every environment variable, and troubleshooting: docs/DEVELOPMENT.md
| Document | Contents |
|---|---|
| Development guide | Running locally or with Docker, environment variables, what DATABASE_URL should be, pgAdmin, email setup, commands, troubleshooting |
| Architecture | Tech stack, data model, request flows, real-time messaging design, security model, project layout |
| Layer | Technology |
|---|---|
| Frontend | HTML, CSS, JavaScript |
| Backend | Python, Django, Django Channels (WebSockets) |
| Database | PostgreSQL (auth, OTPs, profiles, friendships, messages) |
| In-memory store | Redis (Channels layer and rate limiting) |
| Security | cryptography.fernet (authenticated symmetric encryption) |
See Architecture for how these fit together.
python manage.py test
flake8 .The suite needs PostgreSQL (it creates and drops its own test database) but not Redis. CI runs the same on Python 3.12 and 3.13.
This started as an early solo learning project, and some parts still show it. Honest list of what is not done:
- No message pagination. A conversation loads its full history on every open, which will not scale past a few thousand messages.
- Messages are stored in plaintext. There is no end-to-end encryption; the link encryption covers URLs, not message bodies.
- Chat sockets are only authorized per message. A client is admitted to the Channels group named by the URL without a membership check, so a non-member who learned a conversation id could observe traffic, though not write to it.
- No typing indicators, presence, or media attachments. Read receipts are in: one tick sent, two delivered, two coloured once seen. Delivery is stamped when the recipient loads their conversation list, so a recipient who never opens the app in a session is not counted as having received anything.
- Push notification keys are configurable but unused. No service worker subscription flow is wired up yet.
- Test coverage is focused on auth and authorization. The WebSocket consumer is not yet covered by automated tests.
Released under the MIT License.



