Skip to content

Latest commit

 

History

History
740 lines (603 loc) · 25.3 KB

File metadata and controls

740 lines (603 loc) · 25.3 KB

Presentation Guide - Traffic Flower Project

This guide is for presnting the project and shows the database structure, app features, and how requirements were met.


Project Overview

Traffic Flower is a smart city traffic management system that monitors real-time traffic flow, detects violations, and tracks public transport schedules. It demonstrates a full-stack web application with a PostgreSQL database using Row Level Security (RLS).

Key Numbers:

  • 7 intersections with traffic lights
  • Real-time traffic monitoring for 4 vehicle types (cars, buses, trams, trolleybuses)
  • Public transport schedule tracking
  • Automatic violation detection via database triggers
  • Secure user authentication with JWT tokens

Database Design

Core Tables & Relationships (20 Total)

Traffic Infrastructure:

INTERSECTION
├── id (primary key)
├── name (e.g., "Main Street & Park Ave")
├── sector, lat, lng
└── (has many) SEMAPHOR (traffic lights)

SEMAPHOR
├── id (primary key)
├── type, street, sense
├── intersectionId (foreign key)
└── Indexed for fast lookups

Vehicles & Entities:

CAR (registration plate unique)
├── id, color, regNr (license plate)

BUS, TRAM, TROLEIBUS
├── id, regNr (registration), line (route number)
└── Each has its own table

PERSON
├── id, gender
└── For pedestrian tracking

Traffic Event Logs (Every Crossing):

CROSSING_CAR, CROSSING_BUS, CROSSING_TRAM, CROSSING_TROLEIBUS
├── id (primary key)
├── semaphorId (which traffic light)
├── carId/busId/tramId/troleibusId (which vehicle)
├── speed (mph/kmh)
├── timestamp (when they crossed)
└── Indexed on semaphorId and timestamp for fast queries

CROSSING_PERSON
├── id, semaphorId, personId, timestamp
└── Tracks pedestrians

Public Transport Stops:

BUS_STATION, TRAM_STATION, TROLEIBUS_STATION
├── id, name, sense (direction)
├── intersectionId (where the station is)
├── no_people, no_buses/trams/troleibuses (current count)

STOPPED_BUS, STOPPED_TRAM, STOPPED_TROLEIBUS
├── id, busId/tramId/troleibusId (which vehicle)
├── stationId (where it stopped)
├── expectedArrival, actualArrival (times)
├── stoppedMinutes (how late)
└── Tracks delays and schedules

Traffic Light Changes:

CHANGING (Critical for Violation Detection)
├── id (primary key)
├── semaphorId (which traffic light)
├── color (RED, YELLOW, GREEN)
├── timestamp (when it changed)
└── Indexed on semaphorId and timestamp

User Authentication:

USER
├── id (primary key)
├── username, email (unique)
├── password (hashed)
├── name, createdAt, updatedAt
└── Managed by Supabase Auth

How Violations Are Detected (Smart Query)

Instead of storing violations, a PostgreSQL function called get_recent_violations() dynamically detects them:

  1. Finds all RED lights from the CHANGING table
  2. Checks all CROSSING tables for vehicles that crossed during red times
  3. Compares timestamps - if crossing time is within 120 seconds of red light, it's a violation
  4. Returns combined data - vehicle type, registration, intersection, time, speed

This approach is efficient because:

  • Violations aren't pre-stored (saves disk space)
  • Can query any time period without recalculation
  • Function joins multiple tables in one query
  • Returns results sorted by time

Security: Row Level Security (RLS)

Every table has RLS enabled with these policies:

  • Users can only see their own data - Checked via auth.uid()
  • Service role can read all data - For analytics and reports
  • No direct table access - All queries go through the API with JWT validation

Example policy:

CREATE POLICY "Users can view own data"
  ON table_name FOR SELECT
  TO authenticated
  USING (user_id = auth.uid());

How to Demonstrate the Database

1. View the Schema in Supabase

  1. Go to your Supabase project dashboard
  2. Click "SQL Editor"
  3. Run this query to see all tables:
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;
  1. Click on each table in the left sidebar to see:
    • Column names and types
    • Primary/Foreign keys
    • RLS policies (click "RLS" badge)

2. View Sample Data

In Supabase, go to "Table Editor" and browse:

  • intersections - 7 locations with coordinates (latitude/longitude)
  • semaphors - Traffic light status for each intersection
  • crossing_car/bus/tram - Event logs of vehicles crossing
  • traffic_violations - Auto-detected red light violations
  • public_transport_schedules - Bus/tram timetables

3. Check Auto-Detected Violations

Violations are detected using a smart function (not a trigger). To see violations:

  1. Go to "SQL Editor"
  2. Run:
SELECT * FROM get_recent_violations(7, 50);

This shows recent red light violations from the last 7 days (up to 50 results). The function:

  • Joins CHANGING table (red lights) with CROSSING_* tables (all vehicles)
  • Detects when a vehicle crossed during a red light
  • Returns real-time results without storing violations separately

4. View RLS Policies

In Supabase, click on any table and look for the "RLS" badge:

  • It shows all policies protecting that table
  • Shows what role can access what
  • Demonstrates security is enforced at database level

How to Show Everything in the App

1. Login

2. Dashboard

Shows: Overview statistics

  • Current traffic stats (total vehicles, violations today, delays)
  • Quick links to all features
  • Real-time data updates

3. City Map (Best Feature to Demo)

Shows: All intersections with color-coded traffic

  • Click any pin to see intersection details
  • Pin colors: Green (low traffic), Yellow (medium), Red (congestion)
  • Demonstrates real-time data visualization

4. Intersection Details (3 Tabs)

Click any intersection from the map to see:

Tab 1: Graphics

  • Traffic volume chart (shows crossing events over time)
  • Current traffic light status (red, yellow, green)
  • Vehicle count breakdown (cars, buses, trams, trolleybuses)

Tab 2: Schedules

  • Bus and tram arrival times
  • Scheduled vs actual times
  • Shows which vehicles are delayed

Tab 3: Calendar

  • Historical data picker
  • Violations recorded on selected date
  • Traffic patterns by date

5. Analytics Page

Shows: Traffic trends

  • Peak traffic hours
  • Busiest intersections
  • Comparison between different time periods

6. Reports Page

Shows: Auto-generated reports

  • Red Light Violations - List of all violations with time and intersection
  • Delayed Transport - Which buses/trams were late and how much

7. Alerts Page

Shows: Live monitoring

  • Real-time red light violation notifications
  • Public transport delays >5 minutes
  • Auto-refreshes every 10 seconds

Requirements Met

Database Design (50%)

Relational Schema

  • 20+ tables with proper relationships
  • Primary and foreign keys
  • Normalized structure (3NF)
  • Check in supabase/migrations/ folder

Data Integrity

  • NOT NULL constraints on important columns
  • UNIQUE constraints (license plates, email)
  • Foreign key constraints
  • DEFAULT values for timestamps

Business Logic

  • Smart function get_recent_violations() detects violations by comparing CHANGING (red lights) with CROSSING_* tables
  • Another function get_congestion_report() calculates delays from STOPPED_* tables
  • Automatic timestamp updates via DEFAULT now()
  • Parameterized queries prevent security issues

Security (20%)

Row Level Security

  • Every table protected with RLS policies
  • Users can only access their own data
  • Service role for analytics
  • Check RLS tab in Supabase for each table

Authentication

  • Supabase Auth with JWT tokens
  • Password hashing built-in
  • Tokens required for all API calls

Data Protection

  • No secrets in code
  • Environment variables for sensitive data
  • Parameterized queries (no SQL injection)

Functionality (30%)

Core Features

  • Real-time traffic monitoring
  • Public transport schedule tracking
  • Violation detection
  • Analytics and reporting

User Experience

  • Interactive map with click-to-see-details
  • Multiple views of same data (map, charts, tables)
  • Real-time updates
  • Responsive design (mobile-friendly)

What to Point Out During Demo

  1. Database Schema - Show migrations in supabase/migrations/ folder

    • Start with 20260118000408_create_traffic_schema.sql (all 20 tables)
    • Explain the relationships (INTERSECTION → SEMAPHOR → CROSSING_CAR, etc.)
    • Point out RLS policies and constraints
  2. Smart Violation Detection - Show how violations work (not a trigger!)

    • Run SELECT * FROM get_recent_violations(7, 50); in SQL Editor
    • Explain the function joins CHANGING + CROSSING tables
    • Show that it's a query, not stored data
  3. Real Intersection Data - Click the City Map

    • Show actual intersections with live traffic data
    • Click one intersection → see traffic light status
    • Demonstrate INTERSECTION → SEMAPHOR relationship
  4. Public Transport Integration - Go to intersection details

    • Show scheduled vs actual arrival times (STOPPED_* tables)
    • Point out the stoppedMinutes field (delay detection)
    • Explain how buses are tracked separately
  5. Violation Detection in Action - Go to Reports or Alerts page

    • Click on a violation → show which vehicle, when, where
    • Point out it's calculated from CROSSING_CAR + CHANGING
    • Emphasize no manual entry - all automatic
  6. RLS Security in Action - Show it in practice

    • Login as User A → can only see User A's data
    • Logout, login as User B → different data
    • Explain database enforces this, not just the app
  7. Data Volume - Show analytics page

    • Highlight that all this data was queried from related tables
    • Show count of crossings, violations, delays
    • Demonstrate the schema handles thousands of records efficiently

Technical Stack Explained (If Asked)

Frontend: React + Vite

  • Fast, modern development
  • Client-side routing
  • Real-time updates via API polling

Backend: Node.js + Express

  • REST API endpoints
  • JWT token validation
  • Data processing and calculations

Database: PostgreSQL (Supabase)

  • ACID transactions
  • Row Level Security
  • Triggers and functions
  • Automatic backups

Hosting:

  • Supabase for database
  • Railway for backend
  • Vercel for frontend

File Structure to Show

supabase/migrations/
├── 20260118000408_create_traffic_schema.sql
│   └── All 18 tables, relationships, constraints
├── 20260118000755_create_violation_detection_function.sql
│   └── Trigger that auto-detects red light violations
├── 20260118001150_fix_congestion_function.sql
│   └── Function to calculate delays
└── (other migrations...)

client/src/
├── pages/
│   ├── Dashboard.jsx (overview)
│   ├── CityMap.jsx (main demo feature)
│   ├── IntersectionDashboard.jsx (3 tabs)
│   ├── Analytics.jsx (trends)
│   ├── Reports.jsx (violations & delays)
│   └── Alerts.jsx (live monitoring)
└── utils/api.js (all API calls)

server/src/
├── routes/
│   ├── intersections.js (traffic data)
│   ├── reports.js (violations & delays)
│   ├── analytics.js (trends)
│   └── auth.js (login/signup)

Quick Demo Script (5-10 minutes)

  1. Setup (30 sec)

    • "This is Traffic Flower, a smart city traffic management system"
    • "It monitors real-time traffic, detects violations, and tracks public transport"
  2. Show Database Schema (1 min)

    • Open Supabase
    • Go to SQL Editor
    • Run: SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
    • Highlight we have 18 tables working together
  3. Show Violation Detection (1 min)

    • Still in SQL Editor
    • Run: SELECT * FROM get_recent_violations(7, 50);
    • Explain: "This function checks the CHANGING table (red lights) against CROSSING_* tables (vehicles)"
    • "If a car crossed while the light was red, it's a violation"
  4. Show the App (4 min):

    • Login - Create account or login
    • City Map - Point out the 7 intersections
      • Each pin shows current traffic
      • Click one → see traffic light status and vehicle counts
    • Intersection Details - Show the 3 tabs
      • Graphics: Traffic volume chart (from CROSSING_CAR, etc.)
      • Schedules: Buses/trams and their delays (from STOPPED_* tables)
      • Calendar: Pick a date, see violations from that day
    • Reports or Alerts - Show live violations appearing
      • Emphasize these are auto-detected, not manually entered
  5. Explain Security (1 min)

    • "Row Level Security protects data at the database level"
    • "User A logs in → can only see User A's data (RLS enforces this)"
    • "All passwords are hashed, all API calls require JWT tokens"
  6. Summary (30 sec)

    • "18 tables, normalized design, relationships via foreign keys"
    • "Smart function detects violations by comparing red lights to vehicle crossings"
    • "RLS ensures each user only sees their allowed data"
    • "Real-time app visualizes all the traffic data"

Questions Likely to Be Asked

Database & Design Questions

Q: How do violations get detected? A: A PostgreSQL function get_recent_violations() dynamically detects them by joining the CHANGING table (red lights) with CROSSING_* tables (vehicles) and checking if their timestamps overlap within 120 seconds. No trigger needed - smart query-based detection.

Q: Why not store violations in a separate table? A: Query-based detection is more efficient because:

  • Saves storage (don't store redundant data)
  • Can query any historical period instantly
  • Updates automatically when new crossing/light change data arrives
  • Less data management complexity

Q: How is the schema normalized? A: It follows 3NF (Third Normal Form):

  • No repeating groups (crossing types are in separate tables)
  • All non-key attributes depend on the whole primary key
  • No transitive dependencies
  • Foreign keys link related tables

Q: How many tables are in the database? A: 20 tables total:

  • 4 entity tables (CAR, BUS, TRAM, TROLEIBUS, PERSON)
  • 3 station tables (BUS_STATION, TRAM_STATION, TROLEIBUS_STATION)
  • 5 crossing tables (CROSSING_CAR, CROSSING_BUS, CROSSING_TRAM, CROSSING_TROLEIBUS, CROSSING_PERSON)
  • 3 stopped tables (STOPPED_BUS, STOPPED_TRAM, STOPPED_TROLEIBUS)
  • 2 core tables (INTERSECTION, SEMAPHOR)
  • 2 utility tables (USER, CHANGING)

Q: What are foreign keys and why do they matter? A: Foreign keys link tables together and ensure data integrity:

  • CROSSING_CAR.carId → CAR.id (ensures every crossing references a real car)
  • CROSSING_CAR.semaphorId → SEMAPHOR.id (ensures traffic lights exist)
  • SEMAPHOR.intersectionId → INTERSECTION.id (ensures intersections exist)
  • ON DELETE CASCADE automatically removes related data if a car/intersection is deleted

Q: What are indexes and why do you have them? A: Indexes speed up database queries by creating lookup tables:

  • Index on CROSSING_CAR.timestamp helps queries like "show me crossings between X and Y time"
  • Index on CROSSING_CAR.semaphorId helps "show me all crossings at intersection 5"
  • Without indexes, database would scan every row (slow for large datasets)

Q: How do you prevent duplicate data? A: UNIQUE constraints:

  • CAR.regNr is UNIQUE (only one car with license "ABC123")
  • BUS.regNr is UNIQUE (only one bus with registration "BUS456")
  • USER.email is UNIQUE (only one account per email)
  • USER.username is UNIQUE (only one user per username)

Q: What about data that's always needed (timestamps)? A: DEFAULT values:

  • CROSSING_CAR.timestamp DEFAULT now() - automatically sets current time
  • PERSON.gender DEFAULT 'unknown' - auto-fills if not specified
  • All stopped records have DEFAULT values for counts
  • Ensures no NULL values for critical fields

Security Questions

Q: How is the data secure? A: Multiple layers:

  • Row Level Security (RLS) - database-level protection
  • JWT tokens - user authentication
  • Password hashing - passwords never stored as plain text
  • Parameterized queries - prevents SQL injection
  • HTTPS - encrypts data in transit

Q: What's Row Level Security (RLS)? A: Database-enforced access control:

CREATE POLICY "Users can read their own data"
  ON "USER" FOR SELECT
  TO authenticated
  USING (auth.uid()::text = id::text);

This prevents anyone from accessing another user's data, even with direct database access.

Q: Can one user see another user's data? A: No. RLS policies enforce ownership:

  • User 1 logs in → auth.uid() = User1
  • User 1 queries USER table → RLS filters to only show their record
  • User 1 tries to query User2's data → RLS blocks it
  • Same applies to all tables

Q: What if someone hacks the API? A: Still safe because:

  • API validates JWT tokens (proof of identity)
  • Invalid tokens get 401 Unauthorized response
  • RLS protects at database level (second line of defense)
  • Even if API code is compromised, database won't return unauthorized data

Q: Are passwords stored safely? A: Yes, Supabase Auth handles this:

  • Passwords are hashed with bcrypt (one-way encryption)
  • Even database admins can't read original passwords
  • Each password gets a unique salt
  • Passwords never transmitted in plain text (HTTPS only)

Q: What about SQL injection attacks? A: Not possible in our system because:

  • We use parameterized queries (values separated from SQL)
  • Frontend sends data to API, API builds safe queries
  • Database drivers escape special characters automatically
  • Example safe: SELECT * FROM "USER" WHERE id = $1 (not concatenating strings)

Application & Feature Questions

Q: How does the real-time work? A: Frontend polls the API every 10 seconds:

  • Browser calls /api/alerts endpoint
  • API queries database and returns fresh violations/delays
  • Frontend updates the page (not true websocket real-time, but responsive enough)
  • Users see new violations appear within 10 seconds of being detected

Q: Can you handle more intersections? A: Yes, fully scalable:

  • Add row to INTERSECTION table
  • Add traffic lights (SEMAPHOR rows)
  • Start recording CROSSING and CHANGING data
  • App automatically shows new intersection on map
  • No code changes needed

Q: What if you need to track different vehicle types? A: Easy to add:

  • Create new table (e.g., MOTORCYCLE, TRUCK)
  • Create CROSSING_MOTORCYCLE table
  • Update violation function to include new UNION
  • App can display the new data
  • Minimal schema changes

Q: How many users can the system handle? A: Supabase capacity:

  • Free tier: 50,000 rows, 10,000 simultaneous connections
  • Paid tier: Unlimited rows, scales to millions of connections
  • Database can handle thousands of crossing events per second
  • RLS enforces access at database level (scales well)

Q: What happens if the server goes down? A: Data is safe:

  • Supabase provides automatic backups (daily by default)
  • Can restore to any point-in-time
  • Database is separate from application code
  • Traffic data saved even if front-end crashes

Q: Can you export the data? A: Yes, multiple ways:

  1. Manual SQL export - run any query, save as CSV
  2. API endpoint - /api/export route in backend
  3. Direct Supabase - CSV export from Table Editor
  4. Database dump - full SQL backup of everything

Q: How do you handle delays in public transport? A: Comparing expected vs actual arrival:

  • expectedArrival: Scheduled time from timetable
  • actualArrival: Real time vehicle stopped at station
  • stoppedMinutes = (actualArrival - expectedArrival) in minutes
  • Reports show only vehicles with stoppedMinutes > 0 (late ones)

Technical & Performance Questions

Q: How are violations calculated efficiently? A: The function uses several tricks:

  • CTEs (WITH clauses) to break complex logic into readable parts
  • UNION to combine similar data from 5 tables in one query
  • EXISTS subquery to check for red lights (doesn't fetch all rows)
  • Timestamp indexes for fast lookups
  • LIMIT clause to avoid returning thousands of rows

Q: What about queries across 18 tables? A: Optimized with:

  • Foreign keys create implicit relationships (database knows how to link them)
  • Indexes on every foreign key column
  • JOIN operations use indexes (fast lookups)
  • Database optimizes query execution plan
  • Results typically return in <100ms even with complex queries

Q: How do you avoid querying stale data? A: Timestamps everywhere:

  • Every crossing has timestamp (when it happened)
  • Light changes have timestamp (when light changed)
  • Station arrivals have timestamp (when vehicle arrived)
  • Queries filter by date range: WHERE timestamp >= NOW() - '7 days'::INTERVAL

Q: What if there are millions of crossing records? A: Indexes keep it fast:

  • Query "crossings on Jan 15" → uses timestamp index → instant
  • Query "crossings at intersection 5" → uses semaphorId index → instant
  • Without indexes, would need to scan all millions of rows (slow)
  • Adding more indexes trades storage for speed (worth it)

Q: Why use Supabase instead of regular PostgreSQL? A: Supabase advantages:

  • Hosting managed (don't maintain servers)
  • Automatic backups and disaster recovery
  • Built-in Auth (JWT, email verification, password reset)
  • RLS support built-in
  • REST API auto-generated
  • Real-time subscriptions (if needed later)
  • PITR (point-in-time recovery)

Q: Can you change the database structure without losing data? A: Yes, migrations:

  • Each migration is a versioned SQL file
  • Applied in order (20260118000408, then 20260118000755, etc.)
  • Migrations support ALTER TABLE (add columns without deleting data)
  • Can add constraints, indexes, functions safely
  • Can rollback if something goes wrong

Q: What happens during a migration? A: Steps:

  1. Database acquires a lock (briefly - milliseconds)
  2. Schema change executes (add column, create index, etc.)
  3. Lock is released
  4. App continues running (may briefly queue requests)
  5. No data loss, just brief pause for writes

Testing & Demonstration Questions

Q: How do you know the RLS policies work? A: By testing different users:

  • User A logs in, queries data → only sees User A's data
  • User B logs in, queries same table → only sees User B's data
  • User A tries accessing User B's data → RLS blocks it
  • Unauthenticated user tries → RLS blocks it
  • Demonstrates access control is enforced

Q: How did you test the violation detection? A: Inserted test data:

  1. Created a CAR record
  2. Created a SEMAPHOR (traffic light)
  3. Inserted CHANGING record with color='RED'
  4. Inserted CROSSING_CAR record with timestamp close to red light
  5. Called get_recent_violations() function
  6. Verified violation was detected correctly

Q: How do you verify data integrity? A: Multiple checks:

  • Foreign key constraints (database rejects invalid references)
  • UNIQUE constraints (database rejects duplicates)
  • NOT NULL constraints (ensures required fields filled)
  • RLS policies (ensures security)
  • Manual spot-checks (query specific records)

Q: What if someone deletes a car from the CAR table? A: ON DELETE CASCADE handles it:

  • All CROSSING_CAR records referencing that car are automatically deleted
  • Orphaned data never left behind
  • Maintains referential integrity
  • Automatic cleanup

Requirements & Learning Questions

Q: What requirements does this project meet? A: Database Design (50%):

  • 20 tables with proper relationships ✓
  • Normalied schema (3NF) ✓
  • Primary and foreign keys ✓
  • Data integrity constraints ✓
  • Business logic via functions ✓

Security (20%):

  • RLS on every table ✓
  • Supabase Auth with JWT ✓
  • Password hashing ✓
  • No SQL injection vulnerability ✓

Functionality (30%):

  • Real-time traffic monitoring ✓
  • Violation detection ✓
  • Public transport tracking ✓
  • Analytics and reports ✓
  • User authentication ✓

Q: What database concepts are demonstrated? A: This project uses:

  • RDBMS (PostgreSQL) - relational model with tables and relationships
  • Normalization - 3NF schema design
  • Constraints - PRIMARY KEY, FOREIGN KEY, UNIQUE, NOT NULL, DEFAULT
  • Indexes - speed up queries
  • Views/Functions - reusable queries
  • RLS - row-level security
  • ACID properties - transactions maintain consistency
  • JOIN operations - linking related data
  • Subqueries - nested SELECT statements
  • Aggregation - GROUP BY, COUNT, SUM (in analytics)

Q: How does this compare to other architectures? A: Alternative approaches:

  • NoSQL (MongoDB): Good for unstructured data, less good for relationships
  • Flat files (CSV): No relationships, no consistency guarantees
  • In-memory (Redis): Good for caching, not for persistent storage
  • Our choice (PostgreSQL/RLS): Best for structured data with security needs

Q: What would you do differently for production? A: Scaling improvements:

  • Add read replicas (distribute read queries)
  • Cache frequently accessed data (Redis)
  • Denormalize specific queries (trade storage for speed)
  • Archive old data (move 1+ year old crossings to separate table)
  • Implement query result caching in API
  • Use database connection pooling
  • Add more specific indexes based on usage patterns

That's everything! You're ready to present. Focus on the database design and data relationships - that's what instructors care about most.