Backend Architecture & System Flow

Understanding how CuratorAI's backend systems work, connect, and interact with each other

📑 Table of Contents

System Overview

CuratorAI is an AI-powered fashion recommendation platform. The backend serves as the central intelligence layer connecting users, their preferences, wardrobe items, outfit recommendations, social interactions, and e-commerce.

🏗️ Technology Stack

🐍

Django 5.0

Web Framework

🔌

DRF

REST API

🗄️

PostgreSQL

Database

🔐

JWT

Auth

☁️

AWS S3

Storage

⚡

Redis

Cache

✨ Core Components

  • 🔐 Authentication: JWT + OAuth
  • 👤 User Management: Profiles & Preferences
  • 👔 Wardrobe: Personal Inventory
  • 👕 Outfits: Recommendations & Creation
  • 📱 Social Feed: Posts, Comments, Likes
  • 📚 Lookbooks: Curated Collections
  • 🛒 Shopping Cart: E-commerce
  • 🔔 Notifications: Real-time Updates

🎯 Core Purpose

The backend serves as the central intelligence layer that connects users, their fashion preferences, wardrobe items, outfit recommendations, social interactions, and e-commerce functionality.

💡 Mission: Provide intelligent, personalized fashion recommendations powered by AI and user data.

Core Architecture

🔄 Request Flow Through the System

1

Client Request

Frontend sends HTTP request with JWT token

2

URL Router

Django routes request to appropriate view based on URL pattern

3

Authentication

JWT middleware validates token and identifies user

4

View Processing

API view receives request, validates permissions

5

Serializer Validation

Request data validated against serializer rules

6

Business Logic

View executes business logic, interacts with models

7

Database Operations

Create/Read/Update/Delete operations on database

8

Response Serialization

Data serialized to JSON format

9

JSON Response

Formatted response sent back to client

Data Models & Relationships

👤 User

Central Entity

↓ OneToOne Relationships

👤 UserProfile

Personal info, body measurements

1:1

🎨 StylePreference

Fashion preferences, budget

1:1

👔 Wardrobe

Personal clothing inventory

1:1

🛒 ShoppingCart

E-commerce cart

1:1
↓ OneToMany Relationships

👕 Outfit

Outfit recommendations

1:N

📸 Post

Social media posts

1:N

📚 Lookbook

Curated collections

1:N

🔔 Notification

User notifications

1:N

Relationship Legend

OneToOne: Single related record
OneToMany: Multiple related records
Solid Line: Direct relationship
Dashed Line: OneToMany relationship

Key Relationship Types

  • OneToOne: User → Profile, User → Wardrobe, User → Cart
  • OneToMany: User → Outfits, Outfit → Items, Post → Images
  • ManyToMany: User ↔ User (Following), User ↔ Outfit (Likes/Saves)

Authentication Flow

Registration Flow

User Submits Registration

Email, password, username, terms acceptance

Validation

Check email uniqueness, password strength, username format

Create User

User record created in database

Auto-Create Related Records

UserProfile, StylePreference, Wardrobe, ShoppingCart, NotificationPreference

Generate JWT Tokens

Access token (15 min) + Refresh token (7 days)

Return Response

User data + tokens sent to frontend

OAuth Flow (Google/Facebook)

Frontend Gets OAuth Token

User authenticates with Google/Facebook

Backend Verifies Token

Validates token with OAuth provider

Extract User Info

Email, name, picture from provider

Check if User Exists

By OAuth ID or email address

Create or Login

New user created OR existing user logged in

Generate JWT Tokens

Same token system as regular registration

Business Process Flows

Outfit Creation Flow

User Creates Outfit

Title, description, occasion, season, items

Validate Data

Serializer checks all required fields

Create Outfit Record

Outfit saved to database

Create OutfitItems

Each item in outfit saved separately

Upload Images

If provided, upload to S3 and store URLs

Update Counters

User's outfit count, public outfit count

Trigger Notifications

Notify followers of new outfit (if public)

Impact of Creating Outfit

  • Creates Outfit record linked to User
  • Creates multiple OutfitItem records
  • Makes outfit available for lookbooks
  • May trigger notifications to followers
  • Updates user's outfit statistics

Social Post Creation Flow

User Creates Post

Caption, images, tags, optional outfit link

Handle Images

Upload to S3 OR use external URLs

Create Post Record

Post saved with privacy settings

Link to Outfit (if provided)

Post.outfit references Outfit

Process Tags

Extract hashtags, store in tags field

Create Notifications

Notify followers of new post

Update Feed

Post appears in followers' feeds

Impact of Creating Post

  • Creates Post record with images
  • Links to Outfit (if provided)
  • Appears in followers' feeds
  • Triggers notifications
  • Updates engagement counters

Shopping Cart Flow

User Adds Item

Selects outfit item, size, quantity

Get or Create Cart

One cart per user (OneToOne)

Check if Item Exists

Same outfit_item_id + size already in cart?

Update or Create

Update quantity OR create new CartItem

Cache Product Details

Store name, price, image in CartItem

Calculate Totals

Subtotal + Shipping + Tax - Discount

Return Updated Cart

Cart with all items and totals

System Interconnections

User → Outfit → Lookbook Chain

User creates Outfit ↓ Outfit can be added to Lookbook ↓ Lookbook can reference multiple Outfits ↓ Outfit can be in multiple Lookbooks ↓ When Outfit deleted: - LookbookOutfit links removed - Lookbook remains (may be empty)

Post → Outfit Connection

User creates Post ↓ Can link to existing Outfit ↓ Post.outfit → Outfit (ForeignKey) ↓ Outfit.posts → Related Posts (reverse) ↓ When viewing Outfit: - Can see related Posts - Shows outfit in social context

Wardrobe → Outfit Relationship

User has WardrobeItems ↓ When creating Outfit: - Can reference WardrobeItems - OutfitItems can link to WardrobeItems ↓ When marking item as worn: - Creates WardrobeItemWearLog - Updates times_worn counter - Updates last_worn_date

Social Interactions Cascade

User A likes User B's Post ↓ Creates PostLike record ↓ Increments Post.likes_count ↓ Creates Notification for User B ↓ Appears in User B's notification feed ↓ If User B follows User A: - Post may appear in feed - Higher engagement visibility

Impact Analysis

What Happens When User is Deleted?

CASCADE Deletes (Automatically Removed)

  • UserProfile (OneToOne)
  • StylePreference (OneToOne)
  • Wardrobe → All WardrobeItems
  • All Outfits → All OutfitItems
  • All Posts → All PostImages
  • ShoppingCart → All CartItems
  • NotificationPreference (OneToOne)
  • All Likes, Saves, Follows

What Happens When Outfit is Deleted?

Automatic Removals

  • All OutfitItems (CASCADE)
  • All OutfitLikes (junction table)
  • All OutfitSaves (junction table)
  • All LookbookOutfit links (removed from lookbooks)

Preserved Data

  • Posts remain (Post.outfit set to NULL)
  • Lookbooks remain (may become empty)

Soft Delete Pattern

Some models use soft delete (is_deleted flag) instead of hard delete:

  • Post: is_deleted=True (hidden from feeds, but preserved)
  • WardrobeItem: is_deleted=True (hidden but kept for analytics)
  • Comment: is_deleted=True (hidden but preserved)

Benefits

  • Data preservation for analytics
  • Recovery capability
  • Audit trail
  • Historical data retention

Key Design Patterns

Dual Image Storage

All models support both file upload and external URLs:

  • ImageField: File upload to S3/local
  • image_url: External URL (Unsplash, CDN)
  • Priority: image_url first, fallback to ImageField

Counter Cache

Store counts in parent model for performance:

  • Outfit.likes_count
  • Post.comments_count
  • Lookbook.likes_count
  • Updated when likes/saves created/deleted

Junction Tables

Many-to-many via explicit tables:

  • OutfitLike (User ↔ Outfit)
  • PostLike (User ↔ Post)
  • UserFollowing (User ↔ User)
  • Stores metadata (created_at)

Auto-Creation Pattern

Related records created automatically:

  • User → Profile, Preferences, Wardrobe
  • Wardrobe → Created when first item added
  • Cart → Created when first item added
  • Ensures data consistency

💡 Summary

The CuratorAI backend is a complex, interconnected system where User is the central entity. Everything connects to User through various relationship types. Understanding these relationships and flows is crucial for debugging, adding features, optimizing performance, and maintaining data integrity.

Key takeaways: Cascading relationships ensure data consistency, soft deletes preserve important data, counter caches optimize performance, and the dual image storage pattern provides flexibility.