Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
••••
Reverse EngineeringReverse-engineered 8BitDo firmware encryption(27.09.2026 um 01:18 Uhr)
••••
Sichere ProgrammierungHow Hindsight Turned Deployment #1017 Into the Fix for #1057(29.09.2026 um 06:25 Uhr)
••••••
Reverse EngineeringReverse-engineered 8BitDo firmware encryption(27.09.2026 um 01:18 Uhr)
••••
Sichere ProgrammierungHow Hindsight Turned Deployment #1017 Into the Fix for #1057(29.09.2026 um 06:25 Uhr)
••
Intelligence View
⚡ tsecurity.de Intelligence

How PostGIS and DynamoDB Streams Power a Real-Time Delivery Hub Platform

Built for the H0: Hack the Zero Stack hackathon with Vercel and AWS Databases. The Problem Every year, roughly 15% of last-mile deliveries fail on the first attempt. The driver shows up, nobody's home, there's no safe drop…

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

Built for the H0: Hack the Zero Stack hackathon with Vercel and AWS Databases.






The Problem



Every year, roughly 15% of last-mile deliveries fail on the first attempt. The driver shows up, nobody's home, there's no safe drop location, or the community is gated. The carrier tries again the next day — costing $5-15 per re-attempt. Multiply that across millions of packages and the cost is staggering.



From the homeowner's side, you track a package across the country only to see "delivery attempted" — then wait days for the next attempt or drive to a pickup point.



Existing solutions like pickup lockers require the customer to go to the package. But what if instead of making you drive to a locker, a local hub held your package and delivered it to your door — on your schedule?



That's what I built.






What I Built



Hold·My·Package is a B2B SaaS platform for neighborhood delivery hubs. Local businesses (dry cleaners, convenience stores, co-working spaces) operate as hubs. When a carrier can't deliver, the package routes to the nearest hub. The hub holds it and redelivers when the homeowner is actually home.



The platform has four portals:





  • Hub Operators — intake packages, dispatch geo-optimized batches, track analytics


  • Homeowners — schedule redelivery, get real-time notifications


  • Carriers — see rerouting stats and cost savings


  • Network Admins — monitor multiple hubs across a city



The stack: Next.js on Vercel (frontend + API), Aurora PostgreSQL Serverless v2 (PostGIS, Row-Level Security, materialized views), DynamoDB (single-table design, Streams, conditional writes), Lambda, and Pusher for real-time push.






Why Two Databases?



The two databases solve genuinely different problems that would be painful to force into one system.



Aurora PostgreSQL is the source of truth. Users, packages, hubs, delivery schedules, spatial data, analytics — all relational and all benefiting from PostgreSQL's extension ecosystem. PostGIS gives me spatial intelligence at the query layer. Row-Level Security gives me tenant isolation at the database layer. Materialized views give me pre-computed analytics.



DynamoDB handles the event stream. Every status change — package received, scheduled, dispatched, delivered — writes an event. These events need to be queried four different ways (package timeline, homeowner feed, hub live view, carrier report), written at high throughput, and automatically trigger real-time notifications. DynamoDB's single-table design with GSIs, Streams integration, and TTL makes this natural.



The split is clean: Aurora owns state, DynamoDB owns events.






PostGIS: Database-Layer Delivery Intelligence



Three spatial operations power the core product logic — all running as SQL queries, not application code.






Nearest-Hub Routing



When a carrier reports a failed delivery, the system needs to find the closest hub with available capacity:




SELECT id, name,
ST_Distance(location, ST_MakePoint(-104.99, 39.74)::geography) as distance_m
FROM hubs
WHERE ST_DWithin(location, ST_MakePoint(-104.99, 39.74)::geography, coverage_radius_m)
AND current_load < capacity
ORDER BY distance_m
LIMIT 1;






One query. The database handles distance calculation, coverage boundary enforcement, and capacity filtering together.






Batch Delivery Clustering



This is the feature that makes hub operators efficient. When it's time to dispatch, the system groups nearby deliveries into batches:




SELECT
ST_ClusterDBSCAN(p.delivery_address::geometry, eps := 500, minpoints := 2) OVER() as cluster_id,
p.id, p.tracking_number, hp.address
FROM packages p
JOIN delivery_schedules ds ON ds.package_id = p.id
JOIN homeowner_profiles hp ON hp.id = p.homeowner_id
WHERE p.hub_id = $1 AND p.status = 'scheduled'
AND ds.scheduled_window_start BETWEEN $2 AND $3;






ST_ClusterDBSCAN finds packages within 500 meters of each other and groups them. The operator sees "3 packages on Market St — one batch, one trip" without any external optimization service. The database is the intelligence layer.






Coverage Enforcement



Homeowner onboarding uses ST_DWithin to discover which hubs cover their address. The carrier webhook uses the same query to auto-route failed deliveries. One spatial primitive, multiple use cases.






DynamoDB: Single-Table Design for Four Access Patterns



One table. Composite keys. Three Global Secondary Indexes. Four completely different query patterns served efficiently.






Key Structure






PK: PKG#{package_id}
SK: EVENT#{timestamp}#{event_type}

GSI1 (HomeownerFeed): homeowner_id + timestamp
GSI2 (HubFeed): hub_id + timestamp
GSI3 (CarrierDaily): carrier#date + timestamp






Query the main table → full event timeline for a specific package.

Query GSI1 → homeowner's activity feed across all their packages.

Query GSI2 → hub operator's live view of everything happening at their hub.

Query GSI3 → carrier's daily report of all packages they routed.





Conditional Writes



Status transitions use conditional writes to prevent conflicts:




ConditionExpression: 'attribute_not_exists(PK) AND attribute_not_exists(SK)'






If two requests try to write the same event simultaneously, one succeeds and one gets a ConditionalCheckFailedException. No distributed locks needed. The application handles the conflict gracefully.






TTL



Every event gets a TTL set to 90 days from creation. DynamoDB automatically deletes expired items. Built-in lifecycle management without cron jobs.






The Real-Time Pipeline



This is where the two databases work together. Aurora handles the status transition (optimistic locking on a version column). The same API call writes the event to DynamoDB. Then the magic:




DynamoDB write → Stream (automatic) → Lambda → Pusher → All connected clients









Lambda Function



Zero npm dependencies. 5KB of code. Reads Pusher credentials from environment variables and signs requests using native Node.js crypto. It:




  1. Receives DynamoDB Stream records (batch of up to 10)

  2. Extracts event data (package_id, status, homeowner, hub, carrier)

  3. Determines which channels need the event (hub-{id}, homeowner-{id}, carrier-{name})

  4. Publishes to Pusher REST API in batches






Frontend Integration



React components subscribe to their relevant Pusher channel on mount. When an event arrives:




  • Dashboard metric cards update without refetch

  • Toast notification appears ("Your package is on its way!")

  • Event feed prepends the new event with a slide-in animation

  • Notification badge increments



The operator intakes a package → the homeowner sees it appear in their portal within 2 seconds. No refresh button. No polling. The architecture makes real-time the default behavior.






Lessons Learned



A few things that weren't obvious going in:



Aurora Data API can't serialize geography columns. SELECT * from a table with PostGIS geography columns throws UnsupportedResultException. The fix: use ST_Y(location::geometry) and ST_X(location::geometry) to extract lat/lng as floats instead of returning the raw geography value.



RLS with Data API requires transactions. SET LOCAL app.current_user_id doesn't persist between separate Data API calls. You need to wrap it in a transaction: BEGIN → set_config(...) → your query → COMMIT. Otherwise RLS policies silently do nothing.



Advisory locks prevent scheduling race conditions. Two homeowners booking the last delivery slot simultaneously? pg_advisory_xact_lock(hashtext(hub_id || slot_hour)) serializes the capacity check + insert within a transaction. The lock auto-releases on commit.



DynamoDB conditional write failures aren't errors. If a duplicate event write fails, that's fine — the event already exists. Log it, don't retry, don't block the response. Aurora is the source of truth for status; DynamoDB is the notification layer.






Check out



View demo on Youtube →



Or View on Devpost project →



#H0Hackathon

2. Cyber Threat Intelligence & Forensik

CTI Threat Relationship Graph2 Knoten / 1 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten How PostGIS and DynamoDB Streams Power a Real-Time Delivery Hub Platform

Thematisch verwandte Begriffe: PostGIS, DynamoDB, Streams, Power · 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 ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-102367 | mall4j through 4.0 contains an insufficient session expiration vulnerab…
Advisory →
tsecurity.de Icon
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