DEV Community

sneh1117
sneh1117

Posted on • Edited on

I Wanted to Go Beyond "Todo App" — So I Built This Instead

I wanted to go beyond a basic CRUD app.

So I built StitchTales — a full-stack blogging platform designed for creators to publish tutorials and stories, complete with authentication, REST APIs, image storage, visitor analytics, and production deployment.

🔗 Live: https://stitchtales.onrender.com/
🔗 GitHub: https://github.com/sneh1117/stitchtales


🏗 Tech Stack

  • Django 5.2
  • Django REST Framework
  • PostgreSQL (Railway)
  • Supabase Storage (custom backend)
  • HTMX
  • Whitenoise
  • django-allauth
  • Token + session + OAuth authentication

✨ What It Supports

  • Full blog CRUD with draft → publish workflow
  • Slug-based URLs + SEO fields
  • Categories, tags, view tracking
  • Comment moderation + like system (HTMX)
  • Profile system with avatars + social links
  • Google OAuth — login and register via Google account
  • Post-OAuth profile completion flow (username + avatar + bio)
  • Custom visitor analytics — unique visitors, top countries, referrers
  • Public REST API with permission control
  • Production-ready deployment on Railway

🔌 API Design

GET    /api/posts/
GET    /api/posts/<slug>/
POST   /api/posts/
PUT    /api/posts/<slug>/
DELETE /api/posts/<slug>/
POST   /api/auth/token/
Enter fullscreen mode Exit fullscreen mode

Design decisions:

  • Public read access
  • Authenticated write access
  • Author-only updates/deletes
  • Slug-based lookups instead of IDs
  • Pagination enabled

🖼 Why Supabase Instead of S3?

Instead of AWS, I built a custom Django storage backend for Supabase.

This required:

  • Understanding Django's storage API
  • Handling server-side uploads securely
  • Generating public CDN URLs
  • Structuring bucket organization cleanly

It kept the stack simple while still being production-capable.


⚡ Why HTMX Instead of React?

I intentionally avoided a heavy frontend framework.

HTMX gave me:

  • Dynamic likes without reload
  • Cleaner backend focus
  • Simpler architecture
  • Faster development

Right tool for the project size.


🔐 Google OAuth — Beyond Basic Auth

After shipping the core platform I added Google OAuth using django-allauth.

This wasn't just dropping in a library. It required:

  • Configuring OAuth credentials in Google Cloud Console
  • Handling the redirect_uri_mismatch between local and production environments
  • Overriding allauth's default signup template to match the site's theme
  • Building a custom "Complete Your Profile" flow — after Google consent, new users pick a username, upload an avatar, and add a bio before landing on the site
  • Auto-connecting existing email accounts to Google via SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT
  • Forcing the account picker on every login with prompt: select_account
  • Fixing the https vs http callback mismatch in production using ACCOUNT_DEFAULT_HTTP_PROTOCOL

The result is a smooth 3-step flow: click Google → consent screen → profile setup → home.


📊 Custom Visitor Analytics

I built a lightweight analytics system entirely in Django — no third-party tools.

How it works:

  • A custom middleware (VisitorTrackingMiddleware) intercepts every GET request
  • It records IP, path, referrer, and uses a free geolocation API to resolve country + city
  • Staff visits and excluded IPs are automatically filtered out
  • Data is stored in a Visitor model and surfaced in the admin + dashboard

What the superuser dashboard shows:

  • Total visits and unique visitors
  • Visits today
  • Top countries by traffic
  • Top referrers (how people find the site)
  • Most visited pages

This gave me real insight into traffic without handing data to Google Analytics.


🧠 Production Considerations

  • Environment-based configuration via python-decouple
  • SQLite locally, PostgreSQL in production
  • CSRF + trusted origins configured
  • DEBUG=False in production
  • Whitenoise for static files
  • collectstatic runs automatically on every Railway deploy
  • Sitemap + robots.txt for SEO
  • Site domain auto-configured on each deploy via Railway start command

I treated it like a real deployment — not just a localhost demo.


🚀 What I'd Add Next

  • Automated tests
  • CI/CD pipeline
  • Redis caching
  • Rate limiting
  • Structured logging
  • Email notifications for comments

🎯 Why This Project Matters

This wasn't about crochet.

It was about demonstrating:

  • Clean backend architecture
  • Thoughtful API design
  • External storage integration
  • Third-party OAuth integration in production
  • Custom middleware and analytics without external dependencies
  • Production deployment awareness
  • Full-stack decision-making under real constraints

If you're hiring for a backend or full-stack role, I'd love feedback.

— Sneha

Top comments (0)