Database Architecture & Connection Guide

Version 1.0 | June 2026

1. Overview

The current AARIVON website is a static HTML site. While this works well for displaying information, adding dynamic features requires a database. This guide outlines the database architecture needed to power dynamic features such as:

  • Student Login System - Secure authentication for enrolled students
  • Course Management - Dynamic course listings, enrollment, and updates
  • Testimonials - Store and manage student testimonials in a database
  • Application Forms - Collect and manage course applications
  • Contact Submissions - Store and track contact form submissions

Goal: Transition from a static HTML website to a dynamic, database-driven web application while maintaining the existing design and user experience.

2. Recommended Tech Stack

Based on AARIVON's needs as an educational platform, we recommend the following database technologies:

1 PostgreSQL (Primary Recommendation)

PostgreSQL is a powerful, open-source relational database. It is reliable, well-documented, and ideal for structured data like student records, courses, and applications.

  • Pros: ACID compliance, complex queries, excellent performance, free
  • Cons: Requires setup and maintenance on a server
  • Best for: Full control over your database infrastructure

2 Supabase (Recommended for Startups)

Supabase is a managed PostgreSQL service that includes authentication, real-time updates, and an auto-generated REST API. This is our top recommendation for AARIVON.

  • Pros: Free tier available, instant REST API, built-in auth, easy to set up
  • Cons: Less control than self-hosted PostgreSQL
  • Best for: Fast development, low maintenance, startups
  • Free tier includes: 500MB database, unlimited API requests, up to 50,000 monthly active users

3 MongoDB (Alternative)

MongoDB is a document-based NoSQL database. It offers flexibility for unstructured data but is less ideal for relational data like course enrollments.

  • Pros: Flexible schema, easy to get started
  • Cons: Less suited for relational data, eventual consistency
  • Best for: Projects with rapidly changing data structures

Our Recommendation: Start with Supabase. It gives you PostgreSQL power with zero maintenance overhead, built-in authentication, and an instant API.

3. Database Schema

The following tables define the core data structure for the AARIVON platform. Run these SQL statements in your Supabase SQL Editor or PostgreSQL console.

Users Table

Stores student and admin accounts with authentication details.

-- Users table for authentication and user management CREATE TABLE users ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, role VARCHAR(50) DEFAULT 'student', name VARCHAR(255) NOT NULL, phone VARCHAR(20), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Add index for faster email lookups during login CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_users_role ON users(role);

Courses Table

Stores all available courses with their details and pricing.

-- Courses table for course catalog CREATE TABLE courses ( id SERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, slug VARCHAR(255) UNIQUE NOT NULL, description TEXT, duration VARCHAR(100) NOT NULL, price DECIMAL(10, 2) NOT NULL, category VARCHAR(100), featured BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Insert sample courses INSERT INTO courses (title, slug, description, duration, price, category, featured) VALUES ('Full Stack Data Science', 'full-stack-data-science', 'Complete data science program from basics to advanced', '20 Weeks', 29999.00, 'Data Science', TRUE), ('Cloud Computing with AWS', 'cloud-computing-aws', 'Master AWS cloud services and infrastructure', '16 Weeks', 24999.00, 'Cloud', FALSE);

Testimonials Table

Stores student testimonials and success stories.

-- Testimonials table for student reviews CREATE TABLE testimonials ( id SERIAL PRIMARY KEY, student_name VARCHAR(255) NOT NULL, role VARCHAR(255), company VARCHAR(255), salary VARCHAR(50), quote TEXT NOT NULL, avatar_initials VARCHAR(5) DEFAULT 'AA', active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Insert sample testimonial INSERT INTO testimonials (student_name, role, company, salary, quote, avatar_initials) VALUES ('Rahul Sharma', 'Data Analyst', 'Infosys', '8.5 LPA', 'AARIVON completely transformed my career. The hands-on training helped me land my dream job.', 'RS');

Team Members Table

Stores team member profiles displayed on the About page.

-- Team members table for staff profiles CREATE TABLE team_members ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, role VARCHAR(255) NOT NULL, bio TEXT, initials VARCHAR(5) DEFAULT 'AA', active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Insert sample team member INSERT INTO team_members (name, role, bio, initials) VALUES ('Aarushi Mehta', 'Lead Data Science Instructor', 'Former senior data scientist at Google with 10+ years of industry experience.', 'AM');

Applications Table

Stores student applications for courses.

-- Applications table for course enrollment requests CREATE TABLE applications ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, phone VARCHAR(20), course_interest VARCHAR(255), message TEXT, status VARCHAR(50) DEFAULT 'pending', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Status can be: 'pending', 'reviewed', 'contacted', 'enrolled', 'rejected'

Contacts Table

Stores contact form submissions from the website.

-- Contacts table for form submissions CREATE TABLE contacts ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, phone VARCHAR(20), message TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );

Complete Schema (Run All at Once)

You can copy and run all tables together in the Supabase SQL Editor:

-- ==================================================== -- AARIVON Complete Database Schema -- Run this in Supabase SQL Editor -- ==================================================== CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, role VARCHAR(50) DEFAULT 'student', name VARCHAR(255) NOT NULL, phone VARCHAR(20), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS courses ( id SERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, slug VARCHAR(255) UNIQUE NOT NULL, description TEXT, duration VARCHAR(100) NOT NULL, price DECIMAL(10, 2) NOT NULL, category VARCHAR(100), featured BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS testimonials ( id SERIAL PRIMARY KEY, student_name VARCHAR(255) NOT NULL, role VARCHAR(255), company VARCHAR(255), salary VARCHAR(50), quote TEXT NOT NULL, avatar_initials VARCHAR(5) DEFAULT 'AA', active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS team_members ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, role VARCHAR(255) NOT NULL, bio TEXT, initials VARCHAR(5) DEFAULT 'AA', active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS applications ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, phone VARCHAR(20), course_interest VARCHAR(255), message TEXT, status VARCHAR(50) DEFAULT 'pending', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS contacts ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, phone VARCHAR(20), message TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );

4. Connecting to Frontend

There are two recommended approaches for connecting the frontend to the database:

Option A: Node.js/Express REST API

Create a backend server that handles API requests from the frontend.

// server.js - Basic Express server setup const express = require('express'); const { createClient } = require('@supabase/supabase-js'); const app = express(); app.use(express.json()); // Initialize Supabase client const supabase = createClient( 'https://your-project.supabase.co', // Your Supabase URL 'your-anon-key' // Your anon/public key ); // GET all courses app.get('/api/courses', async (req, res) => { const { data, error } = await supabase .from('courses') .select('*') .eq('active', true); if (error) return res.status(500).json({ error: error.message }); res.json(data); }); // POST new contact form submission app.post('/api/contact', async (req, res) => { const { name, email, phone, message } = req.body; const { data, error } = await supabase .from('contacts') .insert([{ name, email, phone, message }]); if (error) return res.status(500).json({ error: error.message }); res.json({ success: true, message: 'Message sent successfully' }); }); app.listen(3000, () => { console.log('Server running on port 3000'); });

Option B: Next.js API Routes

If you are using Next.js for the frontend, you can create API routes directly within the framework.

// pages/api/courses.js - Next.js API route import { createClient } from '@supabase/supabase-js'; const supabase = createClient( process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY ); export default async function handler(req, res) { if (req.method === 'GET') { const { data, error } = await supabase .from('courses') .select('*'); if (error) return res.status(500).json({ error: error.message }); return res.status(200).json(data); } res.status(405).json({ message: 'Method not allowed' }); }

5. Step-by-Step Setup

Follow these steps to set up your database and connect it to the AARIVON website:

1 Create a Supabase Account

  • Go to https://supabase.com
  • Click "Start your project" and sign up with your email or GitHub account
  • Verify your email address

2 Create a New Project

  • Click "New Project" in your Supabase dashboard
  • Choose your organization (default is fine)
  • Enter a project name: AARIVON
  • Set a secure database password (save this somewhere safe)
  • Choose the region closest to your users (e.g., Mumbai for India)
  • Click "Create new project" and wait 1-2 minutes

3 Run the Schema SQL

  • In your project dashboard, click the "SQL Editor" tab on the left
  • Click "New query"
  • Copy the complete schema SQL from Section 3 above
  • Paste it into the SQL Editor
  • Click "Run" to execute all the CREATE TABLE statements
  • Verify all tables were created by checking the "Table Editor" tab

4 Get Your API Keys

  • Click the "Settings" icon (gear) in the left sidebar
  • Go to "API" in the settings menu
  • Copy the following values:
    • Project URL (e.g., https://xxxxx.supabase.co)
    • Anon/public key (starts with eyJ...)
    • Service role key (keep this secret - only for server-side use)
  • Store these in a secure location - you will need them for the frontend connection

5 Connect from the Frontend

Install the Supabase JavaScript client in your project:

# Install Supabase client library npm install @supabase/supabase-js

Then create a configuration file:

// supabase-config.js import { createClient } from '@supabase/supabase-js'; const SUPABASE_URL = 'https://your-project-url.supabase.co'; const SUPABASE_ANON_KEY = 'your-anon-key-here'; export const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);

6. Sample API Calls

Here are practical examples of fetching and sending data from the frontend using JavaScript's fetch API:

Fetch All Courses

// Get all active courses from the database async function getCourses() { const response = await fetch('https://your-project.supabase.co/rest/v1/courses?select=*&active=eq.true', { method: 'GET', headers: { 'apikey': 'your-anon-key', 'Authorization': 'Bearer your-anon-key' } }); const courses = await response.json(); console.log(courses); return courses; } // Usage getCourses().then(courses => { courses.forEach(course => { console.log(`${course.title} - Rs ${course.price}`); }); });

Submit a Contact Form

// Submit a contact form to the database async function submitContact(formData) { const response = await fetch('https://your-project.supabase.co/rest/v1/contacts', { method: 'POST', headers: { 'apikey': 'your-anon-key', 'Authorization': 'Bearer your-anon-key', 'Content-Type': 'application/json', 'Prefer': 'return=minimal' }, body: JSON.stringify({ name: formData.name, email: formData.email, phone: formData.phone, message: formData.message }) }); if (response.ok) { console.log('Contact form submitted successfully!'); return true; } else { console.error('Failed to submit contact form'); return false; } } // Usage with form data const formData = { name: 'John Doe', email: 'john@example.com', phone: '+91 98765 43210', message: 'I am interested in the Data Science course. Please contact me.' }; submitContact(formData);

Submit a Course Application

// Submit a course application async function submitApplication(applicationData) { const response = await fetch( 'https://your-project.supabase.co/rest/v1/applications', { method: 'POST', headers: { 'apikey': 'your-anon-key', 'Authorization': 'Bearer your-anon-key', 'Content-Type': 'application/json' }, body: JSON.stringify(applicationData) } ); return response.ok; } // Usage submitApplication({ name: 'Priya Patel', email: 'priya@example.com', phone: '+91 99887 76655', course_interest: 'Full Stack Data Science', message: 'I want to enroll in the upcoming batch.' });

Fetch Testimonials

// Get all active testimonials async function getTestimonials() { const response = await fetch( 'https://your-project.supabase.co/rest/v1/testimonials?select=*&active=eq.true&order=created_at.desc', { headers: { 'apikey': 'your-anon-key', 'Authorization': 'Bearer your-anon-key' } } ); return await response.json(); }

7. Migration Path

Transitioning from a static HTML site to a dynamic, database-driven application should be done in phases to minimize risk:

1 Phase 1: Forms (Week 1-2)

  • Set up Supabase project and database schema
  • Connect the contact form to store submissions in the contacts table
  • Connect the application form to store submissions in the applications table
  • Add a simple admin page to view submissions

2 Phase 2: Authentication (Week 3-4)

  • Implement Supabase Auth for student login/signup
  • Create protected routes for student dashboard
  • Add role-based access (student vs. admin)
  • Update login page to use real authentication

3 Phase 3: Content Management (Week 5-6)

  • Move courses data from HTML to the courses table
  • Move testimonials from HTML to the testimonials table
  • Move team members from HTML to the team_members table
  • Update frontend to fetch data dynamically from the database
  • Create an admin dashboard to manage content

4 Phase 4: Learning Management System (Week 7-8)

  • Add course enrollment functionality
  • Create student dashboard with enrolled courses
  • Add progress tracking
  • Implement course content delivery (videos, assignments)
  • Add certificate generation

8. Security Notes

Security is critical when working with databases and user data. Follow these guidelines:

1 Never Expose API Keys

The Supabase anon key is safe to use in frontend code. However, the service role key has admin privileges and should never be exposed in client-side code.

  • Use environment variables for API keys
  • Add .env to your .gitignore file
  • Never commit API keys to version control
# .env file - NEVER commit this to Git SUPABASE_URL=https://your-project.supabase.co SUPABASE_ANON_KEY=your-anon-key SUPABASE_SERVICE_ROLE_KEY=your-service-role-key # Server only!

2 Use Row Level Security (RLS)

Supabase provides Row Level Security (RLS) to control access at the database level. Enable RLS on all tables:

-- Enable Row Level Security on all tables ALTER TABLE users ENABLE ROW LEVEL SECURITY; ALTER TABLE courses ENABLE ROW LEVEL SECURITY; ALTER TABLE testimonials ENABLE ROW LEVEL SECURITY; ALTER TABLE applications ENABLE ROW LEVEL SECURITY; ALTER TABLE contacts ENABLE ROW LEVEL SECURITY; -- Example: Allow anyone to read courses, but only admins can write CREATE POLICY "Allow public read access" ON courses FOR SELECT USING (true); -- Example: Users can only see their own applications CREATE POLICY "Users see own applications" ON applications FOR SELECT USING (auth.uid() = user_id);

3 Validate All Inputs

Always validate user input before sending it to the database. Never trust data from the client:

// Input validation example function validateContactForm(data) { const errors = []; if (!data.name || data.name.trim().length < 2) { errors.push('Name must be at least 2 characters'); } if (!data.email || !data.email.includes('@')) { errors.push('Valid email is required'); } if (!data.message || data.message.trim().length < 10) { errors.push('Message must be at least 10 characters'); } return errors.length === 0 ? null : errors; }

4 Use HTTPS

Always serve your website over HTTPS, especially when handling login credentials and personal data:

  • Supabase provides HTTPS by default for all API calls
  • Ensure your frontend hosting also uses HTTPS
  • Never send sensitive data over unencrypted HTTP connections

5 Additional Security Checklist

  • Enable two-factor authentication (2FA) on your Supabase account
  • Regularly rotate API keys (especially service role keys)
  • Monitor database usage and set up alerts for unusual activity
  • Keep Supabase client libraries updated to the latest version
  • Use prepared statements or ORM to prevent SQL injection
  • Rate-limit API endpoints to prevent abuse
  • Log all admin actions for audit purposes

Remember: Security is not a one-time setup. Regularly review your security settings and stay updated on best practices.

This guide is maintained by the AARIVON Technical Team. Last updated: June 2026.