🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)

🔧 Programmierung 🕛 kürzlich 4 Min Lesezeit
0

Twitter Bookmark Organizer

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




How I Built a Secure REST API to Organize My Twitter Bookmarks






The Problem



My Twitter bookmark list was a graveyard. Hundreds of saved tweets — digital art, career advice, ai news — with no way to find anything. Twitter's native bookmarks have zero organization. I needed a way to save a URL, tag it, and pull it back up later. Currently, Twitter does have a folder system, but it is locked behind a pay wall.



So I built one. A backend REST API with exactly three features: store a bookmark, tag it, and filter by tag. No Chrome extension, no AI auto-tagging, no slick UI. Just a backend I could actually ship.









Schema Design Decisions



The database has two tables: users and bookmarks. The decisions behind them were deliberate.



On the users table, username is UNIQUE NOT NULL enforced at the database level — not just in the app. App-level checks can have race conditions (two requests land at the same millisecond; both pass the check; both try to insert). A UNIQUE constraint at the DB level makes that a hard stop, not a maybe.



On the bookmarks table, user_id is a foreign key with ON DELETE CASCADE. Every bookmark is owned by exactly one user. If that user is deleted, their bookmarks go with them — automatically, without needing a separate cleanup query. No orphaned rows left rotting in the database.



I also separated my two database tools intentionally. Knex handles migrations — versioned, rollbackable schema changes. pg.Pool handles all runtime queries. They look interchangeable at first glance, but they're not. Knex is for evolving the schema; the pool is for talking to it day-to-day. Mixing them causes subtle bugs that are hard to trace.









API Architecture



Five routes: POST /register, POST /login, POST /storeBookmark, GET /filterBookmarks, and GET /bookmarks. The auth and bookmark endpoints are kept separate on purpose — different middleware applies to each.



Protected routes follow a consistent middleware chain:




CODE
rateLimiter → authenticateUser → validateBookmark → handler






The order is intentional. Rate limiting runs first because it's the cheapest thing to reject — no DB call, no token verification, just check the IP and bail. Auth runs next. Validation runs last, right before the handler that does real work.



Every catch block in every route calls next(error) — never res.json(). This ensures all errors, no matter where they originate, flow through a single centralized error handler. That handler uses a custom AppError class hierarchy (AuthError, ValidationError, ConflictError) to map errors to the right HTTP status. And critically: any unrecognized 500-level error gets its internal message stripped. Clients only ever see "Internal Server Error" — never a stack trace, never a SQL query, never a file path.









The Debugging Rabbit Hole



I spent hours staring at ECONNREFUSED errors on my database connection. I checked my Supabase credentials. I regenerated the connection string. I restarted the server repeatedly. The credentials looked right in my .env file. I would go back and forth from one project to the current one just see if I typed something wrong. Nothing worked.



The fix was one line I had forgotten: dotenv.config().



dotenv reads your .env file and loads the values into process.env. But if you never call it, process.env.PG_CONNECTION_STRING is undefined when the app starts — and PostgreSQL tries to connect to nothing. The error looks exactly like a database problem. It isn't. It's an environment problem masquerading as one.



The lesson I took: when you see ECONNREFUSED, log process.env.PG_CONNECTION_STRING before you touch anything else. If it's undefined, stop — the bug isn't in your database config, it's upstream. Also, dotenv.config() must be the very first call in your entry file. Any module loaded before it that reads process.env will get undefined, even if you add the call later.









Outcome



The app is a working REST API where authenticated users can store, tag, and retrieve bookmarks. Under the hood it ships six independent security layers: parameterized SQL queries (injection prevention), async bcrypt hashing (password security), stateless JWT auth with 15-minute expiry, two-tier rate limiting (stricter on auth routes to blunt brute-force attempts), input validation with express-validator, and BOLA prevention — every bookmark query is scoped to req.user.userId so no user can read another's data.



It also has a test suite: integration tests with Jest and Supertest against a real database, plus a mock-based suite that simulates database crashes to verify the error handler works without needing a real failure.



This project covered Weeks 9–12 of my SWE roadmap: building servers, designing database schemas, layering in security, and proving correctness with tests. More importantly, it taught me that the bugs that cost the most time are rarely in the code you're focused on — they're in the invisible infrastructure surrounding it.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 42%
🟡 In Evaluierung 23%
🟢 Keine Auswirkung 18%
Spannende Innovation 17%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
GPT-6 Astra Release Today? OpenAI’s Next Major AI Model Is Almost Here
1 Quelle
Apple accuses OpenAI of destroying evidence as trade-secrets fight intensifies
1 Quelle
Major AI platforms go down in unprecedented simultaneous outage
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Twitter Bookmark Organizer

Thematisch verwandte Begriffe: Twitter, Bookmark, Organizer · 6 Treffer

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