Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
IT Security Toolszitadel v4.18.0(22.09.2026 um 11:25 Uhr)
IT Security ToolsPodroid v1.2.9(22.09.2026 um 12:05 Uhr)
IT Security NachrichtenHow the CIA captured Carlos the Jackal(22.09.2026 um 13:00 Uhr)
Sicherheitslücken (CVE)Aikido Security Unveils Altar-1 Open-Weight AI for Cybersecurity Defense(22.09.2026 um 12:50 Uhr)
Sicherheitslücken (CVE)IT Security News Hourly Summary 2026-09-22 13h : 23 posts(22.09.2026 um 13:00 Uhr)
IT Security NachrichtenHow a Managed SOC works: What happens when a cyberattack begins?(22.09.2026 um 13:02 Uhr)
Sicherheitslücken (CVE)[UPDATE] [mittel] libxml2: Schwachstelle ermöglicht Denial of Service(22.09.2026 um 12:47 Uhr)
IT Security Toolszitadel v4.18.0(22.09.2026 um 11:25 Uhr)
IT Security ToolsPodroid v1.2.9(22.09.2026 um 12:05 Uhr)
IT Security NachrichtenHow the CIA captured Carlos the Jackal(22.09.2026 um 13:00 Uhr)
Sicherheitslücken (CVE)Aikido Security Unveils Altar-1 Open-Weight AI for Cybersecurity Defense(22.09.2026 um 12:50 Uhr)
Sicherheitslücken (CVE)IT Security News Hourly Summary 2026-09-22 13h : 23 posts(22.09.2026 um 13:00 Uhr)
IT Security NachrichtenHow a Managed SOC works: What happens when a cyberattack begins?(22.09.2026 um 13:02 Uhr)
Sicherheitslücken (CVE)[UPDATE] [mittel] libxml2: Schwachstelle ermöglicht Denial of Service(22.09.2026 um 12:47 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

How I Built a Full Stack Community Platform from Scratch - And What I Learned

A real story of building AskLoop - combining Medium + Dev.to + Stack Overflow with Django 5 + React 18 The Problem I Kept Seeing I've spent a lot of time on developer platforms. And I kept noticing the same pattern…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

A real story of building AskLoop - combining Medium + Dev.to + Stack Overflow with Django 5 + React 18









The Problem I Kept Seeing



I've spent a lot of time on developer platforms. And I kept noticing the same pattern everywhere.



You ask a question - it gets buried.

You share something valuable - it disappears in 48 hours.

A great discussion starts - nobody follows up.



There's always content. But rarely real depth.

There's always activity. But rarely meaningful interaction.



That bothered me enough to build something about it.



So I built AskLoop - a community platform that combines:




  • ✍️ Medium-style long-form articles

  • ❓ Stack Overflow-style Q&A with voting

  • 💬 Dev.to-style forum discussions



All in one place. No noise. No paywalls.



Live demo: https://askloop-here.netlify.app







What I Built



Before diving into the technical stuff, here's what the platform does:





  • 3 post types - Article, Q&A, Forum Discussion


  • Rich text editor with image upload (TipTap)


  • Nested comments with threaded replies


  • Q&A voting - upvote/downvote + accept answer


  • JWT Authentication - register, login, refresh tokens


  • User profiles - bio, social links, reputation


  • Badge system - auto-awarded at reputation milestones


  • Real-time notifications - likes, comments, follows


  • Full-text search with filters

  • Bookmarks, follows, reports


  • Account deletion with password confirmation







Tech Stack



I wanted to use tools I could actually understand and explain - not just copy-paste a boilerplate.





Backend





Django 5.0.6
Django REST Framework 3.15.2
Simple JWT (djangorestframework-simplejwt)
django-allauth + dj-rest-auth
PostgreSQL via Supabase
Gunicorn + Nginx
Whitenoise







Frontend





React 18 + TypeScript
Vite
TipTap (rich text editor)
shadcn/ui + Tailwind CSS
Axios + React Router v6
date-fns







Infrastructure





Backend → Linode (Ubuntu 22.04)
Frontend → Netlify
Database → Supabase PostgreSQL





Total cost: $5/month (just the Linode server)







Architecture Overview





Browser

https://askloop-here.netlify.app (React — Netlify)
↓ API calls (proxied through Netlify)
http://172.105.40.228/api/ (Django — Linode)

Supabase PostgreSQL





One thing I learned the hard way - Netlify is HTTPS but my Linode server is HTTP. Browsers block mixed content. The fix was proxying the API through Netlify using a _redirects file:




/api/* http://your-server-ip/api/:splat 200
/* /index.html 200






Simple. Elegant. Took me 2 hours to figure out 😅









Django REST Framework - What I Learned






Custom User Model



Always use a custom user model from day one. Changing it later is painful.




class User(AbstractUser):
bio = models.TextField(max_length=500, blank=True)
reputation = models.IntegerField(default=0)
role = models.CharField(max_length=20, choices=Role.choices)
is_banned = models.BooleanField(default=False)

# Use email as login field
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username"]









JWT Authentication



I used dj-rest-auth with Simple-JWT. The setup is straightforward but the token refresh flow took some work to get right.




# settings.py
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(hours=1),
"REFRESH_TOKEN_LIFETIME": timedelta(days=7),
"ROTATE_REFRESH_TOKENS": True,
}






On the frontend, I added an Axios interceptor that automatically refreshes the token on 401 responses:




api.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status == 401) {
// Refresh token and retry
const refresh = localStorage.getItem("refresh_token");
const res = await axios.post("/api/auth/token/refresh/",
{ refresh }
);
localStorage.setItem("access_token", res.data.access);
error.config.headers.Authorization =
`Bearer ${res.data.access}`;
return api(error.config);
}
return Promise.reject(error);
}
);









Slug-Based URLs



Posts use slugs instead of IDs for better URLs.

Auto-generated from the title on save:




class Post(models.Model):
title = models.CharField(max_length=300)
slug = models.SlugField(unique=True, blank=True)

def save(self, *args, **kwargs):
if not self.slug:
base = slugify(self.title)
slug = base
n = 1
while Post.objects.filter(slug=slug).exists():
slug = f"{base}-{n}"
n += 1
self.slug = slug
super().save(*args, **kwargs)









The Badge System



Badges auto-award when a user crosses reputation milestones. The key was overriding save() on the User model so it works regardless of how reputation is updated - even through Django admin:




def save(self, *args, **kwargs):
if self.pk:
try:
old = User.objects.get(pk=pk)
rep_changed = old.reputation != self.reputation
except User.DoesNotExist:
rep_changed = False
else:
rep_changed = False

super().save(*args, **kwargs)

if rep_changed:
self._check_reputation_badges()

def _check_reputation_badge(self):
milestones = {
100: "rising_star",
500: "contributor",
1000: "expert",
5000: "legend",
}
for threshold, slug in milestones.items():
if self.reputation >= threshold:
badge = Badge.objects.get(slug=slug)
UserBadge.objects.get_or_create(
user=self, badge=badge
)









React — Interesting Challenges






The Edited Badge Problem



Django sets created_at and updated_at in two separate operations —they're never exactly equal even on first save. Difference is ~0.5ms.



My first check updated_at !== created_at was always true, so everything showed "edited".



Fix: Use 1 second tolerance:




{comment.updated_at && comment.created_at &&
(new Date(comment.updated_at).getTime() -
new Date(comment.created_at).getTime()) > 1000 && (
<span className="text-xs italic text-muted">edited</span>
)}









Load More Pagination



Django's paginated response returns next as an absolute URL like http://localhost:8000/api/posts/?page=2.



When I passed this to Axios, it double-prepended the base URL and got a 404.



Fix: Strip the origin before passing to Axios:




function relPath(url: string): string {
try {
const u = new URL(url);
return u.pathname + u.search;
// Returns: /api/posts/?page=2
} catch {
return url;
}
}

// Usage
const res = await api.get(relPath(nextUrl));









TipTap Image Alignment



TipTap's default Image extension doesn't support alignment. I built a custom FigureImage node that wraps <img> in <figure> with alignment controlled by CSS margins:




// Center: margin: 0 auto
// Left: margin-right: auto
// Right: margin-left: auto






Text-align on a block element doesn't work for images — margin-based alignment does.









Deployment — Things That Went Wrong






1. Gunicorn 203/EXEC Error



My first production deploy failed with status=203/EXEC. The unix socket path didn't exist. Fix: switched to TCP binding:




ExecStart=... gunicorn --bind 127.0.0.1:8000 ...









2. InconsistentMigrationHistory



Adding django.contrib.sites to INSTALLED_APPS after socialaccount was already migrated caused this error. Fix:




python manage.py migrate sites --fake-initial
python manage.py migrate









3. Mixed Content (HTTPS → HTTP)



Netlify frontend (HTTPS) calling Linode API (HTTP) gets blocked by browsers. Already covered above — Netlify proxy via _redirects solves it.






4. Email Confirmation Template Error



allauth tried to render an email confirmation template that didn't exist. For now:




ACCOUNT_EMAIL_VERIFICATION = "none"






Will add proper email confirmation later.









What I Would Do Differently



1. Plan the data models first



I added fields to models multiple times after the fact. Spending an extra hour designing models upfront saves days of migrations.



2. Use environment variables from day one



I hardcoded some values early and had to hunt them down later. Always use .env from the first commit.



3. Write API docs as you go



Documenting endpoints after the fact is painful. I should have maintained a simple list as I built.



4. Test on mobile early



The UI looked great on desktop but needed work on mobile. Test on real devices early and often.









The Numbers






Lines of code:  ~8,000
Time to build: ~3 months (evenings + weekends)
Server cost: $5/month (Linode)
Domain cost: $0 (using free Netlify subdomain)
Total spent: $15 so far












What's Next




  • Password reset via email

  • HTTPS on the backend server

  • OAuth (Google + GitHub login)

  • Email notifications

  • Mobile app (maybe)









Source Code Available



If you want to build something similar or just learn from the code — I've made the complete source code available:



🔗 https://samwit.gumroad.com/l/askloop-app



Includes:




  • Complete Django backend

  • Complete React frontend

  • Production deployment guide

  • Full API documentation









Try It Live



https://askloop-here.netlify.app



Create an account, write a post, ask a question. The community is just getting started — you'd be one of the first members.









Final Thoughts



Building AskLoop taught me more than any tutorial ever could.



Every bug was a real problem to solve.

Every feature was a real decision to make.

Every deployment error was a real lesson learned.



If you're thinking about building something — stop thinking and start building.



The first version will be ugly. Ship it anyway.






Questions? Drop them in the comments below — I read and respond to every one.



Follow me for more build-in-public content.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten How I Built a Full Stack Community Platform from Scratch - And What I Learned

Thematisch verwandte Begriffe: Built, Full, Stack, Community · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-94493 | A vulnerability was detected in Gigatech PDV5701 1.0.31_240305_112640. T…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick